IMF源码阅读

现在的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.

你可能感兴趣的:(IMF源码阅读)