一、源码
 
1.信号处理函数
 
static void handle_stop_sig(int sig) {
  stop_soon = 1; 
  if (child_pid > 0) kill(child_pid, SIGKILL);
  if (forksrv_pid > 0) kill(forksrv_pid, SIGKILL);
}
static void handle_skipreq(int sig) {
  skip_requested = 1;
}
static void handle_timeout(int sig) {
  if (child_pid > 0) {
    child_timed_out = 1; 
    kill(child_pid, SIGKILL);
  } else if (child_pid == -1 && forksrv_pid > 0) {
    child_timed_out = 1; 
    kill(forksrv_pid, SIGKILL);
  }
}
static void handle_resize(int sig) {
  clear_screen = 1;
}
* Set up signal handlers. More complicated that needs to be, because libc on
   Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call
   siginterrupt(), and does other unnecessary things. */
EXP_ST void setup_signal_handlers(void) {
  struct sigaction sa;
  sa.sa_handler   = NULL;
  sa.sa_flags     = SA_RESTART; 
  sa.sa_sigaction = NULL;
  sigemptyset(&sa.sa_mask);
  
  sa.sa_handler = handle_stop_sig;
  sigaction(SIGHUP, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);
  sigaction(SIGTERM, &sa, NULL);
  
  sa.sa_handler = handle_timeout;
  sigaction(SIGALRM, &sa, NULL);
  
  sa.sa_handler = handle_resize;
  sigaction(SIGWINCH, &sa, NULL);
  
  sa.sa_handler = handle_skipreq;
  sigaction(SIGUSR1, &sa, NULL);
  
  sa.sa_handler = SIG_IGN;
  sigaction(SIGTSTP, &sa, NULL);
  sigaction(SIGPIPE, &sa, NULL);
}
 
2.check_asan_opts(检查内存错误)
 
static void check_asan_opts(void) {
  u8* x = getenv("ASAN_OPTIONS");
  if (x) {
    if (!strstr(x, "abort_on_error=1")) 
      FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!");
    if (!strstr(x, "symbolize=0"))
      FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!");
  }
  x = getenv("MSAN_OPTIONS");
  if (x) {
    if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR)))
      FATAL("Custom MSAN_OPTIONS set without exit_code="
            STRINGIFY(MSAN_ERROR) " - please fix!");
    if (!strstr(x, "symbolize=0"))
      FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
  }
} 
 
3.fix_up_sync(检查ID、sync_id是否过长,检查互斥)
 
static void fix_up_sync(void) {
  u8* x = sync_id;
  if (dumb_mode)
    FATAL("-S / -M and -n are mutually exclusive");
  if (skip_deterministic) {
    if (force_deterministic)
      FATAL("use -S instead of -M -d");
    else
      FATAL("-S already implies -d");
  }
  while (*x) {
    if (!isalnum(*x) && *x != '_' && *x != '-')
      FATAL("Non-alphanumeric fuzzer ID specified via -S or -M");
    x++;
  }
  if (strlen(sync_id) > 32)
   FATAL("Fuzzer ID too long");
  x = alloc_printf("%s/%s", out_dir, sync_id);
  sync_dir = out_dir;
  out_dir  = x;
  if (!force_deterministic) {
    skip_deterministic = 1;
    use_splicing = 1;
  }
}
 
4.save_cmdline(将当前输入参数拷贝进buf空间中)
 
static void save_cmdline(u32 argc, char** argv) {
  u32 len = 1, i;
  u8* buf;
  for (i = 0; i < argc; i++)
    len += strlen(argv[i]) + 1;
  
  buf = orig_cmdline = ck_alloc(len);
  for (i = 0; i < argc; i++) {
    u32 l = strlen(argv[i]);
    memcpy(buf, argv[i], l); 
    buf += l;
    if (i != argc - 1) *(buf++) = ' ';
  }
  *buf = 0;
}
 
5.fix_up_banner(修剪并且创建一个运行横幅)
 
static void fix_up_banner(u8* name) {
  if (!use_banner) {
    if (sync_id) {
      use_banner = sync_id;
    } else {
      u8* trim = strrchr(name, '/'); 
      if (!trim)
       use_banner = name;
      else 
        use_banner = trim + 1;
    }
  }
  if (strlen(use_banner) > 40) {
    u8* tmp = ck_alloc(44);
    sprintf(tmp, "%.40s...", use_banner);
    use_banner = tmp;
  }
}
 
6.check_if_tty(检查是否在tty终端上面运行)
 
