写了个脚本,根据当前传入参数,自动化生成当前整个项目的编译批处理,
执行批处理后,自动化使用clang编译整个项目,
编译完成后,即是一个包含了目标代码的Fuzz程序,双击等崩溃就好了。
我是把这个脚本集成到了VS中,所以编译完成之后,我甚至可以直接用VS来调试,
有源码的情况下,效果比较好,无源码的情况下,不如用WinDBG呢,
但是不管怎么说,总比手动一点点扯蛋强。
1 import os 2 import sys 3 import os.path 4 5 # Clang 路径 6 CLANG_PATH = "" 7 # Clang Fuzz 参数 8 FUZZER_PARAM = "-g -fsanitize=fuzzer -fsanitize=address -fsanitize-coverage=trace-cmp,trace-gep,trace-div" 9 # 中间目录 10 MIDDLE_DIR = "x64\middle" 11 if sys.argv[1] == '32': 12 MIDDLE_DIR = "x86\middle" 13 # 输出目录 14 OUT_DIR = "x64\out" 15 if sys.argv[1] == '32': 16 OUT_DIR = "x86\out" 17 # 编译需要的库,这个是写死的,编译Clang 的时候就定下来的,所以这个也是死的 18 CLANG_LIB_DIR = "E:\LLVM\LLVM\" 19 if sys.argv[1] == '32': 20 CLANG_LIB_DIR32 = "E:\LLVM\LLVM32\" 21 CLANG_LIB_DIR = CLANG_LIB_DIR32 22 CLANG_VERSION = "12.0.1\" 23 CLANG_LIB_DIR_PATH = CLANG_LIB_DIR + "lib\clang\" + CLANG_VERSION + "lib\windows\" 24 FUZZER_LIBRARY = [ 25 CLANG_LIB_DIR_PATH + "clang_rt.fuzzer_no_main-x86_64.lib", 26 CLANG_LIB_DIR_PATH + "clang_rt.fuzzer-x86_64.lib", 27 ] 28 29 # 要处理的文件 30 extend = [".c", ".cpp"] 31 32 33 def MakeDir(path_name): 34 path, name = os.path.split(path_name) 35 if os.path.exists(path): 36 pass 37 else: 38 os.makedirs(path) 39 40 41 def WalkDir(dirname): 42 global extend 43 dirlist = [] 44 filelist = [] 45 try: 46 ls = os.listdir(dirname) 47 except: 48 print("Access Deny.") 49 else: 50 for fn in ls: 51 temp = os.path.join(dirname, fn) 52 if os.path.isdir(temp): 53 dirlist.append(temp) 54 d, f = WalkDir(temp) 55 dirlist.extend(d) 56 filelist.extend(f) 57 else: 58 for ext in extend: 59 if temp.endswith(ext): 60 filelist.append(temp) 61 return dirlist, filelist 62 63 64 def GetAllSourceList(dirname): 65 dirlist, filelist = WalkDir(dirname) 66 str_file = "" 67 for file in filelist: 68 str_file = str_file + """ + file + "" " 69 return str_file 70 71 72 def WriteBuild(dirname, cmd): 73 print(cmd) 74 f = open(dirname + "/" + 'build.bat', 'w+') 75 f.write(cmd) 76 f.close() 77 78 79 def LoadAllFileInDir(file_dir, ext=None): 80 list = [] 81 for root, dirs, files in os.walk(file_dir): 82 for file in files: 83 if ext is not None and os.path.splitext(file)[1] in ext: 84 list.append(os.path.join(root, file)) 85 if ext is None: 86 list.append(os.path.join(root, file)) 87 if not ext: 88 list.append(os.path.join(root, file)) 89 if "*" in ext: 90 list.append(os.path.join(root, file)) 91 return list 92 93 94 # 参数:clang 路径,检测路径,输出路径 95 def Main(): 96 global CLANG_PATH 97 global FUZZER_PARAM 98 global MIDDLE_DIR 99 global OUT_DIR 100 101 argc = len(sys.argv) 102 # 参数 1 必须是 x86或者 x64 位数 103 # plant bit : 32 104 print("plant bit : " + sys.argv[1]) 105 106 # 参数 2 clang 路径 107 if argc >= 2: 108 CLANG_PATH = sys.argv[2] 109 # clang path : E:LLVMllvm-12.0.1.srcllvm-12.0.1.srcProjectRelWithDebInfoinclang.exe 110 print("clang path : " + CLANG_PATH) 111 if CLANG_PATH == "": 112 print("Clang Path Error") 113 return 114 115 # os.path.abspath('.') 116 # os.getcwd() 117 # 初值给一个当前文件所在的同级目录 118 dirname = os.path.dirname(os.path.abspath(sys.argv[0])) 119 # 参数2 当前要扫描的目录 120 if argc >= 3: 121 dirname = sys.argv[3] 122 # dir path : E:LLVMTestFuzzFuzzProjectEmptyProject 123 print("dir path : " + dirname) 124 125 # 如果存在就删了它 126 if os.path.exists(dirname + "/" + 'build.bat'): 127 os.remove(dirname + "/" + 'build.bat') 128 129 # str_file = GetAllSourceList(dirname) 130 131 MIDDLE_DIR = dirname + MIDDLE_DIR 132 MakeDir(MIDDLE_DIR) 133 134 OUT_DIR = dirname + OUT_DIR 135 MakeDir(OUT_DIR) 136 137 files = LoadAllFileInDir(dirname, extend) 138 139 write_file = "" 140 object_array = [] 141 for file in files: 142 file_path = file[len(dirname):] 143 object_name = MIDDLE_DIR + "\" + file_path + ".o" 144 MakeDir(object_name) 145 cmd = CLANG_PATH + " " + FUZZER_PARAM + " -c " + file + " -o " + object_name 146 write_file = write_file + cmd + " " 147 object_array.append(object_name) 148 149 string_command = CLANG_PATH 150 string_command = string_command + " " + FUZZER_PARAM 151 global FUZZER_LIBRARY 152 for library in FUZZER_LIBRARY: 153 string_command = string_command + " -L" + library 154 155 for object in object_array: 156 string_command = string_command + " " + object 157 158 MakeDir(OUT_DIR + "\FuzzMain.exe") 159 print("Out File : " + OUT_DIR + "\FuzzMain.exe") 160 string_command = string_command + " -o " + OUT_DIR + "\FuzzMain.exe" 161 162 write_file = write_file + string_command + " " 163 WriteBuild(dirname, write_file) 164 165 166 if __name__ == "__main__": 167 Main()