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程序的祖父进程。这样接下来的代码就很容易理解了。

https://bbs.pediy.com/upload/attach/201909/760932_S4K5TSQ8M643XMM.png

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/156a7778-53d4-4439-bd1b-4281f073627f/Untitled.png

<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>