static void check_if_tty(void) {
  struct winsize ws;
  if (getenv("AFL_NO_UI")) {
    OKF("Disabling the UI because AFL_NO_UI is set.");
    not_on_tty = 1; 
    return;
  }
  if (ioctl(1, TIOCGWINSZ, &ws)) {
    if (errno == ENOTTY) {
      OKF("Looks like we're not running on a tty, so I'll be a bit less verbose.");
      not_on_tty = 1;
    }
    return;
  }
}
 
7.get_core_count(计算逻辑CPU核的数量)
 
static void get_core_count(void) {
  u32 cur_runnable = 0;
 
8.check_crash_handling(确保核心转储不会进入程序)
 
static void check_crash_handling(void) {
#ifdef __APPLE__
  
  
  if (system("launchctl list 2>/dev/null | grep -q '\\.ReportCrash$'")) return;
  SAYF("\n" cLRD "[-] " cRST
       "Whoops, your system is configured to forward crash notifications to an\n"
       "    external crash reporting utility. This will cause issues due to the\n"
       "    extended delay between the fuzzed binary malfunctioning and this fact\n"
       "    being relayed to the fuzzer via the standard waitpid() API.\n\n"
       "    To avoid having crashes misinterpreted as timeouts, please run the\n" 
       "    following commands:\n\n"
       "    SL=/System/Library; PL=com.apple.ReportCrash\n"
       "    launchctl unload -w ${SL}/LaunchAgents/${PL}.plist\n"
       "    sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist\n");
  if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES"))
    FATAL("Crash reporter detected");
#else
  
  s32 fd = open("/proc/sys/kernel/core_pattern", O_RDONLY);
  u8  fchar;
  if (fd < 0) return;
  ACTF("Checking core_pattern...");
  if (read(fd, &fchar, 1) == 1 && fchar == '|') {
    SAYF("\n" cLRD "[-] " cRST
         "Hmm, your system is configured to send core dump notifications to an\n"
         "    external utility. This will cause issues: there will be an extended delay\n"
         "    between stumbling upon a crash and having this information relayed to the\n"
         "    fuzzer via the standard waitpid() API.\n\n"
         "    To avoid having crashes misinterpreted as timeouts, please log in as root\n" 
         "    and temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n"
         "    echo core >/proc/sys/kernel/core_pattern\n");
    if (!getenv("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES"))
      FATAL("Pipe at the beginning of 'core_pattern'");
  }
 
  close(fd);
#endif 
}
 
8.check_cpu_governor(检查CPU管理者)
 
 
static void check_cpu_governor(void) {
  FILE* f;
  u8 tmp[128];
  u64 min = 0, max = 0;
  if (getenv("AFL_SKIP_CPUFREQ")) 
  return;
  f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "r");
  if (!f) 
  return;
  ACTF("Checking CPU scaling governor...");
  if (!fgets(tmp, 128, f)) PFATAL("fgets() failed");
  fclose(f);
  if (!strncmp(tmp, "perf", 4)) return;
  f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", "r");
  if (f) {
    if (fscanf(f, "%llu", &min) != 1) min = 0;
    fclose(f);
  }
  f = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "r");
  if (f) {
    if (fscanf(f, "%llu", &max) != 1) max = 0;
    fclose(f);
  }
  if (min == max) return;
  SAYF("\n" cLRD "[-] " cRST
       "Whoops, your system uses on-demand CPU frequency scaling, adjusted\n"
       "    between %llu and %llu MHz. Unfortunately, the scaling algorithm in the\n"
       "    kernel is imperfect and can miss the short-lived processes spawned by\n"
       "    afl-fuzz. To keep things moving, run these commands as root:\n\n"
       "    cd /sys/devices/system/cpu\n"
       "    echo performance | tee cpu*/cpufreq/scaling_governor\n\n"
       "    You can later go back to the original state by replacing 'performance' with\n"
       "    'ondemand'. If you don't want to change the settings, set AFL_SKIP_CPUFREQ\n"
       "    to make afl-fuzz skip this check - but expect some performance drop.\n",
       min / 1024, max / 1024);
  FATAL("Suboptimal CPU scaling governor");
}
 
9.setup_post(加载后处理器(如果可用))
 
static void setup_post(void) {
  void* dh;
  u8* fn = getenv("AFL_POST_LIBRARY");
  u32 tlen = 6;
  if (!fn)
   return;
  ACTF("Loading postprocessor from '%s'...", fn);
  dh = dlopen(fn, RTLD_NOW);
  if (!dh) FATAL("%s", dlerror());
  post_handler = dlsym(dh, "afl_postprocess"); 
  if (!post_handler)
   FATAL("Symbol 'afl_postprocess' not found.");
  
  post_handler("hello", &tlen);
  OKF("Postprocessor installed successfully.");
}