xfuzz
本文最后更新于:2023年8月16日 晚上
cc_params传参调用execv
1 |
|
编译器 -D 选项,编译时拓展宏定义
读完 persistent mode 运行流程
1 |
|
首先在main函数之前读取共享内容,然后以当前进程为fork server,去和AFL fuzz通信。
当AFL fuzz通知进行一次fuzz,由于此时child_stopped为0,则fork server先fork出一个子进程。
这个子进程会很快执行到
__AFL_LOOP
包围的代码,因为是第一次执行loop,所以会先清空__afl_area_ptr
和设置__afl_prev_loc
为0,并向共享内存的第一个元素写一个值,然后设置循环次数1000,随后返回1,此时while(__AFL_LOOP)
满足条件,于是执行一次fuzzAPI。然后因为是while循环,会再次进入
__AFL_LOOP
里,此时将循环次数减一,变成999,然后发出信号SIGSTOP
来让当前进程暂停,因为我们设置了WUNTRACED,所以waitpid函数就会返回,fork server将继续执行。fork server在收到
SIGSTOP
信号后就知道fuzzAPI已经被成功执行结束了,就设置child_stopped为1,并告知AFL fuzz然后当AFL fuzz通知再进行一次fuzz的时候,fork server将不再需要去fork出一个新的子进程去进行fuzz,只需要恢复之前的子进程继续执行,并设置child_stopped为0
因为我们是相当于重新执行一次程序,所以将
__afl_prev_loc
设置为0,并向共享内存的第一个元素写一个值,随后直接返回1,此时while(__AFL_LOOP)
满足条件,于是执行一次fuzzAPI,然后因为是while循环,会再次进入__AFL_LOOP
里,再次减少一次循环次数变成998,并发出信号暂停。上述过程重复执行,直到第1000次执行时,先恢复执行,然后返回1,然后执行一次fuzzAPI,然后因为是while循环,会再次进入
__AFL_LOOP
里,再次减少一次循环次数变成0,此时循环次数cnt已经被减到0,就不会再发出信号暂停子进程,而是设置__afl_area_ptr
指向一个无关数组__afl_area_initial
,随后将子进程执行到结束。
这是因为程序依然会向后执行并触发到instrument,这会向__afl_area_ptr
里写值,但是此时我们其实并没有执行fuzzAPI
,我们并不想向共享内存里写值,于是将其指向一个无关数组,随意写值。同理,在deferred instrumentation模式里,在执行__afl_manual_init
之前,也是向无关数组里写值,因为我们将fork点手动设置,就代表在这个fork点之前的path我们并不关心。
重新整理一下上面的逻辑
- loop第一次执行的时候,会初始化,然后返回1,执行一次fuzzAPI,然后cnt会减到999,然后抛出信号暂停子进程。
- loop第二次执行的时候,恢复执行,清空一些值,然后返回1,执行一次fuzzAPI,然后cnt会减到998,然后抛出信号暂停子进程。
- loop第1000次执行的时候,恢复执行,清空一些值,然后返回1,执行一次fuzzAPI,然后cnt会减到0,然后就设置指向无关数组,返回0,while循环结束,程序也将执行结束。
此时fork server将不再收到SIGSTOP信号,于是child_stopped仍为0。
所以当AFL fuzz通知fork server再进行一次fuzz的时候,由于此时child_stopped为0,则fork server会先fork出一个子进程,然后后续过程和之前一样了。
涉及 编译时的 __AFL_LOOP 宏展开,以及宏内定义的 __afl_persistent_loop( ) 函数
参考:
https://eternalsakura13.com/2020/08/23/afl/
内3.3.2部分
回到 xfuzz 关系的分析
C++语法:
throw,try,catch
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!