afl-fuzz的qemu模式中如何去判断是否crash

1. afl-fuzz部分

afl-fuzz部分和非qemu模式是相同的,主要是通过管道接收来自forkserver传入的status信息,通过status信息来判断是否存在crash

  if (unlikely(
          /* A normal crash/abort */
          (WIFSIGNALED(fsrv->child_status)) ||
          /* special handling for msan and lsan */
          (fsrv->uses_asan &&
           (WEXITSTATUS(fsrv->child_status) == MSAN_ERROR ||
            WEXITSTATUS(fsrv->child_status) == LSAN_ERROR)) ||
          /* the custom crash_exitcode was returned by the target */
          (fsrv->uses_crash_exitcode &&
           WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) {

主要是通过这一段判断,如果是crash,child_status的某些值会显示signal的值

2. qemu部分

在cpu-exec.c的afl_forkserver函数中,

    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);

    /* Collect translation requests until child dies and closes the pipe. */

    afl_wait_tsl(cpu, t_fd[0]);
    if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0) {
      printf("waitpid failed with errno: %d (%s)\n", errno, strerror(errno));
      exit(6);
      
    }

    /* In persistent mode, the child stops itself with SIGSTOP to indicate
       a successful run. In this case, we want to wake it up without forking
       again. */

    if (WIFSTOPPED(status))
      child_stopped = 1;
    else if (unlikely(first_run && is_persistent)) {

      fprintf(stderr, "[AFL] ERROR: no persistent iteration executed\n");
      exit(12);  // Persistent is wrong

    }

    first_run = 0;

    if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);

afl_wait_tsl函数return后,waitpid这里去获取子进程的状态,通过wait子进程使其退出,将子进程状态存入status变量,并返回pid,最后write写回管道关于status的值。

posted @ 2024-10-01 17:30  卧龙丹心  阅读(91)  评论(0)    收藏  举报