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

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

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

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

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

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

afl 源码分析 ->>afl-as.c 这里是在合适的地方插桩,比如函数头。

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

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

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

 

然后具体看一下 afl_maybe_log

 

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

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

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

afl 源码分析 ->>afl-as.c 0xc6就是读fd  0xc7 就是写fd  先写到0xc7 通知server 已经初始化完毕,然后读取0xc6  告知可以运行targer    就当成了server  对target 就 一直fork 然后等待子进程  运行结束,然后将子进程的状态传给 fuzz 程序。

子程序就 关闭fd

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

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

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

prelocation 代表的是上一个id/2 

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

相关文章: