fuzzer程序则等待forkprocess程序waitpid(forksrv_pid, &status, 0) <= 0
函数返回。
**疑问:**fuzzer程序fork了一个进程,然后这个进程execv targetBinary ,targetBinary中也启动的了fork(),相当于fuzzer程序是实际被fork程序的祖祖父进程。Fuzzer->Fuzzer forkpoc()->execv targetApp->targetApp forkpoc。然后两个之间使用pipe进行通讯?
**解答:**我本来是学Windows的,以为execv()函数类似于windows中的createprocess,但实际上完全不一样。execv()函数执行之后永远不会返回(除非出错),且运行程序会替换当前进程,pid不变。这样fuzzer先fork出来,然后再调用execv()函数,也就是说子进程成为了targetApp。这样下面的一系列代码就能说的通了。
**实际流程:**fuzzer(调用init_forkserver)->fork fueezer--targetApp(forkserver) call fork ->targetAppfork(实际fuzz的程序)。fuzzer还是实际fuzzer程序的祖父进程。这样接下来的代码就很容易理解了。
<aside> ✉️ 首先alf-fuzz会创建两个管道(init_forkserver()),然后会去执行afl-gcc编译出来的目标程序。结合之前的分析,目标程序的main函数位置已经被插桩,程序的控制流会交到_afl_maybe_log手中。如fuzz是第一次运行,则此时的程序便成为了fuzz server,之后运行的目标程序都是由该server fork出来的子进程。fuzz进行的时候,fuzz server会一直fork子进程,并且将子进程的结束状态通过pipe传递给afl-fuzz。
</aside>
<aside> ✉️ 这里有几点需要注意:afl在这里利用了fork()的特性(creates a new process by duplicating the calling process)来实现目标程序反复执行。实际的fuzz server(_afl_maybe_log)由afl事先插桩在目标程序中,在进入main函数之前,fuzz server便会fork()新的进程,进行fuzz。
</aside>