afl 源码分析 ->>afl-as.c

分析一下插桩代码。 有源码根据gcc提供的信息就可以插桩,无源码就需要了dynamo。。

afl 源码分析 ->>afl-as.c_第1张图片

 这个AFL_USE_ASAN  afl的回显就是用的asan,asan的话,栈是和gs 差不多,然后有函数调用监控,还有危险函数的hook。并且会重写堆的数据结构。

然后 重点函数就是add_instrumentation, 他有一个while 循环每行的读汇编代码,

afl 源码分析 ->>afl-as.c_第2张图片

如果是跳转,那么就直接插桩,

afl 源码分析 ->>afl-as.c_第3张图片 这里是在合适的地方插桩,比如函数头。

来看一下经过gcc编译插桩后的结果

afl 源码分析 ->>afl-as.c_第4张图片

afl 源码分析 ->>afl-as.c_第5张图片

 

然后具体看一下 afl_maybe_log

 

afl 源码分析 ->>afl-as.c_第6张图片 如果没有保存共享空间,那么就是第一次运行 afl_maybe_log 那么这个程序就是 fork server

afl 源码分析 ->>afl-as.c_第7张图片

获取共享内存并且映射到自己的进程内存空间

afl 源码分析 ->>afl-as.c_第8张图片 0xc6就是读fd  0xc7 就是写fd  先写到0xc7 通知server 已经初始化完毕。,然后读取0xc6  告知可以运行targer    就当成了server  对target 就 一直fork 然后等待子进程  运行结束,然后将子进程的状态传给 fuzz 程序。(0xc6(控制队列)和0xc7(状态队列)与fuzzer进程通信)

子程序就 关闭fd

afl 源码分析 ->>afl-as.c_第9张图片

然后进行了共享内存的读写

这个进行读写也是挺有意思的 _afl_prev_loc   这个a2就是传入的参数,他这个是代表的程序块的id 这个值是随机的

prelocation 代表的是上一个id/2 

这样做的原因是  假设target中存在A->AB->B这样两个跳转,如果不右移,那么这两个分支对应的异或后的key都是0,从而无法区分;另一个例子是A->BB->A,如果不右移,这两个分支对应的异或后的key也是相同的。为了防止这样就移位了。

你可能感兴趣的:(fuzz)