现在的IMF只适用于mac系统,应该是API_DEFS中的api都属于mac系统,如果要测试新的系统应该需要改动这个数组。
以下是根据github上使用步骤的顺序进行源代码阅读。
1.Generate hooking library for APIs
$ ./gen-hook [output(hooking code) path]
$ clang -Wall -dynamiclib -framework IOKit -framework CoreFoundation -arch i386 -arch x86_64 hook.c -o hook
gen-hook脚本把命令行的所有参数传入hook.py,实际上就是调用hook.py
hook.py里首先判断参数是否为空,如果不为空则创建一个Hooker类并调用其gen_hook()函数
Hooker类的__init__()函数:调用了basic.load_apis(),这个函数返回了apis{},把const.API_DEFS里面的apis存到apis{}中,每个api用Api类存储。const.API_DEFS是一个数组,每个元素代表一个api,记为data的话,data[0]为rtype和name(用,分开),data[1]为参数数组,每个参数是一个元组,元组的第一个元素是类型,第二个元素是名字,第三个元素没有明白。
gen_hook()函数:遍历apis,调用ApiHook(api)对每个api进行插桩,把code写到文件f里,文件f就是[output(hooking code) path]。code具体内容还没有懂。
hook.py到此结束。
2.Collect logs
$ DYLD_INSERT_LIBRARIES=[hooking library path] [program path] [program args]
这一步还没看明白做了什么操作,DYLD_INSERT_LIBRARIES是一个动态hook库?
3.Filter logs
$ ./filter-log [log dir] [output dir] [# of output(filtered log)] [# of core]
filter-log脚本把命令行参数传给filter.py,并用pypy运行filter.py。参数1为log文件夹路径,参数2为output文件夹路径,参数3为?,参数4为core?。
filter.py首先把参数3存到n,把参数4存到core,然后调用do_filter()函数。
do_filter(log_path, out_path, n, core)函数首先调用list_dir(log_path),把返回的files数组存到log_names,files数组里是log_path路径里的所有文件路径;然后调用utils.multiproc(loader, log_names, core)函数(utils.py是自己实现的,用了multiprocessing中的Pool),返回logs,这一步我猜是多核多线程地运行loader,loader()类的作用是对每个文件,按行读取存到data中然后提取name、selector,依次存到数组ret中并返回ret,name和selector具体是什么内容还没有仔细研究,而且多个线程中的ret是怎么连接成一个logs的?;然后调用find_best([logs], n),返回最佳group和idx,其中调用了categorize()函数和pick_best()函数,这一步不明白;最后save_best(),写到out_path(即第二个参数)里。
我猜这一步是从logs中选择“最佳的”n个logs。
4.Infer a model and generate a fuzzer.
$ ./gen-fuzz [filtered logs path] [output(fuzzer code) path] [# of core]
gen-fuzz脚本把命令行参数传给apifuzz.py,并用pypy运行apifuzz.py。
apifuzz.py首先创建一个ApiFuzz类记为fuzz,数组logs存放参数1里的文件路径,调用get_limit(logs)函数(这个函数的作用还没搞清),最后调用make_model(logs, limit, sys.argv[2], core)函数。
make_model函数调用了utils.multiproc()函数,在这个函数中多线程地跑load_apilog()函数(这个函数的作用也还没搞清),返回值存在apilogs中,然后创建了model类,调用model.fuzz()函数,把code写到文件中。
model这个类还没有看。
我猜这一步是生成用于fuzz的model的c文件。
5.Compile the fuzzer
$ clang -framework IOKit -framework CoreFoundation -arch i386 fuzz.c -o fuzz
我猜这一步是用clang编译上一步得到的c文件。
6.Run the fuzzer
$ ./fuzz -f [log path] -s [seed] -b [bitlen] -r [rate] -l [# of max loops]
这一步就是fuzzing了。
7.You may want to run the generated fuzzer within a while loop.
网友评论