[
  {
    "path": "Makefile",
    "content": "#\n# american fuzzy lop - makefile\n# -----------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n# \n# Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n# \n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n# \n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n\nPROGNAME    = afl\nVERSION     = 1.95b\n\nPREFIX     ?= /usr/local\nBIN_PATH    = $(PREFIX)/bin\nHELPER_PATH = $(PREFIX)/lib/afl\nDOC_PATH    = $(PREFIX)/share/doc/afl\nMISC_PATH   = $(PREFIX)/share/afl\n\nPROGS       = afl-gcc afl-as afl-fuzz afl-showmap afl-tmin afl-gotcpu\n\nCFLAGS     ?= -O3 -funroll-loops\nCFLAGS     += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n\t      -DAFL_PATH=\\\"$(HELPER_PATH)\\\" -DDOC_PATH=\\\"$(DOC_PATH)\\\" \\\n\t      -DBIN_PATH=\\\"$(BIN_PATH)\\\" -DVERSION=\\\"$(VERSION)\\\"\n\nifneq \"$(filter Linux GNU%,$(shell uname))\" \"\"\n  LDFLAGS  += -ldl\nendif\n\nifeq \"$(findstring clang, $(shell $(CC) --version 2>/dev/null))\" \"\"\n  TEST_CC   = afl-gcc\nelse\n  TEST_CC   = afl-clang\nendif\n\nCOMM_HDR    = alloc-inl.h config.h debug.h types.h\n\nall: test_x86 $(PROGS) test_build all_done\n\nifndef AFL_NOX86\n\ntest_x86:\n\t@echo \"[*] Checking for the ability to compile x86 code...\"\n\t@echo 'main() { __asm__(\"xorb %al, %al\"); }' | $(CC) -w -x c - -o .test || ( echo; echo \"Oops, looks like your compiler can't generate x86 code.\"; echo; echo \"You can still try using the LLVM or QEMU mode, but see docs/INSTALL first.\"; echo \"To ignore this error, set AFL_NOX86=1.\"; echo; exit 1 )\n\t@rm -f .test\n\t@echo \"[+] Everything seems to be working, ready to compile.\"\n\nelse\n\ntest_x86:\n\t@echo \"[!] Note: skipping x86 compilation checks (AFL_NOX86 set).\"\n\nendif\n\nafl-gcc: afl-gcc.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\tset -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done\n\nafl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) \n\tln -sf afl-as as\n\nafl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\nafl-showmap: afl-showmap.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\nafl-tmin: afl-tmin.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\nafl-gotcpu: afl-gotcpu.c $(COMM_HDR) | test_x86\n\t$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)\n\nifndef AFL_NOX86\n\ntest_build: afl-gcc afl-as afl-showmap\n\t@echo \"[*] Testing the CC wrapper and instrumentation output...\"\n\tunset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. ./$(TEST_CC) $(CFLAGS) test-instr.c -o test-instr $(LDFLAGS)\n\techo 0 | ./afl-showmap -m none -q -o .test-instr0 ./test-instr\n\techo 1 | ./afl-showmap -m none -q -o .test-instr1 ./test-instr\n\t@rm -f test-instr\n\t@cmp -s .test-instr0 .test-instr1; DR=\"$$?\"; rm -f .test-instr0 .test-instr1; if [ \"$$DR\" = \"0\" ]; then echo; echo \"Oops, the instrumentation does not seem to be behaving correctly!\"; echo; echo \"Please ping <lcamtuf@google.com> to troubleshoot the issue.\"; echo; exit 1; fi\n\t@echo \"[+] All right, the instrumentation seems to be working!\"\n\nelse\n\ntest_build: afl-gcc afl-as afl-showmap\n\t@echo \"[!] Note: skipping build tests (you may need to use LLVM or QEMU mode).\"\n\nendif\n\nall_done: test_build\n\t@echo \"[+] All done! Be sure to review README - it's pretty short and useful.\"\n\t@if [ \"`uname`\" = \"Darwin\" ]; then printf \"\\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\\n\\n\"; fi\n\t@! tty <&1 >/dev/null || printf \"\\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\\nThis will make the UI hard to read. See docs/status_screen.txt for advice.\\033[0m\\n\" 2>/dev/null\n\n.NOTPARALLEL: clean\n\nclean:\n\trm -f $(PROGS) as afl-g++ afl-clang afl-clang++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test test-instr .test-instr0 .test-instr1 qemu_mode/qemu-2.3.0.tar.bz2 afl-qemu-trace\n\trm -rf out_dir qemu_mode/qemu-2.3.0\n\t$(MAKE) -C llvm_mode clean\n\ninstall: all\n\tmkdir -p -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH)\n\trm -f $${DESTDIR}$(BIN_PATH)/afl-plot.sh\n\tinstall -m 755 afl-gcc afl-fuzz afl-showmap afl-plot afl-tmin afl-cmin afl-gotcpu afl-whatsup $${DESTDIR}$(BIN_PATH)\n\tif [ -f afl-qemu-trace ]; then install -m 755 afl-qemu-trace $${DESTDIR}$(BIN_PATH); fi\n\tif [ -f afl-clang-fast -a -f afl-llvm-pass.so -a -f afl-llvm-rt.o ]; then set -e; install -m 755 afl-clang-fast $${DESTDIR}$(BIN_PATH); ln -sf afl-clang-fast $${DESTDIR}$(BIN_PATH)/afl-clang-fast++; install -m 755 afl-llvm-pass.so afl-llvm-rt.o $${DESTDIR}$(HELPER_PATH); fi\n\tset -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $${DESTDIR}$(BIN_PATH)/$$i; done\n\tinstall -m 755 afl-as $${DESTDIR}$(HELPER_PATH)\n\tln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as\n\tinstall -m 644 docs/README docs/ChangeLog docs/*.txt $${DESTDIR}$(DOC_PATH)\n\tcp -r testcases/ $${DESTDIR}$(MISC_PATH)\n\npublish: clean\n\ttest \"`basename $$PWD`\" = \"afl\" || exit 1\n\ttest -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz; if [ \"$$?\" = \"0\" ]; then echo; echo \"Change program version in Makefile, mmkay?\"; echo; exit 1; fi\n\tcd ..; rm -rf $(PROGNAME)-$(VERSION); cp -pr $(PROGNAME) $(PROGNAME)-$(VERSION); \\\n\t  tar -cvz -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz $(PROGNAME)-$(VERSION)\n\tchmod 644 ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz\n\t( cd ~/www/afl/releases/; ln -s -f $(PROGNAME)-$(VERSION).tgz $(PROGNAME)-latest.tgz )\n\tcat docs/README >~/www/afl/README.txt\n\tcat docs/status_screen.txt >~/www/afl/status_screen.txt\n\tcat docs/historical_notes.txt >~/www/afl/historical_notes.txt\n\tcat docs/technical_details.txt >~/www/afl/technical_details.txt\n\tcat docs/ChangeLog >~/www/afl/ChangeLog.txt\n\tcat docs/QuickStartGuide.txt >~/www/afl/QuickStartGuide.txt\n\techo -n \"$(VERSION)\" >~/www/afl/version.txt\n"
  },
  {
    "path": "afl-as.c",
    "content": "/*\n   american fuzzy lop - wrapper for GNU as\n   ---------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   The sole purpose of this wrapper is to preprocess assembly files generated\n   by GCC / clang and inject the instrumentation bits included from afl-as.h. It\n   is automatically invoked by the toolchain when compiling programs using\n   afl-gcc / afl-clang.\n\n   Note that it's an explicit non-goal to instrument hand-written assembly,\n   be it in separate .s files or in __asm__ blocks. The only aspiration this\n   utility has right now is to be able to skip them gracefully and allow the\n   compilation process to continue.\n\n   That said, see experimental/clang_asm_normalize/ for a solution that may\n   allow clang users to make things work even with hand-crafted assembly. Just\n   note that there is no equivalent for GCC.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n\n#include \"afl-as.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <ctype.h>\n#include <fcntl.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n\nstatic u8** as_params;          /* Parameters passed to the real 'as'   */\n\nstatic u8*  input_file;         /* Originally specified input file      */\nstatic u8*  modified_file;      /* Instrumented file for the real 'as'  */\n\nstatic u8   be_quiet,           /* Quiet mode (no stderr output)        */\n            clang_mode,         /* Running in clang mode?               */\n            pass_thru,          /* Just pass data through?              */\n            just_version;       /* Just show version?                   */\n\nstatic u32  inst_ratio = 100,   /* Instrumentation probability (%)      */\n            as_par_cnt = 1;     /* Number of params to 'as'             */\n\n/* If we don't find --32 or --64 in the command line, default to \n   instrumentation for whichever mode we were compiled with. This is not\n   perfect, but should do the trick for almost all use cases. */\n\n#ifdef __x86_64__\n\nstatic u8   use_64bit = 1;\n\n#else\n\nstatic u8   use_64bit = 0;\n\n#ifdef __APPLE__\n#  error \"Sorry, 32-bit Apple platforms are not supported.\"\n#endif /* __APPLE__ */\n\n#endif /* ^__x86_64__ */\n\n\n/* Examine and modify parameters to pass to 'as'. Note that the file name\n   is always the last parameter passed by GCC, so we exploit this property\n   to keep the code simple. */\n\nstatic void edit_params(int argc, char** argv) {\n\n  u8 *tmp_dir = getenv(\"TMPDIR\"), *afl_as = getenv(\"AFL_AS\");\n  u32 i;\n\n#ifdef __APPLE__\n\n  u8 use_clang_as = 0;\n\n  /* On MacOS X, the Xcode cctool 'as' driver is a bit stale and does not work\n     with the code generated by newer versions of clang that are hand-built\n     by the user. See the thread here: http://goo.gl/HBWDtn.\n\n     To work around this, when using clang and running without AFL_AS\n     specified, we will actually call 'clang -c' instead of 'as -q' to\n     compile the assembly file.\n\n     The tools aren't cmdline-compatible, but at least for now, we can\n     seemingly get away with this by making only very minor tweaks. Thanks\n     to Nico Weber for the idea. */\n\n  if (clang_mode && !afl_as) {\n\n    use_clang_as = 1;\n\n    afl_as = getenv(\"AFL_CC\");\n    if (!afl_as) afl_as = getenv(\"AFL_CXX\");\n    if (!afl_as) afl_as = \"clang\";\n\n  }\n\n#endif /* __APPLE__ */\n\n  /* Although this is not documented, GCC also uses TEMP and TMP when TMPDIR\n     is not set. We need to check these non-standard variables to properly\n     handle the pass_thru logic later on. */\n\n  if (!tmp_dir) tmp_dir = getenv(\"TEMP\");\n  if (!tmp_dir) tmp_dir = getenv(\"TMP\");\n  if (!tmp_dir) tmp_dir = \"/tmp\";\n\n  as_params = ck_alloc((argc + 32) * sizeof(u8*));\n\n  as_params[0] = afl_as ? afl_as : (u8*)\"as\";\n\n  as_params[argc] = 0;\n\n  for (i = 1; i < argc - 1; i++) {\n\n    if (!strcmp(argv[i], \"--64\")) use_64bit = 1;\n    else if (!strcmp(argv[i], \"--32\")) use_64bit = 0;\n\n#ifdef __APPLE__\n\n    /* The Apple case is a bit different... */\n\n    if (!strcmp(argv[i], \"-arch\") && i + 1 < argc) {\n\n      if (!strcmp(argv[i + 1], \"x86_64\")) use_64bit = 1;\n      else if (!strcmp(argv[i + 1], \"i386\"))\n        FATAL(\"Sorry, 32-bit Apple platforms are not supported.\");\n\n    }\n\n    /* Strip options that set the preference for a particular upstream\n       assembler in Xcode. */\n\n    if (clang_mode && (!strcmp(argv[i], \"-q\") || !strcmp(argv[i], \"-Q\")))\n      continue;\n\n#endif /* __APPLE__ */\n\n    as_params[as_par_cnt++] = argv[i];\n\n  }\n\n#ifdef __APPLE__\n\n  /* When calling clang as the upstream assembler, append -c -x assembler\n     and hope for the best. */\n\n  if (use_clang_as) {\n\n    as_params[as_par_cnt++] = \"-c\";\n    as_params[as_par_cnt++] = \"-x\";\n    as_params[as_par_cnt++] = \"assembler\";\n\n  }\n\n#endif /* __APPLE__ */\n\n  input_file = argv[argc - 1];\n\n  if (input_file[0] == '-') {\n\n    if (!strcmp(input_file + 1, \"-version\")) {\n      just_version = 1;\n      modified_file = input_file;\n      goto wrap_things_up;\n    }\n\n    if (input_file[1]) FATAL(\"Incorrect use (not called through afl-gcc?)\");\n      else input_file = NULL;\n\n  } else {\n\n    /* Check if this looks like a standard invocation as a part of an attempt\n       to compile a program, rather than using gcc on an ad-hoc .s file in\n       a format we may not understand. This works around an issue compiling\n       NSS. */\n\n    if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&\n        strncmp(input_file, \"/var/tmp/\", 9) &&\n        strncmp(input_file, \"/tmp/\", 5)) pass_thru = 1;\n\n  }\n\n  modified_file = alloc_printf(\"%s/.afl-%u-%u.s\", tmp_dir, getpid(),\n                               (u32)time(NULL));\n\nwrap_things_up:\n\n  as_params[as_par_cnt++] = modified_file;\n  as_params[as_par_cnt]   = NULL;\n\n}\n\n\n/* Process input file, generate modified_file. Insert instrumentation in all\n   the appropriate places. */\n\nstatic void add_instrumentation(void) {\n\n  static u8 line[MAX_LINE];\n\n  FILE* inf;\n  FILE* outf;\n  s32 outfd;\n  u32 ins_lines = 0;\n\n  u8  instr_ok = 0, skip_csect = 0, skip_next_label = 0,\n      skip_intel = 0, skip_app = 0, instrument_next = 0;\n\n#ifdef __APPLE__\n\n  u8* colon_pos;\n\n#endif /* __APPLE__ */\n\n  if (input_file) {\n\n    inf = fopen(input_file, \"r\");\n    if (!inf) PFATAL(\"Unable to read '%s'\", input_file);\n\n  } else inf = stdin;\n\n  outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);\n\n  if (outfd < 0) PFATAL(\"Unable to write to '%s'\", modified_file);\n\n  outf = fdopen(outfd, \"w\");\n\n  if (!outf) PFATAL(\"fdopen() failed\");  \n\n  while (fgets(line, MAX_LINE, inf)) {\n\n    /* In some cases, we want to defer writing the instrumentation trampoline\n       until after all the labels, macros, comments, etc. If we're in this\n       mode, and if the line starts with a tab followed by a character, dump\n       the trampoline now. */\n\n    if (!pass_thru && !skip_intel && !skip_app && !skip_csect && instr_ok &&\n        instrument_next && line[0] == '\\t' && isalpha(line[1])) {\n\n      fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,\n              R(MAP_SIZE));\n\n      instrument_next = 0;\n      ins_lines++;\n\n    }\n\n    /* Output the actual line, call it a day in pass-thru mode. */\n\n    fputs(line, outf);\n\n    if (pass_thru) continue;\n\n    /* All right, this is where the actual fun begins. For one, we only want to\n       instrument the .text section. So, let's keep track of that in processed\n       files - and let's set instr_ok accordingly. */\n\n    if (line[0] == '\\t' && line[1] == '.') {\n\n      /* OpenBSD puts jump tables directly inline with the code, which is\n         a bit annoying. They use a specific format of p2align directives\n         around them, so we use that as a signal. */\n\n      if (!clang_mode && instr_ok && !strncmp(line + 2, \"p2align \", 8) &&\n          isdigit(line[10]) && line[11] == '\\n') skip_next_label = 1;\n\n      if (!strncmp(line + 2, \"text\\n\", 5) ||\n          !strncmp(line + 2, \"section\\t.text\", 13) ||\n          !strncmp(line + 2, \"section\\t__TEXT,__text\", 21) ||\n          !strncmp(line + 2, \"section __TEXT,__text\", 21)) {\n        instr_ok = 1;\n        continue; \n      }\n\n      if (!strncmp(line + 2, \"section\\t\", 8) ||\n          !strncmp(line + 2, \"section \", 8) ||\n          !strncmp(line + 2, \"bss\\n\", 4) ||\n          !strncmp(line + 2, \"data\\n\", 5)) {\n        instr_ok = 0;\n        continue;\n      }\n\n    }\n\n    /* Detect off-flavor assembly (rare, happens in gdb). When this is\n       encountered, we set skip_csect until the opposite directive is\n       seen, and we do not instrument. */\n\n    if (strstr(line, \".code\")) {\n\n      if (strstr(line, \".code32\")) skip_csect = use_64bit;\n      if (strstr(line, \".code64\")) skip_csect = !use_64bit;\n\n    }\n\n    /* Detect syntax changes, as could happen with hand-written assembly.\n       Skip Intel blocks, resume instrumentation when back to AT&T. */\n\n    if (strstr(line, \".intel_syntax\")) skip_intel = 1;\n    if (strstr(line, \".att_syntax\")) skip_intel = 0;\n\n    /* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */\n\n    if (line[0] == '#' || line[1] == '#') {\n\n      if (strstr(line, \"#APP\")) skip_app = 1;\n      if (strstr(line, \"#NO_APP\")) skip_app = 0;\n\n    }\n\n    /* If we're in the right mood for instrumenting, check for function\n       names or conditional labels. This is a bit messy, but in essence,\n       we want to catch:\n\n         ^main:      - function entry point (always instrumented)\n         ^.L0:       - GCC branch label\n         ^.LBB0_0:   - clang branch label (but only in clang mode)\n         ^\\tjnz foo  - conditional branches\n\n       ...but not:\n\n         ^# BB#0:    - clang comments\n         ^ # BB#0:   - ditto\n         ^.Ltmp0:    - clang non-branch labels\n         ^.LC0       - GCC non-branch labels\n         ^.LBB0_0:   - ditto (when in GCC mode)\n         ^\\tjmp foo  - non-conditional jumps\n\n       Additionally, clang and GCC on MacOS X follow a different convention\n       with no leading dots on labels, hence the weird maze of #ifdefs\n       later on.\n\n     */\n\n    if (skip_intel || skip_app || skip_csect || !instr_ok ||\n        line[0] == '#' || line[0] == ' ') continue;\n\n    /* Conditional branch instruction (jnz, etc). We append the instrumentation\n       right after the branch (to instrument the not-taken path) and at the\n       branch destination label (handled later on). */\n\n    if (line[0] == '\\t') {\n\n      if (line[1] == 'j' && line[2] != 'm' && R(100) < inst_ratio) {\n\n        fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32,\n                R(MAP_SIZE));\n\n        ins_lines++;\n\n      }\n\n      continue;\n\n    }\n\n    /* Label of some sort. This may be a branch destination, but we need to\n       tread carefully and account for several different formatting\n       conventions. */\n\n#ifdef __APPLE__\n\n    /* Apple: L<whatever><digit>: */\n\n    if ((colon_pos = strstr(line, \":\"))) {\n\n      if (line[0] == 'L' && isdigit(*(colon_pos - 1))) {\n\n#else\n\n    /* Everybody else: .L<whatever>: */\n\n    if (strstr(line, \":\")) {\n\n      if (line[0] == '.') {\n\n#endif /* __APPLE__ */\n\n        /* .L0: or LBB0_0: style jump destination */\n\n#ifdef __APPLE__\n\n        /* Apple: L<num> / LBB<num> */\n\n        if ((isdigit(line[1]) || (clang_mode && !strncmp(line, \"LBB\", 3)))\n            && R(100) < inst_ratio) {\n\n#else\n\n        /* Apple: .L<num> / .LBB<num> */\n\n        if ((isdigit(line[2]) || (clang_mode && !strncmp(line + 1, \"LBB\", 3)))\n            && R(100) < inst_ratio) {\n\n#endif /* __APPLE__ */\n\n          /* An optimization is possible here by adding the code only if the\n             label is mentioned in the code in contexts other than call / jmp.\n             That said, this complicates the code by requiring two-pass\n             processing (messy with stdin), and results in a speed gain\n             typically under 10%, because compilers are generally pretty good\n             about not generating spurious intra-function jumps.\n\n             We use deferred output chiefly to avoid disrupting\n             .Lfunc_begin0-style exception handling calculations (a problem on\n             MacOS X). */\n\n          if (!skip_next_label) instrument_next = 1; else skip_next_label = 0;\n\n        }\n\n      } else {\n\n        /* Function label (always instrumented, deferred mode). */\n\n        instrument_next = 1;\n    \n      }\n\n    }\n\n  }\n\n  if (ins_lines)\n    fputs(use_64bit ? main_payload_64 : main_payload_32, outf);\n\n  if (input_file) fclose(inf);\n  fclose(outf);\n\n  if (!be_quiet) {\n\n    if (!ins_lines) WARNF(\"No instrumentation targets found%s.\",\n                          pass_thru ? \" (pass-thru mode)\" : \"\");\n    else OKF(\"Instrumented %u locations (%s-bit, %s mode, ratio %u%%).\",\n             ins_lines, use_64bit ? \"64\" : \"32\",\n             getenv(\"AFL_HARDEN\") ? \"hardened\" : \"non-hardened\",\n             inst_ratio);\n \n  }\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 pid;\n  u32 rand_seed;\n  int status;\n  u8* inst_ratio_str = getenv(\"AFL_INST_RATIO\");\n\n  struct timeval tv;\n  struct timezone tz;\n\n  clang_mode = !!getenv(CLANG_ENV_VAR);\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-as \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n \n  } else be_quiet = 1;\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It is a wrapper around GNU 'as',\\n\"\n         \"executed by the toolchain whenever using afl-gcc or afl-clang. You probably\\n\"\n         \"don't want to run this program directly.\\n\\n\"\n\n         \"Rarely, when dealing with extremely complex projects, it may be advisable to\\n\"\n         \"set AFL_INST_RATIO to a value less than 100 in order to reduce the odds of\\n\"\n         \"instrumenting every discovered branch.\\n\\n\");\n\n    exit(1);\n\n  }\n\n  gettimeofday(&tv, &tz);\n\n  rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();\n\n  srandom(rand_seed);\n\n  edit_params(argc, argv);\n\n  if (inst_ratio_str) {\n\n    if (sscanf(inst_ratio_str, \"%u\", &inst_ratio) != 1 || inst_ratio > 100) \n      FATAL(\"Bad value of AFL_INST_RATIO (must be between 0 and 100)\");\n\n  }\n\n  if (getenv(AS_LOOP_ENV_VAR))\n    FATAL(\"Endless loop when calling 'as' (remove '.' from your PATH)\");\n\n  setenv(AS_LOOP_ENV_VAR, \"1\", 1);\n\n  /* When compiling with ASAN, we don't have a particularly elegant way to skip\n     ASAN-specific branches. But we can probabilistically compensate for\n     that... */\n\n  if (getenv(\"AFL_USE_ASAN\") || getenv(\"AFL_USE_MSAN\")) inst_ratio /= 3;\n\n  if (!just_version) add_instrumentation();\n\n  if (!(pid = fork())) {\n\n    execvp(as_params[0], (char**)as_params);\n    FATAL(\"Oops, failed to execute '%s' - check your PATH\", as_params[0]);\n\n  }\n\n  if (pid < 0) PFATAL(\"fork() failed\");\n\n  if (waitpid(pid, &status, 0) <= 0) PFATAL(\"waitpid() failed\");\n\n  if (!getenv(\"AFL_KEEP_ASSEMBLY\")) unlink(modified_file);\n\n  exit(WEXITSTATUS(status));\n\n}\n\n"
  },
  {
    "path": "afl-as.h",
    "content": "/*\n   american fuzzy lop - injectable parts\n   -------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Forkserver design by Jann Horn <jannhorn@googlemail.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file houses the assembly-level instrumentation injected into fuzzed\n   programs. The instrumentation stores XORed pairs of data: identifiers of the\n   currently executing branch and the one that executed immediately before.\n\n   TL;DR: the instrumentation does shm_trace_map[cur_loc ^ prev_loc]++\n\n   The code is designed for 32-bit and 64-bit x86 systems. Both modes should\n   work everywhere except for Apple systems. Apple does relocations differently\n   from everybody else, so since their OSes have been 64-bit for a longer while,\n   I didn't go through the mental effort of porting the 32-bit code.\n\n   In principle, similar code should be easy to inject into any well-behaved\n   binary-only code (e.g., using DynamoRIO). Conditional jumps offer natural\n   targets for instrumentation, and should offer comparable probe density.\n\n */\n\n#ifndef _HAVE_AFL_AS_H\n#define _HAVE_AFL_AS_H\n\n#include \"config.h\"\n#include \"types.h\"\n\n/* \n   ------------------\n   Performances notes\n   ------------------\n\n   Contributions to make this code faster are appreciated! Here are some\n   rough notes that may help with the task:\n\n   - Only the trampoline_fmt and the non-setup __afl_maybe_log code paths are\n     really worth optimizing; the setup / fork server stuff matters a lot less\n     and should be mostly just kept readable.\n\n   - We're aiming for modern CPUs with out-of-order execution and large\n     pipelines; the code is mostly follows intuitive, human-readable\n     instruction ordering, because \"textbook\" manual reorderings make no\n     substantial difference.\n\n   - Interestingly, instrumented execution isn't a lot faster if we store a\n     variable pointer to the setup, log, or return routine and then do a reg\n     call from within trampoline_fmt. It does speed up non-instrumented\n     execution quite a bit, though, since that path just becomes\n     push-call-ret-pop.\n\n   - There is also not a whole lot to be gained by doing SHM attach at a\n     fixed address instead of retrieving __afl_area_ptr. Although it allows us\n     to have a shorter log routine inserted for conditional jumps and jump\n     labels (for a ~10% perf gain), there is a risk of bumping into other\n     allocations created by the program or by tools such as ASAN.\n\n   - popf is *awfully* slow, which is why we're doing the lahf / sahf +\n     overflow test trick. Unfortunately, this forces us to taint eax / rax, but\n     this dependency on a commonly-used register still beats the alternative of\n     using pushf / popf.\n\n     One possible optimization is to avoid touching flags by using a circular\n     buffer that stores just a sequence of current locations, with the XOR stuff\n     happening offline. Alas, this doesn't seem to have a huge impact:\n\n     https://groups.google.com/d/msg/afl-users/MsajVf4fRLo/2u6t88ntUBIJ\n\n   - Preforking one child a bit sooner, and then waiting for the \"go\" command\n     from within the child, doesn't offer major performance gains; fork() seems\n     to be relatively inexpensive these days. Preforking multiple children does\n     help, but badly breaks the \"~1 core per fuzzer\" design, making it harder to\n     scale up. Maybe there is some middle ground.\n\n   Perhaps of note: in the 64-bit version for all platforms except for Apple,\n   the instrumentation is done slightly differently than on 32-bit, with\n   __afl_prev_loc and __afl_area_ptr being local to the object file (.lcomm),\n   rather than global (.comm). This is to avoid GOTRELPC lookups in the critical\n   code path, which AFAICT, are otherwise unavoidable if we want gcc -shared to\n   work; simple relocations between .bss and .text won't work on most 64-bit\n   platforms in such a case.\n\n   (Fun fact: on Apple systems, .lcomm can segfault the linker.)\n\n   The side effect is that state transitions are measured in a somewhat\n   different way, with previous tuple being recorded separately within the scope\n   of every .c file. This should have no impact in any practical sense.\n\n   Another side effect of this design is that getenv() will be called once per\n   every .o file when running in non-instrumented mode; an since getenv() tends\n   to be optimized in funny ways, we need to be very careful to save every\n   oddball register it may touch.\n\n */\n\nstatic const u8* trampoline_fmt_32 =\n\n  \"\\n\"\n  \"/* --- AFL TRAMPOLINE (32-BIT) --- */\\n\"\n  \"\\n\"\n  \".align 4\\n\"\n  \"\\n\"\n  \"leal -16(%%esp), %%esp\\n\"\n  \"movl %%edi,  0(%%esp)\\n\"\n  \"movl %%edx,  4(%%esp)\\n\"\n  \"movl %%ecx,  8(%%esp)\\n\"\n  \"movl %%eax, 12(%%esp)\\n\"\n  \"movl $0x%08x, %%ecx\\n\"\n  \"call __afl_maybe_log\\n\"\n  \"movl 12(%%esp), %%eax\\n\"\n  \"movl  8(%%esp), %%ecx\\n\"\n  \"movl  4(%%esp), %%edx\\n\"\n  \"movl  0(%%esp), %%edi\\n\"\n  \"leal 16(%%esp), %%esp\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\nstatic const u8* trampoline_fmt_64 =\n\n  \"\\n\"\n  \"/* --- AFL TRAMPOLINE (64-BIT) --- */\\n\"\n  \"\\n\"\n  \".align 4\\n\"\n  \"\\n\"\n  \"leaq -(128+24)(%%rsp), %%rsp\\n\"\n  \"movq %%rdx,  0(%%rsp)\\n\"\n  \"movq %%rcx,  8(%%rsp)\\n\"\n  \"movq %%rax, 16(%%rsp)\\n\"\n  \"movq $0x%08x, %%rcx\\n\"\n  \"call __afl_maybe_log\\n\"\n  \"movq 16(%%rsp), %%rax\\n\"\n  \"movq  8(%%rsp), %%rcx\\n\"\n  \"movq  0(%%rsp), %%rdx\\n\"\n  \"leaq (128+24)(%%rsp), %%rsp\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\nstatic const u8* main_payload_32 = \n\n  \"\\n\"\n  \"/* --- AFL MAIN PAYLOAD (32-BIT) --- */\\n\"\n  \"\\n\"\n  \".text\\n\"\n  \".att_syntax\\n\"\n  \".code32\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n\n  \"__afl_maybe_log:\\n\"\n  \"\\n\"\n  \"  lahf\\n\"\n  \"  seto %al\\n\"\n  \"\\n\"\n  \"  /* Check if SHM region is already mapped. */\\n\"\n  \"\\n\"\n  \"  movl  __afl_area_ptr, %edx\\n\"\n  \"  testl %edx, %edx\\n\"\n  \"  je    __afl_setup\\n\"\n  \"\\n\"\n  \"__afl_store:\\n\"\n  \"\\n\"\n  \"  /* Calculate and store hit for the code location specified in ecx. There\\n\"\n  \"     is a double-XOR way of doing this without tainting another register,\\n\"\n  \"     and we use it on 64-bit systems; but it's slower for 32-bit ones. */\\n\"\n  \"\\n\"\n#ifndef COVERAGE_ONLY\n  \"  movl __afl_prev_loc, %edi\\n\"\n  \"  xorl %ecx, %edi\\n\"\n  \"  shrl $1, %ecx\\n\"\n  \"  movl %ecx, __afl_prev_loc\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"\\n\"\n#ifdef SKIP_COUNTS\n  \"  orb  $1, (%edx, %edi, 1)\\n\"\n#else\n  \"  incb (%edx, %edi, 1)\\n\"\n#endif /* ^SKIP_COUNTS */\n  \"\\n\"\n  \"__afl_return:\\n\"\n  \"\\n\"\n  \"  addb $127, %al\\n\"\n  \"  sahf\\n\"\n  \"  ret\\n\"\n  \"\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_setup:\\n\"\n  \"\\n\"\n  \"  /* Do not retry setup if we had previous failures. */\\n\"\n  \"\\n\"\n  \"  cmpb $0, __afl_setup_failure\\n\"\n  \"  jne  __afl_return\\n\"\n  \"\\n\"\n  \"  /* Map SHM, jumping to __afl_setup_abort if something goes wrong.\\n\"\n  \"     We do not save FPU/MMX/SSE registers here, but hopefully, nobody\\n\"\n  \"     will notice this early in the game. */\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  pushl %ecx\\n\"\n  \"\\n\"\n  \"  pushl $.AFL_SHM_ENV\\n\"\n  \"  call  getenv\\n\"\n  \"  addl  $4, %esp\\n\"\n  \"\\n\"\n  \"  testl %eax, %eax\\n\"\n  \"  je    __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  call  atoi\\n\"\n  \"  addl  $4, %esp\\n\"\n  \"\\n\"\n  \"  pushl $0          /* shmat flags    */\\n\"\n  \"  pushl $0          /* requested addr */\\n\"\n  \"  pushl %eax        /* SHM ID         */\\n\"\n  \"  call  shmat\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl $-1, %eax\\n\"\n  \"  je   __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  /* Store the address of the SHM region. */\\n\"\n  \"\\n\"\n  \"  movl %eax, __afl_area_ptr\\n\"\n  \"  movl %eax, %edx\\n\"\n  \"\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"\\n\"\n  \"__afl_forkserver:\\n\"\n  \"\\n\"\n  \"  /* Enter the fork server mode to avoid the overhead of execve() calls. */\\n\"\n  \"\\n\"\n  \"  pushl %eax\\n\"\n  \"  pushl %ecx\\n\"\n  \"  pushl %edx\\n\"\n  \"\\n\"\n  \"  /* Phone home and tell the parent that we're OK. (Note that signals with\\n\"\n  \"     no SA_RESTART will mess it up). If this fails, assume that the fd is\\n\"\n  \"     closed because we were execve()d from an instrumented binary, or because\\n\" \n  \"     the parent doesn't want to use the fork server. */\\n\"\n  \"\\n\"\n  \"  pushl $4          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY((FORKSRV_FD + 1)) \"  /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $4, %eax\\n\"\n  \"  jne   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"__afl_fork_wait_loop:\\n\"\n  \"\\n\"\n  \"  /* Wait for parent by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  pushl $4          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_FD) \"        /* file desc */\\n\"\n  \"  call  read\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $4, %eax\\n\"\n  \"  jne   __afl_die\\n\"\n  \"\\n\"\n  \"  /* Once woken up, create a clone of our process. This is an excellent use\\n\"\n  \"     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\\n\"\n  \"     caches getpid() results and offers no way to update the value, breaking\\n\"\n  \"     abort(), raise(), and a bunch of other things :-( */\\n\"\n  \"\\n\"\n  \"  call fork\\n\"\n  \"\\n\"\n  \"  cmpl $0, %eax\\n\"\n  \"  jl   __afl_die\\n\"\n  \"  je   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"  /* In parent process: write PID to pipe, then wait for child. */\\n\"\n  \"\\n\"\n  \"  movl  %eax, __afl_fork_pid\\n\"\n  \"\\n\"\n  \"  pushl $4              /* length    */\\n\"\n  \"  pushl $__afl_fork_pid /* data      */\\n\"\n  \"  pushl $\" STRINGIFY((FORKSRV_FD + 1)) \"      /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  pushl $0             /* no flags  */\\n\"\n  \"  pushl $__afl_temp    /* status    */\\n\"\n  \"  pushl __afl_fork_pid /* PID       */\\n\"\n  \"  call  waitpid\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  cmpl  $0, %eax\\n\"\n  \"  jle   __afl_die\\n\"\n  \"\\n\"\n  \"  /* Relay wait status to pipe, then loop back. */\\n\"\n  \"\\n\"\n  \"  pushl $4          /* length    */\\n\"\n  \"  pushl $__afl_temp /* data      */\\n\"\n  \"  pushl $\" STRINGIFY((FORKSRV_FD + 1)) \"  /* file desc */\\n\"\n  \"  call  write\\n\"\n  \"  addl  $12, %esp\\n\"\n  \"\\n\"\n  \"  jmp __afl_fork_wait_loop\\n\"\n  \"\\n\"\n  \"__afl_fork_resume:\\n\"\n  \"\\n\"\n  \"  /* In child process: close fds, resume execution. */\\n\"\n  \"\\n\"\n  \"  pushl $\" STRINGIFY(FORKSRV_FD) \"\\n\"\n  \"  call  close\\n\"\n  \"\\n\"\n  \"  pushl $\" STRINGIFY((FORKSRV_FD + 1)) \"\\n\"\n  \"  call  close\\n\"\n  \"\\n\"\n  \"  addl  $8, %esp\\n\"\n  \"\\n\"\n  \"  popl %edx\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"  jmp  __afl_store\\n\"\n  \"\\n\"\n  \"__afl_die:\\n\"\n  \"\\n\"\n  \"  xorl %eax, %eax\\n\"\n  \"  call _exit\\n\"\n  \"\\n\"\n  \"__afl_setup_abort:\\n\"\n  \"\\n\"\n  \"  /* Record setup failure so that we don't keep calling\\n\"\n  \"     shmget() / shmat() over and over again. */\\n\"\n  \"\\n\"\n  \"  incb __afl_setup_failure\\n\"\n  \"  popl %ecx\\n\"\n  \"  popl %eax\\n\"\n  \"  jmp __afl_return\\n\"\n  \"\\n\"\n  \".AFL_VARS:\\n\"\n  \"\\n\"\n  \"  .comm   __afl_area_ptr, 4, 32\\n\"\n  \"  .comm   __afl_setup_failure, 1, 32\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .comm   __afl_prev_loc, 4, 32\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .comm   __afl_fork_pid, 4, 32\\n\"\n  \"  .comm   __afl_temp, 4, 32\\n\"\n  \"\\n\"\n  \".AFL_SHM_ENV:\\n\"\n  \"  .asciz \\\"\" SHM_ENV_VAR \"\\\"\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\n/* The OpenBSD hack is due to lahf and sahf not being recognized by some\n   versions of binutils: http://marc.info/?l=openbsd-cvs&m=141636589924400\n\n   The Apple code is a bit different when calling libc functions because\n   they are doing relocations differently from everybody else. We also need\n   to work around the crash issue with .lcomm and the fact that they don't\n   recognize .string. */\n\n#ifdef __APPLE__\n#  define CALL_L64(str)\t\t\"call _\" str \"\\n\"\n#else\n#  define CALL_L64(str)\t\t\"call \" str \"@PLT\\n\"\n#endif /* ^__APPLE__ */\n\nstatic const u8* main_payload_64 = \n\n  \"\\n\"\n  \"/* --- AFL MAIN PAYLOAD (64-BIT) --- */\\n\"\n  \"\\n\"\n  \".text\\n\"\n  \".att_syntax\\n\"\n  \".code64\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_maybe_log:\\n\"\n  \"\\n\"\n#if defined(__OpenBSD__)  || (defined(__FreeBSD__) && (__FreeBSD__ < 9))\n  \"  .byte 0x9f /* lahf */\\n\"\n#else\n  \"  lahf\\n\"\n#endif /* ^__OpenBSD__, etc */\n  \"  seto  %al\\n\"\n  \"\\n\"\n  \"  /* Check if SHM region is already mapped. */\\n\"\n  \"\\n\"\n  \"  movq  __afl_area_ptr(%rip), %rdx\\n\"\n  \"  testq %rdx, %rdx\\n\"\n  \"  je    __afl_setup\\n\"\n  \"\\n\"\n  \"__afl_store:\\n\"\n  \"\\n\"\n  \"  /* Calculate and store hit for the code location specified in rcx. */\\n\"\n  \"\\n\"\n#ifndef COVERAGE_ONLY\n  \"  xorq __afl_prev_loc(%rip), %rcx\\n\"\n  \"  xorq %rcx, __afl_prev_loc(%rip)\\n\"\n  \"  shrq $1, __afl_prev_loc(%rip)\\n\"\n#endif /* ^!COVERAGE_ONLY */\n  \"\\n\"\n#ifdef SKIP_COUNTS\n  \"  orb  $1, (%rdx, %rcx, 1)\\n\"\n#else\n  \"  incb (%rdx, %rcx, 1)\\n\"\n#endif /* ^SKIP_COUNTS */\n  \"\\n\"\n  \"__afl_return:\\n\"\n  \"\\n\"\n  \"  addb $127, %al\\n\"\n#if defined(__OpenBSD__)  || (defined(__FreeBSD__) && (__FreeBSD__ < 9))\n  \"  .byte 0x9e /* sahf */\\n\"\n#else\n  \"  sahf\\n\"\n#endif /* ^__OpenBSD__, etc */\n  \"  ret\\n\"\n  \"\\n\"\n  \".align 8\\n\"\n  \"\\n\"\n  \"__afl_setup:\\n\"\n  \"\\n\"\n  \"  /* Do not retry setup if we had previous failures. */\\n\"\n  \"\\n\"\n  \"  cmpb $0, __afl_setup_failure(%rip)\\n\"\n  \"  jne __afl_return\\n\"\n  \"\\n\"\n  \"  /* Check out if we have a global pointer on file. */\\n\"\n  \"\\n\"\n#ifndef __APPLE__\n  \"  movq  __afl_global_area_ptr@GOTPCREL(%rip), %rdx\\n\"\n  \"  movq  (%rdx), %rdx\\n\"\n#else\n  \"  movq  __afl_global_area_ptr(%rip), %rdx\\n\"\n#endif /* !^__APPLE__ */\n  \"  testq %rdx, %rdx\\n\"\n  \"  je    __afl_setup_first\\n\"\n  \"\\n\"\n  \"  movq %rdx, __afl_area_ptr(%rip)\\n\"\n  \"  jmp  __afl_store\\n\" \n  \"\\n\"\n  \"__afl_setup_first:\\n\"\n  \"\\n\"\n  \"  /* Save everything that is not yet saved and that may be touched by\\n\"\n  \"     getenv() and several other libcalls we'll be relying on. */\\n\"\n  \"\\n\"\n  \"  leaq -352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  movq %rax,   0(%rsp)\\n\"\n  \"  movq %rcx,   8(%rsp)\\n\"\n  \"  movq %rdi,  16(%rsp)\\n\"\n  \"  movq %rsi,  32(%rsp)\\n\"\n  \"  movq %r8,   40(%rsp)\\n\"\n  \"  movq %r9,   48(%rsp)\\n\"\n  \"  movq %r10,  56(%rsp)\\n\"\n  \"  movq %r11,  64(%rsp)\\n\"\n  \"\\n\"\n  \"  movq %xmm0,  96(%rsp)\\n\"\n  \"  movq %xmm1,  112(%rsp)\\n\"\n  \"  movq %xmm2,  128(%rsp)\\n\"\n  \"  movq %xmm3,  144(%rsp)\\n\"\n  \"  movq %xmm4,  160(%rsp)\\n\"\n  \"  movq %xmm5,  176(%rsp)\\n\"\n  \"  movq %xmm6,  192(%rsp)\\n\"\n  \"  movq %xmm7,  208(%rsp)\\n\"\n  \"  movq %xmm8,  224(%rsp)\\n\"\n  \"  movq %xmm9,  240(%rsp)\\n\"\n  \"  movq %xmm10, 256(%rsp)\\n\"\n  \"  movq %xmm11, 272(%rsp)\\n\"\n  \"  movq %xmm12, 288(%rsp)\\n\"\n  \"  movq %xmm13, 304(%rsp)\\n\"\n  \"  movq %xmm14, 320(%rsp)\\n\"\n  \"  movq %xmm15, 336(%rsp)\\n\"\n  \"\\n\"\n  \"  /* Map SHM, jumping to __afl_setup_abort if something goes wrong. */\\n\"\n  \"\\n\"\n  \"  /* The 64-bit ABI requires 16-byte stack alignment. We'll keep the\\n\"\n  \"     original stack ptr in the callee-saved r12. */\\n\"\n  \"\\n\"\n  \"  pushq %r12\\n\"\n  \"  movq  %rsp, %r12\\n\"\n  \"  subq  $16, %rsp\\n\"\n  \"  andq  $0xfffffffffffffff0, %rsp\\n\"\n  \"\\n\"\n  \"  leaq .AFL_SHM_ENV(%rip), %rdi\\n\"\n  CALL_L64(\"getenv\")\n  \"\\n\"\n  \"  testq %rax, %rax\\n\"\n  \"  je    __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  movq  %rax, %rdi\\n\"\n  CALL_L64(\"atoi\")\n  \"\\n\"\n  \"  xorq %rdx, %rdx   /* shmat flags    */\\n\"\n  \"  xorq %rsi, %rsi   /* requested addr */\\n\"\n  \"  movq %rax, %rdi   /* SHM ID         */\\n\"\n  CALL_L64(\"shmat\")\n  \"\\n\"\n  \"  cmpq $-1, %rax\\n\"\n  \"  je   __afl_setup_abort\\n\"\n  \"\\n\"\n  \"  /* Store the address of the SHM region. */\\n\"\n  \"\\n\"\n  \"  movq %rax, %rdx\\n\"\n  \"  movq %rax, __afl_area_ptr(%rip)\\n\"\n  \"\\n\"\n#ifdef __APPLE__\n  \"  movq %rax, __afl_global_area_ptr(%rip)\\n\"\n#else\n  \"  movq __afl_global_area_ptr@GOTPCREL(%rip), %rdx\\n\"\n  \"  movq %rax, (%rdx)\\n\"\n#endif /* ^__APPLE__ */\n  \"  movq %rax, %rdx\\n\"\n  \"\\n\"\n  \"__afl_forkserver:\\n\"\n  \"\\n\"\n  \"  /* Enter the fork server mode to avoid the overhead of execve() calls. We\\n\"\n  \"     push rdx (area ptr) twice to keep stack alignment neat. */\\n\"\n  \"\\n\"\n  \"  pushq %rdx\\n\"\n  \"  pushq %rdx\\n\"\n  \"\\n\"\n  \"  /* Phone home and tell the parent that we're OK. (Note that signals with\\n\"\n  \"     no SA_RESTART will mess it up). If this fails, assume that the fd is\\n\"\n  \"     closed because we were execve()d from an instrumented binary, or because\\n\"\n  \"     the parent doesn't want to use the fork server. */\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY((FORKSRV_FD + 1)) \", %rdi       /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  cmpq $4, %rax\\n\"\n  \"  jne  __afl_fork_resume\\n\"\n  \"\\n\"\n  \"__afl_fork_wait_loop:\\n\"\n  \"\\n\"\n  \"  /* Wait for parent by reading from the pipe. Abort if read fails. */\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_FD) \", %rdi             /* file desc */\\n\"\n  CALL_L64(\"read\")\n  \"  cmpq $4, %rax\\n\"\n  \"  jne  __afl_die\\n\"\n  \"\\n\"\n  \"  /* Once woken up, create a clone of our process. This is an excellent use\\n\"\n  \"     case for syscall(__NR_clone, 0, CLONE_PARENT), but glibc boneheadedly\\n\"\n  \"     caches getpid() results and offers no way to update the value, breaking\\n\"\n  \"     abort(), raise(), and a bunch of other things :-( */\\n\"\n  \"\\n\"\n  CALL_L64(\"fork\")\n  \"  cmpq $0, %rax\\n\"\n  \"  jl   __afl_die\\n\"\n  \"  je   __afl_fork_resume\\n\"\n  \"\\n\"\n  \"  /* In parent process: write PID to pipe, then wait for child. */\\n\"\n  \"\\n\"\n  \"  movl %eax, __afl_fork_pid(%rip)\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx                   /* length    */\\n\"\n  \"  leaq __afl_fork_pid(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY((FORKSRV_FD + 1)) \", %rdi             /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  movq $0, %rdx                   /* no flags  */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi     /* status    */\\n\"\n  \"  movq __afl_fork_pid(%rip), %rdi /* PID       */\\n\"\n  CALL_L64(\"waitpid\")\n  \"  cmpq $0, %rax\\n\"\n  \"  jle  __afl_die\\n\"\n  \"\\n\"\n  \"  /* Relay wait status to pipe, then loop back. */\\n\"\n  \"\\n\"\n  \"  movq $4, %rdx               /* length    */\\n\"\n  \"  leaq __afl_temp(%rip), %rsi /* data      */\\n\"\n  \"  movq $\" STRINGIFY((FORKSRV_FD + 1)) \", %rdi         /* file desc */\\n\"\n  CALL_L64(\"write\")\n  \"\\n\"\n  \"  jmp  __afl_fork_wait_loop\\n\"\n  \"\\n\"\n  \"__afl_fork_resume:\\n\"\n  \"\\n\"\n  \"  /* In child process: close fds, resume execution. */\\n\"\n  \"\\n\"\n  \"  movq $\" STRINGIFY(FORKSRV_FD) \", %rdi\\n\"\n  CALL_L64(\"close\")\n  \"\\n\"\n  \"  movq $\" STRINGIFY((FORKSRV_FD + 1)) \", %rdi\\n\"\n  CALL_L64(\"close\")\n  \"\\n\"\n  \"  popq %rdx\\n\"\n  \"  popq %rdx\\n\"\n  \"\\n\"\n  \"  movq %r12, %rsp\\n\"\n  \"  popq %r12\\n\"\n  \"\\n\"\n  \"  movq  0(%rsp), %rax\\n\"\n  \"  movq  8(%rsp), %rcx\\n\"\n  \"  movq 16(%rsp), %rdi\\n\"\n  \"  movq 32(%rsp), %rsi\\n\"\n  \"  movq 40(%rsp), %r8\\n\"\n  \"  movq 48(%rsp), %r9\\n\"\n  \"  movq 56(%rsp), %r10\\n\"\n  \"  movq 64(%rsp), %r11\\n\"\n  \"\\n\"\n  \"  movq  96(%rsp), %xmm0\\n\"\n  \"  movq 112(%rsp), %xmm1\\n\"\n  \"  movq 128(%rsp), %xmm2\\n\"\n  \"  movq 144(%rsp), %xmm3\\n\"\n  \"  movq 160(%rsp), %xmm4\\n\"\n  \"  movq 176(%rsp), %xmm5\\n\"\n  \"  movq 192(%rsp), %xmm6\\n\"\n  \"  movq 208(%rsp), %xmm7\\n\"\n  \"  movq 224(%rsp), %xmm8\\n\"\n  \"  movq 240(%rsp), %xmm9\\n\"\n  \"  movq 256(%rsp), %xmm10\\n\"\n  \"  movq 272(%rsp), %xmm11\\n\"\n  \"  movq 288(%rsp), %xmm12\\n\"\n  \"  movq 304(%rsp), %xmm13\\n\"\n  \"  movq 320(%rsp), %xmm14\\n\"\n  \"  movq 336(%rsp), %xmm15\\n\"\n  \"\\n\"\n  \"  leaq 352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  jmp  __afl_store\\n\"\n  \"\\n\"\n  \"__afl_die:\\n\"\n  \"\\n\"\n  \"  xorq %rax, %rax\\n\"\n  CALL_L64(\"_exit\")\n  \"\\n\"\n  \"__afl_setup_abort:\\n\"\n  \"\\n\"\n  \"  /* Record setup failure so that we don't keep calling\\n\"\n  \"     shmget() / shmat() over and over again. */\\n\"\n  \"\\n\"\n  \"  incb __afl_setup_failure(%rip)\\n\"\n  \"\\n\"\n  \"  movq %r12, %rsp\\n\"\n  \"  popq %r12\\n\"\n  \"\\n\"\n  \"  movq  0(%rsp), %rax\\n\"\n  \"  movq  8(%rsp), %rcx\\n\"\n  \"  movq 16(%rsp), %rdi\\n\"\n  \"  movq 32(%rsp), %rsi\\n\"\n  \"  movq 40(%rsp), %r8\\n\"\n  \"  movq 48(%rsp), %r9\\n\"\n  \"  movq 56(%rsp), %r10\\n\"\n  \"  movq 64(%rsp), %r11\\n\"\n  \"\\n\"\n  \"  movq  96(%rsp), %xmm0\\n\"\n  \"  movq 112(%rsp), %xmm1\\n\"\n  \"  movq 128(%rsp), %xmm2\\n\"\n  \"  movq 144(%rsp), %xmm3\\n\"\n  \"  movq 160(%rsp), %xmm4\\n\"\n  \"  movq 176(%rsp), %xmm5\\n\"\n  \"  movq 192(%rsp), %xmm6\\n\"\n  \"  movq 208(%rsp), %xmm7\\n\"\n  \"  movq 224(%rsp), %xmm8\\n\"\n  \"  movq 240(%rsp), %xmm9\\n\"\n  \"  movq 256(%rsp), %xmm10\\n\"\n  \"  movq 272(%rsp), %xmm11\\n\"\n  \"  movq 288(%rsp), %xmm12\\n\"\n  \"  movq 304(%rsp), %xmm13\\n\"\n  \"  movq 320(%rsp), %xmm14\\n\"\n  \"  movq 336(%rsp), %xmm15\\n\"\n  \"\\n\"\n  \"  leaq 352(%rsp), %rsp\\n\"\n  \"\\n\"\n  \"  jmp __afl_return\\n\"\n  \"\\n\"\n  \".AFL_VARS:\\n\"\n  \"\\n\"\n\n#ifdef __APPLE__\n\n  \"  .comm   __afl_area_ptr, 8\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .comm   __afl_prev_loc, 8\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .comm   __afl_fork_pid, 4\\n\"\n  \"  .comm   __afl_temp, 4\\n\"\n  \"  .comm   __afl_setup_failure, 1\\n\"\n\n#else\n\n  \"  .lcomm   __afl_area_ptr, 8\\n\"\n#ifndef COVERAGE_ONLY\n  \"  .lcomm   __afl_prev_loc, 8\\n\"\n#endif /* !COVERAGE_ONLY */\n  \"  .lcomm   __afl_fork_pid, 4\\n\"\n  \"  .lcomm   __afl_temp, 4\\n\"\n  \"  .lcomm   __afl_setup_failure, 1\\n\"\n\n#endif /* ^__APPLE__ */\n\n  \"  .comm    __afl_global_area_ptr, 8, 8\\n\"\n  \"\\n\"\n  \".AFL_SHM_ENV:\\n\"\n  \"  .asciz \\\"\" SHM_ENV_VAR \"\\\"\\n\"\n  \"\\n\"\n  \"/* --- END --- */\\n\"\n  \"\\n\";\n\n#endif /* !_HAVE_AFL_AS_H */\n"
  },
  {
    "path": "afl-cmin",
    "content": "#!/usr/bin/env bash\n#\n# american fuzzy lop - corpus minimization tool\n# ---------------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2014, 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This tool tries to find the smallest subset of files in the input directory\n# that still trigger the full range of instrumentation data points seen in\n# the starting corpus. This has two uses:\n#\n#   - Screening large corpora of input files before using them as a seed for\n#     afl-fuzz. The tool will remove functionally redundant files and likely\n#     leave you with a much smaller set.\n#\n#     (In this case, you probably also want to consider running afl-tmin on\n#     the individual files later on to reduce their size.)\n#\n#   - Minimizing the corpus generated organically by afl-fuzz, perhaps when\n#     planning to feed it to more resource-intensive tools. The tool achieves\n#     this by removing all entries that used to trigger unique behaviors in the\n#     past, but have been made obsolete by later finds.\n#\n# Note that the tool doesn't modify the files themselves. For that, you want\n# afl-tmin.\n#\n# This script must use bash because other shells may have hardcoded limits on\n# array sizes.\n#\n\necho \"corpus minimization tool for afl-fuzz by <lcamtuf@google.com>\"\necho\n\n#########\n# SETUP #\n#########\n\n# Process command-line options...\n\nMEM_LIMIT=100\nTIMEOUT=none\n\nunset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN \\\n  AFL_CMIN_CRASHES_ONLY AFL_CMIN_ALLOW_ANY QEMU_MODE\n\nwhile getopts \"+i:o:f:m:t:eQC\" opt; do\n\n  case \"$opt\" in \n\n    \"i\")\n         IN_DIR=\"$OPTARG\"\n         ;;\n\n    \"o\")\n         OUT_DIR=\"$OPTARG\"\n         ;;\n    \"f\")\n         STDIN_FILE=\"$OPTARG\"\n         ;;\n    \"m\")\n         MEM_LIMIT=\"$OPTARG\"\n         MEM_LIMIT_GIVEN=1\n         ;;\n    \"t\")\n         TIMEOUT=\"$OPTARG\"\n         ;;\n    \"e\")\n         EXTRA_PAR=\"$EXTRA_PAR -e\"\n         ;;\n    \"C\")\n         export AFL_CMIN_CRASHES_ONLY=1\n         ;;\n    \"Q\")\n         EXTRA_PAR=\"$EXTRA_PAR -Q\"\n         test \"$MEM_LIMIT_GIVEN\" = \"\" && MEM_LIMIT=250\n         QEMU_MODE=1\n         ;;\n    \"?\")\n         exit 1\n         ;;\n\n   esac\n\ndone\n\nshift $((OPTIND-1))\n\nTARGET_BIN=\"$1\"\n\nif [ \"$TARGET_BIN\" = \"\" -o \"$IN_DIR\" = \"\" -o \"$OUT_DIR\" = \"\" ]; then\n\n  cat 1>&2 <<_EOF_\nUsage: $0 [ options ] -- /path/to/target_app [ ... ]\n\nRequired parameters:\n\n  -i dir        - input directory with the starting corpus\n  -o dir        - output directory for minimized files\n\nExecution control settings:\n\n  -f file       - location read by the fuzzed program (stdin)\n  -m megs       - memory limit for child process ($MEM_LIMIT MB)\n  -t msec       - run time limit for child process (none)\n  -Q            - use binary-only instrumentation (QEMU mode)\n\nMinimization settings:\n\n  -C            - keep crashing inputs, reject everything else\n  -e            - solve for edge coverage only, ignore hit counts\n\nFor additional tips, please consult docs/README.\n\n_EOF_\n  exit 1\nfi\n\n# Do a sanity check to discourage the use of /tmp, since we can't really\n# handle this safely from a shell script.\n\necho \"$IN_DIR\" | grep -qE '^(/var)?/tmp/'\nT1=\"$?\"\n\necho \"$TARGET_BIN\" | grep -qE '^(/var)?/tmp/'\nT2=\"$?\"\n\necho \"$OUT_DIR\" | grep -qE '^(/var)?/tmp/'\nT3=\"$?\"\n\necho \"$STDIN_FILE\" | grep -qE '^(/var)?/tmp/'\nT4=\"$?\"\n\necho \"$PWD\" | grep -qE '^(/var)?/tmp/'\nT5=\"$?\"\n\nif [ \"$T1\" = \"0\" -o \"$T2\" = \"0\" -o \"$T3\" = \"0\" -o \"$T4\" = \"0\" -o \"$T5\" = \"0\" ]; then\n  echo \"[-] Error: do not use this script in /tmp or /var/tmp.\" 1>&2\n  exit 1\nfi\n\n# If @@ is specified, but there's no -f, let's come up with a temporary input\n# file name.\n\nTRACE_DIR=\"$OUT_DIR/.traces\"\n\nif [ \"$STDIN_FILE\" = \"\" ]; then\n\n  if echo \"$*\" | grep -qF '@@'; then\n    STDIN_FILE=\"$TRACE_DIR/.cur_input\"\n  fi\n\nfi\n\n# Check for obvious errors.\n\nif [ ! \"$MEM_LIMIT\" = \"none\" ]; then\n\n  if [ \"$MEM_LIMIT\" -lt \"5\" ]; then\n    echo \"[-] Error: dangerously low memory limit.\" 1>&2\n    exit 1\n  fi\n\nfi\n\nif [ ! \"$TIMEOUT\" = \"none\" ]; then\n\n  if [ \"$TIMEOUT\" -lt \"10\" ]; then\n    echo \"[-] Error: dangerously low timeout.\" 1>&2\n    exit 1\n  fi\n\nfi\n\nif [ ! -f \"$TARGET_BIN\" -o ! -x \"$TARGET_BIN\" ]; then\n\n  TNEW=\"`which \"$TARGET_BIN\" 2>/dev/null`\"\n\n  if [ ! -f \"$TNEW\" -o ! -x \"$TNEW\" ]; then\n    echo \"[-] Error: binary '$TARGET_BIN' not found or not executable.\" 1>&2\n    exit 1\n  fi\n\n  TARGET_BIN=\"$TNEW\"\n\nfi\n\nif [ \"$AFL_SKIP_BIN_CHECK\" = \"\" -a \"$QEMU_MODE\" = \"\" ]; then\n\n  if ! grep -qF \"__AFL_SHM_ID\" \"$TARGET_BIN\"; then\n    echo \"[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented.\" 1>&2\n    exit 1\n  fi\n\nfi\n\nif [ ! -d \"$IN_DIR\" ]; then\n  echo \"[-] Error: directory '$IN_DIR' not found.\" 1>&2\n  exit 1\nfi\n\ntest -d \"$IN_DIR/queue\" && IN_DIR=\"$IN_DIR/queue\"\n\nfind \"$OUT_DIR\" -name 'id[:_]*' -maxdepth 1 -exec rm -- {} \\; 2>/dev/null\nrm -rf \"$TRACE_DIR\" 2>/dev/null\n\nrmdir \"$OUT_DIR\" 2>/dev/null\n\nif [ -d \"$OUT_DIR\" ]; then\n  echo \"[-] Error: directory '$OUT_DIR' exists and is not empty - delete it first.\" 1>&2\n  exit 1\nfi\n\nmkdir -m 700 -p \"$TRACE_DIR\" || exit 1\n\nif [ ! \"$STDIN_FILE\" = \"\" ]; then\n  rm -f \"$STDIN_FILE\" || exit 1\n  touch \"$STDIN_FILE\" || exit 1\nfi\n\nif [ \"$AFL_PATH\" = \"\" ]; then\n  SHOWMAP=\"${0%/afl-cmin}/afl-showmap\"\nelse\n  SHOWMAP=\"$AFL_PATH/afl-showmap\"\nfi\n\nif [ ! -x \"$SHOWMAP\" ]; then\n  echo \"[-] Error: can't find 'afl-showmap' - please set AFL_PATH.\" 1>&2\n  rm -rf \"$TRACE_DIR\"\n  exit 1\nfi\n\nIN_COUNT=$((`ls -- \"$IN_DIR\" 2>/dev/null | wc -l`))\n\nif [ \"$IN_COUNT\" = \"0\" ]; then\n  echo \"No inputs in the target directory - nothing to be done.\"\n  rm -rf \"$TRACE_DIR\"\n  exit 1\nfi\n\nFIRST_FILE=`ls \"$IN_DIR\" | head -1`\n\nif ln \"$IN_DIR/$FIRST_FILE\" \"$TRACE_DIR/.link_test\" 2>/dev/null; then\n  CP_TOOL=ln\nelse\n  CP_TOOL=cp\nfi\n\n# Make sure that we can actually get anything out of afl-showmap before we\n# waste too much time.\n\necho \"[*] Testing the target binary...\"\n\nif [ \"$STDIN_FILE\" = \"\" ]; then\n\n  AFL_CMIN_ALLOW_ANY=1 \"$SHOWMAP\" -m \"$MEM_LIMIT\" -t \"$TIMEOUT\" -o \"$TRACE_DIR/.run_test\" -Z $EXTRA_PAR -- \"$@\" <\"$IN_DIR/$FIRST_FILE\"\n\nelse\n\n  cp \"$IN_DIR/$FIRST_FILE\" \"$STDIN_FILE\"\n  AFL_CMIN_ALLOW_ANY=1 \"$SHOWMAP\" -m \"$MEM_LIMIT\" -t \"$TIMEOUT\" -o \"$TRACE_DIR/.run_test\" -Z $EXTRA_PAR -A \"$STDIN_FILE\" -- \"$@\" </dev/null\n\nfi\n\nFIRST_COUNT=$((`grep -c . \"$TRACE_DIR/.run_test\"`))\n\nif [ \"$FIRST_COUNT\" -gt \"0\" ]; then\n\n  echo \"[+] OK, $FIRST_COUNT tuples recorded.\"\n\nelse\n\n  echo \"[-] Error: no instrumentation output detected (perhaps crash or timeout).\" 1>&2\n  test \"$AFL_KEEP_TRACES\" = \"\" && rm -rf \"$TRACE_DIR\"\n  exit 1\n\nfi\n\n# Let's roll!\n\n#############################\n# STEP 1: COLLECTING TRACES #\n#############################\n\necho \"[*] Obtaining traces for input files in '$IN_DIR'...\"\n\n(\n\n  CUR=0\n\n  if [ \"$STDIN_FILE\" = \"\" ]; then\n\n    while read -r fn; do\n\n      CUR=$((CUR+1))\n      printf \"\\\\r    Processing file $CUR/$IN_COUNT... \"\n\n      \"$SHOWMAP\" -m \"$MEM_LIMIT\" -t \"$TIMEOUT\" -o \"$TRACE_DIR/$fn\" -Z $EXTRA_PAR -- \"$@\" <\"$IN_DIR/$fn\"\n\n    done < <(ls \"$IN_DIR\")\n\n  else\n\n    while read -r fn; do\n\n      CUR=$((CUR+1))\n      printf \"\\\\r    Processing file $CUR/$IN_COUNT... \"\n\n      cp \"$IN_DIR/$fn\" \"$STDIN_FILE\"\n\n      \"$SHOWMAP\" -m \"$MEM_LIMIT\" -t \"$TIMEOUT\" -o \"$TRACE_DIR/$fn\" -Z $EXTRA_PAR -A \"$STDIN_FILE\" -- \"$@\" </dev/null\n\n    done < <(ls \"$IN_DIR\")\n\n\n  fi\n\n)\n\necho\n\n##########################\n# STEP 2: SORTING TUPLES #\n##########################\n\n# With this out of the way, we sort all tuples by popularity across all\n# datasets. The reasoning here is that we won't be able to avoid the files\n# that trigger unique tuples anyway, so we will want to start with them and\n# see what's left.\n\necho \"[*] Sorting trace sets (this may take a while)...\"\n\nls \"$IN_DIR\" | sed \"s#^#$TRACE_DIR/#\" | tr '\\n' '\\0' | xargs -0 -n 1 cat | \\\n  sort | uniq -c | sort -n >\"$TRACE_DIR/.all_uniq\"\n\nTUPLE_COUNT=$((`grep -c . \"$TRACE_DIR/.all_uniq\"`))\n\necho \"[+] Found $TUPLE_COUNT unique tuples across $IN_COUNT files.\"\n\n#####################################\n# STEP 3: SELECTING CANDIDATE FILES #\n#####################################\n\n# The next step is to find the best candidate for each tuple. The \"best\"\n# part is understood simply as the smallest input that includes a particular\n# tuple in its trace. Empirical evidence suggests that this produces smaller\n# datasets than more involved algorithms that could be still pulled off in\n# a shell script.\n\necho \"[*] Finding best candidates for each tuple...\"\n\nCUR=0\n\nwhile read -r fn; do\n\n  CUR=$((CUR+1))\n  printf \"\\\\r    Processing file $CUR/$IN_COUNT... \"\n\n  sed \"s#\\$# $fn#\" \"$TRACE_DIR/$fn\" >>\"$TRACE_DIR/.candidate_list\"\n\ndone < <(ls -rS \"$IN_DIR\")\n\necho\n\n##############################\n# STEP 4: LOADING CANDIDATES #\n##############################\n\n# At this point, we have a file of tuple-file pairs, sorted by file size\n# in ascending order (as a consequence of ls -rS). By doing sort keyed\n# only by tuple (-k 1,1) and configured to output only the first line for\n# every key (-s -u), we end up with the smallest file for each tuple.\n\necho \"[*] Sorting candidate list (be patient)...\"\n\nsort -k1,1 -s -u \"$TRACE_DIR/.candidate_list\" | \\\n  sed 's/^/BEST_FILE[/;s/ /]=\"/;s/$/\"/' >\"$TRACE_DIR/.candidate_script\"\n\nif [ ! -s \"$TRACE_DIR/.candidate_script\" ]; then\n  echo \"[-] Error: no traces obtained from test cases, check syntax!\"\n  test \"$AFL_KEEP_TRACES\" = \"\" && rm -rf \"$TRACE_DIR\"\n  exit 1\nfi\n\n# The sed command converted the sorted list to a shell script that populates\n# BEST_FILE[tuple]=\"fname\". Let's load that!\n\n. \"$TRACE_DIR/.candidate_script\"\n\n##########################\n# STEP 5: WRITING OUTPUT #\n##########################\n\n# The final trick is to grab the top pick for each tuple, unless said tuple is\n# already set due to the inclusion of an earlier candidate; and then put all\n# tuples associated with the newly-added file to the \"already have\" list. The\n# loop works from least popular tuples and toward the most common ones.\n\necho \"[*] Processing candidates and writing output files...\"\n\nCUR=0\n\ntouch \"$TRACE_DIR/.already_have\"\n\nwhile read -r cnt tuple; do\n\n  CUR=$((CUR+1))\n  printf \"\\\\r    Processing tuple $CUR/$TUPLE_COUNT... \"\n\n  # If we already have this tuple, skip it.\n\n  grep -q \"^$tuple\\$\" \"$TRACE_DIR/.already_have\" && continue\n\n  FN=${BEST_FILE[tuple]}\n\n  $CP_TOOL \"$IN_DIR/$FN\" \"$OUT_DIR/$FN\"\n\n  if [ \"$((CUR % 5))\" = \"0\" ]; then\n    sort -u \"$TRACE_DIR/$FN\" \"$TRACE_DIR/.already_have\" >\"$TRACE_DIR/.tmp\"\n    mv -f \"$TRACE_DIR/.tmp\" \"$TRACE_DIR/.already_have\"\n  else\n    cat \"$TRACE_DIR/$FN\" >>\"$TRACE_DIR/.already_have\"\n  fi\n\ndone <\"$TRACE_DIR/.all_uniq\"\n\necho\n\nOUT_COUNT=`ls -- \"$OUT_DIR\" | wc -l`\n\nif [ \"$OUT_COUNT\" = \"1\" ]; then\n  echo \"[!] WARNING: All test cases had the same traces, check syntax!\"\nfi\n\necho \"[+] Narrowed down to $OUT_COUNT files, saved in '$OUT_DIR'.\"\necho\n\ntest \"$AFL_KEEP_TRACES\" = \"\" && rm -rf \"$TRACE_DIR\"\n\nexit 0\n"
  },
  {
    "path": "afl-fuzz.c",
    "content": "/*\n   american fuzzy lop - fuzzer code\n   --------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Forkserver design by Jann Horn <jannhorn@googlemail.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This is the real deal: the program takes an instrumented binary and\n   attempts a variety of basic fuzzing tricks, paying close attention to\n   how they affect the execution path.\n\n */\n\n#define AFL_MAIN\n#define MESSAGES_TO_STDOUT\n\n#define _GNU_SOURCE\n#define _FILE_OFFSET_BITS 64\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n#include \"hash.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <signal.h>\n#include <dirent.h>\n#include <ctype.h>\n#include <fcntl.h>\n#include <termios.h>\n#include <dlfcn.h>\n#include <netdb.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n#include <sys/shm.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n#include <sys/mman.h>\n#include <sys/ioctl.h>\n#include <sys/file.h>\n#include <sys/socket.h>\n#include <arpa/inet.h>\n#include <sys/sendfile.h>\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)\n#  include <sys/sysctl.h>\n#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */\n\n\n/* Lots of globals, but mostly for the status UI and other things where it\n   really makes no sense to haul them around as function parameters. */\n\nstatic u8 *in_dir,                    /* Input directory with test cases  */\n          *out_file,                  /* File to fuzz, if any             */\n          *out_dir,                   /* Working & output directory       */\n          *sync_dir,                  /* Synchronization directory        */\n          *sync_id,                   /* Fuzzer ID                        */\n          *use_banner,                /* Display banner                   */\n          *in_bitmap,                 /* Input bitmap                     */\n          *doc_path,                  /* Path to documentation dir        */\n          *target_path,               /* Path to target binary            */\n          *orig_cmdline;              /* Original command line            */\n\nstatic u32 exec_tmout = EXEC_TIMEOUT; /* Configurable exec timeout (ms)   */\nstatic u64 mem_limit = MEM_LIMIT;     /* Memory cap for child (MB)        */\n\nstatic u32 stats_update_freq = 1;     /* Stats update frequency (execs)   */\n\nstatic u8  skip_deterministic,        /* Skip deterministic stages?       */\n           force_deterministic,       /* Force deterministic stages?      */\n           use_splicing,              /* Recombine input files?           */\n           dumb_mode,                 /* Run in non-instrumented mode?    */\n           score_changed,             /* Scoring for favorites changed?   */\n           kill_signal,               /* Signal that killed the child     */\n           resuming_fuzz,             /* Resuming an older fuzzing job?   */\n           timeout_given,             /* Specific timeout given?          */\n           not_on_tty,                /* stdout is not a tty              */\n           term_too_small,            /* terminal dimensions too small    */\n           uses_asan,                 /* Target uses ASAN?                */\n           no_forkserver,             /* Disable forkserver?              */\n           crash_mode,                /* Crash mode! Yeah!                */\n           in_place_resume,           /* Attempt in-place resume?         */\n           auto_changed,              /* Auto-generated tokens changed?   */\n           no_cpu_meter_red,          /* Feng shui on the status screen   */\n           no_var_check,              /* Don't detect variable behavior   */\n           bitmap_changed = 1,        /* Time to update bitmap?           */\n           qemu_mode,                 /* Running in QEMU mode?            */\n           skip_requested,            /* Skip request, via SIGUSR1        */\n           run_over10m;               /* Run time over 10 minutes?        */\n\nstatic s32 out_fd,                    /* Persistent fd for out_file       */\n           dev_urandom_fd = -1,       /* Persistent fd for /dev/urandom   */\n           dev_null_fd = -1,          /* Persistent fd for /dev/null      */\n           fsrv_ctl_fd,               /* Fork server control pipe (write) */\n           fsrv_st_fd;                /* Fork server status pipe (read)   */\n\nstatic s32 forksrv_pid,               /* PID of the fork server           */\n           child_pid = -1,            /* PID of the fuzzed program        */\n           out_dir_fd = -1;           /* FD of the lock file              */\n\nstatic u8* trace_bits;                /* SHM with instrumentation bitmap  */\n\nstatic u8  virgin_bits[MAP_SIZE],     /* Regions yet untouched by fuzzing */\n           virgin_hang[MAP_SIZE],     /* Bits we haven't seen in hangs    */\n           virgin_crash[MAP_SIZE];    /* Bits we haven't seen in crashes  */\n\nstatic s32 shm_id;                    /* ID of the SHM region             */\n\nstatic volatile u8 stop_soon,         /* Ctrl-C pressed?                  */\n                   clear_screen = 1,  /* Window resized?                  */\n                   child_timed_out;   /* Traced process timed out?        */\n\nstatic u32 queued_paths,              /* Total number of queued testcases */\n           queued_variable,           /* Testcases with variable behavior */\n           queued_at_start,           /* Total number of initial inputs   */\n           queued_discovered,         /* Items discovered during this run */\n           queued_imported,           /* Items imported via -S            */\n           queued_favored,            /* Paths deemed favorable           */\n           queued_with_cov,           /* Paths with new coverage bytes    */\n           pending_not_fuzzed,        /* Queued but not done yet          */\n           pending_favored,           /* Pending favored paths            */\n           cur_skipped_paths,         /* Abandoned inputs in cur cycle    */\n           cur_depth,                 /* Current path depth               */\n           max_depth,                 /* Max path depth                   */\n           useless_at_start,          /* Number of useless starting paths */\n           current_entry,             /* Current queue entry ID           */\n           havoc_div = 1;             /* Cycle count divisor for havoc    */\n\nstatic u64 total_crashes,             /* Total number of crashes          */\n           unique_crashes,            /* Crashes with unique signatures   */\n           total_hangs,               /* Total number of hangs            */\n           unique_hangs,              /* Hangs with unique signatures     */\n           total_execs,               /* Total execve() calls             */\n           start_time,                /* Unix start time (ms)             */\n           last_path_time,            /* Time for most recent path (ms)   */\n           last_crash_time,           /* Time for most recent crash (ms)  */\n           last_hang_time,            /* Time for most recent hang (ms)   */\n           queue_cycle,               /* Queue round counter              */\n           cycles_wo_finds,           /* Cycles without any new paths     */\n           trim_execs,                /* Execs done to trim input files   */\n           bytes_trim_in,             /* Bytes coming into the trimmer    */\n           bytes_trim_out,            /* Bytes coming outa the trimmer    */\n           blocks_eff_total,          /* Blocks subject to effector maps  */\n           blocks_eff_select;         /* Blocks selected as fuzzable      */\n\nstatic u32 subseq_hangs;              /* Number of hangs in a row         */\n\nstatic u8 *stage_name = \"init\",       /* Name of the current fuzz stage   */\n          *stage_short,               /* Short stage name                 */\n          *syncing_party;             /* Currently syncing with...        */\n\nstatic s32 stage_cur, stage_max;      /* Stage progression                */\nstatic s32 splicing_with = -1;        /* Splicing with which test case?   */\n\nstatic u32 syncing_case;              /* Syncing with case #...           */\n\nstatic s32 stage_cur_byte,            /* Byte offset of current stage op  */\n           stage_cur_val;             /* Value used for stage op          */\n\nstatic u8  stage_val_type;            /* Value type (STAGE_VAL_*)         */\n\nstatic u64 stage_finds[32],           /* Patterns found per fuzz stage    */\n           stage_cycles[32];          /* Execs per fuzz stage             */\n\nstatic u32 rand_cnt;                  /* Random number counter            */\n\nstatic u64 total_cal_us,              /* Total calibration time (us)      */\n           total_cal_cycles;          /* Total calibration cycles         */\n\nstatic u64 total_bitmap_size,         /* Total bit count for all bitmaps  */\n           total_bitmap_entries;      /* Number of bitmaps counted        */\n\nstatic u32 cpu_core_count;            /* CPU core count                   */\n\nstatic FILE* plot_file;               /* Gnuplot output file              */\n\n/* Globals for network support */\n\nstatic struct addrinfo *N_results = NULL, /* for results from getaddrinfo() */\n                       *N_rp = NULL;      /* to iterate through N_results[] */\n\nstatic struct sockaddr_storage N_myaddr; /* to hold send port info        */\nstatic struct sockaddr_storage N_server_addr; /* and server (send side)   */\nstatic socklen_t N_myaddrlen = sizeof (struct sockaddr_storage);\n                                      /* and length of both               */\n\nstatic u32 N_option_specified = 0;    /* 1 if a -N option is present      */\nstatic u8* N_option_string = 0;       /* points to copy of -N option str  */\nstatic u32 N_slen = 0;                /* length of the -N option string   */\nstatic u32 N_valid = 0;               /* 1 if valid URL option to -N      */\nstatic u32 N_fuzz_client = 0;         /* 1 if target is a network client  */\nstatic u32 N_myaddr_valid = 0;        /* use established conn or addr     */\nstatic s32 N_fd;                      /* for network file descriptor      */\n\nstatic u32 N_timeout_given = 0;       /* use delay before network I/O     */\nstatic u32 N_exec_tmout = 0;          /* network I/O delay in msec        */\nstatic struct timespec N_it;          /* structure for nanosleep() call   */\n\n\nstruct queue_entry {\n\n  u8* fname;                          /* File name for the test case      */\n  u32 len;                            /* Input length                     */\n\n  u8  cal_failed,                     /* Calibration failed?              */\n      trim_done,                      /* Trimmed?                         */\n      was_fuzzed,                     /* Had any fuzzing done yet?        */\n      passed_det,                     /* Deterministic stages passed?     */\n      has_new_cov,                    /* Triggers new coverage?           */\n      var_behavior,                   /* Variable behavior?               */\n      favored,                        /* Currently favored?               */\n      fs_redundant;                   /* Marked as redundant in the fs?   */\n\n  u32 bitmap_size,                    /* Number of bits set in bitmap     */\n      exec_cksum;                     /* Checksum of the execution trace  */\n\n  u64 exec_us,                        /* Execution time (us)              */\n      handicap,                       /* Number of queue cycles behind    */\n      depth;                          /* Path depth                       */\n\n  u8* trace_mini;                     /* Trace bytes, if kept             */\n  u32 tc_ref;                         /* Trace bytes ref count            */\n\n  struct queue_entry *next,           /* Next element, if any             */\n                     *next_100;       /* 100 elements ahead               */\n\n};\n\nstatic struct queue_entry *queue,     /* Fuzzing queue (linked list)      */\n                          *queue_cur, /* Current offset within the queue  */\n                          *queue_top, /* Top of the list                  */\n                          *q_prev100; /* Previous 100 marker              */\n\nstatic struct queue_entry*\n  top_rated[MAP_SIZE];                /* Top entries for bitmap bytes     */\n\nstruct extra_data {\n  u8* data;                           /* Dictionary token data            */\n  u32 len;                            /* Dictionary token length          */\n  u32 hit_cnt;                        /* Use count in the corpus          */\n};\n\nstatic struct extra_data* extras;     /* Extra tokens to fuzz with        */\nstatic u32 extras_cnt;                /* Total number of tokens read      */\n\nstatic struct extra_data* a_extras;   /* Automatically selected extras    */\nstatic u32 a_extras_cnt;              /* Total number of tokens available */\n\nstatic u8* (*post_handler)(u8* buf, u32* len);\n\n/* Interesting values, as per config.h */\n\nstatic s8  interesting_8[]  = { INTERESTING_8 };\nstatic s16 interesting_16[] = { INTERESTING_8, INTERESTING_16 };\nstatic s32 interesting_32[] = { INTERESTING_8, INTERESTING_16, INTERESTING_32 };\n\n/* Fuzzing stages */\n\nenum {\n  /* 00 */ STAGE_FLIP1,\n  /* 01 */ STAGE_FLIP2,\n  /* 02 */ STAGE_FLIP4,\n  /* 03 */ STAGE_FLIP8,\n  /* 04 */ STAGE_FLIP16,\n  /* 05 */ STAGE_FLIP32,\n  /* 06 */ STAGE_ARITH8,\n  /* 07 */ STAGE_ARITH16,\n  /* 08 */ STAGE_ARITH32,\n  /* 09 */ STAGE_INTEREST8,\n  /* 10 */ STAGE_INTEREST16,\n  /* 11 */ STAGE_INTEREST32,\n  /* 12 */ STAGE_EXTRAS_UO,\n  /* 13 */ STAGE_EXTRAS_UI,\n  /* 14 */ STAGE_EXTRAS_AO,\n  /* 15 */ STAGE_HAVOC,\n  /* 16 */ STAGE_SPLICE\n};\n\n/* Stage value types */\n\nenum {\n  /* 00 */ STAGE_VAL_NONE,\n  /* 01 */ STAGE_VAL_LE,\n  /* 02 */ STAGE_VAL_BE\n};\n\n/* Execution status fault codes */\n\nenum {\n  /* 00 */ FAULT_NONE,\n  /* 01 */ FAULT_HANG,\n  /* 02 */ FAULT_CRASH,\n  /* 03 */ FAULT_ERROR,\n  /* 04 */ FAULT_NOINST,\n  /* 05 */ FAULT_NOBITS\n};\n\n\n/* Get unix time in milliseconds */\n\nstatic u64 get_cur_time(void) {\n\n  struct timeval tv;\n  struct timezone tz;\n\n  gettimeofday(&tv, &tz);\n\n  return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);\n\n}\n\n\n/* Get unix time in microseconds */\n\nstatic u64 get_cur_time_us(void) {\n\n  struct timeval tv;\n  struct timezone tz;\n\n  gettimeofday(&tv, &tz);\n\n  return (tv.tv_sec * 1000000ULL) + tv.tv_usec;\n\n}\n\n\n/* Generate a random number (from 0 to limit - 1). This may\n   have slight bias. */\n\nstatic inline u32 UR(u32 limit) {\n\n  if (!rand_cnt--) {\n\n    u32 seed[2];\n\n    ck_read(dev_urandom_fd, &seed, sizeof(seed), \"/dev/urandom\");\n\n    srandom(seed[0]);\n    rand_cnt = (RESEED_RNG / 2) + (seed[1] % RESEED_RNG);\n\n  }\n\n  return random() % limit;\n\n}\n\n\n#ifndef IGNORE_FINDS\n\n/* Helper function to compare buffers; returns first and last differing offset. We\n   use this to find reasonable locations for splicing two files. */\n\nstatic void locate_diffs(u8* ptr1, u8* ptr2, u32 len, s32* first, s32* last) {\n\n  s32 f_loc = -1;\n  s32 l_loc = -1;\n  u32 pos;\n\n  for (pos = 0; pos < len; pos++) {\n\n    if (*(ptr1++) != *(ptr2++)) {\n\n      if (f_loc == -1) f_loc = pos;\n      l_loc = pos;\n\n    }\n\n  }\n\n  *first = f_loc;\n  *last = l_loc;\n\n  return;\n\n}\n\n#endif /* !IGNORE_FINDS */\n\n\n/* Describe integer. Uses 12 cyclic static buffers for return values. The value\n   returned should be five characters or less for all the integers we reasonably\n   expect to see. */\n\nstatic u8* DI(u64 val) {\n\n  static u8 tmp[12][16];\n  static u8 cur;\n\n  cur = (cur + 1) % 12;\n\n#define CHK_FORMAT(_divisor, _limit_mult, _fmt, _cast) do { \\\n    if (val < (_divisor) * (_limit_mult)) { \\\n      sprintf(tmp[cur], _fmt, ((_cast)val) / (_divisor)); \\\n      return tmp[cur]; \\\n    } \\\n  } while (0)\n\n  /* 0-9999 */\n  CHK_FORMAT(1, 10000, \"%llu\", u64);\n\n  /* 10.0k - 99.9k */\n  CHK_FORMAT(1000, 99.95, \"%0.01fk\", double);\n\n  /* 100k - 999k */\n  CHK_FORMAT(1000, 1000, \"%lluk\", u64);\n\n  /* 1.00M - 9.99M */\n  CHK_FORMAT(1000 * 1000, 9.995, \"%0.02fM\", double);\n\n  /* 10.0M - 99.9M */\n  CHK_FORMAT(1000 * 1000, 99.95, \"%0.01fM\", double);\n\n  /* 100M - 999M */\n  CHK_FORMAT(1000 * 1000, 1000, \"%lluM\", u64);\n\n  /* 1.00G - 9.99G */\n  CHK_FORMAT(1000LL * 1000 * 1000, 9.995, \"%0.02fG\", double);\n\n  /* 10.0G - 99.9G */\n  CHK_FORMAT(1000LL * 1000 * 1000, 99.95, \"%0.01fG\", double);\n\n  /* 100G - 999G */\n  CHK_FORMAT(1000LL * 1000 * 1000, 1000, \"%lluG\", u64);\n\n  /* 1.00T - 9.99G */\n  CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 9.995, \"%0.02fT\", double);\n\n  /* 10.0T - 99.9T */\n  CHK_FORMAT(1000LL * 1000 * 1000 * 1000, 99.95, \"%0.01fT\", double);\n\n  /* 100T+ */\n  strcpy(tmp[cur], \"infty\");\n  return tmp[cur];\n\n}\n\n\n/* Describe float. Similar to the above, except with a single \n   static buffer. */\n\nstatic u8* DF(double val) {\n\n  static u8 tmp[16];\n\n  if (val < 99.995) {\n    sprintf(tmp, \"%0.02f\", val);\n    return tmp;\n  }\n\n  if (val < 999.95) {\n    sprintf(tmp, \"%0.01f\", val);\n    return tmp;\n  }\n\n  return DI((u64)val);\n\n}\n\n\n/* Describe integer as memory size. */\n\nstatic u8* DMS(u64 val) {\n\n  static u8 tmp[12][16];\n  static u8 cur;\n\n  cur = (cur + 1) % 12;\n\n  /* 0-9999 */\n  CHK_FORMAT(1, 10000, \"%llu B\", u64);\n\n  /* 10.0k - 99.9k */\n  CHK_FORMAT(1024, 99.95, \"%0.01f kB\", double);\n\n  /* 100k - 999k */\n  CHK_FORMAT(1024, 1000, \"%llu kB\", u64);\n\n  /* 1.00M - 9.99M */\n  CHK_FORMAT(1024 * 1024, 9.995, \"%0.02f MB\", double);\n\n  /* 10.0M - 99.9M */\n  CHK_FORMAT(1024 * 1024, 99.95, \"%0.01f MB\", double);\n\n  /* 100M - 999M */\n  CHK_FORMAT(1024 * 1024, 1000, \"%llu MB\", u64);\n\n  /* 1.00G - 9.99G */\n  CHK_FORMAT(1024LL * 1024 * 1024, 9.995, \"%0.02f GB\", double);\n\n  /* 10.0G - 99.9G */\n  CHK_FORMAT(1024LL * 1024 * 1024, 99.95, \"%0.01f GB\", double);\n\n  /* 100G - 999G */\n  CHK_FORMAT(1024LL * 1024 * 1024, 1000, \"%llu GB\", u64);\n\n  /* 1.00T - 9.99G */\n  CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 9.995, \"%0.02f TB\", double);\n\n  /* 10.0T - 99.9T */\n  CHK_FORMAT(1024LL * 1024 * 1024 * 1024, 99.95, \"%0.01f TB\", double);\n\n#undef CHK_FORMAT\n\n  /* 100T+ */\n  strcpy(tmp[cur], \"infty\");\n  return tmp[cur];\n\n}\n\n\n/* Describe time delta. Returns one static buffer, 34 chars of less. */\n\nstatic u8* DTD(u64 cur_ms, u64 event_ms) {\n\n  static u8 tmp[64];\n  u64 delta;\n  s32 t_d, t_h, t_m, t_s;\n\n  if (!event_ms) return \"none seen yet\";\n\n  delta = cur_ms - event_ms;\n\n  t_d = delta / 1000 / 60 / 60 / 24;\n  t_h = (delta / 1000 / 60 / 60) % 24;\n  t_m = (delta / 1000 / 60) % 60;\n  t_s = (delta / 1000) % 60;\n\n  sprintf(tmp, \"%s days, %u hrs, %u min, %u sec\", DI(t_d), t_h, t_m, t_s);\n  return tmp;\n\n}\n\n\n/* Mark deterministic checks as done for a particular queue entry. We use the\n   .state file to avoid repeating deterministic fuzzing when resuming aborted\n   scans. */\n\nstatic void mark_as_det_done(struct queue_entry* q) {\n\n  u8* fn = strrchr(q->fname, '/');\n  s32 fd;\n\n  fn = alloc_printf(\"%s/queue/.state/deterministic_done/%s\", out_dir, fn + 1);\n\n  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n  if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n  close(fd);\n\n  ck_free(fn);\n\n  q->passed_det = 1;\n\n}\n\n\n/* Mark as variable. Create symlinks if possible to make it easier to examine\n   the files. */\n\nstatic void mark_as_variable(struct queue_entry* q) {\n\n  u8 *fn = strrchr(q->fname, '/') + 1, *ldest;\n\n  ldest = alloc_printf(\"../../%s\", fn);\n  fn = alloc_printf(\"%s/queue/.state/variable_behavior/%s\", out_dir, fn);\n\n  if (symlink(ldest, fn)) {\n\n    s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n    close(fd);\n\n  }\n\n  ck_free(ldest);\n  ck_free(fn);\n\n  q->var_behavior = 1;\n\n}\n\n\n/* Mark / unmark as redundant (edge-only). This is not used for restoring state,\n   but may be useful for post-processing datasets. */\n\nstatic void mark_as_redundant(struct queue_entry* q, u8 state) {\n\n  u8* fn;\n  s32 fd;\n\n  if (state == q->fs_redundant) return;\n\n  q->fs_redundant = state;\n\n  fn = strrchr(q->fname, '/');\n  fn = alloc_printf(\"%s/queue/.state/redundant_edges/%s\", out_dir, fn + 1);\n\n  if (state) {\n\n    fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n    close(fd);\n\n  } else {\n\n    if (unlink(fn)) PFATAL(\"Unable to remove '%s'\", fn);\n\n  }\n\n  ck_free(fn);\n\n}\n\n\n/* Append new test case to the queue. */\n\nstatic void add_to_queue(u8* fname, u32 len, u8 passed_det) {\n\n  struct queue_entry* q = ck_alloc(sizeof(struct queue_entry));\n\n  q->fname        = fname;\n  q->len          = len;\n  q->depth        = cur_depth + 1;\n  q->passed_det   = passed_det;\n\n  if (q->depth > max_depth) max_depth = q->depth;\n\n  if (queue_top) {\n\n    queue_top->next = q;\n    queue_top = q;\n\n  } else q_prev100 = queue = queue_top = q;\n\n  queued_paths++;\n  pending_not_fuzzed++;\n\n  if (!(queued_paths % 100)) {\n\n    q_prev100->next_100 = q;\n    q_prev100 = q;\n\n  }\n\n  last_path_time = get_cur_time();\n\n}\n\n\n/* Destroy the entire queue. */\n\nstatic void destroy_queue(void) {\n\n  struct queue_entry *q = queue, *n;\n\n  while (q) {\n\n    n = q->next;\n    ck_free(q->fname);\n    ck_free(q->trace_mini);\n    ck_free(q);\n    q = n;\n\n  }\n\n}\n\n\n/* Write bitmap to file. The bitmap is useful mostly for the secret\n   -B option, to focus a separate fuzzing session on a particular\n   interesting input without rediscovering all the others. */\n\nstatic void write_bitmap(void) {\n\n  u8* fname;\n  s32 fd;\n\n  if (!bitmap_changed) return;\n  bitmap_changed = 0;\n\n  fname = alloc_printf(\"%s/fuzz_bitmap\", out_dir);\n  fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);\n\n  if (fd < 0) PFATAL(\"Unable to open '%s'\", fname);\n\n  ck_write(fd, virgin_bits, MAP_SIZE, fname);\n\n  close(fd);\n  ck_free(fname);\n\n}\n\n\n/* Read bitmap from file. This is for the -B option again. */\n\nstatic void read_bitmap(u8* fname) {\n\n  s32 fd = open(fname, O_RDONLY);\n\n  if (fd < 0) PFATAL(\"Unable to open '%s'\", fname);\n\n  ck_read(fd, virgin_bits, MAP_SIZE, fname);\n\n  close(fd);\n\n}\n\n\n/* Check if the current execution path brings anything new to the table.\n   Update virgin bits to reflect the finds. Returns 1 if the only change is\n   the hit-count for a particular tuple; 2 if there are new tuples seen. \n   Updates the map, so subsequent calls will always return 0.\n\n   This function is called after every exec() on a fairly large buffer, so\n   it needs to be fast. We do this in 32-bit and 64-bit flavors. */\n\n#define FFL(_b) (0xffULL << ((_b) << 3))\n#define FF(_b)  (0xff << ((_b) << 3))\n\nstatic inline u8 has_new_bits(u8* virgin_map) {\n\n#ifdef __x86_64__\n\n  u64* current = (u64*)trace_bits;\n  u64* virgin  = (u64*)virgin_map;\n\n  u32  i = (MAP_SIZE >> 3);\n\n#else\n\n  u32* current = (u32*)trace_bits;\n  u32* virgin  = (u32*)virgin_map;\n\n  u32  i = (MAP_SIZE >> 2);\n\n#endif /* ^__x86_64__ */\n\n  u8   ret = 0;\n\n  while (i--) {\n\n#ifdef __x86_64__\n\n    u64 cur = *current;\n    u64 vir = *virgin;\n\n#else\n\n    u32 cur = *current;\n    u32 vir = *virgin;\n\n#endif /* ^__x86_64__ */\n\n    /* Optimize for *current == ~*virgin, since this will almost always be the\n       case. */\n\n    if (cur & vir) {\n\n      if (ret < 2) {\n\n        /* This trace did not have any new bytes yet; see if there's any\n           current[] byte that is non-zero when virgin[] is 0xff. */\n\n#ifdef __x86_64__\n\n        if (((cur & FFL(0)) && (vir & FFL(0)) == FFL(0)) ||\n            ((cur & FFL(1)) && (vir & FFL(1)) == FFL(1)) ||\n            ((cur & FFL(2)) && (vir & FFL(2)) == FFL(2)) ||\n            ((cur & FFL(3)) && (vir & FFL(3)) == FFL(3)) ||\n            ((cur & FFL(4)) && (vir & FFL(4)) == FFL(4)) ||\n            ((cur & FFL(5)) && (vir & FFL(5)) == FFL(5)) ||\n            ((cur & FFL(6)) && (vir & FFL(6)) == FFL(6)) ||\n            ((cur & FFL(7)) && (vir & FFL(7)) == FFL(7))) ret = 2;\n        else ret = 1;\n\n#else\n\n        if (((cur & FF(0)) && (vir & FF(0)) == FF(0)) ||\n            ((cur & FF(1)) && (vir & FF(1)) == FF(1)) ||\n            ((cur & FF(2)) && (vir & FF(2)) == FF(2)) ||\n            ((cur & FF(3)) && (vir & FF(3)) == FF(3))) ret = 2;\n        else ret = 1;\n\n#endif /* ^__x86_64__ */\n\n      }\n\n      *virgin = vir & ~cur;\n\n    }\n\n    current++;\n    virgin++;\n\n  }\n\n  if (ret && virgin_map == virgin_bits) bitmap_changed = 1;\n\n  return ret;\n\n}\n\n\n/* Count the number of bits set in the provided bitmap. Used for the status\n   screen several times every second, does not have to be fast. */\n\nstatic u32 count_bits(u8* mem) {\n\n  u32* ptr = (u32*)mem;\n  u32  i   = (MAP_SIZE >> 2);\n  u32  ret = 0;\n\n  while (i--) {\n\n    u32 v = *(ptr++);\n\n    /* This gets called on the inverse, virgin bitmap; optimize for sparse\n       data. */\n\n    if (v == 0xffffffff) {\n      ret += 32;\n      continue;\n    }\n\n    v -= ((v >> 1) & 0x55555555);\n    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);\n    ret += (((v + (v >> 4)) & 0xF0F0F0F) * 0x01010101) >> 24;\n\n  }\n\n  return ret;\n\n}\n\n\n/* Count the number of bytes set in the bitmap. Called fairly sporadically,\n   mostly to update the status screen or calibrate and examine confirmed\n   new paths. */\n\nstatic u32 count_bytes(u8* mem) {\n\n  u32* ptr = (u32*)mem;\n  u32  i   = (MAP_SIZE >> 2);\n  u32  ret = 0;\n\n  while (i--) {\n\n    u32 v = *(ptr++);\n\n    if (!v) continue;\n    if (v & FF(0)) ret++;\n    if (v & FF(1)) ret++;\n    if (v & FF(2)) ret++;\n    if (v & FF(3)) ret++;\n\n  }\n\n  return ret;\n\n}\n\n\n/* Count the number of non-255 bytes set in the bitmap. Used strictly for the\n   status screen, several calls per second or so. */\n\nstatic u32 count_non_255_bytes(u8* mem) {\n\n  u32* ptr = (u32*)mem;\n  u32  i   = (MAP_SIZE >> 2);\n  u32  ret = 0;\n\n  while (i--) {\n\n    u32 v = *(ptr++);\n\n    /* This is called on the virgin bitmap, so optimize for the most likely\n       case. */\n\n    if (v == 0xffffffff) continue;\n    if ((v & FF(0)) != FF(0)) ret++;\n    if ((v & FF(1)) != FF(1)) ret++;\n    if ((v & FF(2)) != FF(2)) ret++;\n    if ((v & FF(3)) != FF(3)) ret++;\n\n  }\n\n  return ret;\n\n}\n\n\n/* Destructively simplify trace by eliminating hit count information\n   and replacing it with 0x80 or 0x01 depending on whether the tuple\n   is hit or not. Called on every new crash or hang, should be\n   reasonably fast. */\n\n#define AREP4(_sym)   (_sym), (_sym), (_sym), (_sym)\n#define AREP8(_sym)   AREP4(_sym), AREP4(_sym)\n#define AREP16(_sym)  AREP8(_sym), AREP8(_sym)\n#define AREP32(_sym)  AREP16(_sym), AREP16(_sym)\n#define AREP64(_sym)  AREP32(_sym), AREP32(_sym)\n#define AREP128(_sym) AREP64(_sym), AREP64(_sym)\n\nstatic u8 simplify_lookup[256] = { \n  /*    4 */ 1, 128, 128, 128,\n  /*   +4 */ AREP4(128),\n  /*   +8 */ AREP8(128),\n  /*  +16 */ AREP16(128),\n  /*  +32 */ AREP32(128),\n  /*  +64 */ AREP64(128),\n  /* +128 */ AREP128(128)\n};\n\n#ifdef __x86_64__\n\nstatic void simplify_trace(u64* mem) {\n\n  u32 i = MAP_SIZE >> 3;\n\n  while (i--) {\n\n    /* Optimize for sparse bitmaps. */\n\n    if (*mem) {\n\n      u8* mem8 = (u8*)mem;\n\n      mem8[0] = simplify_lookup[mem8[0]];\n      mem8[1] = simplify_lookup[mem8[1]];\n      mem8[2] = simplify_lookup[mem8[2]];\n      mem8[3] = simplify_lookup[mem8[3]];\n      mem8[4] = simplify_lookup[mem8[4]];\n      mem8[5] = simplify_lookup[mem8[5]];\n      mem8[6] = simplify_lookup[mem8[6]];\n      mem8[7] = simplify_lookup[mem8[7]];\n\n    } else *mem = 0x0101010101010101ULL;\n\n    mem++;\n\n  }\n\n}\n\n#else\n\nstatic void simplify_trace(u32* mem) {\n\n  u32 i = MAP_SIZE >> 2;\n\n  while (i--) {\n\n    /* Optimize for sparse bitmaps. */\n\n    if (*mem) {\n\n      u8* mem8 = (u8*)mem;\n\n      mem8[0] = simplify_lookup[mem8[0]];\n      mem8[1] = simplify_lookup[mem8[1]];\n      mem8[2] = simplify_lookup[mem8[2]];\n      mem8[3] = simplify_lookup[mem8[3]];\n\n    } else *mem = 0x01010101;\n\n    mem++;\n  }\n\n}\n\n#endif /* ^__x86_64__ */\n\n\n/* Destructively classify execution counts in a trace. This is used as a\n   preprocessing step for any newly acquired traces. Called on every exec,\n   must be fast. */\n\nstatic u8 count_class_lookup[256] = {\n\n  /* 0 - 3:       4 */ 0, 1, 2, 4,\n  /* 4 - 7:      +4 */ AREP4(8),\n  /* 8 - 15:     +8 */ AREP8(16),\n  /* 16 - 31:   +16 */ AREP16(32),\n  /* 32 - 127:  +96 */ AREP64(64), AREP32(64),\n  /* 128+:     +128 */ AREP128(128)\n\n};\n\n#ifdef __x86_64__\n\nstatic inline void classify_counts(u64* mem) {\n\n  u32 i = MAP_SIZE >> 3;\n\n  while (i--) {\n\n    /* Optimize for sparse bitmaps. */\n\n    if (*mem) {\n\n      u8* mem8 = (u8*)mem;\n\n      mem8[0] = count_class_lookup[mem8[0]];\n      mem8[1] = count_class_lookup[mem8[1]];\n      mem8[2] = count_class_lookup[mem8[2]];\n      mem8[3] = count_class_lookup[mem8[3]];\n      mem8[4] = count_class_lookup[mem8[4]];\n      mem8[5] = count_class_lookup[mem8[5]];\n      mem8[6] = count_class_lookup[mem8[6]];\n      mem8[7] = count_class_lookup[mem8[7]];\n\n    }\n\n    mem++;\n\n  }\n\n}\n\n#else\n\nstatic inline void classify_counts(u32* mem) {\n\n  u32 i = MAP_SIZE >> 2;\n\n  while (i--) {\n\n    /* Optimize for sparse bitmaps. */\n\n    if (*mem) {\n\n      u8* mem8 = (u8*)mem;\n\n      mem8[0] = count_class_lookup[mem8[0]];\n      mem8[1] = count_class_lookup[mem8[1]];\n      mem8[2] = count_class_lookup[mem8[2]];\n      mem8[3] = count_class_lookup[mem8[3]];\n\n    }\n\n    mem++;\n\n  }\n\n}\n\n#endif /* ^__x86_64__ */\n\n\n/* Get rid of shared memory (atexit handler). */\n\nstatic void remove_shm(void) {\n\n  shmctl(shm_id, IPC_RMID, NULL);\n\n}\n\n\n/* Compact trace bytes into a smaller bitmap. We effectively just drop the\n   count information here. This is called only sporadically, for some\n   new paths. */\n\nstatic void minimize_bits(u8* dst, u8* src) {\n\n  u32 i = 0;\n\n  while (i < MAP_SIZE) {\n\n    if (*(src++)) dst[i >> 3] |= 1 << (i & 7);\n    i++;\n\n  }\n\n}\n\n\n/* When we bump into a new path, we call this to see if the path appears\n   more \"favorable\" than any of the existing ones. The purpose of the\n   \"favorables\" is to have a minimal set of paths that trigger all the bits\n   seen in the bitmap so far, and focus on fuzzing them at the expense of\n   the rest.\n\n   The first step of the process is to maintain a list of top_rated[] entries\n   for every byte in the bitmap. We win that slot if there is no previous\n   contender, or if the contender has a more favorable speed x size factor. */\n\nstatic void update_bitmap_score(struct queue_entry* q) {\n\n  u32 i;\n  u64 fav_factor = q->exec_us * q->len;\n\n  /* For every byte set in trace_bits[], see if there is a previous winner,\n     and how it compares to us. */\n\n  for (i = 0; i < MAP_SIZE; i++)\n\n    if (trace_bits[i]) {\n\n       if (top_rated[i]) {\n\n         /* Faster-executing or smaller test cases are favored. */\n\n         if (fav_factor > top_rated[i]->exec_us * top_rated[i]->len) continue;\n\n         /* Looks like we're going to win. Decrease ref count for the\n            previous winner, discard its trace_bits[] if necessary. */\n\n         if (!--top_rated[i]->tc_ref) {\n           ck_free(top_rated[i]->trace_mini);\n           top_rated[i]->trace_mini = 0;\n         }\n\n       }\n\n       /* Insert ourselves as the new winner. */\n\n       top_rated[i] = q;\n       q->tc_ref++;\n\n       if (!q->trace_mini) {\n         q->trace_mini = ck_alloc(MAP_SIZE >> 3);\n         minimize_bits(q->trace_mini, trace_bits);\n       }\n\n       score_changed = 1;\n\n     }\n\n}\n\n\n/* The second part of the mechanism discussed above is a routine that\n   goes over top_rated[] entries, and then sequentially grabs winners for\n   previously-unseen bytes (temp_v) and marks them as favored, at least\n   until the next run. The favored entries are given more air time during\n   all fuzzing steps. */\n\nstatic void cull_queue(void) {\n\n  struct queue_entry* q;\n  static u8 temp_v[MAP_SIZE >> 3];\n  u32 i;\n\n  if (dumb_mode || !score_changed) return;\n\n  score_changed = 0;\n\n  memset(temp_v, 255, MAP_SIZE >> 3);\n\n  queued_favored  = 0;\n  pending_favored = 0;\n\n  q = queue;\n\n  while (q) {\n    q->favored = 0;\n    q = q->next;\n  }\n\n  /* Let's see if anything in the bitmap isn't captured in temp_v.\n     If yes, and if it has a top_rated[] contender, let's use it. */\n\n  for (i = 0; i < MAP_SIZE; i++)\n    if (top_rated[i] && (temp_v[i >> 3] & (1 << (i & 7)))) {\n\n      u32 j = MAP_SIZE >> 3;\n\n      /* Remove all bits belonging to the current entry from temp_v. */\n\n      while (j--) \n        if (top_rated[i]->trace_mini[j])\n          temp_v[j] &= ~top_rated[i]->trace_mini[j];\n\n      top_rated[i]->favored = 1;\n      queued_favored++;\n\n      if (!top_rated[i]->was_fuzzed) pending_favored++;\n\n    }\n\n  q = queue;\n\n  while (q) {\n    mark_as_redundant(q, !q->favored);\n    q = q->next;\n  }\n\n}\n\n\n/* Configure shared memory and virgin_bits. This is called at startup. */\n\nstatic void setup_shm(void) {\n\n  u8* shm_str;\n\n  if (!in_bitmap) memset(virgin_bits, 255, MAP_SIZE);\n\n  memset(virgin_hang, 255, MAP_SIZE);\n  memset(virgin_crash, 255, MAP_SIZE);\n\n  shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);\n\n  if (shm_id < 0) PFATAL(\"shmget() failed\");\n\n  atexit(remove_shm);\n\n  shm_str = alloc_printf(\"%d\", shm_id);\n\n  /* If somebody is asking us to fuzz instrumented binaries in dumb mode,\n     we don't want them to detect instrumentation, since we won't be sending\n     fork server commands. This should be replaced with better auto-detection\n     later on, perhaps? */\n\n  if (!dumb_mode) setenv(SHM_ENV_VAR, shm_str, 1);\n\n  ck_free(shm_str);\n\n  trace_bits = shmat(shm_id, NULL, 0);\n  \n  if (!trace_bits) PFATAL(\"shmat() failed\");\n\n}\n\n\n/* Load postprocessor, if available. */\n\nstatic void setup_post(void) {\n\n  void* dh;\n  u8* fn = getenv(\"AFL_POST_LIBRARY\");\n  u32 tlen = 6;\n\n  if (!fn) return;\n\n  ACTF(\"Loading postprocessor from '%s'...\", fn);\n\n  dh = dlopen(fn, RTLD_NOW);\n  if (!dh) FATAL(\"%s\", dlerror());\n\n  post_handler = dlsym(dh, \"afl_postprocess\");\n  if (!post_handler) FATAL(\"Symbol 'afl_postprocess' not found.\");\n\n  /* Do a quick test. It's better to segfault now than later =) */\n\n  post_handler(\"hello\", &tlen);\n\n  OKF(\"Postprocessor installed successfully.\");\n\n}\n\n\n/* Read all testcases from the input directory, then queue them for testing.\n   Called at startup. */\n\nstatic void read_testcases(void) {\n\n  struct dirent **nl;\n  s32 nl_cnt;\n  u32 i;\n  u8* fn;\n\n  /* Auto-detect non-in-place resumption attempts. */\n\n  fn = alloc_printf(\"%s/queue\", in_dir);\n  if (!access(fn, F_OK)) in_dir = fn; else ck_free(fn);\n\n  ACTF(\"Scanning '%s'...\", in_dir);\n\n  /* We use scandir() + alphasort() rather than readdir() because otherwise,\n     the ordering  of test cases would vary somewhat randomly and would be\n     difficult to control. */\n\n  nl_cnt = scandir(in_dir, &nl, NULL, alphasort);\n\n  if (nl_cnt < 0) {\n\n    if (errno == ENOENT || errno == ENOTDIR)\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"The input directory does not seem to be valid - try again. The fuzzer needs\\n\"\n           \"    one or more test case to start with - ideally, a small file under 1 kB\\n\"\n           \"    or so. The cases must be stored as regular files directly in the input\\n\"\n           \"    directory.\\n\");\n\n    PFATAL(\"Unable to open '%s'\", in_dir);\n\n  }\n\n  for (i = 0; i < nl_cnt; i++) {\n\n    struct stat st;\n\n    u8* fn = alloc_printf(\"%s/%s\", in_dir, nl[i]->d_name);\n    u8* dfn = alloc_printf(\"%s/.state/deterministic_done/%s\", in_dir, nl[i]->d_name);\n\n    u8  passed_det = 0;\n\n    free(nl[i]); /* not tracked */\n \n    if (lstat(fn, &st) || access(fn, R_OK))\n      PFATAL(\"Unable to access '%s'\", fn);\n\n    /* This also takes care of . and .. */\n\n    if (!S_ISREG(st.st_mode) || !st.st_size || strstr(fn, \"/README.txt\")) {\n\n      ck_free(fn);\n      ck_free(dfn);\n      continue;\n\n    }\n\n    if (st.st_size > MAX_FILE) \n      FATAL(\"Test case '%s' is too big (%s, limit is %s)\", fn,\n            DMS(st.st_size), DMS(MAX_FILE));\n\n    /* Check for metadata that indicates that deterministic fuzzing\n       is complete for this entry. We don't want to repeat deterministic\n       fuzzing when resuming aborted scans, because it would be pointless\n       and probably very time-consuming. */\n\n    if (!access(dfn, F_OK)) passed_det = 1;\n    ck_free(dfn);\n\n    add_to_queue(fn, st.st_size, passed_det);\n\n  }\n\n  free(nl); /* not tracked */\n\n  if (!queued_paths) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Looks like there are no valid test cases in the input directory! The fuzzer\\n\"\n         \"    needs one or more test case to start with - ideally, a small file under\\n\"\n         \"    1 kB or so. The cases must be stored as regular files directly in the\\n\"\n         \"    input directory.\\n\");\n\n    FATAL(\"No usable test cases in '%s'\", in_dir);\n\n  }\n\n  last_path_time = 0;\n  queued_at_start = queued_paths;\n\n}\n\n\n/* Helper function for load_extras. */\n\nstatic int compare_extras_len(const void* p1, const void* p2) {\n  struct extra_data *e1 = (struct extra_data*)p1,\n                    *e2 = (struct extra_data*)p2;\n\n  return e1->len - e2->len;\n}\n\nstatic int compare_extras_use_d(const void* p1, const void* p2) {\n  struct extra_data *e1 = (struct extra_data*)p1,\n                    *e2 = (struct extra_data*)p2;\n\n  return e2->hit_cnt - e1->hit_cnt;\n}\n\n\n/* Read extras from a file, sort by size. */\n\nstatic void load_extras_file(u8* fname, u32* min_len, u32* max_len,\n                             u32 dict_level) {\n\n  FILE* f;\n  u8  buf[MAX_LINE];\n  u8  *lptr;\n  u32 cur_line = 0;\n\n  f = fopen(fname, \"r\");\n\n  if (!f) PFATAL(\"Unable to open '%s'\", fname);\n\n  while ((lptr = fgets(buf, MAX_LINE, f))) {\n\n    u8 *rptr, *wptr;\n    u32 klen = 0;\n\n    cur_line++;\n\n    /* Trim on left and right. */\n\n    while (isspace(*lptr)) lptr++;\n\n    rptr = lptr + strlen(lptr) - 1;\n    while (rptr >= lptr && isspace(*rptr)) rptr--;\n    rptr++;\n    *rptr = 0;\n\n    /* Skip empty lines and comments. */\n\n    if (!*lptr || *lptr == '#') continue;\n\n    /* All other lines must end with '\"', which we can consume. */\n\n    rptr--;\n\n    if (rptr < lptr || *rptr != '\"')\n      FATAL(\"Malformed name=\\\"value\\\" pair in line %u.\", cur_line);\n\n    *rptr = 0;\n\n    /* Skip alphanumerics and dashes (label). */\n\n    while (isalnum(*lptr) || *lptr == '_') lptr++;\n\n    /* If @number follows, parse that. */\n\n    if (*lptr == '@') {\n\n      lptr++;\n      if (atoi(lptr) > dict_level) continue;\n      while (isdigit(*lptr)) lptr++;\n\n    }\n\n    /* Skip whitespace and = signs. */\n\n    while (isspace(*lptr) || *lptr == '=') lptr++;\n\n    /* Consume opening '\"'. */\n\n    if (*lptr != '\"')\n      FATAL(\"Malformed name=\\\"keyword\\\" pair in line %u.\", cur_line);\n\n    lptr++;\n\n    if (!*lptr) FATAL(\"Empty keyword in line %u.\", cur_line);\n\n    /* Okay, let's allocate memory and copy data between \"...\", handling\n       \\xNN escaping, \\\\, and \\\". */\n\n    extras = ck_realloc_block(extras, (extras_cnt + 1) *\n               sizeof(struct extra_data));\n\n    wptr = extras[extras_cnt].data = ck_alloc(rptr - lptr);\n\n    while (*lptr) {\n\n      char* hexdigits = \"0123456789abcdef\";\n\n      switch (*lptr) {\n\n        case 1 ... 31:\n        case 128 ... 255:\n          FATAL(\"Non-printable characters in line %u.\", cur_line);\n\n        case '\\\\':\n\n          lptr++;\n\n          if (*lptr == '\\\\' || *lptr == '\"') {\n            *(wptr++) = *(lptr++);\n            klen++;\n            break;\n          }\n\n          if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2]))\n            FATAL(\"Invalid escaping (not \\\\xNN) in line %u.\", cur_line);\n\n          *(wptr++) =\n            ((strchr(hexdigits, tolower(lptr[1])) - hexdigits) << 4) |\n            (strchr(hexdigits, tolower(lptr[2])) - hexdigits);\n\n          lptr += 3;\n          klen++;\n\n          break;\n\n        default:\n\n          *(wptr++) = *(lptr++);\n          klen++;\n\n      }\n\n    }\n\n    extras[extras_cnt].len = klen;\n\n    if (extras[extras_cnt].len > MAX_DICT_FILE)\n      FATAL(\"Keyword too big in line %u (%s, limit is %s)\", cur_line,\n            DMS(klen), DMS(MAX_DICT_FILE));\n\n    if (*min_len > klen) *min_len = klen;\n    if (*max_len < klen) *max_len = klen;\n\n    extras_cnt++;\n\n  }\n\n  fclose(f);\n\n}\n\n\n/* Read extras from the extras directory and sort them by size. */\n\nstatic void load_extras(u8* dir) {\n\n  DIR* d;\n  struct dirent* de;\n  u32 min_len = MAX_DICT_FILE, max_len = 0, dict_level = 0;\n  u8* x;\n\n  /* If the name ends with @, extract level and continue. */\n\n  if ((x = strchr(dir, '@'))) {\n\n    *x = 0;\n    dict_level = atoi(x + 1);\n\n  }\n\n  ACTF(\"Loading extra dictionary from '%s' (level %u)...\", dir, dict_level);\n\n  d = opendir(dir);\n\n  if (!d) {\n\n    if (errno == ENOTDIR) {\n      load_extras_file(dir, &min_len, &max_len, dict_level);\n      goto check_and_sort;\n    }\n\n    PFATAL(\"Unable to open '%s'\", dir);\n\n  }\n\n  if (x) FATAL(\"Dictinary levels not supported for directories.\");\n\n  while ((de = readdir(d))) {\n\n    struct stat st;\n    u8* fn = alloc_printf(\"%s/%s\", dir, de->d_name);\n    s32 fd;\n\n    if (lstat(fn, &st) || access(fn, R_OK))\n      PFATAL(\"Unable to access '%s'\", fn);\n\n    /* This also takes care of . and .. */\n    if (!S_ISREG(st.st_mode) || !st.st_size) {\n\n      ck_free(fn);\n      continue;\n\n    }\n\n    if (st.st_size > MAX_DICT_FILE)\n      FATAL(\"Extra '%s' is too big (%s, limit is %s)\", fn,\n            DMS(st.st_size), DMS(MAX_DICT_FILE));\n\n    if (min_len > st.st_size) min_len = st.st_size;\n    if (max_len < st.st_size) max_len = st.st_size;\n\n    extras = ck_realloc_block(extras, (extras_cnt + 1) *\n               sizeof(struct extra_data));\n\n    extras[extras_cnt].data = ck_alloc(st.st_size);\n    extras[extras_cnt].len  = st.st_size;\n\n    fd = open(fn, O_RDONLY);\n\n    if (fd < 0) PFATAL(\"Unable to open '%s'\", fn);\n\n    ck_read(fd, extras[extras_cnt].data, st.st_size, fn);\n\n    close(fd);\n    ck_free(fn);\n\n    extras_cnt++;\n\n  }\n\n  closedir(d);\n\ncheck_and_sort:\n\n  if (!extras_cnt) FATAL(\"No usable files in '%s'\", dir);\n\n  qsort(extras, extras_cnt, sizeof(struct extra_data), compare_extras_len);\n\n  OKF(\"Loaded %u extra tokens, size range %s to %s.\", extras_cnt,\n      DMS(min_len), DMS(max_len));\n\n  if (max_len > 32)\n    WARNF(\"Some tokens are relatively large (%s) - consider trimming.\",\n          DMS(max_len));\n\n  if (extras_cnt > MAX_DET_EXTRAS)\n    WARNF(\"More than %u tokens - will use them probabilistically.\",\n          MAX_DET_EXTRAS);\n\n}\n\n\n\n\n/* Helper function for maybe_add_auto() */\n\nstatic inline u8 memcmp_nocase(u8* m1, u8* m2, u32 len) {\n\n  while (len--) if (tolower(*(m1++)) ^ tolower(*(m2++))) return 1;\n  return 0;\n\n}\n\n\n/* Maybe add automatic extra. */\n\nstatic void maybe_add_auto(u8* mem, u32 len) {\n\n  u32 i;\n\n  /* Allow users to specify that they don't want auto dictionaries. */\n\n  if (!MAX_AUTO_EXTRAS || !USE_AUTO_EXTRAS) return;\n\n  /* Skip runs of identical bytes. */\n\n  for (i = 1; i < len; i++)\n    if (mem[0] ^ mem[i]) break;\n\n  if (i == len) return;\n\n  /* Reject builtin interesting values. */\n\n  if (len == 2) {\n\n    i = sizeof(interesting_16) >> 1;\n\n    while (i--) \n      if (*((u16*)mem) == interesting_16[i] ||\n          *((u16*)mem) == SWAP16(interesting_16[i])) return;\n\n  }\n\n  if (len == 4) {\n\n    i = sizeof(interesting_32) >> 2;\n\n    while (i--) \n      if (*((u32*)mem) == interesting_32[i] ||\n          *((u32*)mem) == SWAP32(interesting_32[i])) return;\n\n  }\n\n  /* Reject anything that matches existing extras. Do a case-insensitive\n     match. We optimize by exploiting the fact that extras[] are sorted\n     by size. */\n\n  for (i = 0; i < extras_cnt; i++)\n    if (extras[i].len >= len) break;\n\n  for (; i < extras_cnt && extras[i].len == len; i++)\n    if (!memcmp_nocase(extras[i].data, mem, len)) return;\n\n  /* Last but not least, check a_extras[] for matches. There are no\n     guarantees of a particular sort order. */\n\n  auto_changed = 1;\n\n  for (i = 0; i < a_extras_cnt; i++) {\n\n    if (a_extras[i].len == len && !memcmp_nocase(a_extras[i].data, mem, len)) {\n\n      a_extras[i].hit_cnt++;\n      goto sort_a_extras;\n\n    }\n\n  }\n\n  /* At this point, looks like we're dealing with a new entry. So, let's\n     append it if we have room. Otherwise, let's randomly evict some other\n     entry from the bottom half of the list. */\n\n  if (a_extras_cnt < MAX_AUTO_EXTRAS) {\n\n    a_extras = ck_realloc_block(a_extras, (a_extras_cnt + 1) *\n                                sizeof(struct extra_data));\n\n    a_extras[a_extras_cnt].data = ck_memdup(mem, len);\n    a_extras[a_extras_cnt].len  = len;\n    a_extras_cnt++;\n\n  } else {\n\n    i = MAX_AUTO_EXTRAS / 2 +\n        UR((MAX_AUTO_EXTRAS + 1) / 2);\n\n    ck_free(a_extras[i].data);\n\n    a_extras[i].data    = ck_memdup(mem, len);\n    a_extras[i].len     = len;\n    a_extras[i].hit_cnt = 0;\n\n  }\n\nsort_a_extras:\n\n  /* First, sort all auto extras by use count, descending order. */\n\n  qsort(a_extras, a_extras_cnt, sizeof(struct extra_data),\n        compare_extras_use_d);\n\n  /* Then, sort the top USE_AUTO_EXTRAS entries by size. */\n\n  qsort(a_extras, MIN(USE_AUTO_EXTRAS, a_extras_cnt),\n        sizeof(struct extra_data), compare_extras_len);\n\n}\n\n\n/* Save automatically generated extras. */\n\nstatic void save_auto(void) {\n\n  u32 i;\n\n  if (!auto_changed) return;\n  auto_changed = 0;\n\n  for (i = 0; i < MIN(USE_AUTO_EXTRAS, a_extras_cnt); i++) {\n\n    u8* fn = alloc_printf(\"%s/queue/.state/auto_extras/auto_%06u\", out_dir, i);\n    s32 fd;\n\n    fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);\n\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n\n    ck_write(fd, a_extras[i].data, a_extras[i].len, fn);\n\n    close(fd);\n    ck_free(fn);\n\n  }\n\n}\n\n\n/* Load automatically generated extras. */\n\nstatic void load_auto(void) {\n\n  u32 i;\n\n  for (i = 0; i < USE_AUTO_EXTRAS; i++) {\n\n    u8  tmp[MAX_AUTO_EXTRA + 1];\n    u8* fn = alloc_printf(\"%s/.state/auto_extras/auto_%06u\", in_dir, i);\n    s32 fd, len;\n\n    fd = open(fn, O_RDONLY, 0600);\n\n    if (fd < 0) {\n\n      if (errno != ENOENT) PFATAL(\"Unable to open '%s'\", fn);\n      ck_free(fn);\n      break;\n\n    }\n\n    /* We read one byte more to cheaply detect tokens that are too\n       long (and skip them). */\n\n    len = read(fd, tmp, MAX_AUTO_EXTRA + 1);\n\n    if (len < 0) PFATAL(\"Unable to read from '%s'\", fn);\n\n    if (len >= MIN_AUTO_EXTRA && len <= MAX_AUTO_EXTRA)\n      maybe_add_auto(tmp, len);\n\n    close(fd);\n    ck_free(fn);\n\n  }\n\n  if (i) OKF(\"Loaded %u auto-discovered dictionary tokens.\", i);\n  else OKF(\"No auto-generated dictionary tokens to reuse.\");\n\n}\n\n\n/* Destroy extras. */\n\nstatic void destroy_extras(void) {\n\n  u32 i;\n\n  for (i = 0; i < extras_cnt; i++) \n    ck_free(extras[i].data);\n\n  ck_free(extras);\n\n  for (i = 0; i < a_extras_cnt; i++) \n    ck_free(a_extras[i].data);\n\n  ck_free(a_extras);\n\n}\n\n/* Code to fuzz targets across localhost/127.0.0.1/::1 network interface\n * \n * The network fuzzing code operates in each of two modes depending upon\n * the type of target:\n * \n * (1) as a \"listener\" or \"server\" to fuzz targets that send a request to \n *     another process and expect a response.  These targets are called\n *     \"clients\". The relevant functions are network_setup_listener(),\n *     which creates a socket and binds that socket to a (local) port\n *     specified on the command line, and network_listen(), which expects\n *     to receive a packet (UDP) or stream of data (TCP) from the target\n *     and sends a fuzzed response.  This mode is selected using the -L\n *     command line option, together with the -N command line option.\n * \n * (2) as a \"client\" to fuzz targets that expect to receive a request from\n *     another process.  These targets are called \"servers\" or \"daemons\".\n *     The relevant function is network_send(), which sends a fuzzed\n *     packet (UDP) or stream of data (TCP) to the target.  This mode is\n *     selected using the -N command line option without the -L command\n *     line option.\n * \n *  */\n\nvoid network_setup_listener(void) {\n  /* exit if getaddrinfo() did not return address information structures\n   * that match the specification on the command line */\n  if (N_results != NULL) {\n    /* two cases: SOCK_STREAM (for TCP) and SOCK_DGRAM (for UDP) */\n    if (N_results->ai_socktype == SOCK_STREAM) {\n      /* TCP (stream) and connections are used.\n       * \n       * A connection must be established from the target each \n       * time network_listen() is called, and closed after the data are \n       * transfered.  network_setup_listener() creates a stream socket\n       * (with the file descriptor N_fd) and listens for connection requests.  \n       * This must be done before a target that expects to connect is executed.\n       * N_myaddr_valid tells the codes that the listening socket has been\n       * setup (and keeps this code from running twice as a safety net). \n       * UDP is connectionless and quite different. See below.\n       * \n       * Local variables: */\n      int optval = 1;\n      if (N_myaddr_valid == 0) { /* don't do this twice! */\n        /* Find the first address that works and use it. */\n        for (N_rp = N_results; N_rp != NULL; N_rp = N_rp->ai_next) {\n          /* create the socket, skipping to the next addrinfo object on failure */\n          N_fd = socket(N_rp->ai_family, N_rp->ai_socktype, N_rp->ai_protocol);\n          if (N_fd == -1) {\n            close(N_fd);\n            continue;\n          }\n          /* set the socket option to reuse both the address and port */\n          if (setsockopt(N_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval,\n                  sizeof (optval)) == -1) {\n            close(N_fd);\n            PFATAL(\"failed to set socket option (TCP case)\");\n          }\n          /* if bind() succeeds, we have found an address that works */\n          if (bind(N_fd, N_rp->ai_addr, N_rp->ai_addrlen) != -1) {\n            break;\n          }\n          close(N_fd);\n        }\n        /* if none is found, the user needs to examine the argument list */\n        if (N_rp == NULL) {\n          FATAL(\"failed to bind socket\");\n        }\n        /* listen for connection attempts.  this can fail if another process\n         * is listening to the same port and address */\n        if (listen(N_fd, 8) == -1) PFATAL(\"listen() failed\");\n        /* indicate that the socket has been created & bound to a port, and\n         * that the process is listening for connection attempts. */\n        N_myaddr_valid = 1;\n      }\n    } else if (N_results->ai_socktype == SOCK_DGRAM) {\n      /* UDP datagrams are used.\n       * \n       * Create a socket to be used to both receive and send packets, referenced\n       * by the file descriptor N_fd.\n       * \n       * N_fd is kept open for the duration of the afl run (closed on exit)\n       * and reused.  N_myaddr_valid signals the code that the UDP socket \n       * has been set up and bound to the sending side of the address & port.\n       * \n       * First time: find the appropriate sockaddr structure to be used and\n       * set up the sending side's socket. After the first time's successful\n       * execution, N_rp points to the address information corresonding to\n       * the sending side's socket information.\n       *\n       * Local variables:\n       */\n    int optval = 1;\n    if (N_myaddr_valid == 0) {\n        for (N_rp = N_results; N_rp != NULL; N_rp = N_rp->ai_next) {\n          /* create the socket, skipping to the next addrinfo object on failure */\n          N_fd = socket(N_rp->ai_family, N_rp->ai_socktype, N_rp->ai_protocol);\n          if (N_fd == -1) {\n            fprintf(stderr, \"socket() call failed\\n\");\n            close(N_fd);\n            continue;\n          }\n          /* set the socket option to reuse both the address and port */\n          if (setsockopt(N_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval,\n                  sizeof (optval)) == -1) {\n            close(N_fd);\n            PFATAL(\"failed to set socket option (TCP case)\");\n          }\n          /* if bind() succeeds, we have found an address that works */\n          if (bind(N_fd, N_rp->ai_addr, N_rp->ai_addrlen) != -1) {\n            break;\n          }\n          close(N_fd);\n        }\n        /* if none is found, the user needs to examine the argument list */\n        if (N_rp == NULL) {\n          FATAL(\"failed to bind socket\");\n        }\n        /* indicate that the socket has been created & bound to a port, and\n         * that the process is listening for connection attempts. */\n        N_myaddr_valid = 1;\n      }\n    }\n  } else {\n    /* getaddrinfo() failed to return results matching the spec on the\n     * command line.  */\n    FATAL(\"no matching results from getaddrinfo()\");\n  }\n}\n\nint network_listen(void) {\n  /* This function receives data from the target process, and then sends\n   * fuzzed data back to it.  There are two cases:\n   *\n   * (1) TCP (streams): a connection attempt from the target process is\n   *     solicited.  When the connection has been established, all available\n   *     data are read using non-blocking I/O, and then fuzzed data are\n   *     written.\n   *\n   * (2) UDP (datagrams/packets): all available packets are read using\n   *     non-blocking I/O, and then fuzzed data are written.\n   *\n   * In both cases, all data read are discarded.  Note that for UDP reads\n   * any data in excess of the size of the read buffer are discarded by the\n   * network stack.\n   * \n   * Note that non-blocking reads are attempted, and if they fail then the\n   * calling process is expected to wait for a programmed interval of time\n   * (specified by the -D command line argument) and retry the call to\n   * network_listen(), for a programmed number of times (not user-selectable).\n   * \n   * Note that unlike the case where this code plays the role of a client to\n   * the target process (using network_send()), we typically have no control\n   * over the target's reuse (or not) of ephemeral port numbers.  Therefore,\n   * we are at the mercy of the network stack's ability to scavenge available\n   * port numbers.  A recent Linux kernel appears to do this quite well;\n   * other operating systems may not.\n   *\n   * Local variables:\n   */\n  u32 MAXRECVBUFSIZE = 512;\n  u8 recvbuf[MAXRECVBUFSIZE];\n  s32 currreadlen, client_fd, fd, o;\n  /* network_setup_listener() must be called first, and must succeed */\n  if (!N_myaddr_valid)\n    FATAL(\"error: network_listen() called before network_setup_listener()\");\n  \n  /* Two cases: SOCK_STREAM (for TCP) and SOCK_DGRAM (for UDP) */\n  if (N_rp->ai_socktype == SOCK_STREAM) {\n    /* TCP (stream) and connections are used. */\n    /* accept a connection if the client is ready, but don't block */\n    client_fd = accept4(N_fd, (struct sockaddr *) &N_myaddr,\n            &N_myaddrlen, SOCK_CLOEXEC | SOCK_NONBLOCK);\n    if (client_fd == -1) {\n      if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {\n        return -1; /* return to calling program, which will delay before retrying */\n      } else { /* a serous error occurred */\n        PFATAL(\"accept4() returned error other than EAGAIN or EWOULDBLOCK\");\n      }\n    }\n    /* read whatever the client sends and throw it away, resetting\n     * non-blocking mode first (because some UNIXs propagate it to\n     * the returned client_fd) */\n    o = fcntl(client_fd, F_GETFL);\n    if (o >= 0) {\n      o = o & (~O_NONBLOCK);\n      if (fcntl(client_fd, F_SETFL, o) < 0) {\n        PFATAL(\"failed to reset non-blocking flag on client file descriptor (TCP)\");\n      }\n    }\n    while ((currreadlen = recv(client_fd,recvbuf,MAXRECVBUFSIZE,MSG_DONTWAIT)) > 0);\n    if ((currreadlen <= 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK)) {\n      PFATAL(\"read error\");\n    }\n    /* duplicate the file descriptor used for the fuzzed data, and use the new\n     * file descriptor to read that data and send it to the target process */\n    fd = dup(out_fd);\n    struct stat statbuf;\n    /* stat the file descriptor to obtain the size of the data to be sent */\n    if (fstat(fd, &statbuf) == -1) {\n      PFATAL(\"failed to obtain stat for output file to target\");\n    }\n    /* seek to the beginning of the file */\n    lseek(fd, 0, SEEK_SET);\n    /* use sendfile() to transfer the data if possible because it is efficient */\n    if (sendfile(client_fd, fd, NULL, statbuf.st_size) == -1) {\n      /* if sendfile() didn't work, use read() and write() via a buffer */\n      lseek(fd, 0, SEEK_SET); /* reset to the beginning of the file */\n      u8 tempbuf[512];\n      u32 kread;\n      while ((kread = read(fd, tempbuf, 512)) > 0) {\n        if (write(client_fd, tempbuf, kread) != kread) {\n          PFATAL(\"file copy to network socket failed (TCP)\");\n        }\n      }\n    }\n    /* leave a clean campsite (as we found it) */\n    lseek(fd, 0, SEEK_SET);\n    close(fd);\n    /* and close the file descriptor of the socket for the target */\n    close(client_fd);\n    \n  } else if (N_rp->ai_socktype == SOCK_DGRAM) {\n    /* UDP datagrams are used.\n     *\n     * N_fd is kept open for the duration of the afl run (closed on exit)\n     * and reused.  N_myaddr_valid signals this code that the UDP socket\n     * has been set up and bound to the sending side of the address & port.\n     * N_rp points to the address information used for the socket.\n     *\n     * Local variables:\n     */\n    struct stat statbuf;\n    struct sockaddr_storage clientaddr;\n    u32 clientaddrlen = sizeof (struct sockaddr_storage);\n    /* read all available packets from the socket using non-blocking I/O */\n    {\n      int received_one = 0;\n      while ((currreadlen = recvfrom(N_fd, recvbuf, MAXRECVBUFSIZE, MSG_DONTWAIT,\n              (struct sockaddr *) &clientaddr, &clientaddrlen)) > 0) {\n        received_one = 1;\n      }\n      /* at least one is necessary; otherwise, return & calling program may\n       * wait and then try again */\n      if (!received_one) {\n        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {\n          return -1;\n        } else {\n          /* any other error signals imply a serious problem exists */\n          PFATAL(\"read error\");\n        }\n      }\n   }\n    /* duplicate the file descriptor used for the fuzzed data, and use the new\n     * file descriptor to read that data and send it to the target process */\n    fd = dup(out_fd);\n    /* stat the file descriptor to obtain the size of the data to be sent */\n    if (fstat(fd, &statbuf) == -1) PFATAL(\"fstat()failed\");\n    /* seek to the beginning of the file and create a temporary buffer to\n     * hold all of the data in the file */\n    lseek(fd, 0, SEEK_SET);\n    u8 tempbuf[statbuf.st_size];\n    /* read the entire file into the buffer */\n    if (read(fd, tempbuf, statbuf.st_size) != statbuf.st_size)\n      PFATAL(\"read of outfile's content failed to return expected # of bytes\");\n    /* and send the buffer's content to the target process.  Note that this\n     * code assumes that the entire buffer can be sent in a single packet.  If\n     * it can not (giant packet), the user may be doing something wrong.  */\n    if (sendto(N_fd, tempbuf, statbuf.st_size, 0,\n            (struct sockaddr *)&clientaddr,\n            clientaddrlen) < 0) {\n      PFATAL(\"partial or failed UDP write\");\n    }\n    /* leave a clean campsite (as we found it) */\n    lseek(fd, 0, SEEK_SET);\n    close(fd);\n  }\n  return 0;\n}\n\nint network_send(void) {\n  /* This function sends fuzzed data to a target process.  There are two cases:\n   *\n   * (1) TCP (streams): a connection to the target process is attempted.\n   *     When the connection has been established, the fuzzed data are\n   *     written.\n   *\n   * (2) UDP (datagrams/packets): The fuzzed data are written.\n   *\n   * N_results should never be a NULL pointer because the return code\n   * from getaddrinfo() is checked. */\n  if (N_results != NULL) {\n    \n    /* Two cases: SOCK_STREAM (for TCP) and SOCK_DGRAM (for UDP) */\n    if (N_results->ai_socktype == SOCK_STREAM) {\n      /* TCP (stream) and connections are used.\n       * \n       * NOTE: A TCP connection must be established each time this code\n       * is called, and closed after the data are transfered.  However, the\n       * same port number should be used for the sending (this) side of the\n       * TCP transaction every time.  Otherwise, ephemeral port\n       * numbers might be exhausted because of TCP's TIME_WAIT timeout\n       * interval.  N_myaddr_valid tells this code that the sending side's\n       * address information has been stored in N_myaddr and is to be reused. \n       * UDP is connectionless and is therefore different. See below.\n       * \n       * Note that the other mode of operation, where this code acts as a\n       * server to a target, does not have control over the target's reuse\n       * of ephemeral port numbers.  See the comments in network_listen()\n       * for a discussion.\n       * \n       * Note that \"soft\" failures cause a return with an error code of -1. The\n       * calling process is expected to wait for a programmed interval of time\n       * (specified by the -D command line argument) and retry the call to\n       * network_send(), for a programmed number of times (not user-selectable)\n       * when this occurs.\n       * \n       * Local variables: */\n      int optval = 1;\n\n      if (N_myaddr_valid == 0) {\n        /* First time: Find the correct address and use it, saving the info\n         * in M_myaddr for subsequent calls. */\n        for (N_rp = N_results; N_rp != NULL; N_rp = N_rp->ai_next) {\n          /* create a socket to connect to the target process */\n          N_fd = socket(N_rp->ai_family, N_rp->ai_socktype, N_rp->ai_protocol);\n          if (N_fd == -1) {\n            continue;\n          }\n          /* set the socket options to reuse both the address and port */\n          if (setsockopt(N_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval,\n                  sizeof (optval)) == -1) {\n            PFATAL(\"failed to set socket option (TCP case)\");\n          }\n          /* attempt to connect to the target process, breaking out of the\n           * loop upon success */\n          if (connect(N_fd, N_rp->ai_addr, N_rp->ai_addrlen) != -1) {\n            break;\n          }\n          /* connect() failed, so close the file descriptor and try the\n           * next address information data structure */\n          close(N_fd);\n        }\n        if (N_rp == NULL) {\n          return -1; /* failed to connect; target process probably not ready */\n        }\n        /* obtain the send side socket information for re-use */\n        if (getsockname(N_fd, (struct sockaddr *) (&N_myaddr), &N_myaddrlen) == -1) {\n          PFATAL(\"unable to obtain local socket address information (TCP case)\");\n        }\n        N_myaddr_valid = 1;\n      } else {\n        /* This is not the first time; reuse send side info in N_myaddr. */\n        N_fd = socket(N_rp->ai_family, N_rp->ai_socktype, N_rp->ai_protocol);\n        if (N_fd == -1) {\n          PFATAL(\"Subsequent attempt to create socket failed (TCP case)\");\n        }\n        if (setsockopt(N_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval,\n                sizeof (optval)) == -1) {\n          PFATAL(\"Subsequent attempt to set socket option failed (TCP case)\");\n        }\n        if (bind(N_fd, (struct sockaddr *) (&N_myaddr), N_myaddrlen) == -1) {\n          PFATAL(\"Attempt to bind socket to source address & port failed (TCP case)\");\n        }\n        if (connect(N_fd, N_rp->ai_addr, N_rp->ai_addrlen) != -1) {\n        } else {\n          close(N_fd);\n          return -1; /* error returned from connect; target process not ready */\n        }\n      }\n\n      {\n        /* duplicate the file descriptor used for the fuzzed data, and use\n         * the new file descriptor to read that data and send it to the\n         * target process */\n        s32 fd = dup(out_fd);\n        /* stat the file descriptor to obtain the size of the data to be sent */\n        struct stat statbuf;\n        if (fstat(fd, &statbuf) == -1) PFATAL(\"fstat()failed\");\n        /* seek to the beginning of the file */\n        lseek(fd, 0, SEEK_SET);\n        /* use sendfile() to transfer the data if possible because it is efficient */\n        if (sendfile(N_fd, fd, NULL, statbuf.st_size) == -1) {\n          /* if sendfile() didn't work, use read() and write() via a buffer */\n          lseek(fd, 0, SEEK_SET); /* reset to the beginning of the file */\n          /* create a temporary buffer to hold all of the data in the file */\n          u8 tempbuf[512];\n          u32 kread;\n          while ((kread = read(fd, tempbuf, 512)) > 0) {\n            if (write(N_fd, tempbuf, kread) != kread) {\n              PFATAL(\"file copy to network socket failed (TCP)\");\n            }\n          }\n        }\n        /* leave a clean campsite (as we found it) */\n        lseek(fd, 0, SEEK_SET);\n        close(fd);\n      }\n      /* and close the connection to the target process, signaling EOF */\n      close(N_fd);\n      \n    } else if (N_results->ai_socktype == SOCK_DGRAM) {\n      /* UDP datagrams are used.\n       * \n       * N_fd is kept open for the duration of the afl run (closed on exit)\n       * and reused.  N_myaddr_valid signals this code that the UDP socket\n       * has been set up and bound to the sending side of the address & port.\n       * N_rp points to the recipient side's address information after the\n       * first call. */\n\n      if (N_myaddr_valid == 0) {\n        /* First time: find the appropriate sockaddr structure to be used and\n         * set up the sending side's socket. After the first time's successful\n         * execution, N_myaddr holds the sending side's socket information,\n         * N_rp points to the socket address structure that was used to\n         * create the socket, and N_fd is a valid file descriptor for the\n         * socket. */\n        for (N_rp = N_results; N_rp != NULL; N_rp = N_rp->ai_next) {\n          if (!((N_rp->ai_family == AF_INET) || (N_rp->ai_family == AF_INET6))) {\n            continue;\n          }\n          /* create appropriate struct sockaddr according to ai_family */\n          if (N_rp->ai_family == AF_INET6) {\n            memset(&N_server_addr, 0, sizeof (struct sockaddr_in6));\n            N_server_addr.ss_family = AF_INET6;\n            ((struct sockaddr_in6 *) &N_server_addr)->sin6_family = AF_INET6;\n            ((struct sockaddr_in6 *) &N_server_addr)->sin6_addr = in6addr_any;\n            ((struct sockaddr_in6 *) &N_server_addr)->sin6_port = 0;\n          } else if (N_rp->ai_family == AF_INET) {\n            memset(&N_server_addr, 0, sizeof (struct sockaddr_in));\n            N_server_addr.ss_family = AF_INET;\n            ((struct sockaddr_in *) &N_server_addr)->sin_family = AF_INET;\n            ((struct sockaddr_in *) &N_server_addr)->sin_addr.s_addr = INADDR_ANY;\n            ((struct sockaddr_in *) &N_server_addr)->sin_port = 0;\n          } else {\n            FATAL(\"invalid ai_family (UDP case)\");\n          }\n          /* create socket */\n          N_fd = socket(N_rp->ai_family, N_rp->ai_socktype, N_rp->ai_protocol);\n          if (N_fd == -1) {\n            continue;\n          }\n          /* bind to the address using an ephemeral port number */\n          if (bind(N_fd, (struct sockaddr *) &N_server_addr, sizeof (struct sockaddr_storage)) < 0) {\n            PFATAL(\"bind failed (UDP case)\");\n          } else {\n            /* obtain the local port number that was assigned (for debugging) */\n            N_myaddrlen = sizeof (struct sockaddr_storage);\n            if (getsockname(N_fd, (struct sockaddr *) &N_myaddr, &N_myaddrlen) < 0) {\n              PFATAL(\"get socket name failed (UDP case)\");\n            } else {\n              break;\n            }\n          } \n          close(N_fd);\n        }\n        N_myaddr_valid = 1;\n      }\n      if (N_rp == NULL) {\n        return -1; /* failed to connect on any address (UDP case) */\n      }\n      {\n        /* duplicate the file descriptor used for the fuzzed data, and use\n         * the new file descriptor to read that data and send it to the\n         * target process */\n        s32 fd = dup(out_fd);\n        /* stat the file descriptor to obtain the size of the data to be sent */\n        struct stat statbuf;\n        if (fstat(fd, &statbuf) == -1) PFATAL(\"fstat()failed\");\n        /* seek to the beginning of the file */\n        lseek(fd, 0, SEEK_SET);\n        /* create a temporary buffer to hold all of the data in the file */\n        u8 tempbuf[statbuf.st_size];\n        /* read the entire file into the buffer */\n        if (read(fd, tempbuf, statbuf.st_size) != statbuf.st_size) {\n          PFATAL(\"read of outfile's content failed to return expected # of bytes\");\n        }\n        if (N_rp->ai_family == AF_INET) {\n          /* and send the buffer's content to the target process.  Note that\n           * this code assumes that the entire buffer can be sent in a single\n           * packet.  If it can not (giant packet), the user may be doing\n           * something wrong.  */\n          if (sendto(N_fd, tempbuf, statbuf.st_size, 0,\n                  (struct sockaddr *) ((N_rp)->ai_addr),\n                  sizeof (struct sockaddr_in)) < 0) {\n            PFATAL(\"partial or failed UDP write (IPv4)\");\n          }\n        } else if (N_rp->ai_family == AF_INET6) {\n          if (sendto(N_fd, tempbuf, statbuf.st_size, 0,\n                  (struct sockaddr *) ((N_rp)->ai_addr),\n                  sizeof (struct sockaddr_in6)) < 0) {\n            PFATAL(\"partial or failed UDP write (IPv6)\");\n          }\n        }\n        /* leave a clean campsite (as we found it) */\n        lseek(fd, 0, SEEK_SET);\n        close(fd);\n      }\n    }\n  } else {\n    /* this should never be executed */\n    FATAL(\"no address information structures match command line network spec\");\n  }\n  \n  return 0;\n}\n\n/* Spin up fork server (instrumented mode only). The idea is explained here:\n\n   http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html\n\n   In essence, the instrumentation allows us to skip execve(), and just keep\n   cloning a stopped child. So, we just execute once, and then send commands\n   through a pipe. The other part of this logic is in afl-as.h. */\n\nstatic void init_forkserver(char** argv) {\n\n  static struct itimerval it;\n  int st_pipe[2], ctl_pipe[2];\n  int status;\n  s32 rlen;\n\n  ACTF(\"Spinning up the fork server...\");\n\n  if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL(\"pipe() failed\");\n\n  forksrv_pid = fork();\n\n  if (forksrv_pid < 0) PFATAL(\"fork() failed\");\n\n  if (!forksrv_pid) {\n\n    struct rlimit r;\n\n    /* Umpf. On OpenBSD, the default fd limit for root users is set to\n       soft 128. Let's try to fix that... */\n\n    if (!getrlimit(RLIMIT_NOFILE, &r) && r.rlim_cur < FORKSRV_FD + 2) {\n\n      r.rlim_cur = FORKSRV_FD + 2;\n      setrlimit(RLIMIT_NOFILE, &r); /* Ignore errors */\n\n    }\n\n    if (mem_limit) {\n\n      r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n\n#ifdef RLIMIT_AS\n\n      setrlimit(RLIMIT_AS, &r); /* Ignore errors */\n\n#else\n\n      /* This takes care of OpenBSD, which doesn't have RLIMIT_AS, but\n         according to reliable sources, RLIMIT_DATA covers anonymous\n         maps - so we should be getting good protection against OOM bugs. */\n\n      setrlimit(RLIMIT_DATA, &r); /* Ignore errors */\n\n#endif /* ^RLIMIT_AS */\n\n\n    }\n\n    /* Dumping cores is slow and can lead to anomalies if SIGKILL is delivered\n       before the dump is complete. */\n\n    r.rlim_max = r.rlim_cur = 0;\n\n    setrlimit(RLIMIT_CORE, &r); /* Ignore errors */\n\n    /* Isolate the process and configure standard descriptors. If out_file is\n       specified, stdin is /dev/null; otherwise, out_fd is cloned instead. */\n\n    setsid();\n\n    dup2(dev_null_fd, 1);\n    dup2(dev_null_fd, 2);\n\n    if (out_file || N_valid == 1) { /* no stdin for file or network input */\n\n      dup2(dev_null_fd, 0);\n\n    } else {\n\n      dup2(out_fd, 0);\n      close(out_fd);\n\n    }\n\n    /* Set up control and status pipes, close the unneeded original fds. */\n\n    if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) PFATAL(\"dup2() failed\");\n    if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) PFATAL(\"dup2() failed\");\n\n    close(ctl_pipe[0]);\n    close(ctl_pipe[1]);\n    close(st_pipe[0]);\n    close(st_pipe[1]);\n\n    close(out_dir_fd);\n    close(dev_null_fd);\n    close(dev_urandom_fd);\n    close(fileno(plot_file));\n\n    /* This should improve performance a bit, since it stops the linker from\n       doing extra work post-fork(). */\n\n    if (!getenv(\"LD_BIND_LAZY\")) setenv(\"LD_BIND_NOW\", \"1\", 0);\n\n    /* Set sane defaults for ASAN if nothing else specified. */\n\n    setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                           \"detect_leaks=0:\"\n                           \"allocator_may_return_null=1\", 0);\n\n    /* MSAN is tricky, because it doesn't support abort_on_error=1 at this\n       point. So, we do this in a very hacky way. */\n\n    setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                           \"msan_track_origins=0\", 0);\n\n    execv(target_path, argv);\n\n    /* Use a distinctive bitmap signature to tell the parent about execv()\n       falling through. */\n\n    *(u32*)trace_bits = EXEC_FAIL_SIG;\n    exit(0);\n\n  }\n\n  /* Close the unneeded endpoints. */\n\n  close(ctl_pipe[0]);\n  close(st_pipe[1]);\n\n  fsrv_ctl_fd = ctl_pipe[1];\n  fsrv_st_fd  = st_pipe[0];\n\n  /* Wait for the fork server to come up, but don't wait too long. */\n\n  it.it_value.tv_sec = ((exec_tmout * FORK_WAIT_MULT) / 1000);\n  it.it_value.tv_usec = ((exec_tmout * FORK_WAIT_MULT) % 1000) * 1000;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  rlen = read(fsrv_st_fd, &status, 4);\n\n  it.it_value.tv_sec = 0;\n  it.it_value.tv_usec = 0;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  /* If we have a four-byte \"hello\" message from the server, we're all set.\n     Otherwise, try to figure out what went wrong. */\n\n  if (rlen == 4) {\n    OKF(\"All right - fork server is up.\");\n    return;\n  }\n\n  if (child_timed_out)\n    FATAL(\"Timeout while initializing fork server (adjusting -t may help)\");\n\n  if (waitpid(forksrv_pid, &status, 0) <= 0)\n    PFATAL(\"waitpid() failed\");\n\n  if (WIFSIGNALED(status)) {\n\n    if (mem_limit && mem_limit < 500 && uses_asan) {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! Since it seems to be built with ASAN and you have a\\n\"\n           \"    restrictive memory limit configured, this is expected; please read\\n\"\n           \"    %s/notes_for_asan.txt for help.\\n\", doc_path);\n\n    } else if (!mem_limit) {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! There are several probable explanations:\\n\\n\"\n\n           \"    - The binary is just buggy and explodes entirely on its own. If so, you\\n\"\n           \"      need to fix the underlying problem or find a better replacement.\\n\\n\"\n\n#ifdef __APPLE__\n\n           \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n           \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n           \"      targets. To fix this, set AFL_NO_FORKSRV=1 in the environment.\\n\\n\"\n\n#endif /* __APPLE__ */\n\n           \"    - Less likely, there is a horrible bug in the fuzzer. If other options\\n\"\n           \"      fail, poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\");\n\n    } else {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"Whoops, the target binary crashed suddenly, before receiving any input\\n\"\n           \"    from the fuzzer! There are several probable explanations:\\n\\n\"\n\n           \"    - The current memory limit (%s) is too restrictive, causing the\\n\"\n           \"      target to hit an OOM condition in the dynamic linker. Try bumping up\\n\"\n           \"      the limit with the -m setting in the command line. A simple way confirm\\n\"\n           \"      this diagnosis would be:\\n\\n\"\n\n#ifdef RLIMIT_AS\n           \"      ( ulimit -Sv $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#else\n           \"      ( ulimit -Sd $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#endif /* ^RLIMIT_AS */\n\n           \"      Tip: you can use http://jwilk.net/software/recidivm to quickly\\n\"\n           \"      estimate the required amount of virtual memory for the binary.\\n\\n\"\n\n           \"    - The binary is just buggy and explodes entirely on its own. If so, you\\n\"\n           \"      need to fix the underlying problem or find a better replacement.\\n\\n\"\n\n#ifdef __APPLE__\n\n           \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n           \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n           \"      targets. To fix this, set AFL_NO_FORKSRV=1 in the environment.\\n\\n\"\n\n#endif /* __APPLE__ */\n\n           \"    - Less likely, there is a horrible bug in the fuzzer. If other options\\n\"\n           \"      fail, poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\",\n           DMS(mem_limit << 20), mem_limit - 1);\n\n    }\n\n    FATAL(\"Fork server crashed with signal %d\", WTERMSIG(status));\n\n  }\n\n  if (*(u32*)trace_bits == EXEC_FAIL_SIG)\n    FATAL(\"Unable to execute target application ('%s')\", argv[0]);\n\n  if (mem_limit && mem_limit < 500 && uses_asan) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n           \"    handshake with the injected code. Since it seems to be built with ASAN and\\n\"\n           \"    you have a restrictive memory limit configured, this is expected; please\\n\"\n           \"    read %s/notes_for_asan.txt for help.\\n\", doc_path);\n\n  } else if (!mem_limit) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n         \"    handshake with the injected code. Perhaps there is a horrible bug in the\\n\"\n         \"    fuzzer. Poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\");\n\n  } else {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Hmm, looks like the target binary terminated before we could complete a\\n\"\n         \"    handshake with the injected code. There are %s probable explanations:\\n\\n\"\n\n         \"%s\"\n         \"    - The current memory limit (%s) is too restrictive, causing an OOM\\n\"\n         \"      fault in the dynamic linker. This can be fixed with the -m option. A\\n\"\n         \"      simple way to confirm the diagnosis may be:\\n\\n\"\n\n#ifdef RLIMIT_AS\n         \"      ( ulimit -Sv $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#else\n         \"      ( ulimit -Sd $[%llu << 10]; /path/to/fuzzed_app )\\n\\n\"\n#endif /* ^RLIMIT_AS */\n\n         \"      Tip: you can use http://jwilk.net/software/recidivm to quickly\\n\"\n         \"      estimate the required amount of virtual memory for the binary.\\n\\n\"\n\n         \"    - Less likely, there is a horrible bug in the fuzzer. If other options\\n\"\n         \"      fail, poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\",\n         getenv(DEFER_ENV_VAR) ? \"three\" : \"two\",\n         getenv(DEFER_ENV_VAR) ?\n         \"    - You are using deferred forkserver, but __AFL_INIT() is never\\n\"\n         \"      reached before the program terminates.\\n\\n\" : \"\",\n         DMS(mem_limit << 20), mem_limit - 1);\n\n  }\n\n  FATAL(\"Fork server handshake failed\");\n\n}\n\n\n/* Execute target application, monitoring for timeouts. Return status\n   information. The called program will update trace_bits[]. */\n\nstatic u8 run_target(char** argv) {\n\n  static struct itimerval it;\n  static u32 prev_timed_out = 0;\n\n  int status = 0;\n  u32 tb4;\n\n  child_timed_out = 0;\n  \n  /* check to ensure that network listener has executed if doing network\n   * fuzzing of a client target (where the target writes to a socket first */\n  if (N_fuzz_client && !N_myaddr_valid) {\n    network_setup_listener();\n  }\n  \n\n  /* After this memset, trace_bits[] are effectively volatile, so we\n     must prevent any earlier operations from venturing into that\n     territory. */\n\n  memset(trace_bits, 0, MAP_SIZE);\n  MEM_BARRIER();\n\n  /* If we're running in \"dumb\" mode, we can't rely on the fork server\n     logic compiled into the target program, so we will just keep calling\n     execve(). There is a bit of code duplication between here and \n     init_forkserver(), but c'est la vie. */\n\n  if (dumb_mode == 1 || no_forkserver) {\n\n    child_pid = fork();\n\n    if (child_pid < 0) PFATAL(\"fork() failed\");\n\n    if (!child_pid) {\n\n      struct rlimit r;\n\n      if (mem_limit) {\n\n        r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n\n#ifdef RLIMIT_AS\n\n        setrlimit(RLIMIT_AS, &r); /* Ignore errors */\n\n#else\n\n        setrlimit(RLIMIT_DATA, &r); /* Ignore errors */\n\n#endif /* ^RLIMIT_AS */\n\n      }\n\n      r.rlim_max = r.rlim_cur = 0;\n\n      setrlimit(RLIMIT_CORE, &r); /* Ignore errors */\n\n      /* Isolate the process and configure standard descriptors. If out_file is\n         specified, stdin is /dev/null; otherwise, out_fd is cloned instead. */\n\n      setsid();\n\n      dup2(dev_null_fd, 1);\n      dup2(dev_null_fd, 2);\n\n      if (out_file || N_valid == 1) { /* no stdin for file or network input */\n\n        dup2(dev_null_fd, 0);\n\n      } else {\n\n        dup2(out_fd, 0);\n        close(out_fd);\n\n      }\n\n      /* On Linux, would be faster to use O_CLOEXEC. Maybe TODO. */\n\n      close(dev_null_fd);\n      close(out_dir_fd);\n      close(dev_urandom_fd);\n      close(fileno(plot_file));\n\n      /* Set sane defaults for ASAN if nothing else specified. */\n\n      setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                             \"detect_leaks=0:\"\n                             \"allocator_may_return_null=1\", 0);\n\n      setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                             \"msan_track_origins=0\", 0);\n\n      execv(target_path, argv);\n\n      /* Use a distinctive bitmap value to tell the parent about execv()\n         falling through. */\n\n      *(u32*)trace_bits = EXEC_FAIL_SIG;\n      exit(0);\n\n    }\n\n  } else {\n\n    s32 res;\n\n    /* In non-dumb mode, we have the fork server up and running, so simply\n       tell it to have at it, and then read back PID. */\n\n    if ((res = write(fsrv_ctl_fd, &prev_timed_out, 4)) != 4) {\n\n      if (stop_soon) return 0;\n      RPFATAL(res, \"Unable to request new process from fork server (OOM?)\");\n\n    }\n\n    if ((res = read(fsrv_st_fd, &child_pid, 4)) != 4) {\n\n      if (stop_soon) return 0;\n      RPFATAL(res, \"Unable to request new process from fork server (OOM?)\");\n\n    }\n\n    if (child_pid <= 0) FATAL(\"Fork server is misbehaving (OOM?)\");\n\n  }\n\n  /* Write fuzzed data set to target using network if -N option is specified */\n  \n  if (N_valid) {\n    if (N_timeout_given) {\n      /* Network output to target process after specified delay, and try\n       * up to three times (hard-coded) */\n      N_it.tv_sec = (N_exec_tmout / 1000);\n      N_it.tv_nsec = (N_exec_tmout % 1000) * 1000000;\n      /* ignore errors & accept possibility that delay can be shorter */\n      {\n\tu32 N_tries = 3;\n\tnanosleep(&N_it, NULL);\n\t/* attempt to send up to 3 times (because of target process startup time) */\n\twhile (N_tries-- &&\n               ((N_fuzz_client?network_listen():network_send()) == -1));\n      }\n    } else {\n      /* Network output to target process - no delay.  This usual won't work. */\n      if ((N_fuzz_client?network_listen():network_send()) == -1) {\n\tFATAL(\"Network: failed to connect or send; specify a network delay time\");\n      }\n    }\n  }\n  \n  /* Configure timeout, as requested by user, then wait for child to terminate. */\n\n  it.it_value.tv_sec = (exec_tmout / 1000);\n  it.it_value.tv_usec = (exec_tmout % 1000) * 1000;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  /* The SIGALRM handler simply kills the child_pid and sets child_timed_out. */\n\n  if (dumb_mode == 1 || no_forkserver) {\n\n    if (waitpid(child_pid, &status, 0) <= 0) PFATAL(\"waitpid() failed\");\n\n  } else {\n\n    s32 res;\n\n    if ((res = read(fsrv_st_fd, &status, 4)) != 4) {\n\n      if (stop_soon) return 0;\n      RPFATAL(res, \"Unable to communicate with fork server\");\n\n    }\n\n  }\n\n  child_pid = 0;\n  it.it_value.tv_sec = 0;\n  it.it_value.tv_usec = 0;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  total_execs++;\n\n  /* Any subsequent operations on trace_bits must not be moved by the\n     compiler below this point. Past this location, trace_bits[] behave\n     very normally and do not have to be treated as volatile. */\n\n  MEM_BARRIER();\n\n  tb4 = *(u32*)trace_bits;\n\n#ifdef __x86_64__\n  classify_counts((u64*)trace_bits);\n#else\n  classify_counts((u32*)trace_bits);\n#endif /* ^__x86_64__ */\n\n  prev_timed_out = child_timed_out;\n\n  /* Report outcome to caller. */\n\n  if (child_timed_out) return FAULT_HANG;\n\n  if (WIFSIGNALED(status) && !stop_soon) {\n    kill_signal = WTERMSIG(status);\n    return FAULT_CRASH;\n  }\n\n  /* A somewhat nasty hack for MSAN, which doesn't support abort_on_error and\n     must use a special exit code. */\n\n  if (uses_asan && WEXITSTATUS(status) == MSAN_ERROR) {\n    kill_signal = 0;\n    return FAULT_CRASH;\n  }\n\n  if ((dumb_mode == 1 || no_forkserver) && tb4 == EXEC_FAIL_SIG)\n    return FAULT_ERROR;\n\n  return FAULT_NONE;\n\n}\n\n\n/* Write modified data to file for testing. If out_file is set, the old file\n   is unlinked and a new one is created. Otherwise, out_fd is rewound and\n   truncated. */\n\nstatic void write_to_testcase(void* mem, u32 len) {\n\n  s32 fd = out_fd;\n\n  if (out_file) {\n\n    unlink(out_file); /* Ignore errors. */\n\n    fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);\n\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", out_file);\n\n  } else lseek(fd, 0, SEEK_SET);\n\n  ck_write(fd, mem, len, out_file);\n\n  if (!out_file) {\n\n    if (ftruncate(fd, len)) PFATAL(\"ftruncate() failed\");\n    lseek(fd, 0, SEEK_SET);\n\n  } else close(fd);\n\n}\n\n\n/* The same, but with an adjustable gap. Used for trimming. */\n\nstatic void write_with_gap(void* mem, u32 len, u32 skip_at, u32 skip_len) {\n\n  s32 fd = out_fd;\n  u32 tail_len = len - skip_at - skip_len;\n\n  if (out_file) {\n\n    unlink(out_file); /* Ignore errors. */\n\n    fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);\n\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", out_file);\n\n  } else lseek(fd, 0, SEEK_SET);\n\n  if (skip_at) ck_write(fd, mem, skip_at, out_file);\n\n  if (tail_len) ck_write(fd, mem + skip_at + skip_len, tail_len, out_file);\n\n  if (!out_file) {\n\n    if (ftruncate(fd, len - skip_len)) PFATAL(\"ftruncate() failed\");\n    lseek(fd, 0, SEEK_SET);\n\n  } else close(fd);\n\n}\n\n\nstatic void show_stats(void);\n\n/* Calibrate a new test case. This is done when processing the input directory\n   to warn about flaky or otherwise problematic test cases early on; and when\n   new paths are discovered to detect variable behavior and so on. */\n\nstatic u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem,\n                         u32 handicap, u8 from_queue) {\n\n  u8  fault = 0, new_bits = 0, var_detected = 0, first_run = (q->exec_cksum == 0);\n  u64 start_us, stop_us;\n\n  s32 old_sc = stage_cur, old_sm = stage_max, old_tmout = exec_tmout;\n  u8* old_sn = stage_name;\n\n  /* Be a bit more generous about timeouts when resuming sessions, or when\n     trying to calibrate already-added finds. This helps avoid trouble due\n     to intermittent latency. */\n\n  if (!from_queue || resuming_fuzz)\n    exec_tmout = MAX(exec_tmout + CAL_TMOUT_ADD,\n                     exec_tmout * CAL_TMOUT_PERC / 100);\n\n  q->cal_failed++;\n\n  stage_name = \"calibration\";\n  stage_max  = no_var_check ? CAL_CYCLES_NO_VAR : CAL_CYCLES;\n\n  /* Make sure the forkserver is up before we do anything, and let's not\n     count its spin-up time toward binary calibration. */\n\n  if (dumb_mode != 1 && !no_forkserver && !forksrv_pid)\n    init_forkserver(argv);\n\n  start_us = get_cur_time_us();\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    u32 cksum;\n\n    if (!first_run && !(stage_cur % stats_update_freq)) show_stats();\n\n    write_to_testcase(use_mem, q->len);\n\n    fault = run_target(argv);\n\n    /* stop_soon is set by the handler for Ctrl+C. When it's pressed,\n       we want to bail out quickly. */\n\n    if (stop_soon || fault != crash_mode) goto abort_calibration;\n\n    if (!dumb_mode && !stage_cur && !count_bytes(trace_bits)) {\n      fault = FAULT_NOINST;\n      goto abort_calibration;\n    }\n\n    cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n    if (q->exec_cksum != cksum) {\n\n      u8 hnb = has_new_bits(virgin_bits);\n      if (hnb > new_bits) new_bits = hnb;\n\n      if (!no_var_check && q->exec_cksum) {\n\n        var_detected = 1;\n        stage_max    = CAL_CYCLES_LONG;\n\n      } else q->exec_cksum = cksum;\n\n    }\n\n  }\n\n  stop_us = get_cur_time_us();\n\n  total_cal_us     += stop_us - start_us;\n  total_cal_cycles += stage_max;\n\n  /* OK, let's collect some stats about the performance of this test case.\n     This is used for fuzzing air time calculations in calculate_score(). */\n\n  q->exec_us     = (stop_us - start_us) / stage_max;\n  q->bitmap_size = count_bytes(trace_bits);\n  q->handicap    = handicap;\n  q->cal_failed  = 0;\n\n  total_bitmap_size += q->bitmap_size;\n  total_bitmap_entries++;\n\n  update_bitmap_score(q);\n\n  /* If this case didn't result in new output from the instrumentation, tell\n     parent. This is a non-critical problem, but something to warn the user\n     about. */\n\n  if (!dumb_mode && first_run && !fault && !new_bits) fault = FAULT_NOBITS;\n\nabort_calibration:\n\n  if (new_bits == 2 && !q->has_new_cov) {\n    q->has_new_cov = 1;\n    queued_with_cov++;\n  }\n\n  /* Mark variable paths. */\n\n  if (var_detected && !q->var_behavior) {\n    mark_as_variable(q);\n    queued_variable++;\n  }\n\n  stage_name = old_sn;\n  stage_cur  = old_sc;\n  stage_max  = old_sm;\n  exec_tmout = old_tmout;\n\n  if (!first_run) show_stats();\n\n  return fault;\n\n}\n\n\n/* Examine map coverage. Called once, for first test case. */\n\nstatic void check_map_coverage(void) {\n\n  u32 i;\n\n  if (count_bytes(trace_bits) < 100) return;\n\n  for (i = (1 << (MAP_SIZE_POW2 - 1)); i < MAP_SIZE; i++)\n    if (trace_bits[i]) return;\n\n  WARNF(\"Recompile binary with newer version of afl to improve coverage!\");\n\n}\n\n\n/* Perform dry run of all test cases to confirm that the app is working as\n   expected. This is done only for the initial inputs, and only once. */\n\nstatic void perform_dry_run(char** argv) {\n\n  struct queue_entry* q = queue;\n  u32 cal_failures = 0;\n  u8* skip_crashes = getenv(\"AFL_SKIP_CRASHES\");\n\n  while (q) {\n\n    u8* use_mem;\n    u8  res;\n    s32 fd;\n\n    u8* fn = strrchr(q->fname, '/') + 1;\n\n    ACTF(\"Attempting dry run with '%s'...\", fn);\n\n    fd = open(q->fname, O_RDONLY);\n    if (fd < 0) PFATAL(\"Unable to open '%s'\", q->fname);\n\n    use_mem = ck_alloc_nozero(q->len);\n\n    if (read(fd, use_mem, q->len) != q->len)\n      FATAL(\"Short read from '%s'\", q->fname);\n\n    close(fd);\n\n    res = calibrate_case(argv, q, use_mem, 0, 1);\n    ck_free(use_mem);\n\n    if (stop_soon) return;\n\n    if (res == crash_mode || res == FAULT_NOBITS)\n      SAYF(cGRA \"    len = %u, map size = %u, exec speed = %llu us\\n\" cRST, \n           q->len, q->bitmap_size, q->exec_us);\n\n    switch (res) {\n\n      case FAULT_NONE:\n\n        if (q == queue) check_map_coverage();\n\n        if (crash_mode) FATAL(\"Test case '%s' does *NOT* crash\", fn);\n\n        break;\n\n      case FAULT_HANG:\n\n        if (timeout_given) {\n\n          /* The -t nn+ syntax in the command line sets timeout_given to '2' and\n             instructs afl-fuzz to tolerate but skip queue entries that time\n             out. */\n\n          if (timeout_given > 1) {\n            WARNF(\"Test case results in a hang (skipping)\");\n            q->cal_failed = CAL_CHANCES;\n            cal_failures++;\n            break;\n          }\n\n          SAYF(\"\\n\" cLRD \"[-] \" cRST\n               \"The program took more than %u ms to process one of the initial test cases.\\n\"\n               \"    Usually, the right thing to do is to relax the -t option - or to delete it\\n\"\n               \"    altogether and allow the fuzzer to auto-calibrate. That said, if you know\\n\"\n               \"    what you are doing and want to simply skip the unruly test cases, append\\n\"\n               \"    '+' at the end of the value passed to -t ('-t %u+').\\n\", exec_tmout,\n               exec_tmout);\n\n          FATAL(\"Test case '%s' results in a hang\", fn);\n\n        } else {\n\n          SAYF(\"\\n\" cLRD \"[-] \" cRST\n               \"The program took more than %u ms to process one of the initial test cases.\\n\"\n               \"    This is bad news; raising the limit with the -t option is possible, but\\n\"\n               \"    will probably make the fuzzing process extremely slow.\\n\\n\"\n\n               \"    If this test case is just a fluke, the other option is to just avoid it\\n\"\n               \"    altogether, and find one that is less of a CPU hog.\\n\", exec_tmout);\n\n          FATAL(\"Test case '%s' results in a hang\", fn);\n\n        }\n\n      case FAULT_CRASH:  \n\n        if (crash_mode) break;\n\n        if (skip_crashes) {\n          WARNF(\"Test case results in a crash (skipping)\");\n          q->cal_failed = CAL_CHANCES;\n          cal_failures++;\n          break;\n        }\n\n        if (mem_limit) {\n\n          SAYF(\"\\n\" cLRD \"[-] \" cRST\n               \"Oops, the program crashed with one of the test cases provided. There are\\n\"\n               \"    several possible explanations:\\n\\n\"\n\n               \"    - The test case causes known crashes under normal working conditions. If\\n\"\n               \"      so, please remove it. The fuzzer should be seeded with interesting\\n\"\n               \"      inputs - but not ones that cause an outright crash.\\n\\n\"\n\n               \"    - The current memory limit (%s) is too low for this program, causing\\n\"\n               \"      it to die due to OOM when parsing valid files. To fix this, try\\n\"\n               \"      bumping it up with the -m setting in the command line. If in doubt,\\n\"\n               \"      try something along the lines of:\\n\\n\"\n\n#ifdef RLIMIT_AS\n               \"      ( ulimit -Sv $[%llu << 10]; /path/to/binary [...] <testcase )\\n\\n\"\n#else\n               \"      ( ulimit -Sd $[%llu << 10]; /path/to/binary [...] <testcase )\\n\\n\"\n#endif /* ^RLIMIT_AS */\n\n               \"      Tip: you can use http://jwilk.net/software/recidivm to quickly\\n\"\n               \"      estimate the required amount of virtual memory for the binary. Also,\\n\"\n               \"      if you are using ASAN, see %s/notes_for_asan.txt.\\n\\n\"\n\n#ifdef __APPLE__\n  \n               \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n               \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n               \"      binaries. To fix this, set AFL_NO_FORKSRV=1 in the environment.\\n\\n\"\n\n#endif /* __APPLE__ */\n\n               \"    - Least likely, there is a horrible bug in the fuzzer. If other options\\n\"\n               \"      fail, poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\",\n               DMS(mem_limit << 20), mem_limit - 1, doc_path);\n\n        } else {\n\n          SAYF(\"\\n\" cLRD \"[-] \" cRST\n               \"Oops, the program crashed with one of the test cases provided. There are\\n\"\n               \"    several possible explanations:\\n\\n\"\n\n               \"    - The test case causes known crashes under normal working conditions. If\\n\"\n               \"      so, please remove it. The fuzzer should be seeded with interesting\\n\"\n               \"      inputs - but not ones that cause an outright crash.\\n\\n\"\n\n#ifdef __APPLE__\n  \n               \"    - On MacOS X, the semantics of fork() syscalls are non-standard and may\\n\"\n               \"      break afl-fuzz performance optimizations when running platform-specific\\n\"\n               \"      binaries. To fix this, set AFL_NO_FORKSRV=1 in the environment.\\n\\n\"\n\n#endif /* __APPLE__ */\n\n               \"    - Least likely, there is a horrible bug in the fuzzer. If other options\\n\"\n               \"      fail, poke <lcamtuf@coredump.cx> for troubleshooting tips.\\n\");\n\n        }\n\n        FATAL(\"Test case '%s' results in a crash\", fn);\n\n      case FAULT_ERROR:\n\n        FATAL(\"Unable to execute target application ('%s')\", argv[0]);\n\n      case FAULT_NOINST:\n\n        FATAL(\"No instrumentation detected\");\n\n      case FAULT_NOBITS: \n\n        useless_at_start++;\n\n        if (!in_bitmap)\n          WARNF(\"No new instrumentation output, test case may be useless.\");\n\n        break;\n\n    }\n\n    if (q->var_behavior) WARNF(\"Instrumentation output varies across runs.\");\n\n    q = q->next;\n\n  }\n\n  if (cal_failures) {\n\n    if (cal_failures == queued_paths)\n      FATAL(\"All test cases time out%s, giving up!\",\n            skip_crashes ? \" or crash\" : \"\");\n\n    WARNF(\"Skipped %u test cases (%0.02f%%) due to timeouts%s.\", cal_failures,\n          ((double)cal_failures) * 100 / queued_paths,\n          skip_crashes ? \" or crashes\" : \"\");\n\n    if (cal_failures * 5 > queued_paths)\n      WARNF(cLRD \"High percentage of rejected test cases, check settings!\");\n\n  }\n\n  OKF(\"All test cases processed.\");\n\n}\n\n\n/* Helper function: link() if possible, copy otherwise. */\n\nstatic void link_or_copy(u8* old_path, u8* new_path) {\n\n  s32 i = link(old_path, new_path);\n  s32 sfd, dfd;\n  u8* tmp;\n\n  if (!i) return;\n\n  sfd = open(old_path, O_RDONLY);\n  if (sfd < 0) PFATAL(\"Unable to open '%s'\", old_path);\n\n  dfd = open(new_path, O_WRONLY | O_CREAT | O_EXCL, 0600);\n  if (dfd < 0) PFATAL(\"Unable to create '%s'\", new_path);\n\n  tmp = ck_alloc(64 * 1024);\n\n  while ((i = read(sfd, tmp, 64 * 1024)) > 0) \n    ck_write(dfd, tmp, i, new_path);\n\n  if (i < 0) PFATAL(\"read() failed\");\n\n  ck_free(tmp);\n  close(sfd);\n  close(dfd);\n\n}\n\n\nstatic void nuke_resume_dir(void);\n\n/* Create hard links for input test cases in the output directory, choosing\n   good names and pivoting accordingly. */\n\nstatic void pivot_inputs(void) {\n\n  struct queue_entry* q = queue;\n  u32 id = 0;\n\n  ACTF(\"Creating hard links for all input files...\");\n\n  while (q) {\n\n    u8  *nfn, *rsl = strrchr(q->fname, '/');\n    u32 orig_id;\n\n    if (!rsl) rsl = q->fname; else rsl++;\n\n    /* If the original file name conforms to the syntax and the recorded\n       ID matches the one we'd assign, just use the original file name.\n       This is valuable for resuming fuzzing runs. */\n\n#ifndef SIMPLE_FILES\n#  define CASE_PREFIX \"id:\"\n#else\n#  define CASE_PREFIX \"id_\"\n#endif /* ^!SIMPLE_FILES */\n\n    if (!strncmp(rsl, CASE_PREFIX, 3) &&\n        sscanf(rsl + 3, \"%06u\", &orig_id) == 1 && orig_id == id) {\n\n      u8* src_str;\n      u32 src_id;\n\n      resuming_fuzz = 1;\n      nfn = alloc_printf(\"%s/queue/%s\", out_dir, rsl);\n\n      /* Since we're at it, let's also try to find parent and figure out the\n         appropriate depth for this entry. */\n\n      src_str = strchr(rsl + 3, ':');\n\n      if (src_str && sscanf(src_str + 1, \"%06u\", &src_id) == 1) {\n\n        struct queue_entry* s = queue;\n        while (src_id-- && s) s = s->next;\n        if (s) q->depth = s->depth + 1;\n\n        if (max_depth < q->depth) max_depth = q->depth;\n\n      }\n\n    } else {\n\n      /* No dice - invent a new name, capturing the original one as a\n         substring. */\n\n#ifndef SIMPLE_FILES\n\n      u8* use_name = strstr(rsl, \",orig:\");\n\n      if (use_name) use_name += 6; else use_name = rsl;\n      nfn = alloc_printf(\"%s/queue/id:%06u,orig:%s\", out_dir, id, use_name);\n\n#else\n\n      nfn = alloc_printf(\"%s/queue/id_%06u\", out_dir, id);\n\n#endif /* ^!SIMPLE_FILES */\n\n    }\n\n    /* Pivot to the new queue entry. */\n\n    link_or_copy(q->fname, nfn);\n    ck_free(q->fname);\n    q->fname = nfn;\n\n    /* Make sure that the passed_det value carries over, too. */\n\n    if (q->passed_det) mark_as_det_done(q);\n\n    q = q->next;\n    id++;\n\n  }\n\n  if (in_place_resume) nuke_resume_dir();\n\n}\n\n\n#ifndef SIMPLE_FILES\n\n/* Construct a file name for a new test case, capturing the operation\n   that led to its discovery. Uses a static buffer. */\n\nstatic u8* describe_op(u8 hnb) {\n\n  static u8 ret[256];\n\n  if (syncing_party) {\n\n    sprintf(ret, \"sync:%s,src:%06u\", syncing_party, syncing_case);\n\n  } else {\n\n    sprintf(ret, \"src:%06u\", current_entry);\n\n    if (splicing_with >= 0)\n      sprintf(ret + strlen(ret), \"+%06u\", splicing_with);\n\n    sprintf(ret + strlen(ret), \",op:%s\", stage_short);\n\n    if (stage_cur_byte >= 0) {\n\n      sprintf(ret + strlen(ret), \",pos:%u\", stage_cur_byte);\n\n      if (stage_val_type != STAGE_VAL_NONE)\n        sprintf(ret + strlen(ret), \",val:%s%+d\", \n                (stage_val_type == STAGE_VAL_BE) ? \"be:\" : \"\",\n                stage_cur_val);\n\n    } else sprintf(ret + strlen(ret), \",rep:%u\", stage_cur_val);\n\n  }\n\n  if (hnb == 2) strcat(ret, \",+cov\");\n\n  return ret;\n\n}\n\n#endif /* !SIMPLE_FILES */\n\n\n/* Write a message accompanying the crash directory :-) */\n\nstatic void write_crash_readme(void) {\n\n  u8* fn = alloc_printf(\"%s/crashes/README.txt\", out_dir);\n  s32 fd;\n  FILE* f;\n\n  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n  ck_free(fn);\n\n  /* Do not die on errors here - that would be impolite. */\n\n  if (fd < 0) return;\n\n  f = fdopen(fd, \"w\");\n\n  if (!f) {\n    close(fd);\n    return;\n  }\n\n  fprintf(f, \"Command line used to find this crash:\\n\\n\"\n\n             \"%s\\n\\n\"\n\n             \"If you can't reproduce a bug outside of afl-fuzz, be sure to set the same\\n\"\n             \"memory limit. The limit used for this fuzzing session was %s.\\n\\n\"\n\n             \"Need a tool to minimize test cases before investigating the crashes or sending\\n\"\n             \"them to a vendor? Check out the afl-tmin that comes with the fuzzer!\\n\\n\"\n\n             \"Found any cool bugs in open-source tools using afl-fuzz? If yes, please drop\\n\"\n             \"me a mail at <lcamtuf@coredump.cx> once the issues are fixed - I'd love to\\n\"\n             \"add your finds to the gallery at:\\n\\n\"\n\n             \"  http://lcamtuf.coredump.cx/afl/\\n\\n\"\n\n             \"Thanks :-)\\n\",\n\n             orig_cmdline, DMS(mem_limit << 20)); /* ignore errors */\n\n  fclose(f);\n\n}\n\n\n/* Check if the result of an execve() during routine fuzzing is interesting,\n   save or queue the input test case for further analysis if so. Returns 1 if\n   entry is saved, 0 otherwise. */\n\nstatic u8 save_if_interesting(char** argv, void* mem, u32 len, u8 fault) {\n\n  u8  *fn = \"\";\n  u8  hnb;\n  s32 fd;\n  u8  keeping = 0, res;\n\n  if (fault == crash_mode) {\n\n    /* Keep only if there are new bits in the map, add to queue for\n       future fuzzing, etc. */\n\n    if (!(hnb = has_new_bits(virgin_bits))) {\n      if (crash_mode) total_crashes++;\n      return 0;\n    }    \n\n#ifndef SIMPLE_FILES\n\n    fn = alloc_printf(\"%s/queue/id:%06u,%s\", out_dir, queued_paths,\n                      describe_op(hnb));\n\n#else\n\n    fn = alloc_printf(\"%s/queue/id_%06u\", out_dir, queued_paths);\n\n#endif /* ^!SIMPLE_FILES */\n\n    add_to_queue(fn, len, 0);\n\n    if (hnb == 2) {\n      queue_top->has_new_cov = 1;\n      queued_with_cov++;\n    }\n\n    queue_top->exec_cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n    /* Try to calibrate inline; this also calls update_bitmap_score() when\n       successful. */\n\n    res = calibrate_case(argv, queue_top, mem, queue_cycle - 1, 0);\n\n    if (res == FAULT_ERROR)\n      FATAL(\"Unable to execute target application\");\n\n    fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n    ck_write(fd, mem, len, fn);\n    close(fd);\n\n    keeping = 1;\n\n  }\n\n  switch (fault) {\n\n    case FAULT_HANG:\n\n      /* Hangs are not very interesting, but we're still obliged to keep\n         a handful of samples. We use the presence of new bits in the\n         hang-specific bitmap as a signal of uniqueness. In \"dumb\" mode, we\n         just keep everything. */\n\n      total_hangs++;\n\n      if (unique_hangs >= KEEP_UNIQUE_HANG) return keeping;\n\n      if (!dumb_mode) {\n\n#ifdef __x86_64__\n        simplify_trace((u64*)trace_bits);\n#else\n        simplify_trace((u32*)trace_bits);\n#endif /* ^__x86_64__ */\n\n        if (!has_new_bits(virgin_hang)) return keeping;\n\n      }\n\n#ifndef SIMPLE_FILES\n\n      fn = alloc_printf(\"%s/hangs/id:%06llu,%s\", out_dir,\n                        unique_hangs, describe_op(0));\n\n#else\n\n      fn = alloc_printf(\"%s/hangs/id_%06llu\", out_dir,\n                        unique_hangs);\n\n#endif /* ^!SIMPLE_FILES */\n\n      unique_hangs++;\n\n      last_hang_time = get_cur_time();\n\n      break;\n\n    case FAULT_CRASH:\n\n      /* This is handled in a manner roughly similar to hangs,\n         except for slightly different limits. */\n\n      total_crashes++;\n\n      if (unique_crashes >= KEEP_UNIQUE_CRASH) return keeping;\n\n      if (!dumb_mode) {\n\n#ifdef __x86_64__\n        simplify_trace((u64*)trace_bits);\n#else\n        simplify_trace((u32*)trace_bits);\n#endif /* ^__x86_64__ */\n\n        if (!has_new_bits(virgin_crash)) return keeping;\n\n      }\n\n      if (!unique_crashes) write_crash_readme();\n\n#ifndef SIMPLE_FILES\n\n      fn = alloc_printf(\"%s/crashes/id:%06llu,sig:%02u,%s\", out_dir,\n                        unique_crashes, kill_signal, describe_op(0));\n\n#else\n\n      fn = alloc_printf(\"%s/crashes/id_%06llu_%02u\", out_dir, unique_crashes,\n                        kill_signal);\n\n#endif /* ^!SIMPLE_FILES */\n\n      unique_crashes++;\n\n      last_crash_time = get_cur_time();\n\n      break;\n\n    case FAULT_ERROR: FATAL(\"Unable to execute target application\");\n\n    default: return keeping;\n\n  }\n\n  /* If we're here, we apparently want to save the crash or hang\n     test case, too. */\n\n  fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);\n  if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n  ck_write(fd, mem, len, fn);\n  close(fd);\n\n  ck_free(fn);\n\n  return keeping;\n\n}\n\n\n/* When resuming, try to find the queue position to start from. This makes sense\n   only when resuming, and when we can find the original fuzzer_stats. */\n\nstatic u32 find_start_position(void) {\n\n  static u8 tmp[4096]; /* Ought to be enough for anybody. */\n\n  u8  *fn, *off;\n  s32 fd, i;\n  u32 ret;\n\n  if (!resuming_fuzz) return 0;\n\n  if (in_place_resume) fn = alloc_printf(\"%s/fuzzer_stats\", out_dir);\n  else fn = alloc_printf(\"%s/../fuzzer_stats\", in_dir);\n\n  fd = open(fn, O_RDONLY);\n  ck_free(fn);\n\n  if (fd < 0) return 0;\n\n  i = read(fd, tmp, sizeof(tmp) - 1); (void)i; /* Ignore errors */\n  close(fd);\n\n  off = strstr(tmp, \"cur_path       : \");\n  if (!off) return 0;\n\n  ret = atoi(off + 17);\n  if (ret >= queued_paths) ret = 0;\n  return ret;\n\n}\n\n\n/* The same, but for timeouts. The idea is that when resuming sessions without\n   -t given, we don't want to keep auto-scaling the timeout over and over\n   again to prevent it from growing due to random flukes. */\n\nstatic void find_timeout(void) {\n\n  static u8 tmp[4096]; /* Ought to be enough for anybody. */\n\n  u8  *fn, *off;\n  s32 fd, i;\n  u32 ret;\n\n  if (!resuming_fuzz) return;\n\n  if (in_place_resume) fn = alloc_printf(\"%s/fuzzer_stats\", out_dir);\n  else fn = alloc_printf(\"%s/../fuzzer_stats\", in_dir);\n\n  fd = open(fn, O_RDONLY);\n  ck_free(fn);\n\n  if (fd < 0) return;\n\n  i = read(fd, tmp, sizeof(tmp) - 1); (void)i; /* Ignore errors */\n  close(fd);\n\n  off = strstr(tmp, \"exec_timeout   : \");\n  if (!off) return;\n\n  ret = atoi(off + 17);\n  if (ret <= 4) return;\n\n  exec_tmout = ret;\n  timeout_given = 3;\n\n}\n\n\n/* Update stats file for unattended monitoring. */\n\nstatic void write_stats_file(double bitmap_cvg, double eps) {\n\n  static double last_bcvg, last_eps;\n\n  u8* fn = alloc_printf(\"%s/fuzzer_stats\", out_dir);\n  s32 fd;\n  FILE* f;\n\n  fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);\n\n  if (fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n\n  ck_free(fn);\n\n  f = fdopen(fd, \"w\");\n\n  if (!f) PFATAL(\"fdopen() failed\");\n\n  /* Keep last values in case we're called from another context\n     where exec/sec stats and such are not readily available. */\n\n  if (!bitmap_cvg && !eps) {\n    bitmap_cvg = last_bcvg;\n    eps        = last_eps;\n  } else {\n    last_bcvg = bitmap_cvg;\n    last_eps  = eps;\n  }\n\n  fprintf(f, \"start_time     : %llu\\n\"\n             \"last_update    : %llu\\n\"\n             \"fuzzer_pid     : %u\\n\"\n             \"cycles_done    : %llu\\n\"\n             \"execs_done     : %llu\\n\"\n             \"execs_per_sec  : %0.02f\\n\"\n             \"paths_total    : %u\\n\"\n             \"paths_favored  : %u\\n\"\n             \"paths_found    : %u\\n\"\n             \"paths_imported : %u\\n\"\n             \"max_depth      : %u\\n\"\n             \"cur_path       : %u\\n\"\n             \"pending_favs   : %u\\n\"\n             \"pending_total  : %u\\n\"\n             \"variable_paths : %u\\n\"\n             \"bitmap_cvg     : %0.02f%%\\n\"\n             \"unique_crashes : %llu\\n\"\n             \"unique_hangs   : %llu\\n\"\n             \"last_path      : %llu\\n\"\n             \"last_crash     : %llu\\n\"\n             \"last_hang      : %llu\\n\"\n             \"exec_timeout   : %u\\n\"\n             \"afl_banner     : %s\\n\"\n             \"afl_version    : \" VERSION \"\\n\"\n             \"command_line   : %s\\n\",\n             start_time / 1000, get_cur_time() / 1000, getpid(),\n             queue_cycle ? (queue_cycle - 1) : 0, total_execs, eps,\n             queued_paths, queued_favored, queued_discovered, queued_imported,\n             max_depth, current_entry, pending_favored, pending_not_fuzzed,\n             queued_variable, bitmap_cvg, unique_crashes, unique_hangs,\n             last_path_time / 1000, last_crash_time / 1000,\n             last_hang_time / 1000, exec_tmout, use_banner, orig_cmdline);\n             /* ignore errors */\n\n  fclose(f);\n\n}\n\n\n/* Update the plot file if there is a reason to. */\n\nstatic void maybe_update_plot_file(double bitmap_cvg, double eps) {\n\n  static u32 prev_qp, prev_pf, prev_pnf, prev_ce, prev_md;\n  static u64 prev_qc, prev_uc, prev_uh;\n\n  if (prev_qp == queued_paths && prev_pf == pending_favored && \n      prev_pnf == pending_not_fuzzed && prev_ce == current_entry &&\n      prev_qc == queue_cycle && prev_uc == unique_crashes &&\n      prev_uh == unique_hangs && prev_md == max_depth) return;\n\n  prev_qp  = queued_paths;\n  prev_pf  = pending_favored;\n  prev_pnf = pending_not_fuzzed;\n  prev_ce  = current_entry;\n  prev_qc  = queue_cycle;\n  prev_uc  = unique_crashes;\n  prev_uh  = unique_hangs;\n  prev_md  = max_depth;\n\n  /* Fields in the file:\n\n     unix_time, cycles_done, cur_path, paths_total, paths_not_fuzzed,\n     favored_not_fuzzed, unique_crashes, unique_hangs, max_depth,\n     execs_per_sec */\n\n  fprintf(plot_file, \n          \"%llu, %llu, %u, %u, %u, %u, %0.02f%%, %llu, %llu, %u, %0.02f\\n\",\n          get_cur_time() / 1000, queue_cycle - 1, current_entry, queued_paths,\n          pending_not_fuzzed, pending_favored, bitmap_cvg, unique_crashes,\n          unique_hangs, max_depth, eps); /* ignore errors */\n\n  fflush(plot_file);\n\n}\n\n\n\n/* A helper function for maybe_delete_out_dir(), deleting all prefixed\n   files in a directory. */\n\nstatic u8 delete_files(u8* path, u8* prefix) {\n\n  DIR* d;\n  struct dirent* d_ent;\n\n  d = opendir(path);\n\n  if (!d) return 0;\n\n  while ((d_ent = readdir(d))) {\n\n    if (d_ent->d_name[0] != '.' && (!prefix ||\n        !strncmp(d_ent->d_name, prefix, strlen(prefix)))) {\n\n      u8* fname = alloc_printf(\"%s/%s\", path, d_ent->d_name);\n      if (unlink(fname)) PFATAL(\"Unable to delete '%s'\", fname);\n      ck_free(fname);\n\n    }\n\n  }\n\n  closedir(d);\n\n  return !!rmdir(path);\n\n}\n\n\n/* Get the number of runnable processes, with some simple smoothing. */\n\nstatic double get_runnable_processes(void) {\n\n  static double res;\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)\n\n  /* I don't see any portable sysctl or so that would quickly give us the\n     number of runnable processes; the 1-minute load average can be a\n     semi-decent approximation, though. */\n\n  if (getloadavg(&res, 1) != 1) return 0;\n\n#else\n\n  /* On Linux, /proc/stat is probably the best way; load averages are\n     computed in funny ways and sometimes don't reflect extremely short-lived\n     processes well. */\n\n  FILE* f = fopen(\"/proc/stat\", \"r\");\n  u8 tmp[1024];\n  u32 val = 0;\n\n  if (!f) return 0;\n\n  while (fgets(tmp, sizeof(tmp), f)) {\n\n    if (!strncmp(tmp, \"procs_running \", 14) ||\n        !strncmp(tmp, \"procs_blocked \", 14)) val += atoi(tmp + 14);\n\n  }\n \n  fclose(f);\n\n  if (!res) {\n\n    res = val;\n\n  } else {\n\n    res = res * (1.0 - 1.0 / AVG_SMOOTHING) +\n          ((double)val) * (1.0 / AVG_SMOOTHING);\n\n  }\n\n#endif /* ^(__APPLE__ || __FreeBSD__ || __OpenBSD__) */\n\n  return res;\n\n}\n\n\n/* Delete the temporary directory used for in-place session resume. */\n\nstatic void nuke_resume_dir(void) {\n\n  u8* fn;\n\n  fn = alloc_printf(\"%s/_resume/.state/deterministic_done\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/_resume/.state/auto_extras\", out_dir);\n  if (delete_files(fn, \"auto_\")) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/_resume/.state/redundant_edges\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/_resume/.state/variable_behavior\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/_resume/.state\", out_dir);\n  if (rmdir(fn) && errno != ENOENT) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/_resume\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  return;\n\ndir_cleanup_failed:\n\n  FATAL(\"_resume directory cleanup failed\");\n\n}\n\n\n/* Delete fuzzer output directory if we recognize it as ours, if the fuzzer\n   is not currently running, and if the last run time isn't too great. */\n\nstatic void maybe_delete_out_dir(void) {\n\n  FILE* f;\n  u8 *fn = alloc_printf(\"%s/fuzzer_stats\", out_dir);\n\n  /* See if the output directory is locked. If yes, bail out. If not,\n     create a lock that will persist for the lifetime of the process\n     (this requires leaving the descriptor open).*/\n\n  out_dir_fd = open(out_dir, O_RDONLY);\n  if (out_dir_fd < 0) PFATAL(\"Unable to open '%s'\", out_dir);\n\n#ifndef __sun\n\n  if (flock(out_dir_fd, LOCK_EX | LOCK_NB) && errno == EWOULDBLOCK) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Looks like the job output directory is being actively used by another\\n\"\n         \"    instance of afl-fuzz. You will need to choose a different %s\\n\"\n         \"    or stop the other process first.\\n\",\n         sync_id ? \"fuzzer ID\" : \"output location\");\n\n    FATAL(\"Directory '%s' is in use\", out_dir);\n\n  }\n\n#endif /* !__sun */\n\n  f = fopen(fn, \"r\");\n\n  if (f) {\n\n    u64 start_time, last_update;\n\n    if (fscanf(f, \"start_time     : %llu\\n\"\n                  \"last_update    : %llu\\n\", &start_time, &last_update) != 2)\n      FATAL(\"Malformed data in '%s'\", fn);\n\n    fclose(f);\n\n    /* Let's see how much work is at stake. */\n\n    if (!in_place_resume && last_update - start_time > OUTPUT_GRACE * 60) {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"The job output directory already exists and contains the results of more\\n\"\n           \"    than %u minutes worth of fuzzing. To avoid data loss, afl-fuzz will *NOT*\\n\"\n           \"    automatically delete this data for you.\\n\\n\"\n\n           \"    If you wish to start a new session, remove or rename the directory manually,\\n\"\n           \"    or specify a different output location for this job. To resume the old\\n\"\n           \"    session, put '-' as the input directory in the command line ('-i -') and\\n\"\n           \"    try again.\\n\", OUTPUT_GRACE);\n\n       FATAL(\"At-risk data found in in '%s'\", out_dir);\n\n    }\n\n  }\n\n  ck_free(fn);\n\n  /* The idea for in-place resume is pretty simple: we temporarily move the old\n     queue/ to a new location that gets deleted once import to the new queue/\n     is finished. If _resume/ already exists, the current queue/ may be\n     incomplete due to an earlier abort, so we want to use the old _resume/\n     dir instead, and we let rename() fail silently. */\n\n  if (in_place_resume) {\n\n    u8* orig_q = alloc_printf(\"%s/queue\", out_dir);\n\n    in_dir = alloc_printf(\"%s/_resume\", out_dir);\n\n    rename(orig_q, in_dir); /* Ignore errors */\n\n    OKF(\"Output directory exists, will attempt session resume.\");\n\n    ck_free(orig_q);\n\n  } else {\n\n    OKF(\"Output directory exists but deemed OK to reuse.\");\n\n  }\n\n  ACTF(\"Deleting old session data...\");\n\n  /* Okay, let's get the ball rolling! First, we need to get rid of the entries\n     in <out_dir>/.synced/.../id:*, if any are present. */\n\n  fn = alloc_printf(\"%s/.synced\", out_dir);\n  if (delete_files(fn, NULL)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  /* Next, we need to clean up <out_dir>/queue/.state/ subdirectories: */\n\n  fn = alloc_printf(\"%s/queue/.state/deterministic_done\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/queue/.state/auto_extras\", out_dir);\n  if (delete_files(fn, \"auto_\")) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/queue/.state/redundant_edges\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/queue/.state/variable_behavior\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  /* Then, get rid of the .state subdirectory itself (should be empty by now)\n     and everything matching <out_dir>/queue/id:*. */\n\n  fn = alloc_printf(\"%s/queue/.state\", out_dir);\n  if (rmdir(fn) && errno != ENOENT) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/queue\", out_dir);\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  /* All right, let's do <out_dir>/crashes/id:* and <out_dir>/hangs/id:*. */\n\n  if (!in_place_resume) {\n\n    fn = alloc_printf(\"%s/crashes/README.txt\", out_dir);\n    unlink(fn); /* Ignore errors */\n    ck_free(fn);\n\n  }\n\n  fn = alloc_printf(\"%s/crashes\", out_dir);\n\n  /* Make backup of the crashes directory if it's not empty and if we're\n     doing in-place resume. */\n\n  if (in_place_resume && rmdir(fn)) {\n\n    time_t cur_t = time(0);\n    struct tm* t = localtime(&cur_t);\n\n#ifndef SIMPLE_FILES\n\n    u8* nfn = alloc_printf(\"%s.%04u-%02u-%02u-%02u:%02u:%02u\", fn,\n                           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,\n                           t->tm_hour, t->tm_min, t->tm_sec);\n\n#else\n\n    u8* nfn = alloc_printf(\"%s_%04u%02u%02u%02u%02u%02u\", fn,\n                           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,\n                           t->tm_hour, t->tm_min, t->tm_sec);\n\n#endif /* ^!SIMPLE_FILES */\n\n    rename(fn, nfn); /* Ignore errors. */\n    ck_free(nfn);\n\n  }\n\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/hangs\", out_dir);\n\n  /* Backup hangs, too. */\n\n  if (in_place_resume && rmdir(fn)) {\n\n    time_t cur_t = time(0);\n    struct tm* t = localtime(&cur_t);\n\n#ifndef SIMPLE_FILES\n\n    u8* nfn = alloc_printf(\"%s.%04u-%02u-%02u-%02u:%02u:%02u\", fn,\n                           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,\n                           t->tm_hour, t->tm_min, t->tm_sec);\n\n#else\n\n    u8* nfn = alloc_printf(\"%s_%04u%02u%02u%02u%02u%02u\", fn,\n                           t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,\n                           t->tm_hour, t->tm_min, t->tm_sec);\n\n#endif /* ^!SIMPLE_FILES */\n\n    rename(fn, nfn); /* Ignore errors. */\n    ck_free(nfn);\n\n  }\n\n  if (delete_files(fn, CASE_PREFIX)) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  /* And now, for some finishing touches. */\n\n  fn = alloc_printf(\"%s/.cur_input\", out_dir);\n  if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  fn = alloc_printf(\"%s/fuzz_bitmap\", out_dir);\n  if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  if (!in_place_resume) {\n    fn  = alloc_printf(\"%s/fuzzer_stats\", out_dir);\n    if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;\n    ck_free(fn);\n  }\n\n  fn = alloc_printf(\"%s/plot_data\", out_dir);\n  if (unlink(fn) && errno != ENOENT) goto dir_cleanup_failed;\n  ck_free(fn);\n\n  OKF(\"Output dir cleanup successful.\");\n\n  /* Wow... is that all? If yes, celebrate! */\n\n  return;\n\ndir_cleanup_failed:\n\n  SAYF(\"\\n\" cLRD \"[-] \" cRST\n       \"Whoops, the fuzzer tried to reuse your output directory, but bumped into\\n\"\n       \"    some files that shouldn't be there or that couldn't be removed - so it\\n\"\n       \"    decided to abort! This happened while processing this path:\\n\\n\"\n\n       \"    %s\\n\\n\"\n       \"    Please examine and manually delete the files, or specify a different\\n\"\n       \"    output location for the tool.\\n\", fn);\n\n  FATAL(\"Output directory cleanup failed\");\n\n}\n\n\nstatic void check_term_size(void);\n\n\n/* A spiffy retro stats screen! This is called every stats_update_freq\n   execve() calls, plus in several other circumstances. */\n\nstatic void show_stats(void) {\n\n  static u64 last_stats_ms, last_plot_ms, last_ms, last_execs;\n  static double avg_exec;\n  double t_byte_ratio;\n\n  u64 cur_ms;\n  u32 t_bytes, t_bits;\n\n  u32 banner_len, banner_pad;\n  u8  tmp[256];\n\n  cur_ms = get_cur_time();\n\n  /* If not enough time has passed since last UI update, bail out. */\n\n  if (cur_ms - last_ms < 1000 / UI_TARGET_HZ) return;\n\n  /* Check if we're past the 10 minute mark. */\n\n  if (cur_ms - start_time > 10 * 60 * 1000) run_over10m = 1;\n\n  /* Calculate smoothed exec speed stats. */\n\n  if (!last_execs) {\n  \n    avg_exec = ((double)total_execs) * 1000 / (cur_ms - start_time);\n\n  } else {\n\n    double cur_avg = ((double)(total_execs - last_execs)) * 1000 /\n                     (cur_ms - last_ms);\n\n    /* If there is a dramatic (5x+) jump in speed, reset the indicator\n       more quickly. */\n\n    if (cur_avg * 5 < avg_exec || cur_avg / 5 > avg_exec)\n      avg_exec = cur_avg;\n\n    avg_exec = avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +\n               cur_avg * (1.0 / AVG_SMOOTHING);\n\n  }\n\n  last_ms = cur_ms;\n  last_execs = total_execs;\n\n  /* Tell the callers when to contact us (as measured in execs). */\n\n  stats_update_freq = avg_exec / (UI_TARGET_HZ * 10);\n  if (!stats_update_freq) stats_update_freq = 1;\n\n  /* Do some bitmap stats. */\n\n  t_bytes = count_non_255_bytes(virgin_bits);\n  t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE;\n\n  /* Roughly every minute, update fuzzer stats and save auto tokens. */\n\n  if (cur_ms - last_stats_ms > STATS_UPDATE_SEC * 1000) {\n\n    last_stats_ms = cur_ms;\n    write_stats_file(t_byte_ratio, avg_exec);\n    save_auto();\n    write_bitmap();\n\n  }\n\n  /* Every now and then, write plot data. */\n\n  if (cur_ms - last_plot_ms > PLOT_UPDATE_SEC * 1000) {\n\n    last_plot_ms = cur_ms;\n    maybe_update_plot_file(t_byte_ratio, avg_exec);\n \n  }\n\n  /* Honor AFL_EXIT_WHEN_DONE. */\n\n  if (!dumb_mode && cycles_wo_finds > 20 && !pending_not_fuzzed &&\n      getenv(\"AFL_EXIT_WHEN_DONE\")) stop_soon = 2;\n\n  /* If we're not on TTY, bail out. */\n\n  if (not_on_tty) return;\n\n  /* Compute some mildly useful bitmap stats. */\n\n  t_bits = (MAP_SIZE << 3) - count_bits(virgin_bits);\n\n  /* Now, for the visuals... */\n\n  if (clear_screen) {\n\n    SAYF(TERM_CLEAR CURSOR_HIDE);\n    clear_screen = 0;\n\n    check_term_size();\n\n  }\n\n  SAYF(TERM_HOME);\n\n  if (term_too_small) {\n\n    SAYF(cBRI \"Your terminal is too small to display the UI.\\n\"\n         \"Please resize terminal window to at least 80x25.\\n\" cNOR);\n\n    return;\n\n  }\n\n  /* Let's start by drawing a centered banner. */\n\n  banner_len = (crash_mode ? 24 : 22) + strlen(VERSION) + strlen(use_banner);\n  banner_pad = (80 - banner_len) / 2;\n  memset(tmp, ' ', banner_pad);\n\n  sprintf(tmp + banner_pad, \"%s \" cLCY VERSION cLGN\n          \" (%s)\",  crash_mode ? cPIN \"peruvian were-rabbit\" : \n          cYEL \"american fuzzy lop\", use_banner);\n\n  SAYF(\"\\n%s\\n\\n\", tmp);\n\n  /* \"Handy\" shortcuts for drawing boxes... */\n\n#define bSTG    bSTART cGRA\n#define bH2     bH bH\n#define bH5     bH2 bH2 bH\n#define bH10    bH5 bH5\n#define bH20    bH10 bH10\n#define bH30    bH20 bH10\n#define SP5     \"     \"\n#define SP10    SP5 SP5\n#define SP20    SP10 SP10\n\n  /* Lord, forgive me this. */\n\n  SAYF(SET_G1 bSTG bLT bH bSTOP cCYA \" process timing \" bSTG bH30 bH5 bH2 bHB\n       bH bSTOP cCYA \" overall results \" bSTG bH5 bRT \"\\n\");\n\n  if (dumb_mode) {\n\n    strcpy(tmp, cNOR);\n\n  } else {\n\n    /* First queue cycle: don't stop now! */\n    if (queue_cycle == 1) strcpy(tmp, cMGN); else\n\n    /* Subsequent cycles, but we're still making finds. */\n    if (cycles_wo_finds < 3) strcpy(tmp, cYEL); else\n\n    /* No finds for a long time and no test cases to try. */\n    if (cycles_wo_finds > 20 && !pending_not_fuzzed) strcpy(tmp, cLGN);\n\n    /* Default: cautiously OK to stop? */\n    else strcpy(tmp, cLBL);\n\n  }\n\n  SAYF(bV bSTOP \"        run time : \" cNOR \"%-34s \" bSTG bV bSTOP\n       \"  cycles done : %s%-5s  \" bSTG bV \"\\n\",\n       DTD(cur_ms, start_time), tmp, DI(queue_cycle - 1));\n\n  /* We want to warn people about not seeing new paths after a full cycle,\n     except when resuming fuzzing or running in non-instrumented mode. */\n\n  if (!dumb_mode && (last_path_time || resuming_fuzz || queue_cycle == 1 ||\n      in_bitmap || crash_mode)) {\n\n    SAYF(bV bSTOP \"   last new path : \" cNOR \"%-34s \",\n         DTD(cur_ms, last_path_time));\n\n  } else {\n\n    if (dumb_mode)\n\n      SAYF(bV bSTOP \"   last new path : \" cPIN \"n/a\" cNOR \n           \" (non-instrumented mode)        \");\n\n     else\n\n      SAYF(bV bSTOP \"   last new path : \" cNOR \"none yet \" cLRD\n           \"(odd, check syntax!)      \");\n\n  }\n\n  SAYF(bSTG bV bSTOP \"  total paths : \" cNOR \"%-5s  \" bSTG bV \"\\n\",\n       DI(queued_paths));\n\n  /* Highlight crashes in red if found, denote going over the KEEP_UNIQUE_CRASH\n     limit with a '+' appended to the count. */\n\n  sprintf(tmp, \"%s%s\", DI(unique_crashes),\n          (unique_crashes >= KEEP_UNIQUE_CRASH) ? \"+\" : \"\");\n\n  SAYF(bV bSTOP \" last uniq crash : \" cNOR \"%-34s \" bSTG bV bSTOP\n       \" uniq crashes : %s%-6s \" bSTG bV \"\\n\",\n       DTD(cur_ms, last_crash_time), unique_crashes ? cLRD : cNOR,\n       tmp);\n\n  sprintf(tmp, \"%s%s\", DI(unique_hangs),\n         (unique_hangs >= KEEP_UNIQUE_HANG) ? \"+\" : \"\");\n\n  SAYF(bV bSTOP \"  last uniq hang : \" cNOR \"%-34s \" bSTG bV bSTOP \n       \"   uniq hangs : \" cNOR \"%-6s \" bSTG bV \"\\n\",\n       DTD(cur_ms, last_hang_time), tmp);\n\n  SAYF(bVR bH bSTOP cCYA \" cycle progress \" bSTG bH20 bHB bH bSTOP cCYA\n       \" map coverage \" bSTG bH bHT bH20 bH2 bH bVL \"\\n\");\n\n  /* This gets funny because we want to print several variable-length variables\n     together, but then cram them into a fixed-width field - so we need to\n     put them in a temporary buffer first. */\n\n  sprintf(tmp, \"%s%s (%0.02f%%)\", DI(current_entry),\n          queue_cur->favored ? \"\" : \"*\",\n          ((double)current_entry * 100) / queued_paths);\n\n  SAYF(bV bSTOP \"  now processing : \" cNOR \"%-17s \" bSTG bV bSTOP, tmp);\n\n\n  sprintf(tmp, \"%s (%0.02f%%)\", DI(t_bytes), t_byte_ratio);\n\n  SAYF(\"    map density : %s%-21s \" bSTG bV \"\\n\", t_byte_ratio > 70 ? cLRD : \n       ((t_bytes < 200 && !dumb_mode) ? cPIN : cNOR), tmp);\n\n  sprintf(tmp, \"%s (%0.02f%%)\", DI(cur_skipped_paths),\n          ((double)cur_skipped_paths * 100) / queued_paths);\n\n  SAYF(bV bSTOP \" paths timed out : \" cNOR \"%-17s \" bSTG bV, tmp);\n\n  sprintf(tmp, \"%0.02f bits/tuple\",\n          t_bytes ? (((double)t_bits) / t_bytes) : 0);\n\n  SAYF(bSTOP \" count coverage : \" cNOR \"%-21s \" bSTG bV \"\\n\", tmp);\n\n  SAYF(bVR bH bSTOP cCYA \" stage progress \" bSTG bH20 bX bH bSTOP cCYA\n       \" findings in depth \" bSTG bH20 bVL \"\\n\");\n\n  sprintf(tmp, \"%s (%0.02f%%)\", DI(queued_favored),\n          ((double)queued_favored) * 100 / queued_paths);\n\n  /* Yeah... it's still going on... halp? */\n\n  SAYF(bV bSTOP \"  now trying : \" cNOR \"%-21s \" bSTG bV bSTOP \n       \" favored paths : \" cNOR \"%-22s \" bSTG bV \"\\n\", stage_name, tmp);\n\n  if (!stage_max) {\n\n    sprintf(tmp, \"%s/-\", DI(stage_cur));\n\n  } else {\n\n    sprintf(tmp, \"%s/%s (%0.02f%%)\", DI(stage_cur), DI(stage_max),\n            ((double)stage_cur) * 100 / stage_max);\n\n  }\n\n  SAYF(bV bSTOP \" stage execs : \" cNOR \"%-21s \" bSTG bV bSTOP, tmp);\n\n  sprintf(tmp, \"%s (%0.02f%%)\", DI(queued_with_cov),\n          ((double)queued_with_cov) * 100 / queued_paths);\n\n  SAYF(\"  new edges on : \" cNOR \"%-22s \" bSTG bV \"\\n\", tmp);\n\n  sprintf(tmp, \"%s (%s%s unique)\", DI(total_crashes), DI(unique_crashes),\n          (unique_crashes >= KEEP_UNIQUE_CRASH) ? \"+\" : \"\");\n\n  if (crash_mode) {\n\n    SAYF(bV bSTOP \" total execs : \" cNOR \"%-21s \" bSTG bV bSTOP\n         \"   new crashes : %s%-22s \" bSTG bV \"\\n\", DI(total_execs),\n         unique_crashes ? cLRD : cNOR, tmp);\n\n  } else {\n\n    SAYF(bV bSTOP \" total execs : \" cNOR \"%-21s \" bSTG bV bSTOP\n         \" total crashes : %s%-22s \" bSTG bV \"\\n\", DI(total_execs),\n         unique_crashes ? cLRD : cNOR, tmp);\n\n  }\n\n  /* Show a warning about slow execution. */\n\n  if (avg_exec < 100) {\n\n    sprintf(tmp, \"%s/sec (%s)\", DF(avg_exec), avg_exec < 20 ?\n            \"zzzz...\" : \"slow!\");\n\n    SAYF(bV bSTOP \"  exec speed : \" cLRD \"%-21s \", tmp);\n\n  } else {\n\n    sprintf(tmp, \"%s/sec\", DF(avg_exec));\n    SAYF(bV bSTOP \"  exec speed : \" cNOR \"%-21s \", tmp);\n\n  }\n\n  sprintf(tmp, \"%s (%s%s unique)\", DI(total_hangs), DI(unique_hangs),\n          (unique_hangs >= KEEP_UNIQUE_HANG) ? \"+\" : \"\");\n\n  SAYF (bSTG bV bSTOP \"   total hangs : \" cNOR \"%-22s \" bSTG bV \"\\n\", tmp);\n\n  /* Aaaalmost there... hold on! */\n\n  SAYF(bVR bH cCYA bSTOP \" fuzzing strategy yields \" bSTG bH10 bH bHT bH10\n       bH5 bHB bH bSTOP cCYA \" path geometry \" bSTG bH5 bH2 bH bVL \"\\n\");\n\n  if (skip_deterministic) {\n\n    strcpy(tmp, \"n/a, n/a, n/a\");\n\n  } else {\n\n    sprintf(tmp, \"%s/%s, %s/%s, %s/%s\",\n            DI(stage_finds[STAGE_FLIP1]), DI(stage_cycles[STAGE_FLIP1]),\n            DI(stage_finds[STAGE_FLIP2]), DI(stage_cycles[STAGE_FLIP2]),\n            DI(stage_finds[STAGE_FLIP4]), DI(stage_cycles[STAGE_FLIP4]));\n\n  }\n\n  SAYF(bV bSTOP \"   bit flips : \" cNOR \"%-37s \" bSTG bV bSTOP \"    levels : \"\n       cNOR \"%-10s \" bSTG bV \"\\n\", tmp, DI(max_depth));\n\n  if (!skip_deterministic)\n    sprintf(tmp, \"%s/%s, %s/%s, %s/%s\",\n            DI(stage_finds[STAGE_FLIP8]), DI(stage_cycles[STAGE_FLIP8]),\n            DI(stage_finds[STAGE_FLIP16]), DI(stage_cycles[STAGE_FLIP16]),\n            DI(stage_finds[STAGE_FLIP32]), DI(stage_cycles[STAGE_FLIP32]));\n\n  SAYF(bV bSTOP \"  byte flips : \" cNOR \"%-37s \" bSTG bV bSTOP \"   pending : \"\n       cNOR \"%-10s \" bSTG bV \"\\n\", tmp, DI(pending_not_fuzzed));\n\n  if (!skip_deterministic)\n    sprintf(tmp, \"%s/%s, %s/%s, %s/%s\",\n            DI(stage_finds[STAGE_ARITH8]), DI(stage_cycles[STAGE_ARITH8]),\n            DI(stage_finds[STAGE_ARITH16]), DI(stage_cycles[STAGE_ARITH16]),\n            DI(stage_finds[STAGE_ARITH32]), DI(stage_cycles[STAGE_ARITH32]));\n\n  SAYF(bV bSTOP \" arithmetics : \" cNOR \"%-37s \" bSTG bV bSTOP \"  pend fav : \"\n       cNOR \"%-10s \" bSTG bV \"\\n\", tmp, DI(pending_favored));\n\n  if (!skip_deterministic)\n    sprintf(tmp, \"%s/%s, %s/%s, %s/%s\",\n            DI(stage_finds[STAGE_INTEREST8]), DI(stage_cycles[STAGE_INTEREST8]),\n            DI(stage_finds[STAGE_INTEREST16]), DI(stage_cycles[STAGE_INTEREST16]),\n            DI(stage_finds[STAGE_INTEREST32]), DI(stage_cycles[STAGE_INTEREST32]));\n\n  SAYF(bV bSTOP \"  known ints : \" cNOR \"%-37s \" bSTG bV bSTOP \" own finds : \"\n       cNOR \"%-10s \" bSTG bV \"\\n\", tmp, DI(queued_discovered));\n\n  if (!skip_deterministic)\n    sprintf(tmp, \"%s/%s, %s/%s, %s/%s\",\n            DI(stage_finds[STAGE_EXTRAS_UO]), DI(stage_cycles[STAGE_EXTRAS_UO]),\n            DI(stage_finds[STAGE_EXTRAS_UI]), DI(stage_cycles[STAGE_EXTRAS_UI]),\n            DI(stage_finds[STAGE_EXTRAS_AO]), DI(stage_cycles[STAGE_EXTRAS_AO]));\n\n  SAYF(bV bSTOP \"  dictionary : \" cNOR \"%-37s \" bSTG bV bSTOP\n       \"  imported : \" cNOR \"%-10s \" bSTG bV \"\\n\", tmp,\n       sync_id ? DI(queued_imported) : (u8*)\"n/a\");\n\n  sprintf(tmp, \"%s/%s, %s/%s\",\n          DI(stage_finds[STAGE_HAVOC]), DI(stage_cycles[STAGE_HAVOC]),\n          DI(stage_finds[STAGE_SPLICE]), DI(stage_cycles[STAGE_SPLICE]));\n\n  SAYF(bV bSTOP \"       havoc : \" cNOR \"%-37s \" bSTG bV bSTOP \n       \"  variable : %s%-10s \" bSTG bV \"\\n\", tmp, queued_variable ? cLRD : cNOR,\n      no_var_check ? (u8*)\"n/a\" : DI(queued_variable));\n\n  if (!bytes_trim_out) {\n\n    sprintf(tmp, \"n/a, \");\n\n  } else {\n\n    sprintf(tmp, \"%0.02f%%/%s, \",\n            ((double)(bytes_trim_in - bytes_trim_out)) * 100 / bytes_trim_in,\n            DI(trim_execs));\n\n  }\n\n  if (!blocks_eff_total) {\n\n    u8 tmp2[128];\n\n    sprintf(tmp2, \"n/a\");\n    strcat(tmp, tmp2);\n\n  } else {\n\n    u8 tmp2[128];\n\n    sprintf(tmp2, \"%0.02f%%\",\n            ((double)(blocks_eff_total - blocks_eff_select)) * 100 /\n            blocks_eff_total);\n\n    strcat(tmp, tmp2);\n\n  }\n\n  SAYF(bV bSTOP \"        trim : \" cNOR \"%-37s \" bSTG bVR bH20 bH2 bH2 bRB \"\\n\"\n       bLB bH30 bH20 bH2 bH bRB bSTOP cRST RESET_G1, tmp);\n\n  /* Provide some CPU utilization stats. */\n\n  if (cpu_core_count) {\n\n    double cur_runnable = get_runnable_processes();\n    u32 cur_utilization = cur_runnable * 100 / cpu_core_count;\n\n    u8* cpu_color = cCYA;\n\n    /* If we could still run one or more processes, use green. */\n\n    if (cpu_core_count > 1 && cur_runnable + 1 <= cpu_core_count)\n      cpu_color = cLGN;\n\n    /* If we're clearly oversubscribed, use red. */\n\n    if (!no_cpu_meter_red && cur_utilization >= 150) cpu_color = cLRD;\n\n    SAYF(SP10 cGRA \"   [cpu:%s%3u%%\" cGRA \"]\\r\" cRST,\n         cpu_color, cur_utilization < 999 ? cur_utilization : 999);\n\n  } else SAYF(\"\\r\");\n\n  /* Hallelujah! */\n\n  fflush(0);\n\n}\n\n\n/* Display quick statistics at the end of processing the input directory,\n   plus a bunch of warnings. Some calibration stuff also ended up here,\n   along with several hardcoded constants. Maybe clean up eventually. */\n\nstatic void show_init_stats(void) {\n\n  struct queue_entry* q = queue;\n  u32 min_bits = 0, max_bits = 0;\n  u64 min_us = 0, max_us = 0;\n  u64 avg_us = 0;\n  u32 max_len = 0;\n\n  if (total_cal_cycles) avg_us = total_cal_us / total_cal_cycles;\n\n  while (q) {\n\n    if (!min_us || q->exec_us < min_us) min_us = q->exec_us;\n    if (q->exec_us > max_us) max_us = q->exec_us;\n\n    if (!min_bits || q->bitmap_size < min_bits) min_bits = q->bitmap_size;\n    if (q->bitmap_size > max_bits) max_bits = q->bitmap_size;\n\n    if (q->len > max_len) max_len = q->len;\n\n    q = q->next;\n\n  }\n\n  SAYF(\"\\n\");\n\n  if (avg_us > (qemu_mode ? 50000 : 10000)) \n    WARNF(cLRD \"The target binary is pretty slow! See %s/perf_tips.txt.\",\n          doc_path);\n\n  /* Let's keep things moving with slow binaries. */\n\n  if (avg_us > 50000) havoc_div = 10;     /* 0-19 execs/sec   */\n  else if (avg_us > 20000) havoc_div = 5; /* 20-49 execs/sec  */\n  else if (avg_us > 10000) havoc_div = 2; /* 50-100 execs/sec */\n\n  if (!resuming_fuzz) {\n\n    if (max_len > 50 * 1024)\n      WARNF(cLRD \"Some test cases are huge (%s) - see %s/perf_tips.txt!\",\n            DMS(max_len), doc_path);\n    else if (max_len > 10 * 1024)\n      WARNF(\"Some test cases are big (%s) - see %s/perf_tips.txt.\",\n            DMS(max_len), doc_path);\n\n    if (useless_at_start && !in_bitmap)\n      WARNF(cLRD \"Some test cases look useless. Consider using a smaller set.\");\n\n    if (queued_paths > 100)\n      WARNF(cLRD \"You probably have far too many input files! Consider trimming down.\");\n    else if (queued_paths > 20)\n      WARNF(\"You have lots of input files; try starting small.\");\n\n  }\n\n  OKF(\"Here are some useful stats:\\n\\n\"\n\n      cGRA \"    Test case count : \" cNOR \"%u favored, %u variable, %u total\\n\"\n      cGRA \"       Bitmap range : \" cNOR \"%u to %u bits (average: %0.02f bits)\\n\"\n      cGRA \"        Exec timing : \" cNOR \"%s to %s us (average: %s us)\\n\",\n      queued_favored, queued_variable, queued_paths, min_bits, max_bits, \n      ((double)total_bitmap_size) / (total_bitmap_entries ? total_bitmap_entries : 1),\n      DI(min_us), DI(max_us), DI(avg_us));\n\n  if (!timeout_given) {\n\n    /* Figure out the appropriate timeout. The basic idea is: 5x average or\n       1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second.\n\n       If the program is slow, the multiplier is lowered to 2x or 3x, because\n       random scheduler jitter is less likely to have any impact, and because\n       our patience is wearing thin =) */\n\n    if (avg_us > 50000) exec_tmout = avg_us * 2 / 1000;\n    else if (avg_us > 10000) exec_tmout = avg_us * 3 / 1000;\n    else exec_tmout = avg_us * 5 / 1000;\n\n    exec_tmout = MAX(exec_tmout, max_us / 1000);\n    exec_tmout = (exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;\n\n    if (exec_tmout > EXEC_TIMEOUT) exec_tmout = EXEC_TIMEOUT;\n\n    ACTF(\"No -t option specified, so I'll use exec timeout of %u ms.\", \n         exec_tmout);\n\n    timeout_given = 1;\n\n  } else if (timeout_given == 3) {\n\n    ACTF(\"Applying timeout settings from resumed session (%u ms).\", exec_tmout);\n\n  }\n\n  OKF(\"All set and ready to roll!\");\n\n}\n\n\n/* Find first power of two greater or equal to val. */\n\nstatic u32 next_p2(u32 val) {\n\n  u32 ret = 1;\n  while (val > ret) ret <<= 1;\n  return ret;\n\n} \n\n\n/* Trim all new test cases to save cycles when doing deterministic checks. The\n   trimmer uses power-of-two increments somewhere between 1/16 and 1/1024 of\n   file size, to keep the stage short and sweet. */\n\nstatic u8 trim_case(char** argv, struct queue_entry* q, u8* in_buf) {\n\n  static u8 tmp[64];\n  static u8 clean_trace[MAP_SIZE];\n\n  u8  needs_write = 0, fault = 0;\n  u32 trim_exec = 0;\n  u32 remove_len;\n  u32 len_p2;\n\n  /* Although the trimmer will be less useful when variable behavior is\n     detected, it will still work to some extent, so we don't check for\n     this. */\n\n  if (q->len < 5) return 0;\n\n  stage_name = tmp;\n  bytes_trim_in += q->len;\n\n  /* Select initial chunk len, starting with large steps. */\n\n  len_p2 = next_p2(q->len);\n\n  remove_len = MAX(len_p2 / TRIM_START_STEPS, TRIM_MIN_BYTES);\n\n  /* Continue until the number of steps gets too high or the stepover\n     gets too small. */\n\n  while (remove_len >= MAX(len_p2 / TRIM_END_STEPS, TRIM_MIN_BYTES)) {\n\n    u32 remove_pos = remove_len;\n\n    sprintf(tmp, \"trim %s/%s\", DI(remove_len), DI(remove_len));\n\n    stage_cur = 0;\n    stage_max = q->len / remove_len;\n\n    while (remove_pos < q->len) {\n\n      u32 trim_avail = MIN(remove_len, q->len - remove_pos);\n      u32 cksum;\n\n      write_with_gap(in_buf, q->len, remove_pos, trim_avail);\n\n      fault = run_target(argv);\n      trim_execs++;\n\n      if (stop_soon || fault == FAULT_ERROR) goto abort_trimming;\n\n      /* Note that we don't keep track of crashes or hangs here; maybe TODO? */\n\n      cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n      /* If the deletion had no impact on the trace, make it permanent. This\n         isn't perfect for variable-path inputs, but we're just making a\n         best-effort pass, so it's not a big deal if we end up with false\n         negatives every now and then. */\n\n      if (cksum == q->exec_cksum) {\n\n        u32 move_tail = q->len - remove_pos - trim_avail;\n\n        q->len -= trim_avail;\n        len_p2  = next_p2(q->len);\n\n        memmove(in_buf + remove_pos, in_buf + remove_pos + trim_avail, \n                move_tail);\n\n        /* Let's save a clean trace, which will be needed by\n           update_bitmap_score once we're done with the trimming stuff. */\n\n        if (!needs_write) {\n\n          needs_write = 1;\n          memcpy(clean_trace, trace_bits, MAP_SIZE);\n\n        }\n\n      } else remove_pos += remove_len;\n\n      /* Since this can be slow, update the screen every now and then. */\n\n      if (!(trim_exec++ % stats_update_freq)) show_stats();\n      stage_cur++;\n\n    }\n\n    remove_len >>= 1;\n\n  }\n\n  /* If we have made changes to in_buf, we also need to update the on-disk\n     version of the test case. */\n\n  if (needs_write) {\n\n    s32 fd;\n\n    unlink(q->fname); /* ignore errors */\n\n    fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);\n\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", q->fname);\n\n    ck_write(fd, in_buf, q->len, q->fname);\n    close(fd);\n\n    memcpy(trace_bits, clean_trace, MAP_SIZE);\n    update_bitmap_score(q);\n\n  }\n\n\n\nabort_trimming:\n\n  bytes_trim_out += q->len;\n  return fault;\n\n}\n\n\n/* Write a modified test case, run program, process results. Handle\n   error conditions, returning 1 if it's time to bail out. This is\n   a helper function for fuzz_one(). */\n\nstatic u8 common_fuzz_stuff(char** argv, u8* out_buf, u32 len) {\n\n  u8 fault;\n\n  if (post_handler) {\n\n    out_buf = post_handler(out_buf, &len);\n    if (!out_buf || !len) return 0;\n\n  }\n\n  write_to_testcase(out_buf, len);\n\n  fault = run_target(argv);\n\n  if (stop_soon) return 1;\n\n  if (fault == FAULT_HANG) {\n\n    if (subseq_hangs++ > HANG_LIMIT) {\n      cur_skipped_paths++;\n      return 1;\n    }\n\n  } else subseq_hangs = 0;\n\n  /* Users can hit us with SIGUSR1 to request the current input\n     to be abandoned. */\n\n  if (skip_requested) {\n\n     skip_requested = 0;\n     cur_skipped_paths++;\n     return 1;\n\n  }\n\n  /* This handles FAULT_ERROR for us: */\n\n  queued_discovered += save_if_interesting(argv, out_buf, len, fault);\n\n  if (!(stage_cur % stats_update_freq) || stage_cur + 1 == stage_max)\n    show_stats();\n\n  return 0;\n\n}\n\n\n/* Helper to choose random block len for block operations in fuzz_one().\n   Doesn't return zero, provided that max_len is > 0. */\n\nstatic u32 choose_block_len(u32 limit) {\n\n  u32 min_value, max_value;\n  u32 rlim = MIN(queue_cycle, 3);\n\n  if (!run_over10m) rlim = 1;\n\n  switch (UR(rlim)) {\n\n    case 0:  min_value = 1;\n             max_value = HAVOC_BLK_SMALL;\n             break;\n\n    case 1:  min_value = HAVOC_BLK_SMALL;\n             max_value = HAVOC_BLK_MEDIUM;\n             break;\n\n    default: min_value = HAVOC_BLK_MEDIUM;\n             max_value = HAVOC_BLK_LARGE;\n\n\n  }\n\n  if (min_value >= limit) min_value = 1;\n\n  return min_value + UR(MIN(max_value, limit) - min_value + 1);\n\n}\n\n\n/* Calculate case desirability score to adjust the length of havoc fuzzing.\n   A helper function for fuzz_one(). Maybe some of these constants should\n   go into config.h. */\n\nstatic u32 calculate_score(struct queue_entry* q) {\n\n  u32 avg_exec_us = total_cal_us / total_cal_cycles;\n  u32 avg_bitmap_size = total_bitmap_size / total_bitmap_entries;\n  u32 perf_score = 100;\n\n  /* Adjust score based on execution speed of this path, compared to the\n     global average. Multiplier ranges from 0.1x to 3x. Fast inputs are\n     less expensive to fuzz, so we're giving them more air time. */\n\n  if (q->exec_us * 0.1 > avg_exec_us) perf_score = 10;\n  else if (q->exec_us * 0.25 > avg_exec_us) perf_score = 25;\n  else if (q->exec_us * 0.5 > avg_exec_us) perf_score = 50;\n  else if (q->exec_us * 0.75 > avg_exec_us) perf_score = 75;\n  else if (q->exec_us * 4 < avg_exec_us) perf_score = 300;\n  else if (q->exec_us * 3 < avg_exec_us) perf_score = 200;\n  else if (q->exec_us * 2 < avg_exec_us) perf_score = 150;\n\n  /* Adjust score based on bitmap size. The working theory is that better\n     coverage translates to better targets. Multiplier from 0.25x to 3x. */\n\n  if (q->bitmap_size * 0.3 > avg_bitmap_size) perf_score *= 3;\n  else if (q->bitmap_size * 0.5 > avg_bitmap_size) perf_score *= 2;\n  else if (q->bitmap_size * 0.75 > avg_bitmap_size) perf_score *= 1.5;\n  else if (q->bitmap_size * 3 < avg_bitmap_size) perf_score *= 0.25;\n  else if (q->bitmap_size * 2 < avg_bitmap_size) perf_score *= 0.5;\n  else if (q->bitmap_size * 1.5 < avg_bitmap_size) perf_score *= 0.75;\n\n  /* Adjust score based on handicap. Handicap is proportional to how late\n     in the game we learned about this path. Latecomers are allowed to run\n     for a bit longer until they catch up with the rest. */\n\n  if (q->handicap >= 4) {\n\n    perf_score *= 4;\n    q->handicap -= 4;\n\n  } else if (q->handicap) {\n\n    perf_score *= 2;\n    q->handicap--;\n\n  }\n\n  /* Final adjustment based on input depth, under the assumption that fuzzing\n     deeper test cases is more likely to reveal stuff that can't be\n     discovered with traditional fuzzers. */\n\n  switch (q->depth) {\n\n    case 0 ... 3:   break;\n    case 4 ... 7:   perf_score *= 2; break;\n    case 8 ... 13:  perf_score *= 4; break;\n    case 14 ... 25: perf_score *= 6; break;\n    default:        perf_score *= 8;\n\n  }\n\n  /* Make sure that we don't go over limit. */\n\n  if (perf_score > HAVOC_MAX_MULT * 100) perf_score = HAVOC_MAX_MULT * 100;\n\n  return perf_score;\n\n}\n\n\n/* Helper function to see if a particular change (xor_val = old ^ new) could\n   be a product of deterministic bit flips with the lengths and stepovers\n   attempted by afl-fuzz. This is used to avoid dupes in some of the\n   deterministic fuzzing operations that follow bit flips. We also\n   return 1 if xor_val is zero, which implies that the old and attempted new\n   values are identical and the exec would be a waste of time. */\n\nstatic u8 could_be_bitflip(u32 xor_val) {\n\n  u32 sh = 0;\n\n  if (!xor_val) return 1;\n\n  /* Shift left until first bit set. */\n\n  while (!(xor_val & 1)) { sh++; xor_val >>= 1; }\n\n  /* 1-, 2-, and 4-bit patterns are OK anywhere. */\n\n  if (xor_val == 1 || xor_val == 3 || xor_val == 15) return 1;\n\n  /* 8-, 16-, and 32-bit patterns are OK only if shift factor is\n     divisible by 8, since that's the stepover for these ops. */\n\n  if (sh & 7) return 0;\n\n  if (xor_val == 0xff || xor_val == 0xffff || xor_val == 0xffffffff)\n    return 1;\n\n  return 0;\n\n}\n\n\n/* Helper function to see if a particular value is reachable through\n   arithmetic operations. Used for similar purposes. */\n\nstatic u8 could_be_arith(u32 old_val, u32 new_val, u8 blen) {\n\n  u32 i, ov = 0, nv = 0, diffs = 0;\n\n  if (old_val == new_val) return 1;\n\n  /* See if one-byte adjustments to any byte could produce this result. */\n\n  for (i = 0; i < blen; i++) {\n\n    u8 a = old_val >> (8 * i),\n       b = new_val >> (8 * i);\n\n    if (a != b) { diffs++; ov = a; nv = b; }\n\n  }\n\n  /* If only one byte differs and the values are within range, return 1. */\n\n  if (diffs == 1) {\n\n    if ((u8)(ov - nv) <= ARITH_MAX ||\n        (u8)(nv - ov) <= ARITH_MAX) return 1;\n\n  }\n\n  if (blen == 1) return 0;\n\n  /* See if two-byte adjustments to any byte would produce this result. */\n\n  diffs = 0;\n\n  for (i = 0; i < blen / 2; i++) {\n\n    u16 a = old_val >> (16 * i),\n        b = new_val >> (16 * i);\n\n    if (a != b) { diffs++; ov = a; nv = b; }\n\n  }\n\n  /* If only one word differs and the values are within range, return 1. */\n\n  if (diffs == 1) {\n\n    if ((u16)(ov - nv) <= ARITH_MAX ||\n        (u16)(nv - ov) <= ARITH_MAX) return 1;\n\n    ov = SWAP16(ov); nv = SWAP16(nv);\n\n    if ((u16)(ov - nv) <= ARITH_MAX ||\n        (u16)(nv - ov) <= ARITH_MAX) return 1;\n\n  }\n\n  /* Finally, let's do the same thing for dwords. */\n\n  if (blen == 4) {\n\n    if ((u32)(old_val - new_val) <= ARITH_MAX ||\n        (u32)(new_val - old_val) <= ARITH_MAX) return 1;\n\n    new_val = SWAP32(new_val);\n    old_val = SWAP32(old_val);\n\n    if ((u32)(old_val - new_val) <= ARITH_MAX ||\n        (u32)(new_val - old_val) <= ARITH_MAX) return 1;\n\n  }\n\n  return 0;\n\n}\n\n\n/* Last but not least, a similar helper to see if insertion of an \n   interesting integer is redundant given the insertions done for\n   shorter blen. The last param (check_le) is set if the caller\n   already executed LE insertion for current blen and wants to see\n   if BE variant passed in new_val is unique. */\n\nstatic u8 could_be_interest(u32 old_val, u32 new_val, u8 blen, u8 check_le) {\n\n  u32 i, j;\n\n  if (old_val == new_val) return 1;\n\n  /* See if one-byte insertions from interesting_8 over old_val could\n     produce new_val. */\n\n  for (i = 0; i < blen; i++) {\n\n    for (j = 0; j < sizeof(interesting_8); j++) {\n\n      u32 tval = (old_val & ~(0xff << (i * 8))) |\n                 (((u8)interesting_8[j]) << (i * 8));\n\n      if (new_val == tval) return 1;\n\n    }\n\n  }\n\n  /* Bail out unless we're also asked to examine two-byte LE insertions\n     as a preparation for BE attempts. */\n\n  if (blen == 2 && !check_le) return 0;\n\n  /* See if two-byte insertions over old_val could give us new_val. */\n\n  for (i = 0; i < blen - 1; i++) {\n\n    for (j = 0; j < sizeof(interesting_16) / 2; j++) {\n\n      u32 tval = (old_val & ~(0xffff << (i * 8))) |\n                 (((u16)interesting_16[j]) << (i * 8));\n\n      if (new_val == tval) return 1;\n\n      /* Continue here only if blen > 2. */\n\n      if (blen > 2) {\n\n        tval = (old_val & ~(0xffff << (i * 8))) |\n               (SWAP16(interesting_16[j]) << (i * 8));\n\n        if (new_val == tval) return 1;\n\n      }\n\n    }\n\n  }\n\n  if (blen == 4 && check_le) {\n\n    /* See if four-byte insertions could produce the same result\n       (LE only). */\n\n    for (j = 0; j < sizeof(interesting_32) / 4; j++)\n      if (new_val == (u32)interesting_32[j]) return 1;\n\n  }\n\n  return 0;\n\n}\n\n\n/* Take the current entry from the queue, fuzz it for a while. This\n   function is a tad too long... returns 0 if fuzzed successfully, 1 if\n   skipped or bailed out. */\n\nstatic u8 fuzz_one(char** argv) {\n\n  s32 len, fd, temp_len, i, j;\n  u8  *in_buf, *out_buf, *orig_in, *ex_tmp, *eff_map = 0;\n  u64 havoc_queued,  orig_hit_cnt, new_hit_cnt;\n  u32 splice_cycle = 0, perf_score = 100, orig_perf, prev_cksum, eff_cnt = 1;\n\n  u8  ret_val = 1;\n\n  u8  a_collect[MAX_AUTO_EXTRA];\n  u32 a_len = 0;\n\n#ifdef IGNORE_FINDS\n\n  /* In IGNORE_FINDS mode, skip any entries that weren't in the\n     initial data set. */\n\n  if (queue_cur->depth > 1) return 1;\n\n#else\n\n  if (pending_favored) {\n\n    /* If we have any favored, non-fuzzed new arrivals in the queue,\n       possibly skip to them at the expense of already-fuzzed or non-favored\n       cases. */\n\n    if ((queue_cur->was_fuzzed || !queue_cur->favored) &&\n        UR(100) < SKIP_TO_NEW_PROB) return 1;\n\n  } else if (!dumb_mode && !queue_cur->favored && queued_paths > 10) {\n\n    /* Otherwise, still possibly skip non-favored cases, albeit less often.\n       The odds of skipping stuff are higher for already-fuzzed inputs and\n       lower for never-fuzzed entries. */\n\n    if (queue_cycle > 1 && !queue_cur->was_fuzzed) {\n\n      if (UR(100) < SKIP_NFAV_NEW_PROB) return 1;\n\n    } else {\n\n      if (UR(100) < SKIP_NFAV_OLD_PROB) return 1;\n\n    }\n\n  }\n\n#endif /* ^IGNORE_FINDS */\n\n  if (not_on_tty)\n    ACTF(\"Fuzzing test case #%u (%u total)...\", current_entry, queued_paths);\n\n  /* Map the test case into memory. */\n\n  fd = open(queue_cur->fname, O_RDONLY);\n\n  if (fd < 0) PFATAL(\"Unable to open '%s'\", queue_cur->fname);\n\n  len = queue_cur->len;\n\n  orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);\n\n  if (orig_in == MAP_FAILED) PFATAL(\"Unable to mmap '%s'\", queue_cur->fname);\n\n  close(fd);\n\n  /* We could mmap() out_buf as MAP_PRIVATE, but we end up clobbering every\n     single byte anyway, so it wouldn't give us any performance or memory usage\n     benefits. */\n\n  out_buf = ck_alloc_nozero(len);\n\n  subseq_hangs = 0;\n\n  cur_depth = queue_cur->depth;\n\n  /*******************************************\n   * CALIBRATION (only if failed earlier on) *\n   *******************************************/\n\n  if (queue_cur->cal_failed) {\n\n    u8 res = FAULT_HANG;\n\n    if (queue_cur->cal_failed < CAL_CHANCES) {\n\n      res = calibrate_case(argv, queue_cur, in_buf, queue_cycle - 1, 0);\n\n      if (res == FAULT_ERROR)\n        FATAL(\"Unable to execute target application\");\n\n    }\n\n    if (stop_soon || res != crash_mode) {\n      cur_skipped_paths++;\n      goto abandon_entry;\n    }\n\n  }\n\n  /************\n   * TRIMMING *\n   ************/\n\n  if (!dumb_mode && !queue_cur->trim_done) {\n\n    u8 res = trim_case(argv, queue_cur, in_buf);\n\n    if (res == FAULT_ERROR)\n      FATAL(\"Unable to execute target application\");\n\n    if (stop_soon) {\n      cur_skipped_paths++;\n      goto abandon_entry;\n    }\n\n    /* Don't retry trimming, even if it failed. */\n\n    queue_cur->trim_done = 1;\n\n    if (len != queue_cur->len) len = queue_cur->len;\n\n  }\n\n  memcpy(out_buf, in_buf, len);\n\n  /*********************\n   * PERFORMANCE SCORE *\n   *********************/\n\n  orig_perf = perf_score = calculate_score(queue_cur);\n\n  /* Skip right away if -d is given, if we have done deterministic fuzzing on\n     this entry ourselves (was_fuzzed), or if it has gone through deterministic\n     testing in earlier, resumed runs (passed_det). */\n\n  if (skip_deterministic || queue_cur->was_fuzzed || queue_cur->passed_det)\n    goto havoc_stage;\n\n  /*********************************************\n   * SIMPLE BITFLIP (+dictionary construction) *\n   *********************************************/\n\n#define FLIP_BIT(_ar, _b) do { \\\n    u8* _arf = (u8*)(_ar); \\\n    u32 _bf = (_b); \\\n    _arf[(_bf) >> 3] ^= (128 >> ((_bf) & 7)); \\\n  } while (0)\n\n  /* Single walking bit. */\n\n  stage_short = \"flip1\";\n  stage_max   = len << 3;\n  stage_name  = \"bitflip 1/1\";\n\n  stage_val_type = STAGE_VAL_NONE;\n\n  orig_hit_cnt = queued_paths + unique_crashes;\n\n  prev_cksum = queue_cur->exec_cksum;\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    stage_cur_byte = stage_cur >> 3;\n\n    FLIP_BIT(out_buf, stage_cur);\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n    FLIP_BIT(out_buf, stage_cur);\n\n    /* While flipping the least significant bit in every byte, pull of an extra\n       trick to detect possible syntax tokens. In essence, the idea is that if\n       you have a binary blob like this:\n\n       xxxxxxxxIHDRxxxxxxxx\n\n       ...and changing the leading and trailing bytes causes variable or no\n       changes in program flow, but touching any character in the \"IHDR\" string\n       always produces the same, distinctive path, it's highly likely that\n       \"IHDR\" is an atomically-checked magic value of special significance to\n       the fuzzed format.\n\n       We do this here, rather than as a separate stage, because it's a nice\n       way to keep the operation approximately \"free\" (i.e., no extra execs).\n       \n       Empirically, performing the check when flipping the least significant bit\n       is advantageous, compared to doing it at the time of more disruptive\n       changes, where the program flow may be affected in more violent ways.\n\n       The caveat is that we won't generate dictionaries in the -d mode or -S\n       mode - but that's probably a fair trade-off.\n\n       This won't work particularly well with paths that exhibit variable\n       behavior, but fails gracefully, so we'll carry out the checks anyway.\n\n      */\n\n    if (!dumb_mode && (stage_cur & 7) == 7) {\n\n      u32 cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n      if (stage_cur == stage_max - 1 && cksum == prev_cksum) {\n\n        /* If at end of file and we are still collecting a string, grab the\n           final character and force output. */\n\n        if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[stage_cur >> 3];\n        a_len++;\n\n        if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)\n          maybe_add_auto(a_collect, a_len);\n\n      } else if (cksum != prev_cksum) {\n\n        /* Otherwise, if the checksum has changed, see if we have something\n           worthwhile queued up, and collect that if the answer is yes. */\n\n        if (a_len >= MIN_AUTO_EXTRA && a_len <= MAX_AUTO_EXTRA)\n          maybe_add_auto(a_collect, a_len);\n\n        a_len = 0;\n        prev_cksum = cksum;\n\n      }\n\n      /* Continue collecting string, but only if the bit flip actually made\n         any difference - we don't want no-op tokens. */\n\n      if (cksum != queue_cur->exec_cksum) {\n\n        if (a_len < MAX_AUTO_EXTRA) a_collect[a_len] = out_buf[stage_cur >> 3];        \n        a_len++;\n\n      }\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP1]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP1] += stage_max;\n\n  if (queue_cur->passed_det) goto havoc_stage;\n\n  /* Two walking bits. */\n\n  stage_name  = \"bitflip 2/1\";\n  stage_short = \"flip2\";\n  stage_max   = (len << 3) - 1;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    stage_cur_byte = stage_cur >> 3;\n\n    FLIP_BIT(out_buf, stage_cur);\n    FLIP_BIT(out_buf, stage_cur + 1);\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n    FLIP_BIT(out_buf, stage_cur);\n    FLIP_BIT(out_buf, stage_cur + 1);\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP2]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP2] += stage_max;\n\n  /* Four walking bits. */\n\n  stage_name  = \"bitflip 4/1\";\n  stage_short = \"flip4\";\n  stage_max   = (len << 3) - 3;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    stage_cur_byte = stage_cur >> 3;\n\n    FLIP_BIT(out_buf, stage_cur);\n    FLIP_BIT(out_buf, stage_cur + 1);\n    FLIP_BIT(out_buf, stage_cur + 2);\n    FLIP_BIT(out_buf, stage_cur + 3);\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n    FLIP_BIT(out_buf, stage_cur);\n    FLIP_BIT(out_buf, stage_cur + 1);\n    FLIP_BIT(out_buf, stage_cur + 2);\n    FLIP_BIT(out_buf, stage_cur + 3);\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP4]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP4] += stage_max;\n\n  /* Effector map setup. These macros calculate:\n\n     EFF_APOS      - position of a particular file offset in the map.\n     EFF_ALEN      - length of an map with a particular number of bytes.\n     EFF_SPAN_ALEN - map span for a sequence of bytes.\n\n   */\n\n#define EFF_APOS(_p)          ((_p) >> EFF_MAP_SCALE2)\n#define EFF_REM(_x)           ((_x) & ((1 << EFF_MAP_SCALE2) - 1))\n#define EFF_ALEN(_l)          (EFF_APOS(_l) + !!EFF_REM(_l))\n#define EFF_SPAN_ALEN(_p, _l) (EFF_APOS((_p) + (_l) - 1) - EFF_APOS(_p) + 1)\n\n  /* Initialize effector map for the next step (see comments below). Always\n     flag first and last byte as doing something. */\n\n  eff_map    = ck_alloc(EFF_ALEN(len));\n  eff_map[0] = 1;\n\n  if (EFF_APOS(len - 1) != 0) {\n    eff_map[EFF_APOS(len - 1)] = 1;\n    eff_cnt++;\n  }\n\n  /* Walking byte. */\n\n  stage_name  = \"bitflip 8/8\";\n  stage_short = \"flip8\";\n  stage_max   = len;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    stage_cur_byte = stage_cur;\n\n    out_buf[stage_cur] ^= 0xFF;\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n    /* We also use this stage to pull off a simple trick: we identify\n       bytes that seem to have no effect on the current execution path\n       even when fully flipped - and we skip them during more expensive\n       deterministic stages, such as arithmetics or known ints. */\n\n    if (!eff_map[EFF_APOS(stage_cur)]) {\n\n      u32 cksum;\n\n      /* If in dumb mode or if the file is very short, just flag everything\n         without wasting time on checksums. */\n\n      if (!dumb_mode && len >= EFF_MIN_LEN)\n        cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n      else\n        cksum = ~queue_cur->exec_cksum;\n\n      if (cksum != queue_cur->exec_cksum) {\n        eff_map[EFF_APOS(stage_cur)] = 1;\n        eff_cnt++;\n      }\n\n    }\n\n    out_buf[stage_cur] ^= 0xFF;\n\n  }\n\n  /* If the effector map is more than EFF_MAX_PERC dense, just flag the\n     whole thing as worth fuzzing, since we wouldn't be saving much time\n     anyway. */\n\n  if (eff_cnt != EFF_ALEN(len) &&\n      eff_cnt * 100 / EFF_ALEN(len) > EFF_MAX_PERC) {\n\n    memset(eff_map, 1, EFF_ALEN(len));\n\n    blocks_eff_select += EFF_ALEN(len);\n\n  } else {\n\n    blocks_eff_select += eff_cnt;\n\n  }\n\n  blocks_eff_total += EFF_ALEN(len);\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP8]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP8] += stage_max;\n\n  /* Two walking bytes. */\n\n  if (len < 2) goto skip_bitflip;\n\n  stage_name  = \"bitflip 16/8\";\n  stage_short = \"flip16\";\n  stage_cur   = 0;\n  stage_max   = len - 1;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 1; i++) {\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {\n      stage_max--;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    *(u16*)(out_buf + i) ^= 0xFFFF;\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n    stage_cur++;\n\n    *(u16*)(out_buf + i) ^= 0xFFFF;\n\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP16]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP16] += stage_max;\n\n  if (len < 4) goto skip_bitflip;\n\n  /* Four walking bytes. */\n\n  stage_name  = \"bitflip 32/8\";\n  stage_short = \"flip32\";\n  stage_cur   = 0;\n  stage_max   = len - 3;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 3; i++) {\n\n    /* Let's consult the effector map... */\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&\n        !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {\n      stage_max--;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    *(u32*)(out_buf + i) ^= 0xFFFFFFFF;\n\n    if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n    stage_cur++;\n\n    *(u32*)(out_buf + i) ^= 0xFFFFFFFF;\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_FLIP32]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_FLIP32] += stage_max;\n\nskip_bitflip:\n\n  /**********************\n   * ARITHMETIC INC/DEC *\n   **********************/\n\n  /* 8-bit arithmetics. */\n\n  stage_name  = \"arith 8/8\";\n  stage_short = \"arith8\";\n  stage_cur   = 0;\n  stage_max   = 2 * len * ARITH_MAX;\n\n  stage_val_type = STAGE_VAL_LE;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len; i++) {\n\n    u8 orig = out_buf[i];\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)]) {\n      stage_max -= 2 * ARITH_MAX;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 1; j <= ARITH_MAX; j++) {\n\n      u8 r = orig ^ (orig + j);\n\n      /* Do arithmetic operations only if the result couldn't be a product\n         of a bitflip. */\n\n      if (!could_be_bitflip(r)) {\n\n        stage_cur_val = j;\n        out_buf[i] = orig + j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      r =  orig ^ (orig - j);\n\n      if (!could_be_bitflip(r)) {\n\n        stage_cur_val = -j;\n        out_buf[i] = orig - j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      out_buf[i] = orig;\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_ARITH8]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_ARITH8] += stage_max;\n\n  /* 16-bit arithmetics, both endians. */\n\n  if (len < 2) goto skip_arith;\n\n  stage_name  = \"arith 16/8\";\n  stage_short = \"arith16\";\n  stage_cur   = 0;\n  stage_max   = 4 * (len - 1) * ARITH_MAX;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 1; i++) {\n\n    u16 orig = *(u16*)(out_buf + i);\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {\n      stage_max -= 4 * ARITH_MAX;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 1; j <= ARITH_MAX; j++) {\n\n      u16 r1 = orig ^ (orig + j),\n          r2 = orig ^ (orig - j),\n          r3 = orig ^ SWAP16(SWAP16(orig) + j),\n          r4 = orig ^ SWAP16(SWAP16(orig) - j);\n\n      /* Try little endian addition and subtraction first. Do it only\n         if the operation would affect more than one byte (hence the \n         & 0xff overflow checks) and if it couldn't be a product of\n         a bitflip. */\n\n      stage_val_type = STAGE_VAL_LE; \n\n      if ((orig & 0xff) + j > 0xff && !could_be_bitflip(r1)) {\n\n        stage_cur_val = j;\n        *(u16*)(out_buf + i) = orig + j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n \n      } else stage_max--;\n\n      if ((orig & 0xff) < j && !could_be_bitflip(r2)) {\n\n        stage_cur_val = -j;\n        *(u16*)(out_buf + i) = orig - j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      /* Big endian comes next. Same deal. */\n\n      stage_val_type = STAGE_VAL_BE;\n\n\n      if ((orig >> 8) + j > 0xff && !could_be_bitflip(r3)) {\n\n        stage_cur_val = j;\n        *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) + j);\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      if ((orig >> 8) < j && !could_be_bitflip(r4)) {\n\n        stage_cur_val = -j;\n        *(u16*)(out_buf + i) = SWAP16(SWAP16(orig) - j);\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      *(u16*)(out_buf + i) = orig;\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_ARITH16]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_ARITH16] += stage_max;\n\n  /* 32-bit arithmetics, both endians. */\n\n  if (len < 4) goto skip_arith;\n\n  stage_name  = \"arith 32/8\";\n  stage_short = \"arith32\";\n  stage_cur   = 0;\n  stage_max   = 4 * (len - 3) * ARITH_MAX;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 3; i++) {\n\n    u32 orig = *(u32*)(out_buf + i);\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&\n        !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {\n      stage_max -= 4 * ARITH_MAX;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 1; j <= ARITH_MAX; j++) {\n\n      u32 r1 = orig ^ (orig + j),\n          r2 = orig ^ (orig - j),\n          r3 = orig ^ SWAP32(SWAP32(orig) + j),\n          r4 = orig ^ SWAP32(SWAP32(orig) - j);\n\n      /* Little endian first. Same deal as with 16-bit: we only want to\n         try if the operation would have effect on more than two bytes. */\n\n      stage_val_type = STAGE_VAL_LE; \n\n      if ((orig & 0xffff) + j > 0xffff && !could_be_bitflip(r1)) {\n\n        stage_cur_val = j;\n        *(u32*)(out_buf + i) = orig + j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      if ((orig & 0xffff) < j && !could_be_bitflip(r2)) {\n\n        stage_cur_val = -j;\n        *(u32*)(out_buf + i) = orig - j;\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      /* Big endian next. */\n\n      stage_val_type = STAGE_VAL_BE;\n\n      if ((SWAP32(orig) & 0xffff) + j > 0xffff && !could_be_bitflip(r3)) {\n\n        stage_cur_val = j;\n        *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) + j);\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      if ((SWAP32(orig) & 0xffff) < j && !could_be_bitflip(r4)) {\n\n        stage_cur_val = -j;\n        *(u32*)(out_buf + i) = SWAP32(SWAP32(orig) - j);\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      *(u32*)(out_buf + i) = orig;\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_ARITH32]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_ARITH32] += stage_max;\n\nskip_arith:\n\n  /**********************\n   * INTERESTING VALUES *\n   **********************/\n\n  stage_name  = \"interest 8/8\";\n  stage_short = \"int8\";\n  stage_cur   = 0;\n  stage_max   = len * sizeof(interesting_8);\n\n  stage_val_type = STAGE_VAL_LE;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  /* Setting 8-bit integers. */\n\n  for (i = 0; i < len; i++) {\n\n    u8 orig = out_buf[i];\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)]) {\n      stage_max -= sizeof(interesting_8);\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 0; j < sizeof(interesting_8); j++) {\n\n      /* Skip if the value could be a product of bitflips or arithmetics. */\n\n      if (could_be_bitflip(orig ^ (u8)interesting_8[j]) ||\n          could_be_arith(orig, (u8)interesting_8[j], 1)) {\n        stage_max--;\n        continue;\n      }\n\n      stage_cur_val = interesting_8[j];\n      out_buf[i] = interesting_8[j];\n\n      if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n      out_buf[i] = orig;\n      stage_cur++;\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_INTEREST8]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_INTEREST8] += stage_max;\n\n  /* Setting 16-bit integers, both endians. */\n\n  if (len < 2) goto skip_interest;\n\n  stage_name  = \"interest 16/8\";\n  stage_short = \"int16\";\n  stage_cur   = 0;\n  stage_max   = 2 * (len - 1) * (sizeof(interesting_16) >> 1);\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 1; i++) {\n\n    u16 orig = *(u16*)(out_buf + i);\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)]) {\n      stage_max -= sizeof(interesting_16);\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 0; j < sizeof(interesting_16) / 2; j++) {\n\n      stage_cur_val = interesting_16[j];\n\n      /* Skip if this could be a product of a bitflip, arithmetics,\n         or single-byte interesting value insertion. */\n\n      if (!could_be_bitflip(orig ^ (u16)interesting_16[j]) &&\n          !could_be_arith(orig, (u16)interesting_16[j], 2) &&\n          !could_be_interest(orig, (u16)interesting_16[j], 2, 0)) {\n\n        stage_val_type = STAGE_VAL_LE;\n\n        *(u16*)(out_buf + i) = interesting_16[j];\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      if ((u16)interesting_16[j] != SWAP16(interesting_16[j]) &&\n          !could_be_bitflip(orig ^ SWAP16(interesting_16[j])) &&\n          !could_be_arith(orig, SWAP16(interesting_16[j]), 2) &&\n          !could_be_interest(orig, SWAP16(interesting_16[j]), 2, 1)) {\n\n        stage_val_type = STAGE_VAL_BE;\n\n        *(u16*)(out_buf + i) = SWAP16(interesting_16[j]);\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n    }\n\n    *(u16*)(out_buf + i) = orig;\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_INTEREST16]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_INTEREST16] += stage_max;\n\n  if (len < 4) goto skip_interest;\n\n  /* Setting 32-bit integers, both endians. */\n\n  stage_name  = \"interest 32/8\";\n  stage_short = \"int32\";\n  stage_cur   = 0;\n  stage_max   = 2 * (len - 3) * (sizeof(interesting_32) >> 2);\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len - 3; i++) {\n\n    u32 orig = *(u32*)(out_buf + i);\n\n    /* Let's consult the effector map... */\n\n    if (!eff_map[EFF_APOS(i)] && !eff_map[EFF_APOS(i + 1)] &&\n        !eff_map[EFF_APOS(i + 2)] && !eff_map[EFF_APOS(i + 3)]) {\n      stage_max -= sizeof(interesting_32) >> 1;\n      continue;\n    }\n\n    stage_cur_byte = i;\n\n    for (j = 0; j < sizeof(interesting_32) / 4; j++) {\n\n      stage_cur_val = interesting_32[j];\n\n      /* Skip if this could be a product of a bitflip, arithmetics,\n         or word interesting value insertion. */\n\n      if (!could_be_bitflip(orig ^ (u32)interesting_32[j]) &&\n          !could_be_arith(orig, interesting_32[j], 4) &&\n          !could_be_interest(orig, interesting_32[j], 4, 0)) {\n\n        stage_val_type = STAGE_VAL_LE;\n\n        *(u32*)(out_buf + i) = interesting_32[j];\n\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n      if ((u32)interesting_32[j] != SWAP32(interesting_32[j]) &&\n          !could_be_bitflip(orig ^ SWAP32(interesting_32[j])) &&\n          !could_be_arith(orig, SWAP32(interesting_32[j]), 4) &&\n          !could_be_interest(orig, SWAP32(interesting_32[j]), 4, 1)) {\n\n        stage_val_type = STAGE_VAL_BE;\n\n        *(u32*)(out_buf + i) = SWAP32(interesting_32[j]);\n        if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n        stage_cur++;\n\n      } else stage_max--;\n\n    }\n\n    *(u32*)(out_buf + i) = orig;\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_INTEREST32]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_INTEREST32] += stage_max;\n\nskip_interest:\n\n  /********************\n   * DICTIONARY STUFF *\n   ********************/\n\n  if (!extras_cnt) goto skip_user_extras;\n\n  /* Overwrite with user-supplied extras. */\n\n  stage_name  = \"user extras (over)\";\n  stage_short = \"ext_UO\";\n  stage_cur   = 0;\n  stage_max   = extras_cnt * len;\n\n  stage_val_type = STAGE_VAL_NONE;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len; i++) {\n\n    u32 last_len = 0;\n\n    stage_cur_byte = i;\n\n    /* Extras are sorted by size, from smallest to largest. This means\n       that we don't have to worry about restoring the buffer in\n       between writes at a particular offset determined by the outer\n       loop. */\n\n    for (j = 0; j < extras_cnt; j++) {\n\n      /* Skip extras probabilistically if extras_cnt > MAX_DET_EXTRAS. Also\n         skip them if there's no room to insert the payload, if the token\n         is redundant, or if its entire span has no bytes set in the effector\n         map. */\n\n      if ((extras_cnt > MAX_DET_EXTRAS && UR(extras_cnt) >= MAX_DET_EXTRAS) ||\n          extras[j].len > len - i ||\n          !memcmp(extras[j].data, out_buf + i, extras[j].len) ||\n          !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, extras[j].len))) {\n\n        stage_max--;\n        continue;\n\n      }\n\n      last_len = extras[j].len;\n      memcpy(out_buf + i, extras[j].data, last_len);\n\n      if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n      stage_cur++;\n\n    }\n\n    /* Restore all the clobbered memory. */\n    memcpy(out_buf + i, in_buf + i, last_len);\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_EXTRAS_UO]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_EXTRAS_UO] += stage_max;\n\n  /* Insertion of user-supplied extras. */\n\n  stage_name  = \"user extras (insert)\";\n  stage_short = \"ext_UI\";\n  stage_cur   = 0;\n  stage_max   = extras_cnt * len;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  ex_tmp = ck_alloc(len + MAX_DICT_FILE);\n\n  for (i = 0; i < len; i++) {\n\n    stage_cur_byte = i;\n\n    for (j = 0; j < extras_cnt; j++) {\n\n      /* Insert token */\n      memcpy(ex_tmp + i, extras[j].data, extras[j].len);\n\n      /* Copy tail */\n      memcpy(ex_tmp + i + extras[j].len, out_buf + i, len - i);\n\n      if (common_fuzz_stuff(argv, ex_tmp, len + extras[j].len)) {\n        ck_free(ex_tmp);\n        goto abandon_entry;\n      }\n\n      stage_cur++;\n\n    }\n\n    /* Copy head */\n    ex_tmp[i] = out_buf[i];\n\n  }\n\n  ck_free(ex_tmp);\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_EXTRAS_UI]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_EXTRAS_UI] += stage_max;\n\nskip_user_extras:\n\n  if (!a_extras_cnt) goto skip_extras;\n\n  stage_name  = \"auto extras (over)\";\n  stage_short = \"ext_AO\";\n  stage_cur   = 0;\n  stage_max   = MIN(a_extras_cnt, USE_AUTO_EXTRAS) * len;\n\n  stage_val_type = STAGE_VAL_NONE;\n\n  orig_hit_cnt = new_hit_cnt;\n\n  for (i = 0; i < len; i++) {\n\n    u32 last_len = 0;\n\n    stage_cur_byte = i;\n\n    for (j = 0; j < MIN(a_extras_cnt, USE_AUTO_EXTRAS); j++) {\n\n      /* See the comment in the earlier code; extras are sorted by size. */\n\n      if (a_extras[j].len > len - i ||\n          !memcmp(a_extras[j].data, out_buf + i, a_extras[j].len) ||\n          !memchr(eff_map + EFF_APOS(i), 1, EFF_SPAN_ALEN(i, a_extras[j].len))) {\n\n        stage_max--;\n        continue;\n\n      }\n\n      last_len = a_extras[j].len;\n      memcpy(out_buf + i, a_extras[j].data, last_len);\n\n      if (common_fuzz_stuff(argv, out_buf, len)) goto abandon_entry;\n\n      stage_cur++;\n\n    }\n\n    /* Restore all the clobbered memory. */\n    memcpy(out_buf + i, in_buf + i, last_len);\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  stage_finds[STAGE_EXTRAS_AO]  += new_hit_cnt - orig_hit_cnt;\n  stage_cycles[STAGE_EXTRAS_AO] += stage_max;\n\nskip_extras:\n\n  /* If we made this to here without jumping to havoc_stage or abandon_entry,\n     we're properly done with deterministic steps and can mark it as such\n     in the .state/ directory. */\n\n  if (!queue_cur->passed_det) mark_as_det_done(queue_cur);\n\n  /****************\n   * RANDOM HAVOC *\n   ****************/\n\nhavoc_stage:\n\n  stage_cur_byte = -1;\n\n  /* The havoc stage mutation code is also invoked when splicing files; if the\n     splice_cycle variable is set, generate different descriptions and such. */\n\n  if (!splice_cycle) {\n\n    stage_name  = \"havoc\";\n    stage_short = \"havoc\";\n    stage_max   = HAVOC_CYCLES * perf_score / havoc_div / 100;\n\n  } else {\n\n    static u8 tmp[32];\n\n    perf_score = orig_perf;\n\n    sprintf(tmp, \"splice %u\", splice_cycle);\n    stage_name  = tmp;\n    stage_short = \"splice\";\n    stage_max   = SPLICE_HAVOC * perf_score / havoc_div / 100;\n\n  }\n\n  if (stage_max < HAVOC_MIN) stage_max = HAVOC_MIN;\n\n  temp_len = len;\n\n  orig_hit_cnt = queued_paths + unique_crashes;\n\n  havoc_queued = queued_paths;\n\n  /* We essentially just do several thousand runs (depending on perf_score)\n     where we take the input file and make random stacked tweaks. */\n\n  for (stage_cur = 0; stage_cur < stage_max; stage_cur++) {\n\n    u32 use_stacking = 1 << (1 + UR(HAVOC_STACK_POW2));\n\n    stage_cur_val = use_stacking;\n \n    for (i = 0; i < use_stacking; i++) {\n\n      switch (UR(15 + ((extras_cnt + a_extras_cnt) ? 2 : 0))) {\n\n        case 0:\n\n          /* Flip a single bit somewhere. Spooky! */\n\n          FLIP_BIT(out_buf, UR(temp_len << 3));\n          break;\n\n        case 1: \n\n          /* Set byte to interesting value. */\n\n          out_buf[UR(temp_len)] = interesting_8[UR(sizeof(interesting_8))];\n          break;\n\n        case 2:\n\n          /* Set word to interesting value, randomly choosing endian. */\n\n          if (temp_len < 2) break;\n\n          if (UR(2)) {\n\n            *(u16*)(out_buf + UR(temp_len - 1)) =\n              interesting_16[UR(sizeof(interesting_16) >> 1)];\n\n          } else {\n\n            *(u16*)(out_buf + UR(temp_len - 1)) = SWAP16(\n              interesting_16[UR(sizeof(interesting_16) >> 1)]);\n\n          }\n\n          break;\n\n        case 3:\n\n          /* Set dword to interesting value, randomly choosing endian. */\n\n          if (temp_len < 4) break;\n\n          if (UR(2)) {\n  \n            *(u32*)(out_buf + UR(temp_len - 3)) =\n              interesting_32[UR(sizeof(interesting_32) >> 2)];\n\n          } else {\n\n            *(u32*)(out_buf + UR(temp_len - 3)) = SWAP32(\n              interesting_32[UR(sizeof(interesting_32) >> 2)]);\n\n          }\n\n          break;\n\n        case 4:\n\n          /* Randomly subtract from byte. */\n\n          out_buf[UR(temp_len)] -= 1 + UR(ARITH_MAX);\n          break;\n\n        case 5:\n\n          /* Randomly add to byte. */\n\n          out_buf[UR(temp_len)] += 1 + UR(ARITH_MAX);\n          break;\n\n        case 6:\n\n          /* Randomly subtract from word, random endian. */\n\n          if (temp_len < 2) break;\n\n          if (UR(2)) {\n\n            u32 pos = UR(temp_len - 1);\n\n            *(u16*)(out_buf + pos) -= 1 + UR(ARITH_MAX);\n\n          } else {\n\n            u32 pos = UR(temp_len - 1);\n            u16 num = 1 + UR(ARITH_MAX);\n\n            *(u16*)(out_buf + pos) =\n              SWAP16(SWAP16(*(u16*)(out_buf + pos)) - num);\n\n          }\n\n          break;\n\n        case 7:\n\n          /* Randomly add to word, random endian. */\n\n          if (temp_len < 2) break;\n\n          if (UR(2)) {\n\n            u32 pos = UR(temp_len - 1);\n\n            *(u16*)(out_buf + pos) += 1 + UR(ARITH_MAX);\n\n          } else {\n\n            u32 pos = UR(temp_len - 1);\n            u16 num = 1 + UR(ARITH_MAX);\n\n            *(u16*)(out_buf + pos) =\n              SWAP16(SWAP16(*(u16*)(out_buf + pos)) + num);\n\n          }\n\n          break;\n\n        case 8:\n\n          /* Randomly subtract from dword, random endian. */\n\n          if (temp_len < 4) break;\n\n          if (UR(2)) {\n\n            u32 pos = UR(temp_len - 3);\n\n            *(u32*)(out_buf + pos) -= 1 + UR(ARITH_MAX);\n\n          } else {\n\n            u32 pos = UR(temp_len - 3);\n            u32 num = 1 + UR(ARITH_MAX);\n\n            *(u32*)(out_buf + pos) =\n              SWAP32(SWAP32(*(u32*)(out_buf + pos)) - num);\n\n          }\n\n          break;\n\n        case 9:\n\n          /* Randomly add to dword, random endian. */\n\n          if (temp_len < 4) break;\n\n          if (UR(2)) {\n\n            u32 pos = UR(temp_len - 3);\n\n            *(u32*)(out_buf + pos) += 1 + UR(ARITH_MAX);\n\n          } else {\n\n            u32 pos = UR(temp_len - 3);\n            u32 num = 1 + UR(ARITH_MAX);\n\n            *(u32*)(out_buf + pos) =\n              SWAP32(SWAP32(*(u32*)(out_buf + pos)) + num);\n\n          }\n\n          break;\n\n        case 10:\n\n          /* Just set a random byte to a random value. Because,\n             why not. We use XOR with 1-255 to eliminate the\n             possibility of a no-op. */\n\n          out_buf[UR(temp_len)] ^= 1 + UR(255);\n          break;\n\n        case 11 ... 12: {\n\n            /* Delete bytes. We're making this a bit more likely\n               than insertion (the next option) in hopes of keeping\n               files reasonably small. */\n\n            u32 del_from, del_len;\n\n            if (temp_len < 2) break;\n\n            /* Don't delete too much. */\n\n            del_len = choose_block_len(temp_len - 1);\n\n            del_from = UR(temp_len - del_len + 1);\n\n            memmove(out_buf + del_from, out_buf + del_from + del_len,\n                    temp_len - del_from - del_len);\n\n            temp_len -= del_len;\n\n            break;\n\n          }\n\n        case 13:\n\n          if (temp_len + HAVOC_BLK_LARGE < MAX_FILE) {\n\n            /* Clone bytes (75%) or insert a block of constant bytes (25%). */\n\n            u32 clone_from, clone_to, clone_len;\n            u8* new_buf;\n\n            clone_len  = choose_block_len(temp_len);\n\n            clone_from = UR(temp_len - clone_len + 1);\n            clone_to   = UR(temp_len);\n\n            new_buf = ck_alloc_nozero(temp_len + clone_len);\n\n            /* Head */\n\n            memcpy(new_buf, out_buf, clone_to);\n\n            /* Inserted part */\n\n            if (UR(4))\n              memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);\n            else\n              memset(new_buf + clone_to, UR(256), clone_len);\n\n            /* Tail */\n            memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,\n                   temp_len - clone_to);\n\n            ck_free(out_buf);\n            out_buf = new_buf;\n            temp_len += clone_len;\n\n          }\n\n          break;\n\n        case 14: {\n\n            /* Overwrite bytes with a randomly selected chunk (75%) or fixed\n               bytes (25%). */\n\n            u32 copy_from, copy_to, copy_len;\n\n            if (temp_len < 2) break;\n\n            copy_len  = choose_block_len(temp_len - 1);\n\n            copy_from = UR(temp_len - copy_len + 1);\n            copy_to   = UR(temp_len - copy_len + 1);\n\n            if (UR(4)) {\n\n              if (copy_from != copy_to)\n                memmove(out_buf + copy_to, out_buf + copy_from, copy_len);\n\n            } else memset(out_buf + copy_to, UR(256), copy_len);\n\n            break;\n\n          }\n\n        /* Values 16 and 17 can be selected only if there are any extras\n           present in the dictionaries. */\n\n        case 16: {\n\n            /* Overwrite bytes with an extra. */\n\n            if (!extras_cnt || (a_extras_cnt && UR(2))) {\n\n              /* No user-specified extras or odds in our favor. Let's use an\n                 auto-detected one. */\n\n              u32 use_extra = UR(a_extras_cnt);\n              u32 extra_len = a_extras[use_extra].len;\n              u32 insert_at;\n\n              if (extra_len > temp_len) break;\n\n              insert_at = UR(temp_len - extra_len + 1);\n              memcpy(out_buf + insert_at, a_extras[use_extra].data, extra_len);\n\n            } else {\n\n              /* No auto extras or odds in our favor. Use the dictionary. */\n\n              u32 use_extra = UR(extras_cnt);\n              u32 extra_len = extras[use_extra].len;\n              u32 insert_at;\n\n              if (extra_len > temp_len) break;\n\n              insert_at = UR(temp_len - extra_len + 1);\n              memcpy(out_buf + insert_at, extras[use_extra].data, extra_len);\n\n            }\n\n            break;\n\n          }\n\n        case 17: {\n\n            u32 use_extra, extra_len, insert_at = UR(temp_len);\n            u8* new_buf;\n\n            /* Insert an extra. Do the same dice-rolling stuff as for the\n               previous case. */\n\n            if (!extras_cnt || (a_extras_cnt && UR(2))) {\n\n              use_extra = UR(a_extras_cnt);\n              extra_len = a_extras[use_extra].len;\n\n              if (temp_len + extra_len >= MAX_FILE) break;\n\n              new_buf = ck_alloc_nozero(temp_len + extra_len);\n\n              /* Head */\n              memcpy(new_buf, out_buf, insert_at);\n\n              /* Inserted part */\n              memcpy(new_buf + insert_at, a_extras[use_extra].data, extra_len);\n\n            } else {\n\n              use_extra = UR(extras_cnt);\n              extra_len = extras[use_extra].len;\n\n              if (temp_len + extra_len >= MAX_FILE) break;\n\n              new_buf = ck_alloc_nozero(temp_len + extra_len);\n\n              /* Head */\n              memcpy(new_buf, out_buf, insert_at);\n\n              /* Inserted part */\n              memcpy(new_buf + insert_at, extras[use_extra].data, extra_len);\n\n            }\n\n            /* Tail */\n            memcpy(new_buf + insert_at + extra_len, out_buf + insert_at,\n                   temp_len - insert_at);\n\n            ck_free(out_buf);\n            out_buf   = new_buf;\n            temp_len += extra_len;\n\n            break;\n\n          }\n\n      }\n\n    }\n\n    if (common_fuzz_stuff(argv, out_buf, temp_len))\n      goto abandon_entry;\n\n    /* out_buf might have been mangled a bit, so let's restore it to its\n       original size and shape. */\n\n    if (temp_len < len) out_buf = ck_realloc(out_buf, len);\n    temp_len = len;\n    memcpy(out_buf, in_buf, len);\n\n    /* If we're finding new stuff, let's run for a bit longer, limits\n       permitting. */\n\n    if (queued_paths != havoc_queued) {\n\n      if (perf_score <= HAVOC_MAX_MULT * 100) {\n        stage_max  *= 2;\n        perf_score *= 2;\n      }\n\n      havoc_queued = queued_paths;\n\n    }\n\n  }\n\n  new_hit_cnt = queued_paths + unique_crashes;\n\n  if (!splice_cycle) {\n    stage_finds[STAGE_HAVOC]  += new_hit_cnt - orig_hit_cnt;\n    stage_cycles[STAGE_HAVOC] += stage_max;\n  } else {\n    stage_finds[STAGE_SPLICE]  += new_hit_cnt - orig_hit_cnt;\n    stage_cycles[STAGE_SPLICE] += stage_max;\n  }\n\n#ifndef IGNORE_FINDS\n\n  /************\n   * SPLICING *\n   ************/\n\n  /* This is a last-resort strategy triggered by a full round with no findings.\n     It takes the current input file, randomly selects another input, and\n     splices them together at some offset, then relies on the havoc\n     code to mutate that blob. */\n\nretry_splicing:\n\n  if (use_splicing && splice_cycle++ < SPLICE_CYCLES &&\n      queued_paths > 1 && queue_cur->len > 1) {\n\n    struct queue_entry* target;\n    u32 tid, split_at;\n    u8* new_buf;\n    s32 f_diff, l_diff;\n\n    /* First of all, if we've modified in_buf for havoc, let's clean that\n       up... */\n\n    if (in_buf != orig_in) {\n      ck_free(in_buf);\n      in_buf = orig_in;\n      len = queue_cur->len;\n    }\n\n    /* Pick a random queue entry and seek to it. Don't splice with yourself. */\n\n    do { tid = UR(queued_paths); } while (tid == current_entry);\n\n    splicing_with = tid;\n    target = queue;\n\n    while (tid >= 100) { target = target->next_100; tid -= 100; }\n    while (tid--) target = target->next;\n\n    /* Make sure that the target has a reasonable length. */\n\n    while (target && (target->len < 2 || target == queue_cur)) {\n      target = target->next;\n      splicing_with++;\n    }\n\n    if (!target) goto retry_splicing;\n\n    /* Read the testcase into a new buffer. */\n\n    fd = open(target->fname, O_RDONLY);\n\n    if (fd < 0) PFATAL(\"Unable to open '%s'\", target->fname);\n\n    new_buf = ck_alloc_nozero(target->len);\n\n    ck_read(fd, new_buf, target->len, target->fname);\n\n    close(fd);\n\n    /* Find a suitable splicing location, somewhere between the first and\n       the last differing byte. Bail out if the difference is just a single\n       byte or so. */\n\n    locate_diffs(in_buf, new_buf, MIN(len, target->len), &f_diff, &l_diff);\n\n    if (f_diff < 0 || l_diff < 2 || f_diff == l_diff) {\n      ck_free(new_buf);\n      goto retry_splicing;\n    }\n\n    /* Split somewhere between the first and last differing byte. */\n\n    split_at = f_diff + UR(l_diff - f_diff);\n\n    /* Do the thing. */\n\n    len = target->len;\n    memcpy(new_buf, in_buf, split_at);\n    in_buf = new_buf;\n\n    ck_free(out_buf);\n    out_buf = ck_alloc_nozero(len);\n    memcpy(out_buf, in_buf, len);\n\n    goto havoc_stage;\n\n  }\n\n#endif /* !IGNORE_FINDS */\n\n  ret_val = 0;\n\nabandon_entry:\n\n  splicing_with = -1;\n\n  /* Update pending_not_fuzzed count if we made it through the calibration\n     cycle and have not seen this entry before. */\n\n  if (!stop_soon && !queue_cur->cal_failed && !queue_cur->was_fuzzed) {\n    queue_cur->was_fuzzed = 1;\n    pending_not_fuzzed--;\n    if (queue_cur->favored) pending_favored--;\n  }\n\n  munmap(orig_in, queue_cur->len);\n\n  if (in_buf != orig_in) ck_free(in_buf);\n  ck_free(out_buf);\n  ck_free(eff_map);\n\n  return ret_val;\n\n#undef FLIP_BIT\n\n}\n\n\n/* Grab interesting test cases from other fuzzers. */\n\nstatic void sync_fuzzers(char** argv) {\n\n  DIR* sd;\n  struct dirent* sd_ent;\n  u32 sync_cnt = 0;\n\n  sd = opendir(sync_dir);\n  if (!sd) PFATAL(\"Unable to open '%s'\", sync_dir);\n\n  stage_max = stage_cur = 0;\n  cur_depth = 0;\n\n  /* Look at the entries created for every other fuzzer in the sync directory. */\n\n  while ((sd_ent = readdir(sd))) {\n\n    static u8 stage_tmp[128];\n\n    DIR* qd;\n    struct dirent* qd_ent;\n    u8 *qd_path, *qd_synced_path;\n    u32 min_accept = 0, next_min_accept;\n\n    s32 id_fd;\n\n    /* Skip dot files and our own output directory. */\n\n    if (sd_ent->d_name[0] == '.' || !strcmp(sync_id, sd_ent->d_name)) continue;\n\n    /* Skip anything that doesn't have a queue/ subdirectory. */\n\n    qd_path = alloc_printf(\"%s/%s/queue\", sync_dir, sd_ent->d_name);\n\n    if (!(qd = opendir(qd_path))) {\n      ck_free(qd_path);\n      continue;\n    }\n\n    /* Retrieve the ID of the last seen test case. */\n\n    qd_synced_path = alloc_printf(\"%s/.synced/%s\", out_dir, sd_ent->d_name);\n\n    id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);\n\n    if (id_fd < 0) PFATAL(\"Unable to create '%s'\", qd_synced_path);\n\n    if (read(id_fd, &min_accept, sizeof(u32)) > 0) \n      lseek(id_fd, 0, SEEK_SET);\n\n    next_min_accept = min_accept;\n\n    /* Show stats */    \n\n    sprintf(stage_tmp, \"sync %u\", ++sync_cnt);\n    stage_name = stage_tmp;\n    stage_cur  = 0;\n    stage_max  = 0;\n\n    /* For every file queued by this fuzzer, parse ID and see if we have looked at\n       it before; exec a test case if not. */\n\n    while ((qd_ent = readdir(qd))) {\n\n      u8* path;\n      s32 fd;\n      struct stat st;\n\n      if (qd_ent->d_name[0] == '.' ||\n          sscanf(qd_ent->d_name, CASE_PREFIX \"%06u\", &syncing_case) != 1 || \n          syncing_case < min_accept) continue;\n\n      /* OK, sounds like a new one. Let's give it a try. */\n\n      if (syncing_case >= next_min_accept)\n        next_min_accept = syncing_case + 1;\n\n      path = alloc_printf(\"%s/%s\", qd_path, qd_ent->d_name);\n\n      fd = open(path, O_RDONLY);\n      if (fd < 0) PFATAL(\"Unable to open '%s'\", path);\n\n      if (fstat(fd, &st)) PFATAL(\"fstat() failed\");\n\n      /* Ignore zero-sized or oversized files. */\n\n      if (st.st_size && st.st_size <= MAX_FILE) {\n\n        u8  fault;\n        u8* mem = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);\n\n        if (mem == MAP_FAILED) PFATAL(\"Unable to mmap '%s'\", path);\n\n        /* See what happens. We rely on save_if_interesting() to catch major\n           errors and save the test case. */\n\n        write_to_testcase(mem, st.st_size);\n\n        fault = run_target(argv);\n\n        if (stop_soon) return;\n\n        syncing_party = sd_ent->d_name;\n        queued_imported += save_if_interesting(argv, mem, st.st_size, fault);\n        syncing_party = 0;\n\n        munmap(mem, st.st_size);\n\n        if (!(stage_cur++ % stats_update_freq)) show_stats();\n\n      }\n\n      ck_free(path);\n      close(fd);\n\n    }\n\n    ck_write(id_fd, &next_min_accept, sizeof(u32), qd_synced_path);\n\n    close(id_fd);\n    closedir(qd);\n    ck_free(qd_path);\n    ck_free(qd_synced_path);\n    \n  }  \n\n  closedir(sd);\n\n}\n\n\n/* Handle stop signal (Ctrl-C, etc). */\n\nstatic void handle_stop_sig(int sig) {\n\n  stop_soon = 1; \n\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n  if (forksrv_pid > 0) kill(forksrv_pid, SIGKILL);\n\n}\n\n\n/* Handle skip request (SIGUSR1). */\n\nstatic void handle_skipreq(int sig) {\n\n  skip_requested = 1;\n\n}\n\n/* Handle timeout (SIGALRM). */\n\nstatic void handle_timeout(int sig) {\n\n  if (child_pid > 0) {\n\n    child_timed_out = 1; \n    kill(child_pid, SIGKILL);\n\n  } else if (child_pid == -1 && forksrv_pid > 0) {\n\n    child_timed_out = 1; \n    kill(forksrv_pid, SIGKILL);\n\n  }\n\n}\n\n\n/* Do a PATH search and find target binary to see that it exists and\n   isn't a shell script - a common and painful mistake. We also check for\n   a valid ELF header and for evidence of AFL instrumentation. */\n\nstatic void check_binary(u8* fname) {\n\n  u8* env_path = 0;\n  struct stat st;\n\n  s32 fd;\n  u8* f_data;\n  u32 f_len = 0;\n\n  ACTF(\"Validating target binary...\");\n\n  if (strchr(fname, '/') || !(env_path = getenv(\"PATH\"))) {\n\n    target_path = ck_strdup(fname);\n    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||\n        !(st.st_mode & 0111) || (f_len = st.st_size) < 4)\n      FATAL(\"Program '%s' not found or not executable\", fname);\n\n  } else {\n\n    while (env_path) {\n\n      u8 *cur_elem, *delim = strchr(env_path, ':');\n\n      if (delim) {\n\n        cur_elem = ck_alloc(delim - env_path + 1);\n        memcpy(cur_elem, env_path, delim - env_path);\n        delim++;\n\n      } else cur_elem = ck_strdup(env_path);\n\n      env_path = delim;\n\n      if (cur_elem[0])\n        target_path = alloc_printf(\"%s/%s\", cur_elem, fname);\n      else\n        target_path = ck_strdup(fname);\n\n      ck_free(cur_elem);\n\n      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&\n          (st.st_mode & 0111) && (f_len = st.st_size) >= 4) break;\n\n      ck_free(target_path);\n      target_path = 0;\n\n    }\n\n    if (!target_path) FATAL(\"Program '%s' not found or not executable\", fname);\n\n  }\n\n  if (getenv(\"AFL_SKIP_BIN_CHECK\")) return;\n\n  /* Check for blatant user errors. */\n\n  if ((!strncmp(target_path, \"/tmp/\", 5) && !strchr(target_path + 5, '/')) ||\n      (!strncmp(target_path, \"/var/tmp/\", 9) && !strchr(target_path + 9, '/')))\n     FATAL(\"Please don't keep binaries in /tmp or /var/tmp\");\n\n  fd = open(target_path, O_RDONLY);\n\n  if (fd < 0) PFATAL(\"Unable to open '%s'\", target_path);\n\n  f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);\n\n  if (f_data == MAP_FAILED) PFATAL(\"Unable to mmap file '%s'\", target_path);\n\n  close(fd);\n\n  if (f_data[0] == '#' && f_data[1] == '!') {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Oops, the target binary looks like a shell script. Some build systems will\\n\"\n         \"    sometimes generate shell stubs for dynamically linked programs; try static\\n\"\n         \"    library mode (./configure --disable-shared) if that's the case.\\n\\n\"\n\n         \"    Another possible cause is that you are actually trying to use a shell\\n\" \n         \"    wrapper around the fuzzed component. Invoking shell can slow down the\\n\" \n         \"    fuzzing process by a factor of 20x or more; it's best to write the wrapper\\n\"\n         \"    in a compiled language instead.\\n\");\n\n    FATAL(\"Program '%s' is a shell script\", target_path);\n\n  }\n\n#ifndef __APPLE__\n\n  if (f_data[0] != 0x7f || memcmp(f_data + 1, \"ELF\", 3))\n    FATAL(\"Program '%s' is not an ELF binary\", target_path);\n\n#else\n\n  if (f_data[0] != 0xCF || f_data[1] != 0xFA || f_data[2] != 0xED)\n    FATAL(\"Program '%s' is not a 64-bit Mach-O binary\", target_path);\n\n#endif /* ^!__APPLE__ */\n\n  if (!qemu_mode && !dumb_mode &&\n      !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Looks like the target binary is not instrumented! The fuzzer depends on\\n\"\n         \"    compile-time instrumentation to isolate interesting test cases while\\n\"\n         \"    mutating the input data. For more information, and for tips on how to\\n\"\n         \"    instrument binaries, please see %s/README.\\n\\n\"\n\n         \"    When source code is not available, you may be able to leverage QEMU\\n\"\n         \"    mode support. Consult the README for tips on how to enable this.\\n\"\n\n         \"    (It is also possible to use afl-fuzz as a traditional, \\\"dumb\\\" fuzzer.\\n\"\n         \"    For that, you can use the -n option - but expect much worse results.)\\n\",\n         doc_path);\n\n    FATAL(\"No instrumentation detected\");\n\n  }\n\n  if (qemu_mode &&\n      memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"This program appears to be instrumented with afl-gcc, but is being run in\\n\"\n         \"    QEMU mode (-Q). This is probably not what you want - this setup will be\\n\"\n         \"    slow and offer no practical benefits.\\n\");\n\n    FATAL(\"Instrumentation found in -Q mode\");\n\n  }\n\n  if (memmem(f_data, f_len, \"libasan.so\", 10) ||\n      memmem(f_data, f_len, \"__msan_init\", 11)) uses_asan = 1;\n\n  /* Detect persistent & deferred init signatures in the binary. */\n\n  if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) {\n\n    OKF(cPIN \"Persistent mode binary detected.\");\n    setenv(PERSIST_ENV_VAR, \"1\", 1);\n    no_var_check = 1;\n\n  } else if (getenv(\"AFL_PERSISTENT\")) {\n\n    WARNF(\"AFL_PERSISTENT is no longer supported and may misbehave!\");\n\n  }\n\n  if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) {\n\n    OKF(cPIN \"Deferred forkserver binary detected.\");\n    setenv(DEFER_ENV_VAR, \"1\", 1);\n\n  } else if (getenv(\"AFL_DEFER_FORKSRV\")) {\n\n    WARNF(\"AFL_DEFER_FORKSRV is no longer supported and may misbehave!\");\n\n  }\n\n  if (munmap(f_data, f_len)) PFATAL(\"unmap() failed\");\n\n}\n\n\n/* Trim and possibly create a banner for the run. */\n\nstatic void fix_up_banner(u8* name) {\n\n  if (!use_banner) {\n\n    if (sync_id) {\n\n      use_banner = sync_id;\n\n    } else {\n\n      u8* trim = strrchr(name, '/');\n      if (!trim) use_banner = name; else use_banner = trim + 1;\n\n    }\n\n  }\n\n  if (strlen(use_banner) > 40) {\n\n    u8* tmp = ck_alloc(44);\n    sprintf(tmp, \"%.40s...\", use_banner);\n    use_banner = tmp;\n\n  }\n\n}\n\n\n/* Check if we're on TTY. */\n\nstatic void check_if_tty(void) {\n\n  struct winsize ws;\n\n  if (ioctl(1, TIOCGWINSZ, &ws)) {\n\n    if (errno == ENOTTY) {\n      OKF(\"Looks like we're not running on a tty, so I'll be a bit less verbose.\");\n      not_on_tty = 1;\n    }\n\n    return;\n  }\n\n}\n\n\n/* Check terminal dimensions after resize. */\n\nstatic void check_term_size(void) {\n\n  struct winsize ws;\n\n  term_too_small = 0;\n\n  if (ioctl(1, TIOCGWINSZ, &ws)) return;\n\n  if (ws.ws_row < 25 || ws.ws_col < 80) term_too_small = 1;\n\n}\n\n\n\n/* Display usage hints. */\n\nstatic void usage(u8* argv0) {\n\n  SAYF(\"\\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\\n\\n\"\n\n       \"Required parameters:\\n\\n\"\n\n       \"  -i dir        - input directory with test cases\\n\"\n       \"  -o dir        - output directory for fuzzer findings\\n\\n\"\n\n       \"Execution control settings:\\n\\n\"\n\n       \"  -f file       - location read by the fuzzed program (stdin)\\n\"\n       \"  -N URL        - fuzzed program is to read from a network port.\\n\"\n       \"                  The network is specified by URL = type://path:port\\n\"\n       \"                  where type= {udp|tcp}, path={::1|127.0.0.1|localhost},\\n\"\n       \"                  and port is a port number or service name.\\n\"\n       \"                  There are two cases, where the target program to be\\n\"\n       \"                  fuzzed is either a server to afl-fuzz (the default)\\n\"\n       \"                  or a client of afl-fuzz (using the -L option).  If the\\n\"\n       \"                  target is a server, then afl-fuzz sends fuzzed data\\n\"\n       \"                  to the address and port specified in the URL.  If\\n\"\n       \"                  the target is a client, then afl-fuzz listens for\\n\"\n       \"                  data on the specified port and responds by sending\\n\"\n       \"                  fuzzed data to the (typically ephemeral) port used\\n\"\n       \"                  by the target.  Note that the '+' is likely to be\\n\"\n       \"                  necessary after the -t delay option for network\\n\"\n       \"                  fuzzing.\\n\"\n       \"  -D msec       - for network fuzzing only: delay in msec before\\n\"\n       \"                  a network read/write/connection is attempted;\\n\"\n       \"                  Note that 3 attempts are made, with this\\n\"\n       \"                  delay between each (-t is still in effect)\\n\"\n       \"  -L            - specify this option if the fuzzed program is a\\n\"\n       \"                  network client (meaning it writes to the network\\n\"\n       \"                  before reading (a fuzzed input) from the network.\\n\"\n       \"                  The port is the port number to which the network\\n\"\n       \"                  client is expected to write.\\n\"\n       \"  -t msec       - timeout for each run (auto-scaled, 50-%u ms)\\n\"\n       \"  -m megs       - memory limit for child process (%u MB)\\n\"\n       \"  -Q            - use binary-only instrumentation (QEMU mode)\\n\\n\"     \n \n       \"Fuzzing behavior settings:\\n\\n\"\n\n       \"  -d            - quick & dirty mode (skips deterministic steps)\\n\"\n       \"  -n            - fuzz without instrumentation (dumb mode)\\n\"\n       \"  -x dir        - optional fuzzer dictionary (see README)\\n\\n\"\n\n       \"Other stuff:\\n\\n\"\n\n       \"  -T text       - text banner to show on the screen\\n\"\n       \"  -M / -S id    - distributed mode (see parallel_fuzzing.txt)\\n\"\n       \"  -C            - crash exploration mode (the peruvian rabbit thing)\\n\\n\"\n\n       \"For additional tips, please consult %s/README.\\n\\n\",\n\n       argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);\n\n  exit(1);\n\n}\n\n\n/* Prepare output directories and fds. */\n\nstatic void setup_dirs_fds(void) {\n\n  u8* tmp;\n  s32 fd;\n\n  ACTF(\"Setting up output directories...\");\n\n  if (sync_id && mkdir(sync_dir, 0700) && errno != EEXIST)\n      PFATAL(\"Unable to create '%s'\", sync_dir);\n\n  if (mkdir(out_dir, 0700)) {\n\n    if (errno != EEXIST) PFATAL(\"Unable to create '%s'\", out_dir);\n\n    maybe_delete_out_dir();\n\n  } else {\n\n    if (in_place_resume)\n      FATAL(\"Resume attempted but old output directory not found\");\n\n    out_dir_fd = open(out_dir, O_RDONLY);\n\n#ifndef __sun\n\n    if (out_dir_fd < 0 || flock(out_dir_fd, LOCK_EX | LOCK_NB))\n      PFATAL(\"Unable to flock() output directory.\");\n\n#endif /* !__sun */\n\n  }\n\n  /* Queue directory for any starting & discovered paths. */\n\n  tmp = alloc_printf(\"%s/queue\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* Top-level directory for queue metadata used for session\n     resume and related tasks. */\n\n  tmp = alloc_printf(\"%s/queue/.state/\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* Directory for flagging queue entries that went through\n     deterministic fuzzing in the past. */\n\n  tmp = alloc_printf(\"%s/queue/.state/deterministic_done/\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* Directory with the auto-selected dictionary entries. */\n\n  tmp = alloc_printf(\"%s/queue/.state/auto_extras/\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* The set of paths currently deemed redundant. */\n\n  tmp = alloc_printf(\"%s/queue/.state/redundant_edges/\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* The set of paths showing variable behavior. */\n\n  tmp = alloc_printf(\"%s/queue/.state/variable_behavior/\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* Sync directory for keeping track of cooperating fuzzers. */\n\n  if (sync_id) {\n\n    tmp = alloc_printf(\"%s/.synced/\", out_dir);\n    if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n    ck_free(tmp);\n\n  }\n\n  /* All recorded crashes. */\n\n  tmp = alloc_printf(\"%s/crashes\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* All recorded hangs. */\n\n  tmp = alloc_printf(\"%s/hangs\", out_dir);\n  if (mkdir(tmp, 0700)) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  /* Generally useful file descriptors. */\n\n  dev_null_fd = open(\"/dev/null\", O_RDWR);\n  if (dev_null_fd < 0) PFATAL(\"Unable to open /dev/null\");\n\n  dev_urandom_fd = open(\"/dev/urandom\", O_RDONLY);\n  if (dev_urandom_fd < 0) PFATAL(\"Unable to open /dev/urandom\");\n\n  /* Gnuplot output file. */\n\n  tmp = alloc_printf(\"%s/plot_data\", out_dir);\n  fd = open(tmp, O_WRONLY | O_CREAT | O_EXCL, 0600);\n  if (fd < 0) PFATAL(\"Unable to create '%s'\", tmp);\n  ck_free(tmp);\n\n  plot_file = fdopen(fd, \"w\");\n  if (!plot_file) PFATAL(\"fdopen() failed\");\n\n  fprintf(plot_file, \"# unix_time, cycles_done, cur_path, paths_total, \"\n                     \"pending_total, pending_favs, map_size, unique_crashes, \"\n                     \"unique_hangs, max_depth, execs_per_sec\\n\");\n                     /* ignore errors */\n\n}\n\n\n/* Setup the output file for fuzzed data, if not using -f. */\n\nstatic void setup_stdio_file(void) {\n\n  u8* fn = alloc_printf(\"%s/.cur_input\", out_dir);\n\n  unlink(fn); /* Ignore errors */\n\n  out_fd = open(fn, O_RDWR | O_CREAT | O_EXCL, 0600);\n\n  if (out_fd < 0) PFATAL(\"Unable to create '%s'\", fn);\n\n  ck_free(fn);\n\n}\n\n\n/* Make sure that core dumps don't go to a program. */\n\nstatic void check_crash_handling(void) {\n\n#ifdef __APPLE__\n\n  /* Yuck! There appears to be no simple C API to query for the state of \n     loaded daemons on MacOS X, and I'm a bit hesitant to do something\n     more sophisticated, such as disabling crash reporting via Mach ports,\n     until I get a box to test the code. So, for now, we check for crash\n     reporting the awful way. */\n  \n  if (system(\"launchctl list 2>/dev/null | grep -q '\\\\.ReportCrash$'\")) return;\n\n  SAYF(\"\\n\" cLRD \"[-] \" cRST\n       \"Whoops, your system is configured to forward crash notifications to an\\n\"\n       \"    external crash reporting utility. This will cause issues due to the\\n\"\n       \"    extended delay between the fuzzed binary malfunctioning and this fact\\n\"\n       \"    being relayed to the fuzzer via the standard waitpid() API.\\n\\n\"\n       \"    To avoid having crashes misinterpreted as hangs, please run the\\n\" \n       \"    following commands:\\n\\n\"\n\n       \"    SL=/System/Library; PL=com.apple.ReportCrash\\n\"\n       \"    launchctl unload -w ${SL}/LaunchAgents/${PL}.plist\\n\"\n       \"    sudo launchctl unload -w ${SL}/LaunchDaemons/${PL}.Root.plist\\n\");\n\n  if (!getenv(\"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES\"))\n    FATAL(\"Crash reporter detected\");\n\n#else\n\n  /* This is Linux specific, but I don't think there's anything equivalent on\n     *BSD, so we can just let it slide for now. */\n\n  s32 fd = open(\"/proc/sys/kernel/core_pattern\", O_RDONLY);\n  u8  fchar;\n\n  if (fd < 0) return;\n\n  ACTF(\"Checking core_pattern...\");\n\n  if (read(fd, &fchar, 1) == 1 && fchar == '|') {\n\n    SAYF(\"\\n\" cLRD \"[-] \" cRST\n         \"Hmm, your system is configured to send core dump notifications to an\\n\"\n         \"    external utility. This will cause issues due to an extended delay\\n\"\n         \"    between the fuzzed binary malfunctioning and this information being\\n\"\n         \"    eventually relayed to the fuzzer via the standard waitpid() API.\\n\\n\"\n\n         \"    To avoid having crashes misinterpreted as hangs, please log in as root\\n\" \n         \"    and temporarily modify /proc/sys/kernel/core_pattern, like so:\\n\\n\"\n\n         \"    echo core >/proc/sys/kernel/core_pattern\\n\");\n\n    if (!getenv(\"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES\"))\n      FATAL(\"Pipe at the beginning of 'core_pattern'\");\n\n  }\n \n  close(fd);\n\n#endif /* ^__APPLE__ */\n\n}\n\n\n/* Check CPU governor. */\n\nstatic void check_cpu_governor(void) {\n\n  FILE* f;\n  u8 tmp[128];\n  u64 min = 0, max = 0;\n\n  if (getenv(\"AFL_SKIP_CPUFREQ\")) return;\n\n  f = fopen(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor\", \"r\");\n  if (!f) return;\n\n  ACTF(\"Checking CPU scaling governor...\");\n\n  if (!fgets(tmp, 128, f)) PFATAL(\"fgets() failed\");\n\n  fclose(f);\n\n  if (!strncmp(tmp, \"perf\", 4)) return;\n\n  f = fopen(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq\", \"r\");\n\n  if (f) {\n    if (fscanf(f, \"%llu\", &min) != 1) min = 0;\n    fclose(f);\n  }\n\n  f = fopen(\"/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq\", \"r\");\n\n  if (f) {\n    if (fscanf(f, \"%llu\", &max) != 1) max = 0;\n    fclose(f);\n  }\n\n  if (min == max) return;\n\n  SAYF(\"\\n\" cLRD \"[-] \" cRST\n       \"Whoops, your system uses on-demand CPU frequency scaling, adjusted\\n\"\n       \"    between %llu and %llu MHz. Unfortunately, the scaling algorithm in the\\n\"\n       \"    kernel is imperfect and can miss the short-lived processes spawned by\\n\"\n       \"    afl-fuzz. To keep things moving, run these commands as root:\\n\\n\"\n\n       \"    cd /sys/devices/system/cpu\\n\"\n       \"    echo performance | tee cpu*/cpufreq/scaling_governor\\n\\n\"\n\n       \"    You can later go back to the original state by replacing 'performance' with\\n\"\n       \"    'ondemand'. If you don't want to change the settings, set AFL_SKIP_CPUFREQ\\n\"\n       \"    to make afl-fuzz skip this check - but expect some performance drop.\\n\",\n       min / 1024, max / 1024);\n\n  FATAL(\"Suboptimal CPU scaling governor\");\n\n}\n\n\n/* Count the number of logical CPU cores. */\n\nstatic void get_core_count(void) {\n\n  u32 cur_runnable = 0;\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)\n\n  size_t s = sizeof(cpu_core_count);\n\n  /* On *BSD systems, we can just use a sysctl to get the number of CPUs. */\n\n#ifdef __APPLE__\n\n  if (sysctlbyname(\"hw.logicalcpu\", &cpu_core_count, &s, NULL, 0) < 0)\n    return;\n\n#else\n\n  int s_name[2] = { CTL_HW, HW_NCPU };\n\n  if (sysctl(s_name, 2, &cpu_core_count, &s, NULL, 0) < 0) return;\n\n#endif /* ^__APPLE__ */\n\n#else\n\n  /* On Linux, a simple way is to look at /proc/stat, especially since we'd\n     be parsing it anyway for other reasons later on. */\n\n  FILE* f = fopen(\"/proc/stat\", \"r\");\n  u8 tmp[1024];\n\n  if (!f) return;\n\n  while (fgets(tmp, sizeof(tmp), f))\n    if (!strncmp(tmp, \"cpu\", 3) && isdigit(tmp[3])) cpu_core_count++;\n\n  fclose(f);\n  \n#endif /* ^(__APPLE__ || __FreeBSD__ || __OpenBSD__) */\n\n  if (cpu_core_count) {\n\n    cur_runnable = (u32)get_runnable_processes();\n\n#if defined(__APPLE__) || defined(__FreeBSD__) || defined (__OpenBSD__)\n\n    /* Add ourselves, since the 1-minute average doesn't include that yet. */\n\n    cur_runnable++;\n\n#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */\n\n    OKF(\"You have %u CPU cores and %u runnable tasks (utilization: %0.0f%%).\",\n        cpu_core_count, cur_runnable, cur_runnable * 100.0 / cpu_core_count);\n\n    if (cpu_core_count > 1) {\n\n      if (cur_runnable > cpu_core_count * 1.5) {\n\n        WARNF(\"System under apparent load, performance may be spotty.\");\n\n      } else if (cur_runnable + 1 <= cpu_core_count) {\n\n        OKF(\"Try parallel jobs - see %s/parallel_fuzzing.txt.\", doc_path);\n  \n      }\n\n    }\n\n  } else WARNF(\"Unable to figure out the number of CPU cores.\");\n\n}\n\n\n/* Validate and fix up out_dir and sync_dir when using -S. */\n\nstatic void fix_up_sync(void) {\n\n  u8* x = sync_id;\n\n  if (dumb_mode)\n    FATAL(\"-S / -M and -n are mutually exclusive\");\n\n  if (skip_deterministic) {\n\n    if (force_deterministic)\n      FATAL(\"use -S instead of -M -d\");\n    else\n      FATAL(\"-S already implies -d\");\n\n  }\n\n  while (*x) {\n\n    if (!isalnum(*x) && *x != '_' && *x != '-')\n      FATAL(\"Non-alphanumeric fuzzer ID specified via -S or -M\");\n\n    x++;\n\n  }\n\n  if (strlen(sync_id) > 32) FATAL(\"Fuzzer ID too long\");\n\n  x = alloc_printf(\"%s/%s\", out_dir, sync_id);\n\n  sync_dir = out_dir;\n  out_dir  = x;\n\n  if (!force_deterministic) {\n    skip_deterministic = 1;\n    use_splicing = 1;\n  }\n\n}\n\n\n/* Handle screen resize (SIGWINCH). */\n\nstatic void handle_resize(int sig) {\n  clear_screen = 1;\n}\n\n\n/* Check ASAN options. */\n\nstatic void check_asan_opts(void) {\n  u8* x = getenv(\"ASAN_OPTIONS\");\n\n  if (x && !strstr(x, \"abort_on_error=1\"))\n    FATAL(\"Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!\");\n\n  x = getenv(\"MSAN_OPTIONS\");\n\n  if (x && !strstr(x, \"exit_code=\" STRINGIFY(MSAN_ERROR)))\n    FATAL(\"Custom MSAN_OPTIONS set without exit_code=\"\n          STRINGIFY(MSAN_ERROR) \" - please fix!\");\n\n} \n\n\n/* Detect @@ in args. */\n\nstatic void detect_file_args(char** argv) {\n\n  u32 i = 0;\n  u8* cwd = getcwd(NULL, 0);\n\n  if (!cwd) PFATAL(\"getcwd() failed\");\n\n  while (argv[i]) {\n\n    u8* aa_loc = strstr(argv[i], \"@@\");\n\n    if (aa_loc) {\n\n      u8 *aa_subst, *n_arg;\n\n      /* If we don't have a file name chosen yet, use a safe default. */\n\n      if (!out_file)\n        out_file = alloc_printf(\"%s/.cur_input\", out_dir);\n\n      /* Be sure that we're always using fully-qualified paths. */\n\n      if (out_file[0] == '/') aa_subst = out_file;\n      else aa_subst = alloc_printf(\"%s/%s\", cwd, out_file);\n\n      /* Construct a replacement argv value. */\n\n      *aa_loc = 0;\n      n_arg = alloc_printf(\"%s%s%s\", argv[i], aa_subst, aa_loc + 2);\n      argv[i] = n_arg;\n      *aa_loc = '@';\n\n      if (out_file[0] != '/') ck_free(aa_subst);\n\n    }\n\n    i++;\n\n  }\n\n  free(cwd); /* not tracked */\n\n}\n\n\n/* Set up signal handlers. More complicated that needs to be, because libc on\n   Solaris doesn't resume interrupted reads(), sets SA_RESETHAND when you call\n   siginterrupt(), and does other stupid things. */\n\nstatic void setup_signal_handlers(void) {\n\n  struct sigaction sa;\n\n  sa.sa_handler   = NULL;\n  sa.sa_flags     = SA_RESTART;\n  sa.sa_sigaction = NULL;\n\n  sigemptyset(&sa.sa_mask);\n\n  /* Various ways of saying \"stop\". */\n\n  sa.sa_handler = handle_stop_sig;\n  sigaction(SIGHUP, &sa, NULL);\n  sigaction(SIGINT, &sa, NULL);\n  sigaction(SIGTERM, &sa, NULL);\n\n  /* Exec timeout notifications. */\n\n  sa.sa_handler = handle_timeout;\n  sigaction(SIGALRM, &sa, NULL);\n\n  /* Window resize */\n\n  sa.sa_handler = handle_resize;\n  sigaction(SIGWINCH, &sa, NULL);\n\n  /* SIGUSR1: skip entry */\n\n  sa.sa_handler = handle_skipreq;\n  sigaction(SIGUSR1, &sa, NULL);\n\n  /* Things we don't care about. */\n\n  sa.sa_handler = SIG_IGN;\n  sigaction(SIGTSTP, &sa, NULL);\n  sigaction(SIGPIPE, &sa, NULL);\n\n}\n\n\n/* Rewrite argv for QEMU. */\n\nstatic char** get_qemu_argv(u8* own_loc, char** argv, int argc) {\n\n  char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));\n  u8 *tmp, *cp, *rsl, *own_copy;\n\n  memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);\n\n  new_argv[2] = target_path;\n  new_argv[1] = \"--\";\n\n  /* Now we need to actually find the QEMU binary to put in argv[0]. */\n\n  tmp = getenv(\"AFL_PATH\");\n\n  if (tmp) {\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", tmp);\n\n    if (access(cp, X_OK))\n      FATAL(\"Unable to find '%s'\", tmp);\n\n    target_path = new_argv[0] = cp;\n    return new_argv;\n\n  }\n\n  own_copy = ck_strdup(own_loc);\n  rsl = strrchr(own_copy, '/');\n\n  if (rsl) {\n\n    *rsl = 0;\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", own_copy);\n    ck_free(own_copy);\n\n    if (!access(cp, X_OK)) {\n\n      target_path = new_argv[0] = cp;\n      return new_argv;\n\n    }\n\n  } else ck_free(own_copy);\n\n  if (!access(BIN_PATH \"/afl-qemu-trace\", X_OK)) {\n\n    target_path = new_argv[0] = ck_strdup(BIN_PATH \"/afl-qemu-trace\");\n    return new_argv;\n\n  }\n\n  SAYF(\"\\n\" cLRD \"[-] \" cRST\n       \"Oops, unable to find the 'afl-qemu-trace' binary. The binary must be built\\n\"\n       \"    separately by following the instructions in qemu_mode/README.qemu. If you\\n\"\n       \"    already have the binary installed, you may need to specify AFL_PATH in the\\n\"\n       \"    environment.\\n\\n\"\n\n       \"    Of course, even without QEMU, afl-fuzz can still work with binaries that are\\n\"\n       \"    instrumented at compile time with afl-gcc. It is also possible to use it as a\\n\"\n       \"    traditional \\\"dumb\\\" fuzzer by specifying '-n' in the command line.\\n\");\n\n  FATAL(\"Failed to locate 'afl-qemu-trace'.\");\n\n}\n\n\n/* Make a copy of the current command line. */\n\nstatic void save_cmdline(u32 argc, char** argv) {\n\n  u32 len = 1, i;\n  u8* buf;\n\n  for (i = 0; i < argc; i++)\n    len += strlen(argv[i]) + 1;\n  \n  buf = orig_cmdline = ck_alloc(len);\n\n  for (i = 0; i < argc; i++) {\n\n    u32 l = strlen(argv[i]);\n\n    memcpy(buf, argv[i], l);\n    buf += l;\n\n    if (i != argc - 1) *(buf++) = ' ';\n\n  }\n\n  *buf = 0;\n\n}\n\n\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 opt;\n  u64 prev_queued = 0;\n  u32 sync_interval_cnt = 0, seek_to;\n  u8  *extras_dir = 0;\n  u8  mem_limit_given = 0;\n\n  char** use_argv;\n\n  SAYF(cCYA \"afl-fuzz \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n  doc_path = access(DOC_PATH, F_OK) ? \"docs\" : DOC_PATH;\n\n  while ((opt = getopt(argc, argv, \"+i:o:f:m:t:T:dnCB:S:M:x:QN:D:L\")) > 0) {\n\n    switch (opt) {\n\n      case 'i':\n\n        if (in_dir) FATAL(\"Multiple -i options not supported\");\n        in_dir = optarg;\n\n        if (!strcmp(in_dir, \"-\")) in_place_resume = 1;\n\n        break;\n\n      case 'o': /* output dir */\n\n        if (out_dir) FATAL(\"Multiple -o options not supported\");\n        out_dir = optarg;\n        break;\n\n      case 'M':\n\n        force_deterministic = 1;\n        /* Fall through */\n\n      case 'S': /* sync ID */\n\n        if (sync_id) FATAL(\"Multiple -S or -M options not supported\");\n        sync_id = optarg;\n        break;\n\n      case 'f': /* target file */\n\n        if (out_file) FATAL(\"Multiple -f options not supported\");\n        out_file = optarg;\n        break;\n\n      case 'x':\n\n        if (extras_dir) FATAL(\"Multiple -x options not supported\");\n        extras_dir = optarg;\n        break;\n\n      case 't': {\n\n          u8 suffix = 0;\n\n          if (timeout_given) FATAL(\"Multiple -t options not supported\");\n\n          if (sscanf(optarg, \"%u%c\", &exec_tmout, &suffix) < 1 ||\n              optarg[0] == '-') FATAL(\"Bad syntax used for -t\");\n\n          if (exec_tmout < 5) FATAL(\"Dangerously low value of -t\");\n\n          if (suffix == '+') timeout_given = 2; else timeout_given = 1;\n\n          break;\n\n      }\n\n      case 'm': {\n\n          u8 suffix = 'M';\n\n          if (mem_limit_given) FATAL(\"Multiple -m options not supported\");\n          mem_limit_given = 1;\n\n          if (!strcmp(optarg, \"none\")) {\n\n            mem_limit = 0;\n            break;\n\n          }\n\n          if (sscanf(optarg, \"%llu%c\", &mem_limit, &suffix) < 1 ||\n              optarg[0] == '-') FATAL(\"Bad syntax used for -m\");\n\n          switch (suffix) {\n\n            case 'T': mem_limit *= 1024 * 1024; break;\n            case 'G': mem_limit *= 1024; break;\n            case 'k': mem_limit /= 1024; break;\n            case 'M': break;\n\n            default:  FATAL(\"Unsupported suffix or bad syntax for -m\");\n\n          }\n\n          if (mem_limit < 5) FATAL(\"Dangerously low value of -m\");\n\n          if (sizeof(rlim_t) == 4 && mem_limit > 2000)\n            FATAL(\"Value of -m out of range on 32-bit systems\");\n\n        }\n\n        break;\n\n      case 'd':\n\n        if (skip_deterministic) FATAL(\"Multiple -d options not supported\");\n        skip_deterministic = 1;\n        use_splicing = 1;\n        break;\n\n      case 'B':\n\n        /* This is a secret undocumented option! It is useful if you find\n           an interesting test case during a normal fuzzing process, and want\n           to mutate it without rediscovering any of the test cases already\n           found during an earlier run.\n\n           To use this mode, you need to point -B to the fuzz_bitmap produced\n           by an earlier run for the exact same binary... and that's it.\n\n           I only used this once or twice to get variants of a particular\n           file, so I'm not making this an official setting. */\n\n        if (in_bitmap) FATAL(\"Multiple -B options not supported\");\n\n        in_bitmap = optarg;\n        read_bitmap(in_bitmap);\n        break;\n\n      case 'C':\n\n        if (crash_mode) FATAL(\"Multiple -C options not supported\");\n        crash_mode = FAULT_CRASH;\n        break;\n\n      case 'n':\n\n        if (dumb_mode) FATAL(\"Multiple -n options not supported\");\n        if (getenv(\"AFL_DUMB_FORKSRV\")) dumb_mode = 2; else dumb_mode = 1;\n\n        break;\n\n      case 'T':\n\n        if (use_banner) FATAL(\"Multiple -T options not supported\");\n        use_banner = optarg;\n        break;\n\n      case 'Q':\n\n        if (qemu_mode) FATAL(\"Multiple -Q options not supported\");\n        qemu_mode = 1;\n\n        if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;\n\n        break;\n\n      case 'N':\n\n        /* -N{network-path} : inject data to target via network connection\n         * \n         * The network-path has the form \"type://path:port\" where\n         * \n         * type is one of \"udp\", or \"tcp\",\n         * path is a host name or IP address (IPv4 or IPv6), and\n         * port is a port number or service name.\n         * \n         * for the moment, make a copy of the -N option string and\n         * indicate that the -N option has been specified\n         * \n         */\n\n        if (N_option_specified) FATAL(\"multiple -N options not allowed\");\n        N_slen = strlen(optarg);\n        if (N_slen > 0) {\n          N_option_string = (u8*)ck_alloc(N_slen+1);\n          strcpy(N_option_string,optarg);\n          N_option_specified = 1;\n        } else {\n          FATAL(\"-N: missing argument\");\n        }\n        break;\n\n      case 'D':\n        \n        if (N_timeout_given) FATAL(\"Multiple -D options not supported\");\n        if (sscanf(optarg, \"%u\", &N_exec_tmout) < 1 ||\n                optarg[0] == '-') FATAL(\"Bad syntax used for -D\");\n        N_timeout_given = 1;\n        break;\n\n      case 'L':\n        \n        if (N_fuzz_client) FATAL(\"Multiple -L options not supported\");\n        N_fuzz_client = 1;\n        break;\n        \n      default:\n\n        usage(argv[0]);\n\n    }\n  }\n\n  /* check for consistent use of network options (-N, -D, and -L) */\n  if (N_fuzz_client && !N_option_specified)\n    FATAL(\"-L (network client) option requires -N (network) option\");\n  if (N_timeout_given && !N_option_specified)\n    FATAL(\"-D option can not be used without -N option\");\n  \n  /* process network option(s), creating and configuring socket */\n  if (N_option_specified) {\n    \n    /* local variables (not needed later):      */\n    struct addrinfo N_hints; /* used for getaddrinfo() call */\n    /* These are all pointers used to process the -N network-path        */\n    u8  *N_found1 = 0,\n        *N_found2 = 0,\n        *N_pchar,\n        *N_type;\n    u8  *N_servicename = 0, /* ptr to start of servicename */\n        *N_hostspec = 0; /* ptr to start of hostname    */\n    \n    /* prepare (zero) addrinfo structure used for hints to getaddrinfo()*/\n    memset(&N_hints, 0, sizeof (struct addrinfo));\n    \n    /* process the -N option string -- two cases depending on N_fuzz_client */\n    if (N_fuzz_client) {\n      /* this is the case where afl-fuzz listens for the target to either\n       * connect and write (TCP) to afl-fuzz's socket or create a socket\n       * and send to (UDP) the afl-fuzz socket. */\n      N_found1 = strpbrk(N_option_string, \"://\");\n      if (!N_found1) {\n        FATAL(\"-N: invalid specification\");\n      } else {\n        if (*N_found1 != ':')\n          FATAL(\"-N: first char after type must be ':'\");\n        N_type = N_option_string;\n        *N_found1 = 0;\n        N_pchar = N_type;\n        while (*N_pchar != 0) {\n          *N_pchar = tolower(*N_pchar);\n          ++N_pchar;\n        }\n        if (strcmp(N_type, \"tcp\") == 0) {\n          N_hints.ai_flags = (AI_PASSIVE);\n          N_hints.ai_family = AF_UNSPEC;\n          N_hints.ai_socktype = SOCK_STREAM;\n        } else if (strcmp(N_type, \"udp\") == 0) {\n          N_hints.ai_flags = (AI_PASSIVE /* | AI_NUMERICSERV */); //COMMENTED OUT\n          N_hints.ai_family = AF_UNSPEC;\n          N_hints.ai_socktype = SOCK_DGRAM;\n        } else {\n          FATAL(\"-N: invalid type\");\n        }\n      }\n\n      if ((N_found1 - N_option_string) >= N_slen)\n        FATAL(\"-N: incomplete specification\");\n\n      /* find the port number */\n      N_found2 = strrchr(N_found1 + 1, ':');\n      if (!N_found2) {\n        FATAL(\"-N: TCP and UDP operation require a port number\");\n      } else {\n        *N_found2 = 0;\n        if (*(N_found2 + 1) == 0) {\n          FATAL(\"-N: no port number or service name specified\");\n        } else {\n          N_servicename = N_found2 + 1;\n        }\n      }\n\n      if ((strncmp(N_found1 + 1, \"//\", 2)) != 0) {\n        FATAL(\"-N: invalid network specification - malformed \\\"://\\\"\");\n      } else {\n        *N_found1 = 0;\n        N_hostspec = N_found1 + 3;\n      }\n      if (!(\n              (strcmp(\"localhost\", N_hostspec) == 0)\n              || (strcmp(\"::1\", N_hostspec) == 0)\n              || (strcmp(\"127.0.0.1\", N_hostspec) == 0)\n              )\n              ) FATAL(\"-N: only hosts allowed are localhost, ::1, and 127.0.0.1\");\n\n      if (strcmp(\"localhost\",N_hostspec) == 0) {\n        N_hints.ai_family = AF_UNSPEC;\n      } else if (strcmp(\"::1\",N_hostspec) == 0) {\n        N_hints.ai_family = AF_INET6;\n      } else {\n        N_hints.ai_family = AF_INET;\n      }\n      if (getaddrinfo(N_hostspec, N_servicename, &N_hints, &N_results) != 0) {\n        FATAL(\"-N: getaddrinfo() lookup failed\");\n      } else {\n        N_valid = 1;\n      }\n    } else {\n      /* This is the case where afl-fuzz either connects to the target\n       * and writes (TCP) or creates a socket and sends to the target (UDP). */\n      N_found1 = strpbrk(N_option_string, \"://\");\n      if (!N_found1) {\n        FATAL(\"-N: invalid specification\");\n      } else {\n        if (*N_found1 != ':')\n          FATAL(\"-N: first char after type must be ':'\");\n        N_type = N_option_string;\n        *N_found1 = 0;\n        N_pchar = N_type;\n        while (*N_pchar != 0) {\n          *N_pchar = tolower(*N_pchar);\n          ++N_pchar;\n        }\n        if (strcmp(N_type, \"tcp\") == 0) {\n          N_hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);\n          N_hints.ai_family = AF_UNSPEC;\n          N_hints.ai_socktype = SOCK_STREAM;\n        } else if (strcmp(N_type, \"udp\") == 0) {\n          N_hints.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);\n          N_hints.ai_family = AF_UNSPEC;\n          N_hints.ai_socktype = SOCK_DGRAM;\n        } else {\n          FATAL(\"-N: invalid type\");\n        }\n      }\n\n      if ((N_found1 - N_option_string) >= N_slen)\n        FATAL(\"-N: incomplete specification\");\n\n      if (N_hints.ai_family == AF_UNSPEC) { //redundant - for future use\n        /* TCP and UDP operation require a port number */\n        N_found2 = strrchr(N_found1 + 1, ':');\n        if (!N_found2) {\n          FATAL(\"-N: TCP and UDP operation require a port number\");\n        } else {\n          *N_found2 = 0;\n          if (*(N_found2 + 1) == 0) {\n            FATAL(\"-N: no port number or service name specified\");\n          } else {\n            N_servicename = N_found2 + 1;\n          }\n        }\n      }\n\n      if ((strncmp(N_found1 + 1, \"//\", 2)) != 0) {\n        FATAL(\"-N: invalid network specification - malformed \\\"://\\\"\");\n      } else {\n        *N_found1 = 0;\n        N_hostspec = N_found1 + 3;\n      }\n      if (!(\n              (strcmp(\"localhost\", N_hostspec) == 0)\n              || (strcmp(\"::1\", N_hostspec) == 0)\n              || (strcmp(\"127.0.0.1\", N_hostspec) == 0)\n              )\n              ) FATAL(\"-N: only hosts allowed are localhost, ::1, and 127.0.0.1\");\n\n      if (N_hints.ai_family == AF_UNSPEC) {\n        if (getaddrinfo(N_hostspec, N_servicename, &N_hints, &N_results) != 0) {\n          FATAL(  \"-N: getaddrinfo() lookup failed\");\n        } else {\n          N_valid = 1;\n        }\n      }\n    }\n  }\n\n  //  exit(0); //TESTING\n    \n  if (optind == argc || !in_dir || !out_dir) usage(argv[0]);\n\n  setup_signal_handlers();\n  check_asan_opts();\n\n  if (sync_id) fix_up_sync();\n\n  if (!strcmp(in_dir, out_dir))\n    FATAL(\"Input and output directories can't be the same\");\n\n  if (dumb_mode) {\n\n    if (crash_mode) FATAL(\"-C and -n are mutually exclusive\");\n    if (qemu_mode)  FATAL(\"-Q and -n are mutually exclusive\");\n\n  }\n\n  if (getenv(\"AFL_NO_FORKSRV\"))   no_forkserver    = 1;\n  if (getenv(\"AFL_NO_CPU_RED\"))   no_cpu_meter_red = 1;\n  if (getenv(\"AFL_NO_VAR_CHECK\")) no_var_check     = 1;\n\n  if (dumb_mode == 2 && no_forkserver)\n    FATAL(\"AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive\");\n\n  save_cmdline(argc, argv);\n\n  fix_up_banner(argv[optind]);\n\n  check_if_tty();\n\n  get_core_count();\n  check_crash_handling();\n  check_cpu_governor();\n\n  setup_post();\n  setup_shm();\n\n  setup_dirs_fds();\n  read_testcases();\n  load_auto();\n\n  pivot_inputs();\n\n  if (extras_dir) load_extras(extras_dir);\n\n  if (!timeout_given) find_timeout();\n\n  detect_file_args(argv + optind + 1);\n\n  if (!out_file) setup_stdio_file();\n\n  check_binary(argv[optind]);\n\n  start_time = get_cur_time();\n\n  if (qemu_mode)\n    use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);\n  else\n    use_argv = argv + optind;\n\n  perform_dry_run(use_argv);\n\n  cull_queue();\n\n  show_init_stats();\n\n  seek_to = find_start_position();\n\n  write_stats_file(0, 0);\n  save_auto();\n\n  if (stop_soon) goto stop_fuzzing;\n\n  /* Woop woop woop */\n\n  if (!not_on_tty) {\n    sleep(4);\n    start_time += 4000;\n    if (stop_soon) goto stop_fuzzing;\n  }\n\n  while (1) {\n\n    u8 skipped_fuzz;\n\n    cull_queue();\n\n    if (!queue_cur) {\n\n      queue_cycle++;\n      current_entry     = 0;\n      cur_skipped_paths = 0;\n      queue_cur         = queue;\n\n      while (seek_to) {\n        current_entry++;\n        seek_to--;\n        queue_cur = queue_cur->next;\n      }\n\n      show_stats();\n\n      if (not_on_tty) {\n        ACTF(\"Entering queue cycle %llu.\", queue_cycle);\n        fflush(stdout);\n      }\n\n      /* If we had a full queue cycle with no new finds, try\n         recombination strategies next. */\n\n      if (queued_paths == prev_queued) {\n\n        if (use_splicing) cycles_wo_finds++; else use_splicing = 1;\n\n      } else cycles_wo_finds = 0;\n\n      prev_queued = queued_paths;\n\n      if (sync_id && queue_cycle == 1 && getenv(\"AFL_IMPORT_FIRST\"))\n        sync_fuzzers(use_argv);\n\n    }\n\n    skipped_fuzz = fuzz_one(use_argv);\n\n    if (!stop_soon && sync_id && !skipped_fuzz) {\n      \n      if (!(sync_interval_cnt++ % SYNC_INTERVAL))\n        sync_fuzzers(use_argv);\n\n    }\n\n    if (stop_soon) break;\n\n    queue_cur = queue_cur->next;\n    current_entry++;\n\n  }\n\n  if (queue_cur) show_stats();\n\n  write_bitmap();\n  write_stats_file(0, 0);\n  save_auto();\n\nstop_fuzzing:\n\n  SAYF(CURSOR_SHOW cLRD \"\\n\\n+++ Testing %s +++\\n\" cRST,\n       stop_soon == 2 ? \"ended via AFL_EXIT_WHEN_DONE\" : \"aborted by user\");\n\n  /* Running for more than 30 minutes but still doing first cycle? */\n\n  if (queue_cycle == 1 && get_cur_time() - start_time > 30 * 60 * 1000) {\n\n    SAYF(\"\\n\" cYEL \"[!] \" cRST\n           \"Stopped during the first cycle, results may be incomplete.\\n\"\n           \"    (For info on resuming, see %s/README.)\\n\", doc_path);\n\n  }\n\n  fclose(plot_file);\n  destroy_queue();\n  destroy_extras();\n  ck_free(target_path);\n\n  alloc_report();\n\n  OKF(\"We're done here. Have a nice day!\\n\");\n\n  exit(0);\n\n}\n"
  },
  {
    "path": "afl-gcc.c",
    "content": "/*\n   american fuzzy lop - wrapper for GCC and clang\n   ----------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This program is a drop-in replacement for GCC or clang. The most common way\n   of using it is to pass the path to afl-gcc or afl-clang via CC when invoking\n   ./configure.\n\n   (Of course, use CXX and point it to afl-g++ / afl-clang++ for C++ code.)\n\n   The wrapper needs to know the path to afl-as (renamed to 'as'). The default\n   is /usr/local/lib/afl/. A convenient way to specify alternative directories\n   would be to set AFL_PATH.\n\n   If AFL_HARDEN is set, the wrapper will compile the target app with various\n   hardening options that may help detect memory management issues more\n   reliably. You can also specify AFL_USE_ASAN to enable ASAN.\n\n   If you want to call a non-default compiler as a next step of the chain,\n   specify its location via AFL_CC or AFL_CXX.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n\nstatic u8*  as_path;                /* Path to the AFL 'as' wrapper      */\nstatic u8** cc_params;              /* Parameters passed to the real CC  */\nstatic u32  cc_par_cnt = 1;         /* Param count, including argv0      */\nstatic u8   be_quiet,               /* Quiet mode                        */\n            clang_mode;             /* Invoked as afl-clang*?            */\n\n\n/* Try to find our \"fake\" GNU assembler in AFL_PATH or at the location derived\n   from argv[0]. If that fails, abort. */\n\nstatic void find_as(u8* argv0) {\n\n  u8 *afl_path = getenv(\"AFL_PATH\");\n  u8 *slash, *tmp;\n\n  if (afl_path) {\n\n    tmp = alloc_printf(\"%s/as\", afl_path);\n\n    if (!access(tmp, X_OK)) {\n      as_path = afl_path;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n\n  }\n\n  slash = strrchr(argv0, '/');\n\n  if (slash) {\n\n    u8 *dir;\n\n    *slash = 0;\n    dir = ck_strdup(argv0);\n    *slash = '/';\n\n    tmp = alloc_printf(\"%s/afl-as\", dir);\n\n    if (!access(tmp, X_OK)) {\n      as_path = dir;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n    ck_free(dir);\n\n  }\n\n  if (!access(AFL_PATH \"/as\", X_OK)) {\n    as_path = AFL_PATH;\n    return;\n  }\n\n  FATAL(\"Unable to find AFL wrapper binary for 'as'. Please set AFL_PATH\");\n \n}\n\n\n/* Copy argv to cc_params, making the necessary edits. */\n\nstatic void edit_params(u32 argc, char** argv) {\n\n  u8 fortify_set = 0, asan_set = 0;\n  u8 *name;\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n  u8 m32_set = 0;\n#endif\n\n  cc_params = ck_alloc((argc + 16) * sizeof(u8*));\n\n  name = strrchr(argv[0], '/');\n  if (!name) name = argv[0]; else name++;\n\n  if (!strncmp(name, \"afl-clang\", 9)) {\n\n    clang_mode = 1;\n\n    setenv(CLANG_ENV_VAR, \"1\", 1);\n\n    if (!strcmp(name, \"afl-clang++\")) {\n      u8* alt_cxx = getenv(\"AFL_CXX\");\n      cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"clang++\";\n    } else {\n      u8* alt_cc = getenv(\"AFL_CC\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"clang\";\n    }\n\n  } else {\n\n    /* With GCJ and Eclipse installed, you can actually compile Java! The\n       instrumentation will work (amazingly). Alas, unhandled exceptions do\n       not call abort(), so afl-fuzz would need to be modified to equate\n       non-zero exit codes with crash conditions when working with Java\n       binaries. Meh. */\n\n#ifdef __APPLE__\n\n    if (!strcmp(name, \"afl-g++\")) cc_params[0] = getenv(\"AFL_CXX\");\n    else if (!strcmp(name, \"afl-gcj\")) cc_params[0] = getenv(\"AFL_GCJ\");\n    else cc_params[0] = getenv(\"AFL_CC\");\n\n    if (!cc_params[0]) {\n\n      SAYF(\"\\n\" cLRD \"[-] \" cRST\n           \"On Apple systems, 'gcc' is usually just a wrapper for clang. Please use the\\n\"\n           \"    'afl-clang' utility instead of 'afl-gcc'. If you really have GCC installed,\\n\"\n           \"    set AFL_CC or AFL_CXX to specify the correct path to that compiler.\\n\");\n\n      FATAL(\"AFL_CC or AFL_CXX required on MacOS X\");\n\n    }\n\n#else\n\n    if (!strcmp(name, \"afl-g++\")) {\n      u8* alt_cxx = getenv(\"AFL_CXX\");\n      cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"g++\";\n    } else if (!strcmp(name, \"afl-gcj\")) {\n      u8* alt_cc = getenv(\"AFL_GCJ\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"gcj\";\n    } else {\n      u8* alt_cc = getenv(\"AFL_CC\");\n      cc_params[0] = alt_cc ? alt_cc : (u8*)\"gcc\";\n    }\n\n#endif /* __APPLE__ */\n\n  }\n\n  while (--argc) {\n    u8* cur = *(++argv);\n\n    if (!strncmp(cur, \"-B\", 2)) {\n\n      if (!be_quiet) WARNF(\"-B is already set, overriding\");\n\n      if (!cur[2] && argc > 1) { argc--; argv++; }\n      continue;\n\n    }\n\n    if (!strcmp(cur, \"-integrated-as\")) continue;\n\n    if (!strcmp(cur, \"-pipe\")) continue;\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n    if (!strcmp(cur, \"-m32\")) m32_set = 1;\n#endif\n\n    if (!strcmp(cur, \"-fsanitize=address\") ||\n        !strcmp(cur, \"-fsanitize=memory\")) asan_set = 1;\n\n    if (strstr(cur, \"FORTIFY_SOURCE\")) fortify_set = 1;\n\n    cc_params[cc_par_cnt++] = cur;\n\n  }\n\n  cc_params[cc_par_cnt++] = \"-B\";\n  cc_params[cc_par_cnt++] = as_path;\n\n  if (clang_mode)\n    cc_params[cc_par_cnt++] = \"-no-integrated-as\";\n\n  if (getenv(\"AFL_HARDEN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fstack-protector-all\";\n\n    if (!fortify_set)\n      cc_params[cc_par_cnt++] = \"-D_FORTIFY_SOURCE=2\";\n\n  }\n\n  if (asan_set) {\n\n    /* Pass this on to afl-as to adjust map density. */\n\n    setenv(\"AFL_USE_ASAN\", \"1\", 1);\n\n  } else if (getenv(\"AFL_USE_ASAN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fsanitize=address\";\n\n    if (getenv(\"AFL_USE_MSAN\"))\n      FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n  } else if (getenv(\"AFL_USE_MSAN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fsanitize=memory\";\n\n    if (getenv(\"AFL_USE_ASAN\"))\n      FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n  }\n\n  if (!getenv(\"AFL_DONT_OPTIMIZE\")) {\n\n#if defined(__FreeBSD__) && defined(__x86_64__)\n\n    /* On 64-bit FreeBSD systems, clang -g -m32 is broken, but -m32 itself\n       works OK. This has nothing to do with us, but let's avoid triggering\n       that bug. */\n\n    if (!clang_mode || !m32_set)\n      cc_params[cc_par_cnt++] = \"-g\";\n\n#else\n\n      cc_params[cc_par_cnt++] = \"-g\";\n\n#endif\n\n    cc_params[cc_par_cnt++] = \"-O3\";\n    cc_params[cc_par_cnt++] = \"-funroll-loops\";\n\n  }\n\n  cc_params[cc_par_cnt] = NULL;\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-cc \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n  } else be_quiet = 1;\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It serves as a drop-in replacement\\n\"\n         \"for gcc or clang, letting you recompile third-party code with the required\\n\"\n         \"runtime instrumentation. A common use pattern would be one of the following:\\n\\n\"\n\n         \"  CC=%s/afl-gcc ./configure\\n\"\n         \"  CXX=%s/afl-g++ ./configure\\n\\n\"\n\n         \"You can specify custom next-stage toolchain via AFL_CC, AFL_CXX, and AFL_AS.\\n\"\n         \"Setting AFL_HARDEN enables hardening optimizations in the compiled code.\\n\\n\",\n         BIN_PATH, BIN_PATH);\n\n    exit(1);\n\n  }\n\n\n  find_as(argv[0]);\n\n  edit_params(argc, argv);\n\n  execvp(cc_params[0], (char**)cc_params);\n\n  FATAL(\"Oops, failed to execute '%s' - check your PATH\", cc_params[0]);\n\n  return 0;\n\n}\n"
  },
  {
    "path": "afl-gotcpu.c",
    "content": "/*\n   american fuzzy lop - free CPU gizmo\n   -----------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This tool provides a fairly accurate measurement of CPU preemption rate.\n   It is meant to complement the quick-and-dirty load average widget shown\n   in the afl-fuzz UI. See docs/parallel_fuzzing.txt for more info.\n\n   For some work loads, the tool may actually suggest running more instances\n   than you have CPU cores. This can happen if the tested program is spending\n   a portion of its run time waiting for I/O, rather than being 100%\n   CPU-bound.\n\n   The idea for the getrusage()-based approach comes from Jakub Wilk.\n\n */\n\n#define AFL_MAIN\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sched.h>\n\n#include <sys/time.h>\n#include <sys/times.h>\n#include <sys/resource.h>\n\n#include \"types.h\"\n#include \"debug.h\"\n\n\n/* Get unix time in microseconds. */\n\nstatic u64 get_cur_time_us(void) {\n\n  struct timeval tv;\n  struct timezone tz;\n\n  gettimeofday(&tv, &tz);\n\n  return (tv.tv_sec * 1000000ULL) + tv.tv_usec;\n\n}\n\n\n/* Get CPU usage in microseconds. */\n\nstatic u64 get_cpu_usage_us(void) {\n\n  struct rusage u;\n\n  getrusage(RUSAGE_SELF, &u);\n\n  return (u.ru_utime.tv_sec * 1000000ULL) + u.ru_utime.tv_usec +\n         (u.ru_stime.tv_sec * 1000000ULL) + u.ru_stime.tv_usec;\n\n}\n\n\n/* Do the benchmark thing. */\n\nint main(int argc, char** argv) {\n\n  static volatile u32 v1, v2;\n\n  s32 loop_repeats = 0, util_perc;\n  u64 st_t, en_t, st_c, en_c, real_delta, slice_delta;\n\n  SAYF(cCYA \"afl-gotcpu \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n  /* Run a busy loop for CTEST_TARGET_MS. */\n\n  ACTF(\"Measuring preemption rate (this will take %0.02f sec)...\",\n       ((double)CTEST_TARGET_MS) / 1000);\n\n  st_t = get_cur_time_us();\n  st_c = get_cpu_usage_us();\n\nrepeat_loop:\n\n  v1 = CTEST_BUSY_CYCLES;\n\n  while (v1--) v2++;\n  sched_yield();\n\n  en_t = get_cur_time_us();\n\n  if (en_t - st_t < CTEST_TARGET_MS * 1000) {\n    loop_repeats++;\n    goto repeat_loop;\n  }\n\n  /* Let's see what percentage of this time we actually had a chance to\n     run, and how much time was spent in the penalty box. */\n\n  en_c = get_cpu_usage_us();\n\n  real_delta  = (en_t - st_t) / 1000;\n  slice_delta = (en_c - st_c) / 1000;\n\n  OKF(\"Busy loop hit %u times, real = %llu ms, slice = %llu ms.\",\n      loop_repeats, real_delta, slice_delta);\n\n  util_perc = real_delta * 100 / slice_delta;\n\n  /* Deliver the final verdict. */\n\n  SAYF(cGRA \"\\n>>> \");\n\n  if (util_perc < 105) {\n\n    SAYF(cLGN \"PASS: \" cRST \"You can probably run additional processes.\");\n\n  } else if (util_perc < 130) {\n\n    SAYF(cYEL \"CAUTION: \" cRST \"Your CPU may be somewhat overbooked (%u%%).\",\n         util_perc);\n\n  } else {\n\n    SAYF(cLRD \"FAIL: \" cRST \"Your CPU is overbooked (%u%%).\", util_perc);\n\n  }\n\n  SAYF(cGRA \" <<<\" cRST \"\\n\\n\");\n\n  return (util_perc > 105) + (util_perc > 130);\n\n}\n"
  },
  {
    "path": "afl-plot",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - Advanced Persistent Graphing\n# -------------------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n# Based on a design & prototype by Michael Rash.\n#\n# Copyright 2014, 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n\necho \"progress plotting utility for afl-fuzz by <lcamtuf@google.com>\"\necho\n\nif [ ! \"$#\" = \"2\" ]; then\n\n  cat 1>&2 <<_EOF_\nThis program generates gnuplot images from afl-fuzz output data. Usage:\n\n$0 afl_state_dir graph_output_dir\n\nThe afl_state_dir parameter should point to an existing state directory for any\nactive or stopped instance of afl-fuzz; while graph_output_dir should point to\nan empty directory where this tool can write the resulting plots to.\n\nThe program will put index.html and three PNG images in the output directory;\nyou should be able to view it with any web browser of your choice.\n\n_EOF_\n\n  exit 1\n\nfi\n\necho \"$1\" | grep -qE '^(/var)?/tmp/'\nT1=\"$?\"\n\necho \"$2\" | grep -qE '^(/var)?/tmp/'\nT2=\"$?\"\n\nif [ \"$T1\" = \"0\" -o \"$T2\" = \"0\" ]; then\n\n  echo \"[-] Error: this script shouldn't be used with shared /tmp directories.\" 1>&2\n  exit 1\n\nfi\n\nif [ ! -f \"$1/plot_data\" ]; then\n\n  echo \"[-] Error: input directory is not valid (missing 'plot_data').\" 1>&2\n  exit 1\n\nfi\n\nBANNER=\"`cat \"$1/fuzzer_stats\" | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`\"\n\ntest \"$BANNER\" = \"\" && BANNER=\"(none)\"\n\nGNUPLOT=`which gnuplot 2>/dev/null`\n\nif [ \"$GNUPLOT\" = \"\" ]; then\n\n  echo \"[-] Error: can't find 'gnuplot' in your \\$PATH.\" 1>&2\n  exit 1\n\nfi\n\nmkdir \"$2\" 2>/dev/null\n\nif [ ! -d \"$2\" ]; then\n\n  echo \"[-] Error: unable to create the output directory - pick another location.\" 1>&2\n  exit 1\n\nfi\n\nrm -f \"$2/high_freq.png\" \"$2/low_freq.png\" \"$2/exec_speed.png\"\nmv -f \"$2/index.html\" \"$2/index.html.orig\" 2>/dev/null\n\necho \"[*] Generating plots...\"\n\n(\n\ncat <<_EOF_\nset terminal png truecolor enhanced size 1000,300 butt\n\nset output '$2/high_freq.png'\n\nset xdata time\nset timefmt '%s'\nset format x \"%b %d\\n%H:%M\"\nset tics font 'small'\nunset mxtics\nunset mytics\n\nset grid xtics linetype 0 linecolor rgb '#e0e0e0'\nset grid ytics linetype 0 linecolor rgb '#e0e0e0'\nset border linecolor rgb '#50c0f0'\nset tics textcolor rgb '#000000'\nset key outside\n\nset autoscale xfixmin\nset autoscale xfixmax\n\nplot '$1/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\\\\n     '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\\\\n     '' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\\\\n     '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\\\\n     '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3\n\nset terminal png truecolor enhanced size 1000,200 butt\nset output '$2/low_freq.png'\n\nplot '$1/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\\\\n     '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\\\\n     '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\\\\n     '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3\n\nset terminal png truecolor enhanced size 1000,200 butt\nset output '$2/exec_speed.png'\n\nplot '$1/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\\\\n     '$1/plot_data' using 1:11 with lines title '    execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier;\n\n_EOF_\n\n) | gnuplot \n\nif [ ! -s \"$2/exec_speed.png\" ]; then\n\n  echo \"[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?\" 1>&2\n  exit 1\n\nfi\n\necho \"[*] Generating index.html...\"\n\ncat >\"$2/index.html\" <<_EOF_\n<table style=\"font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'\">\n<tr><td style=\"width: 18ex\"><b>Banner:</b></td><td>$BANNER</td></tr>\n<tr><td><b>Directory:</b></td><td>$1</td></tr>\n<tr><td><b>Generated on:</b></td><td>`date`</td></tr>\n</table>\n<p>\n<img src=\"high_freq.png\" width=1000 height=300><p>\n<img src=\"low_freq.png\" width=1000 height=200><p>\n<img src=\"exec_speed.png\" width=1000 height=200>\n\n_EOF_\n\n# Make it easy to remotely view results when outputting directly to a directory\n# served by Apache or other HTTP daemon. Since the plots aren't horribly\n# sensitive, this seems like a reasonable trade-off.\n\nchmod 755 \"$2\"\nchmod 644 \"$2/high_freq.png\" \"$2/low_freq.png\" \"$2/exec_speed.png\" \"$2/index.html\"\n\necho \"[+] All done - enjoy your charts!\"\n\nexit 0\n"
  },
  {
    "path": "afl-showmap.c",
    "content": "/*\n   american fuzzy lop - map display utility\n   ----------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   A very simple tool that runs the targeted binary and displays\n   the contents of the trace bitmap in a human-readable form. Useful in\n   scripts to eliminate redundant inputs and perform other checks.\n\n   Exit code is 2 if the target program crashes; 1 if it times out or\n   there is a problem executing it; or 0 if execution is successful.\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n#include \"hash.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <signal.h>\n#include <dirent.h>\n#include <fcntl.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n#include <sys/shm.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n\nstatic s32 child_pid;                 /* PID of the tested program         */\n\nstatic u8* trace_bits;                /* SHM with instrumentation bitmap   */\n\nstatic u8 *out_file,                  /* Trace output file                 */\n          *doc_path,                  /* Path to docs                      */\n          *target_path,               /* Path to target binary             */\n          *at_file;                   /* Substitution string for @@        */\n\nstatic u32 exec_tmout;                /* Exec timeout (ms)                 */\n\nstatic u64 mem_limit = MEM_LIMIT;     /* Memory limit (MB)                 */\n\nstatic s32 shm_id;                    /* ID of the SHM region              */\n\nstatic u8  quiet_mode,                /* Hide non-essential messages?      */\n           edges_only,                /* Ignore hit counts?                */\n           cmin_mode;                 /* Generate output in afl-cmin mode? */\n\nstatic volatile u8\n           stop_soon,                 /* Ctrl-C pressed?                   */\n           child_timed_out,           /* Child timed out?                  */\n           child_crashed;             /* Child crashed?                    */\n\n/* Classify tuple counts. Instead of mapping to individual bits, as in\n   afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */\n\n#define AREP4(_sym)   (_sym), (_sym), (_sym), (_sym)\n#define AREP8(_sym)   AREP4(_sym),  AREP4(_sym)\n#define AREP16(_sym)  AREP8(_sym),  AREP8(_sym)\n#define AREP32(_sym)  AREP16(_sym), AREP16(_sym)\n#define AREP64(_sym)  AREP32(_sym), AREP32(_sym)\n#define AREP128(_sym) AREP64(_sym), AREP64(_sym)\n\nstatic u8 count_class_lookup[256] = {\n\n  /* 0 - 3:       4 */ 0, 1, 2, 3,\n  /* 4 - 7:      +4 */ AREP4(4),\n  /* 8 - 15:     +8 */ AREP8(5),\n  /* 16 - 31:   +16 */ AREP16(6),\n  /* 32 - 127:  +96 */ AREP64(7), AREP32(7),\n  /* 128+:     +128 */ AREP128(8)\n\n};\n\nstatic void classify_counts(u8* mem) {\n\n  u32 i = MAP_SIZE;\n\n  if (edges_only) {\n\n    while (i--) {\n      if (*mem) *mem = 1;\n      mem++;\n    }\n\n  } else {\n\n    while (i--) {\n      *mem = count_class_lookup[*mem];\n      mem++;\n    }\n\n  }\n\n}\n\n\n/* Get rid of shared memory (atexit handler). */\n\nstatic void remove_shm(void) {\n\n  shmctl(shm_id, IPC_RMID, NULL);\n\n}\n\n\n/* Configure shared memory. */\n\nstatic void setup_shm(void) {\n\n  u8* shm_str;\n\n  shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);\n\n  if (shm_id < 0) PFATAL(\"shmget() failed\");\n\n  atexit(remove_shm);\n\n  shm_str = alloc_printf(\"%d\", shm_id);\n\n  setenv(SHM_ENV_VAR, shm_str, 1);\n\n  ck_free(shm_str);\n\n  trace_bits = shmat(shm_id, NULL, 0);\n  \n  if (!trace_bits) PFATAL(\"shmat() failed\");\n\n}\n\n/* Write results. */\n\nstatic u32 write_results(void) {\n\n  s32 fd;\n  FILE* f;\n  u32 i, ret = 0;\n  u8  cco = !!getenv(\"AFL_CMIN_CRASHES_ONLY\"),\n      caa = !!getenv(\"AFL_CMIN_ALLOW_ANY\");\n\n  if (!strncmp(out_file,\"/dev/\", 5)) {\n\n    fd = open(out_file, O_WRONLY, 0600);\n    if (fd < 0) PFATAL(\"Unable to open '%s'\", out_file);\n\n  } else {\n\n    unlink(out_file); /* Ignore errors */\n    fd = open(out_file, O_WRONLY | O_CREAT | O_EXCL, 0600);\n    if (fd < 0) PFATAL(\"Unable to create '%s'\", out_file);\n\n  }\n\n  f = fdopen(fd, \"w\");\n\n  if (!f) PFATAL(\"fdopen() failed\");\n\n  for (i = 0; i < MAP_SIZE; i++) {\n\n    if (!trace_bits[i]) continue;\n    ret++;\n\n    if (cmin_mode) {\n\n      if (child_timed_out) break;\n      if (!caa && child_crashed != cco) break;\n\n      fprintf(f, \"%u%u\\n\", trace_bits[i], i);\n\n    } else fprintf(f, \"%06u:%u\\n\", i, trace_bits[i]);\n\n  }\n  \n  fclose(f);\n\n  return ret;\n\n}\n\n\n/* Handle timeout signal. */\n\nstatic void handle_timeout(int sig) {\n\n  child_timed_out = 1;\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Execute target application. */\n\nstatic void run_target(char** argv) {\n\n  static struct itimerval it;\n  int status = 0;\n\n  if (!quiet_mode)\n    SAYF(\"-- Program output begins --\\n\");\n\n  MEM_BARRIER();\n\n  child_pid = fork();\n\n  if (child_pid < 0) PFATAL(\"fork() failed\");\n\n  if (!child_pid) {\n\n    struct rlimit r;\n\n    if (quiet_mode) {\n\n      s32 fd = open(\"/dev/null\", O_RDWR);\n\n      if (fd < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0) {\n        *(u32*)trace_bits = EXEC_FAIL_SIG;\n        PFATAL(\"Descriptor initialization failed\");\n      }\n\n      close(fd);\n\n    }\n\n    if (mem_limit) {\n\n      r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n\n#ifdef RLIMIT_AS\n\n      setrlimit(RLIMIT_AS, &r); /* Ignore errors */\n\n#else\n\n      setrlimit(RLIMIT_DATA, &r); /* Ignore errors */\n\n#endif /* ^RLIMIT_AS */\n\n    }\n\n    r.rlim_max = r.rlim_cur = 0;\n    setrlimit(RLIMIT_CORE, &r); /* Ignore errors */\n\n    execv(target_path, argv);\n\n    *(u32*)trace_bits = EXEC_FAIL_SIG;\n    exit(0);\n\n  }\n\n  /* Configure timeout, wait for child, cancel timeout. */\n\n  if (exec_tmout) {\n\n    child_timed_out = 0;\n    it.it_value.tv_sec = (exec_tmout / 1000);\n    it.it_value.tv_usec = (exec_tmout % 1000) * 1000;\n\n  }\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  if (waitpid(child_pid, &status, 0) <= 0) FATAL(\"waitpid() failed\");\n\n  child_pid = 0;\n  it.it_value.tv_sec = 0;\n  it.it_value.tv_usec = 0;\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  MEM_BARRIER();\n\n  /* Clean up bitmap, analyze exit condition, etc. */\n\n  if (*(u32*)trace_bits == EXEC_FAIL_SIG)\n    FATAL(\"Unable to execute '%s'\", argv[0]);\n\n  classify_counts(trace_bits);\n\n  if (!quiet_mode)\n    SAYF(\"-- Program output ends --\\n\");\n\n  if (!child_timed_out && !stop_soon && WIFSIGNALED(status))\n    child_crashed = 1;\n\n  if (!quiet_mode) {\n\n    if (child_timed_out)\n      SAYF(cLRD \"\\n+++ Program timed off +++\\n\" cRST);\n    else if (stop_soon)\n      SAYF(cLRD \"\\n+++ Program aborted by user +++\\n\" cRST);\n    else if (child_crashed)\n      SAYF(cLRD \"\\n+++ Program killed by signal %u +++\\n\" cRST, WTERMSIG(status));\n\n  }\n\n\n}\n\n\n/* Handle Ctrl-C and the like. */\n\nstatic void handle_stop_sig(int sig) {\n\n  stop_soon = 1;\n\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Do basic preparations - persistent fds, filenames, etc. */\n\nstatic void set_up_environment(void) {\n\n  setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                         \"detect_leaks=0:\"\n                         \"allocator_may_return_null=1\", 0);\n\n  setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                         \"msan_track_origins=0\", 0);\n\n}\n\n\n/* Setup signal handlers, duh. */\n\nstatic void setup_signal_handlers(void) {\n\n  struct sigaction sa;\n\n  sa.sa_handler   = NULL;\n  sa.sa_flags     = SA_RESTART;\n  sa.sa_sigaction = NULL;\n\n  sigemptyset(&sa.sa_mask);\n\n  /* Various ways of saying \"stop\". */\n\n  sa.sa_handler = handle_stop_sig;\n  sigaction(SIGHUP, &sa, NULL);\n  sigaction(SIGINT, &sa, NULL);\n  sigaction(SIGTERM, &sa, NULL);\n\n  /* Exec timeout notifications. */\n\n  sa.sa_handler = handle_timeout;\n  sigaction(SIGALRM, &sa, NULL);\n\n}\n\n\n/* Detect @@ in args. */\n\nstatic void detect_file_args(char** argv) {\n\n  u32 i = 0;\n  u8* cwd = getcwd(NULL, 0);\n\n  if (!cwd) PFATAL(\"getcwd() failed\");\n\n  while (argv[i]) {\n\n    u8* aa_loc = strstr(argv[i], \"@@\");\n\n    if (aa_loc) {\n\n      u8 *aa_subst, *n_arg;\n\n      if (!at_file) FATAL(\"@@ syntax is not supported by this tool.\");\n\n      /* Be sure that we're always using fully-qualified paths. */\n\n      if (at_file[0] == '/') aa_subst = at_file;\n      else aa_subst = alloc_printf(\"%s/%s\", cwd, at_file);\n\n      /* Construct a replacement argv value. */\n\n      *aa_loc = 0;\n      n_arg = alloc_printf(\"%s%s%s\", argv[i], aa_subst, aa_loc + 2);\n      argv[i] = n_arg;\n      *aa_loc = '@';\n\n      if (at_file[0] != '/') ck_free(aa_subst);\n\n    }\n\n    i++;\n\n  }\n\n  free(cwd); /* not tracked */\n\n}\n\n\n/* Show banner. */\n\nstatic void show_banner(void) {\n\n  SAYF(cCYA \"afl-showmap \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n}\n\n/* Display usage hints. */\n\nstatic void usage(u8* argv0) {\n\n  show_banner();\n\n  SAYF(\"\\n%s [ options ] -- /path/to/target_app [ ... ]\\n\\n\"\n\n       \"Required parameters:\\n\\n\"\n\n       \"  -o file       - file to write the trace data to\\n\\n\"\n\n       \"Execution control settings:\\n\\n\"\n\n       \"  -t msec       - timeout for each run (none)\\n\"\n       \"  -m megs       - memory limit for child process (%u MB)\\n\"\n       \"  -Q            - use binary-only instrumentation (QEMU mode)\\n\\n\"\n\n       \"Other settings:\\n\\n\"\n\n       \"  -q            - sink program's output and don't show messages\\n\"\n       \"  -e            - show edge coverage only, ignore hit counts\\n\\n\"\n\n       \"This tool displays raw tuple data captured by AFL instrumentation.\\n\"\n       \"For additional help, consult %s/README.\\n\\n\",\n\n       argv0, MEM_LIMIT, doc_path);\n\n  exit(1);\n\n}\n\n\n/* Find binary. */\n\nstatic void find_binary(u8* fname) {\n\n  u8* env_path = 0;\n  struct stat st;\n\n  if (strchr(fname, '/') || !(env_path = getenv(\"PATH\"))) {\n\n    target_path = ck_strdup(fname);\n\n    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||\n        !(st.st_mode & 0111) || st.st_size < 4)\n      FATAL(\"Program '%s' not found or not executable\", fname);\n\n  } else {\n\n    while (env_path) {\n\n      u8 *cur_elem, *delim = strchr(env_path, ':');\n\n      if (delim) {\n\n        cur_elem = ck_alloc(delim - env_path + 1);\n        memcpy(cur_elem, env_path, delim - env_path);\n        delim++;\n\n      } else cur_elem = ck_strdup(env_path);\n\n      env_path = delim;\n\n      if (cur_elem[0])\n        target_path = alloc_printf(\"%s/%s\", cur_elem, fname);\n      else\n        target_path = ck_strdup(fname);\n\n      ck_free(cur_elem);\n\n      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&\n          (st.st_mode & 0111) && st.st_size >= 4) break;\n\n      ck_free(target_path);\n      target_path = 0;\n\n    }\n\n    if (!target_path) FATAL(\"Program '%s' not found or not executable\", fname);\n\n  }\n\n}\n\n\n/* Fix up argv for QEMU. */\n\nstatic char** get_qemu_argv(u8* own_loc, char** argv, int argc) {\n\n  char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));\n  u8 *tmp, *cp, *rsl, *own_copy;\n\n  memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);\n\n  new_argv[2] = target_path;\n  new_argv[1] = \"--\";\n\n  /* Now we need to actually find qemu for argv[0]. */\n\n  tmp = getenv(\"AFL_PATH\");\n\n  if (tmp) {\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", tmp);\n\n    if (access(cp, X_OK))\n      FATAL(\"Unable to find '%s'\", tmp);\n\n    target_path = new_argv[0] = cp;\n    return new_argv;\n\n  }\n\n  own_copy = ck_strdup(own_loc);\n  rsl = strrchr(own_copy, '/');\n\n  if (rsl) {\n\n    *rsl = 0;\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", own_copy);\n    ck_free(own_copy);\n\n    if (!access(cp, X_OK)) {\n\n      target_path = new_argv[0] = cp;\n      return new_argv;\n\n    }\n\n  } else ck_free(own_copy);\n\n  if (!access(BIN_PATH \"/afl-qemu-trace\", X_OK)) {\n\n    target_path = new_argv[0] = BIN_PATH \"/afl-qemu-trace\";\n    return new_argv;\n\n  }\n\n  FATAL(\"Unable to find 'afl-qemu-trace'.\");\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 opt;\n  u8  mem_limit_given = 0, timeout_given = 0, qemu_mode = 0;\n  u32 tcnt;\n  char** use_argv;\n\n  doc_path = access(DOC_PATH, F_OK) ? \"docs\" : DOC_PATH;\n\n  while ((opt = getopt(argc,argv,\"+o:m:t:A:eqZQ\")) > 0)\n\n    switch (opt) {\n\n      case 'o':\n\n        if (out_file) FATAL(\"Multiple -o options not supported\");\n        out_file = optarg;\n        break;\n\n      case 'm': {\n\n          u8 suffix = 'M';\n\n          if (mem_limit_given) FATAL(\"Multiple -m options not supported\");\n          mem_limit_given = 1;\n\n          if (!strcmp(optarg, \"none\")) {\n\n            mem_limit = 0;\n            break;\n\n          }\n\n          if (sscanf(optarg, \"%llu%c\", &mem_limit, &suffix) < 1 ||\n              optarg[0] == '-') FATAL(\"Bad syntax used for -m\");\n\n          switch (suffix) {\n\n            case 'T': mem_limit *= 1024 * 1024; break;\n            case 'G': mem_limit *= 1024; break;\n            case 'k': mem_limit /= 1024; break;\n            case 'M': break;\n\n            default:  FATAL(\"Unsupported suffix or bad syntax for -m\");\n\n          }\n\n          if (mem_limit < 5) FATAL(\"Dangerously low value of -m\");\n\n          if (sizeof(rlim_t) == 4 && mem_limit > 2000)\n            FATAL(\"Value of -m out of range on 32-bit systems\");\n\n        }\n\n        break;\n\n      case 't':\n\n        if (timeout_given) FATAL(\"Multiple -t options not supported\");\n        timeout_given = 1;\n\n        if (strcmp(optarg, \"none\")) {\n          exec_tmout = atoi(optarg);\n\n          if (exec_tmout < 20 || optarg[0] == '-')\n            FATAL(\"Dangerously low value of -t\");\n\n        }\n\n        break;\n\n      case 'e':\n\n        if (edges_only) FATAL(\"Multiple -e options not supported\");\n        edges_only = 1;\n        break;\n\n      case 'q':\n\n        if (quiet_mode) FATAL(\"Multiple -q options not supported\");\n        quiet_mode = 1;\n        break;\n\n      case 'Z':\n\n        /* This is an undocumented option to write data in the syntax expected\n           by afl-cmin. Nobody else should have any use for this. */\n\n        cmin_mode  = 1;\n        quiet_mode = 1;\n        break;\n\n      case 'A':\n\n        /* Another afl-cmin specific feature. */\n        at_file = optarg;\n        break;\n\n      case 'Q':\n\n        if (qemu_mode) FATAL(\"Multiple -Q options not supported\");\n        if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;\n\n        qemu_mode = 1;\n        break;\n\n      default:\n\n        usage(argv[0]);\n\n    }\n\n  if (optind == argc || !out_file) usage(argv[0]);\n\n  setup_shm();\n  setup_signal_handlers();\n\n  set_up_environment();\n\n  find_binary(argv[optind]);\n\n  if (!quiet_mode) {\n    show_banner();\n    ACTF(\"Executing '%s'...\\n\", target_path);\n  }\n\n  detect_file_args(argv + optind);\n\n  if (qemu_mode)\n    use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);\n  else\n    use_argv = argv + optind;\n\n  run_target(use_argv);\n\n  tcnt = write_results();\n\n  if (!quiet_mode) {\n\n    if (!tcnt) FATAL(\"No instrumentation detected\");\n    OKF(\"Captured %u tuples in '%s'.\", tcnt, out_file);\n\n  }\n\n  exit(child_crashed * 2 + child_timed_out);\n\n}\n\n"
  },
  {
    "path": "afl-tmin.c",
    "content": "/*\n   american fuzzy lop - test case minimizer\n   ----------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   A simple test case minimizer that takes an input file and tries to remove\n   as much data as possible while keeping the binary in a crashing state\n   *or* producing consistent instrumentation output (the mode is auto-selected\n   based on initially observed behavior).\n\n */\n\n#define AFL_MAIN\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n#include \"alloc-inl.h\"\n#include \"hash.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <errno.h>\n#include <signal.h>\n#include <dirent.h>\n#include <fcntl.h>\n\n#include <sys/wait.h>\n#include <sys/time.h>\n#include <sys/shm.h>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <sys/resource.h>\n\nstatic s32 child_pid;                 /* PID of the tested program         */\n\nstatic u8* trace_bits;                /* SHM with instrumentation bitmap   */\n\nstatic u8 *in_file,                   /* Minimizer input test case         */\n          *out_file,                  /* Minimizer output file             */\n          *prog_in,                   /* Targeted program input file       */\n          *target_path,               /* Path to target binary             */\n          *doc_path;                  /* Path to docs                      */\n\nstatic u8* in_data;                   /* Input data for trimming           */\n\nstatic u32 in_len,                    /* Input data length                 */\n           orig_cksum,                /* Original checksum                 */\n           total_execs,               /* Total number of execs             */\n           missed_hangs,              /* Misses due to hangs               */\n           missed_crashes,            /* Misses due to crashes             */\n           missed_paths,              /* Misses due to exec path diffs     */\n           exec_tmout = EXEC_TIMEOUT; /* Exec timeout (ms)                 */\n\nstatic u64 mem_limit = MEM_LIMIT;     /* Memory limit (MB)                 */\n\nstatic s32 shm_id,                    /* ID of the SHM region              */\n           dev_null_fd = -1;          /* FD to /dev/null                   */\n\nstatic u8  crash_mode,                /* Crash-centric mode?               */\n           exit_crash,                /* Treat non-zero exit as crash?     */\n           edges_only,                /* Ignore hit counts?                */\n           use_stdin = 1;             /* Use stdin for program input?      */\n\nstatic volatile u8\n           stop_soon,                 /* Ctrl-C pressed?                   */\n           child_timed_out;           /* Child timed out?                  */\n\n\n/* Classify tuple counts. This is a slow & naive version, but good enough here. */\n\n#define AREP4(_sym)   (_sym), (_sym), (_sym), (_sym)\n#define AREP8(_sym)   AREP4(_sym),  AREP4(_sym)\n#define AREP16(_sym)  AREP8(_sym),  AREP8(_sym)\n#define AREP32(_sym)  AREP16(_sym), AREP16(_sym)\n#define AREP64(_sym)  AREP32(_sym), AREP32(_sym)\n#define AREP128(_sym) AREP64(_sym), AREP64(_sym)\n\nstatic u8 count_class_lookup[256] = {\n\n  /* 0 - 3:       4 */ 0, 1, 2, 4,\n  /* 4 - 7:      +4 */ AREP4(8),\n  /* 8 - 15:     +8 */ AREP8(16),\n  /* 16 - 31:   +16 */ AREP16(32),\n  /* 32 - 127:  +96 */ AREP64(64), AREP32(64),\n  /* 128+:     +128 */ AREP128(128)\n\n};\n\nstatic void classify_counts(u8* mem) {\n\n  u32 i = MAP_SIZE;\n\n  if (edges_only) {\n\n    while (i--) {\n      if (*mem) *mem = 1;\n      mem++;\n    }\n\n  } else {\n\n    while (i--) {\n      *mem = count_class_lookup[*mem];\n      mem++;\n    }\n\n  }\n\n}\n\n\n/* See if any bytes are set in the bitmap. */\n\nstatic inline u8 anything_set(void) {\n\n  u32* ptr = (u32*)trace_bits;\n  u32  i   = (MAP_SIZE >> 2);\n\n  while (i--) if (*(ptr++)) return 1;\n\n  return 0;\n\n}\n\n\n\n/* Get rid of shared memory and temp files (atexit handler). */\n\nstatic void remove_shm(void) {\n\n  unlink(prog_in); /* Ignore errors */\n  shmctl(shm_id, IPC_RMID, NULL);\n\n}\n\n\n/* Configure shared memory. */\n\nstatic void setup_shm(void) {\n\n  u8* shm_str;\n\n  shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);\n\n  if (shm_id < 0) PFATAL(\"shmget() failed\");\n\n  atexit(remove_shm);\n\n  shm_str = alloc_printf(\"%d\", shm_id);\n\n  setenv(SHM_ENV_VAR, shm_str, 1);\n\n  ck_free(shm_str);\n\n  trace_bits = shmat(shm_id, NULL, 0);\n  \n  if (!trace_bits) PFATAL(\"shmat() failed\");\n\n}\n\n\n/* Read initial file. */\n\nstatic void read_initial_file(void) {\n\n  struct stat st;\n  s32 fd = open(in_file, O_RDONLY);\n\n  if (fd < 0) PFATAL(\"Unable to open '%s'\", in_file);\n\n  if (fstat(fd, &st) || !st.st_size)\n    FATAL(\"Zero-sized input file.\");\n\n  if (st.st_size >= TMIN_MAX_FILE)\n    FATAL(\"Input file is too large (%u MB max)\", TMIN_MAX_FILE / 1024 / 1024);\n\n  in_len  = st.st_size;\n  in_data = ck_alloc_nozero(in_len);\n\n  ck_read(fd, in_data, in_len, in_file);\n\n  close(fd);\n\n  OKF(\"Read %u byte%s from '%s'.\", in_len, in_len == 1 ? \"\" : \"s\", in_file);\n\n}\n\n\n/* Write output file. */\n\nstatic s32 write_to_file(u8* path, u8* mem, u32 len) {\n\n  s32 ret;\n\n  unlink(path); /* Ignore errors */\n\n  ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);\n\n  if (ret < 0) PFATAL(\"Unable to create '%s'\", path);\n\n  ck_write(ret, mem, len, path);\n\n  lseek(ret, 0, SEEK_SET);\n\n  return ret;\n\n}\n\n\n/* Handle timeout signal. */\n\nstatic void handle_timeout(int sig) {\n\n  child_timed_out = 1;\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Execute target application. Returns 0 if the changes are a dud, or\n   1 if they should be kept. */\n\nstatic u8 run_target(char** argv, u8* mem, u32 len, u8 first_run) {\n\n  static struct itimerval it;\n  int status = 0;\n\n  s32 prog_in_fd;\n  u32 cksum;\n\n  memset(trace_bits, 0, MAP_SIZE);\n  MEM_BARRIER();\n\n  prog_in_fd = write_to_file(prog_in, mem, len);\n\n  child_pid = fork();\n\n  if (child_pid < 0) PFATAL(\"fork() failed\");\n\n  if (!child_pid) {\n\n    struct rlimit r;\n\n    if (dup2(use_stdin ? prog_in_fd : dev_null_fd, 0) < 0 ||\n        dup2(dev_null_fd, 1) < 0 ||\n        dup2(dev_null_fd, 2) < 0) {\n\n      *(u32*)trace_bits = EXEC_FAIL_SIG;\n      PFATAL(\"dup2() failed\");\n\n    }\n\n    close(dev_null_fd);\n    close(prog_in_fd);\n\n    if (mem_limit) {\n\n      r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;\n\n#ifdef RLIMIT_AS\n\n      setrlimit(RLIMIT_AS, &r); /* Ignore errors */\n\n#else\n\n      setrlimit(RLIMIT_DATA, &r); /* Ignore errors */\n\n#endif /* ^RLIMIT_AS */\n\n    }\n\n    r.rlim_max = r.rlim_cur = 0;\n    setrlimit(RLIMIT_CORE, &r); /* Ignore errors */\n\n    execv(target_path, argv);\n\n    *(u32*)trace_bits = EXEC_FAIL_SIG;\n    exit(0);\n\n  }\n\n  close(prog_in_fd);\n\n  /* Configure timeout, wait for child, cancel timeout. */\n\n  child_timed_out = 0;\n  it.it_value.tv_sec = (exec_tmout / 1000);\n  it.it_value.tv_usec = (exec_tmout % 1000) * 1000;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  if (waitpid(child_pid, &status, 0) <= 0) FATAL(\"waitpid() failed\");\n\n  child_pid = 0;\n  it.it_value.tv_sec = 0;\n  it.it_value.tv_usec = 0;\n\n  setitimer(ITIMER_REAL, &it, NULL);\n\n  MEM_BARRIER();\n\n  /* Clean up bitmap, analyze exit condition, etc. */\n\n  if (*(u32*)trace_bits == EXEC_FAIL_SIG)\n    FATAL(\"Unable to execute '%s'\", argv[0]);\n\n  classify_counts(trace_bits);\n  total_execs++;\n\n  if (stop_soon) {\n    SAYF(cLRD \"\\n+++ Minimization aborted by user +++\\n\" cRST);\n    exit(1);\n  }\n\n  /* Always discard inputs that time out. */\n\n  if (child_timed_out) {\n\n    missed_hangs++;\n    return 0;\n\n  }\n\n  /* Handle crashing inputs depending on current mode. */\n\n  if (WIFSIGNALED(status) ||\n      (WIFEXITED(status) && WEXITSTATUS(status) == MSAN_ERROR) ||\n      (WIFEXITED(status) && WEXITSTATUS(status) && exit_crash)) {\n\n    if (first_run) crash_mode = 1;\n\n    if (crash_mode) {\n\n      return 1;\n\n    } else {\n\n      missed_crashes++;\n      return 0;\n\n    }\n\n  }\n\n  /* Handle non-crashing inputs appropriately. */\n\n  if (crash_mode) {\n\n    missed_paths++;\n    return 0;\n\n  }\n\n  cksum = hash32(trace_bits, MAP_SIZE, HASH_CONST);\n\n  if (first_run) orig_cksum = cksum;\n\n  if (orig_cksum == cksum) return 1;\n  \n  missed_paths++;\n  return 0;\n\n}\n\n\n/* Find first power of two greater or equal to val. */\n\nstatic u32 next_p2(u32 val) {\n\n  u32 ret = 1;\n  while (val > ret) ret <<= 1;\n  return ret;\n\n}\n\n\n/* Actually minimize! */\n\nstatic void minimize(char** argv) {\n\n  static u32 alpha_map[256];\n\n  u8* tmp_buf = ck_alloc_nozero(in_len);\n  u32 orig_len = in_len, stage_o_len;\n\n  u32 del_len, set_len, del_pos, set_pos, i, alpha_size, cur_pass = 0;\n  u32 syms_removed, alpha_del0 = 0, alpha_del1, alpha_del2, alpha_d_total = 0;\n  u8  changed_any, prev_del;\n\n  /***********************\n   * BLOCK NORMALIZATION *\n   ***********************/\n\n  set_len    = next_p2(in_len / TMIN_SET_STEPS);\n  set_pos    = 0;\n\n  if (set_len < TMIN_SET_MIN_SIZE) set_len = TMIN_SET_MIN_SIZE;\n\n  ACTF(cBRI \"Stage #0: \" cNOR \"One-time block normalization...\");\n\n  while (set_pos < in_len) {\n\n    u8  res;\n    u32 use_len = MIN(set_len, in_len - set_pos);\n\n    for (i = 0; i < use_len; i++)\n      if (in_data[set_pos + i] != '0') break;\n\n    if (i != use_len) {\n\n      memcpy(tmp_buf, in_data, in_len);\n      memset(tmp_buf + set_pos, '0', use_len);\n  \n      res = run_target(argv, tmp_buf, in_len, 0);\n\n      if (res) {\n\n        memset(in_data + set_pos, '0', use_len);\n        changed_any = 1;\n        alpha_del0 += use_len;\n\n      }\n\n    }\n\n    set_pos += set_len;\n\n  }\n\n  alpha_d_total += alpha_del0;\n\n  OKF(\"Block normalization complete, %u byte%s replaced.\", alpha_del0,\n      alpha_del0 == 1 ? \"\" : \"s\");\n\nnext_pass:\n\n  ACTF(cYEL \"--- \" cBRI \"Pass #%u \" cYEL \"---\", ++cur_pass);\n  changed_any = 0;\n\n  /******************\n   * BLOCK DELETION *\n   ******************/\n\n  del_len = next_p2(in_len / TRIM_START_STEPS);\n  stage_o_len = in_len;\n\n  ACTF(cBRI \"Stage #1: \" cNOR \"Removing blocks of data...\");\n\nnext_del_blksize:\n\n  if (!del_len) del_len = 1;\n  del_pos  = 0;\n  prev_del = 1;\n\n  SAYF(cGRA \"    Block length = %u, remaining size = %u\\n\" cNOR,\n       del_len, in_len);\n\n  while (del_pos < in_len) {\n\n    u8  res;\n    s32 tail_len;\n\n    tail_len = in_len - del_pos - del_len;\n    if (tail_len < 0) tail_len = 0;\n\n    /* If we have processed at least one full block (initially, prev_del == 1),\n       and we did so without deleting the previous one, and we aren't at the\n       very end of the buffer (tail_len > 0), and the current block is the same\n       as the previous one... skip this step as a no-op. */\n\n    if (!prev_del && tail_len && !memcmp(in_data + del_pos - del_len,\n        in_data + del_pos, del_len)) {\n\n      del_pos += del_len;\n      continue;\n\n    }\n\n    prev_del = 0;\n\n    /* Head */\n    memcpy(tmp_buf, in_data, del_pos);\n\n    /* Tail */\n    memcpy(tmp_buf + del_pos, in_data + del_pos + del_len, tail_len);\n\n    res = run_target(argv, tmp_buf, del_pos + tail_len, 0);\n\n    if (res) {\n\n      memcpy(in_data, tmp_buf, del_pos + tail_len);\n      prev_del = 1;\n      in_len   = del_pos + tail_len;\n\n      changed_any = 1;\n\n    } else del_pos += del_len;\n\n  }\n\n  if (del_len > 1 && in_len >= 1) {\n\n    del_len /= 2;\n    goto next_del_blksize;\n\n  }\n\n  OKF(\"Block removal complete, %u bytes deleted.\", stage_o_len - in_len);\n\n  if (!in_len && changed_any)\n    WARNF(cLRD \"Down to zero bytes - check the command line and mem limit!\" cRST);\n\n  if (cur_pass > 1 && !changed_any) goto finalize_all;\n\n  /*************************\n   * ALPHABET MINIMIZATION *\n   *************************/\n\n  alpha_size   = 0;\n  alpha_del1   = 0;\n  syms_removed = 0;\n\n  memset(alpha_map, 0, 256);\n\n  for (i = 0; i < in_len; i++) {\n    if (!alpha_map[in_data[i]]) alpha_size++;\n    alpha_map[in_data[i]]++;\n  }\n\n  ACTF(cBRI \"Stage #2: \" cNOR \"Minimizing symbols (%u code point%s)...\",\n       alpha_size, alpha_size == 1 ? \"\" : \"s\");\n\n  for (i = 0; i < 256; i++) {\n\n    u32 r;\n    u8 res;\n\n    if (i == '0' || !alpha_map[i]) continue;\n\n    memcpy(tmp_buf, in_data, in_len);\n\n    for (r = 0; r < in_len; r++)\n      if (tmp_buf[r] == i) tmp_buf[r] = '0'; \n\n    res = run_target(argv, tmp_buf, in_len, 0);\n\n    if (res) {\n\n      memcpy(in_data, tmp_buf, in_len);\n      syms_removed++;\n      alpha_del1 += alpha_map[i];\n      changed_any = 1;\n\n    }\n\n  }\n\n  alpha_d_total += alpha_del1;\n\n  OKF(\"Symbol minimization finished, %u symbol%s (%u byte%s) replaced.\",\n      syms_removed, syms_removed == 1 ? \"\" : \"s\",\n      alpha_del1, alpha_del1 == 1 ? \"\" : \"s\");\n\n  /**************************\n   * CHARACTER MINIMIZATION *\n   **************************/\n\n  alpha_del2 = 0;\n\n  ACTF(cBRI \"Stage #3: \" cNOR \"Character minimization...\");\n\n  memcpy(tmp_buf, in_data, in_len);\n\n  for (i = 0; i < in_len; i++) {\n\n    u8 res, orig = tmp_buf[i];\n\n    if (orig == '0') continue;\n    tmp_buf[i] = '0';\n\n    res = run_target(argv, tmp_buf, in_len, 0);\n\n    if (res) {\n\n      in_data[i] = '0';\n      alpha_del2++;\n      changed_any = 1;\n\n    } else tmp_buf[i] = orig;\n\n  }\n\n  alpha_d_total += alpha_del2;\n\n  OKF(\"Character minimization done, %u byte%s replaced.\",\n      alpha_del2, alpha_del2 == 1 ? \"\" : \"s\");\n\n  if (changed_any) goto next_pass;\n\nfinalize_all:\n\n  SAYF(\"\\n\"\n       cGRA \"     File size reduced by : \" cNOR \"%0.02f%% (to %u byte%s)\\n\"\n       cGRA \"    Characters simplified : \" cNOR \"%0.02f%%\\n\"\n       cGRA \"     Number of execs done : \" cNOR \"%u\\n\"\n       cGRA \"          Fruitless execs : \" cNOR \"path=%u crash=%u hang=%s%u\\n\\n\",\n       100 - ((double)in_len) * 100 / orig_len, in_len, in_len == 1 ? \"\" : \"s\",\n       ((double)(alpha_d_total)) * 100 / (in_len ? in_len : 1),\n       total_execs, missed_paths, missed_crashes, missed_hangs ? cLRD : \"\",\n       missed_hangs);\n\n  if (total_execs > 50 && missed_hangs * 10 > total_execs)\n    WARNF(cLRD \"Frequent timeouts - results may be skewed.\" cRST);\n\n}\n\n\n\n/* Handle Ctrl-C and the like. */\n\nstatic void handle_stop_sig(int sig) {\n\n  stop_soon = 1;\n\n  if (child_pid > 0) kill(child_pid, SIGKILL);\n\n}\n\n\n/* Do basic preparations - persistent fds, filenames, etc. */\n\nstatic void set_up_environment(void) {\n\n  u8* x;\n\n  dev_null_fd = open(\"/dev/null\", O_RDWR);\n  if (dev_null_fd < 0) PFATAL(\"Unable to open /dev/null\");\n\n  if (!prog_in) {\n\n    u8* use_dir = \".\";\n\n    if (!access(use_dir, R_OK | W_OK | X_OK)) {\n\n      use_dir = getenv(\"TMPDIR\");\n      if (!use_dir) use_dir = \"/tmp\";\n\n      prog_in = alloc_printf(\"%s/.afl-tmin-temp-%u\", use_dir, getpid());\n\n    }\n\n  }\n\n  /* Set sane defaults... */\n\n  x = getenv(\"ASAN_OPTIONS\");\n\n  if (x && !strstr(x, \"abort_on_error=1\"))\n    FATAL(\"Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!\");\n\n  x = getenv(\"MSAN_OPTIONS\");\n\n  if (x && !strstr(x, \"exit_code=\" STRINGIFY(MSAN_ERROR)))\n    FATAL(\"Custom MSAN_OPTIONS set without exit_code=\"\n          STRINGIFY(MSAN_ERROR) \" - please fix!\");\n\n  setenv(\"ASAN_OPTIONS\", \"abort_on_error=1:\"\n                         \"detect_leaks=0:\"\n                         \"allocator_may_return_null=1\", 0);\n\n  setenv(\"MSAN_OPTIONS\", \"exit_code=\" STRINGIFY(MSAN_ERROR) \":\"\n                         \"msan_track_origins=0\", 0);\n\n}\n\n\n/* Setup signal handlers, duh. */\n\nstatic void setup_signal_handlers(void) {\n\n  struct sigaction sa;\n\n  sa.sa_handler   = NULL;\n  sa.sa_flags     = SA_RESTART;\n  sa.sa_sigaction = NULL;\n\n  sigemptyset(&sa.sa_mask);\n\n  /* Various ways of saying \"stop\". */\n\n  sa.sa_handler = handle_stop_sig;\n  sigaction(SIGHUP, &sa, NULL);\n  sigaction(SIGINT, &sa, NULL);\n  sigaction(SIGTERM, &sa, NULL);\n\n  /* Exec timeout notifications. */\n\n  sa.sa_handler = handle_timeout;\n  sigaction(SIGALRM, &sa, NULL);\n\n}\n\n\n/* Detect @@ in args. */\n\nstatic void detect_file_args(char** argv) {\n\n  u32 i = 0;\n  u8* cwd = getcwd(NULL, 0);\n\n  if (!cwd) PFATAL(\"getcwd() failed\");\n\n  while (argv[i]) {\n\n    u8* aa_loc = strstr(argv[i], \"@@\");\n\n    if (aa_loc) {\n\n      u8 *aa_subst, *n_arg;\n\n      /* Be sure that we're always using fully-qualified paths. */\n\n      if (prog_in[0] == '/') aa_subst = prog_in;\n      else aa_subst = alloc_printf(\"%s/%s\", cwd, prog_in);\n\n      /* Construct a replacement argv value. */\n\n      *aa_loc = 0;\n      n_arg = alloc_printf(\"%s%s%s\", argv[i], aa_subst, aa_loc + 2);\n      argv[i] = n_arg;\n      *aa_loc = '@';\n\n      if (prog_in[0] != '/') ck_free(aa_subst);\n\n    }\n\n    i++;\n\n  }\n\n  free(cwd); /* not tracked */\n\n}\n\n\n/* Display usage hints. */\n\nstatic void usage(u8* argv0) {\n\n  SAYF(\"\\n%s [ options ] -- /path/to/target_app [ ... ]\\n\\n\"\n\n       \"Required parameters:\\n\\n\"\n\n       \"  -i file       - input test case to be shrunk by the tool\\n\"\n       \"  -o file       - final output location for the minimized data\\n\\n\"\n\n       \"Execution control settings:\\n\\n\"\n\n       \"  -f file       - input file read by the tested program (stdin)\\n\"\n       \"  -t msec       - timeout for each run (%u ms)\\n\"\n       \"  -m megs       - memory limit for child process (%u MB)\\n\"\n       \"  -Q            - use binary-only instrumentation (QEMU mode)\\n\\n\"\n\n       \"Minimization settings:\\n\\n\"\n\n       \"  -e            - solve for edge coverage only, ignore hit counts\\n\"\n       \"  -x            - treat non-zero exit codes as crashes\\n\\n\"\n\n       \"For additional tips, please consult %s/README.\\n\\n\",\n\n       argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);\n\n  exit(1);\n\n}\n\n\n/* Find binary. */\n\nstatic void find_binary(u8* fname) {\n\n  u8* env_path = 0;\n  struct stat st;\n\n  if (strchr(fname, '/') || !(env_path = getenv(\"PATH\"))) {\n\n    target_path = ck_strdup(fname);\n\n    if (stat(target_path, &st) || !S_ISREG(st.st_mode) ||\n        !(st.st_mode & 0111) || st.st_size < 4)\n      FATAL(\"Program '%s' not found or not executable\", fname);\n\n  } else {\n\n    while (env_path) {\n\n      u8 *cur_elem, *delim = strchr(env_path, ':');\n\n      if (delim) {\n\n        cur_elem = ck_alloc(delim - env_path + 1);\n        memcpy(cur_elem, env_path, delim - env_path);\n        delim++;\n\n      } else cur_elem = ck_strdup(env_path);\n\n      env_path = delim;\n\n      if (cur_elem[0])\n        target_path = alloc_printf(\"%s/%s\", cur_elem, fname);\n      else\n        target_path = ck_strdup(fname);\n\n      ck_free(cur_elem);\n\n      if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&\n          (st.st_mode & 0111) && st.st_size >= 4) break;\n\n      ck_free(target_path);\n      target_path = 0;\n\n    }\n\n    if (!target_path) FATAL(\"Program '%s' not found or not executable\", fname);\n\n  }\n\n}\n\n\n/* Fix up argv for QEMU. */\n\nstatic char** get_qemu_argv(u8* own_loc, char** argv, int argc) {\n\n  char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));\n  u8 *tmp, *cp, *rsl, *own_copy;\n\n  memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);\n\n  /* Now we need to actually find qemu for argv[0]. */\n\n  new_argv[2] = target_path;\n  new_argv[1] = \"--\";\n\n  tmp = getenv(\"AFL_PATH\");\n\n  if (tmp) {\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", tmp);\n\n    if (access(cp, X_OK))\n      FATAL(\"Unable to find '%s'\", tmp);\n\n    target_path = new_argv[0] = cp;\n    return new_argv;\n\n  }\n\n  own_copy = ck_strdup(own_loc);\n  rsl = strrchr(own_copy, '/');\n\n  if (rsl) {\n\n    *rsl = 0;\n\n    cp = alloc_printf(\"%s/afl-qemu-trace\", own_copy);\n    ck_free(own_copy);\n\n    if (!access(cp, X_OK)) {\n\n      target_path = new_argv[0] = cp;\n      return new_argv;\n\n    }\n\n  } else ck_free(own_copy);\n\n  if (!access(BIN_PATH \"/afl-qemu-trace\", X_OK)) {\n\n    target_path = new_argv[0] = BIN_PATH \"/afl-qemu-trace\";\n    return new_argv;\n\n  }\n\n  FATAL(\"Unable to find 'afl-qemu-trace'.\");\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  s32 opt;\n  u8  mem_limit_given = 0, timeout_given = 0, qemu_mode = 0;\n  char** use_argv;\n\n  doc_path = access(DOC_PATH, F_OK) ? \"docs\" : DOC_PATH;\n\n  SAYF(cCYA \"afl-tmin \" cBRI VERSION cRST \" by <lcamtuf@google.com>\\n\");\n\n  while ((opt = getopt(argc,argv,\"+i:o:f:m:t:xeQ\")) > 0)\n\n    switch (opt) {\n\n      case 'i':\n\n        if (in_file) FATAL(\"Multiple -i options not supported\");\n        in_file = optarg;\n        break;\n\n      case 'o':\n\n        if (out_file) FATAL(\"Multiple -o options not supported\");\n        out_file = optarg;\n        break;\n\n      case 'f':\n\n        if (prog_in) FATAL(\"Multiple -f options not supported\");\n        use_stdin = 0;\n        prog_in   = optarg;\n        break;\n\n      case 'e':\n\n        if (edges_only) FATAL(\"Multiple -e options not supported\");\n        edges_only = 1;\n        break;\n\n      case 'x':\n\n        if (exit_crash) FATAL(\"Multiple -x options not supported\");\n        exit_crash = 1;\n        break;\n\n      case 'm': {\n\n          u8 suffix = 'M';\n\n          if (mem_limit_given) FATAL(\"Multiple -m options not supported\");\n          mem_limit_given = 1;\n\n          if (!strcmp(optarg, \"none\")) {\n\n            mem_limit = 0;\n            break;\n\n          }\n\n          if (sscanf(optarg, \"%llu%c\", &mem_limit, &suffix) < 1 ||\n              optarg[0] == '-') FATAL(\"Bad syntax used for -m\");\n\n          switch (suffix) {\n\n            case 'T': mem_limit *= 1024 * 1024; break;\n            case 'G': mem_limit *= 1024; break;\n            case 'k': mem_limit /= 1024; break;\n            case 'M': break;\n\n            default:  FATAL(\"Unsupported suffix or bad syntax for -m\");\n\n          }\n\n          if (mem_limit < 5) FATAL(\"Dangerously low value of -m\");\n\n          if (sizeof(rlim_t) == 4 && mem_limit > 2000)\n            FATAL(\"Value of -m out of range on 32-bit systems\");\n\n        }\n\n        break;\n\n      case 't':\n\n        if (timeout_given) FATAL(\"Multiple -t options not supported\");\n        timeout_given = 1;\n\n        exec_tmout = atoi(optarg);\n\n        if (exec_tmout < 10 || optarg[0] == '-')\n          FATAL(\"Dangerously low value of -t\");\n\n        break;\n\n      case 'Q':\n\n        if (qemu_mode) FATAL(\"Multiple -Q options not supported\");\n        if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;\n\n        qemu_mode = 1;\n        break;\n\n      default:\n\n        usage(argv[0]);\n\n    }\n\n  if (optind == argc || !in_file || !out_file) usage(argv[0]);\n\n  setup_shm();\n  setup_signal_handlers();\n\n  set_up_environment();\n\n  find_binary(argv[optind]);\n  detect_file_args(argv + optind);\n\n  if (qemu_mode)\n    use_argv = get_qemu_argv(argv[0], argv + optind, argc - optind);\n  else\n    use_argv = argv + optind;\n\n  SAYF(\"\\n\");\n\n  read_initial_file();\n\n  ACTF(\"Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...\",\n       mem_limit, exec_tmout, edges_only ? \", edges only\" : \"\");\n\n  run_target(use_argv, in_data, in_len, 1);\n\n  if (child_timed_out)\n    FATAL(\"Target binary times out (adjusting -t may help).\");\n\n  if (!crash_mode) {\n\n     OKF(\"Program terminates normally, minimizing in \" cCYA \"instrumented\" cNOR \" mode.\");\n     if (!anything_set()) FATAL(\"No instrumentation detected.\");\n\n  } else {\n\n     OKF(\"Program exits with a signal, minimizing in \" cMGN \"crash\" cNOR \" mode.\");\n\n  }\n\n  minimize(use_argv);\n\n  ACTF(\"Writing output to '%s'...\", out_file);\n\n  close(write_to_file(out_file, in_data, in_len));\n\n  OKF(\"We're done here. Have a nice day!\\n\");\n\n  exit(0);\n\n}\n\n"
  },
  {
    "path": "afl-whatsup",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - status check tool\n# --------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This tool summarizes the status of any locally-running synchronized\n# instances of afl-fuzz.\n#\n\necho \"status check tool for afl-fuzz by <lcamtuf@google.com>\"\necho\n\nif [ \"$1\" = \"-s\" ]; then\n\n  SUMMARY_ONLY=1\n  DIR=\"$2\"\n\nelse\n\n  unset SUMMARY_ONLY\n  DIR=\"$1\"\n\nfi\n\nif [ \"$DIR\" = \"\" ]; then\n\n  echo \"Usage: $0 [ -s ] afl_sync_dir\" 1>&2\n  echo 1>&2\n  echo \"The -s option causes the tool to skip all the per-fuzzer trivia and show\" 1>&2\n  echo \"just the summary results. See docs/parallel_fuzzing.txt for additional tips.\" 1>&2\n  echo 1>&2\n  exit 1\n\nfi\n\ncd \"$DIR\" || exit 1\n\nif [ -d queue ]; then\n\n  echo \"[-] Error: parameter is an individual output directory, not a sync dir.\" 1>&2\n  exit 1\n\nfi\n\nCUR_TIME=`date +%s`\n\nTMP=`mktemp -t .afl-whatsup-XXXXXXXX` || exit 1\n\nALIVE_CNT=0\nDEAD_CNT=0\n\nTOTAL_TIME=0\nTOTAL_EXECS=0\nTOTAL_CRASHES=0\nTOTAL_PFAV=0\nTOTAL_PENDING=0\n\nif [ \"$SUMMARY_ONLY\" = \"\" ]; then\n\n  echo \"Individual fuzzers\"\n  echo \"==================\"\n  echo\n\nfi\n\nfor i in `find . -maxdepth 2 -iname fuzzer_stats`; do\n\n  sed 's/^command_line.*$/_skip:1/;s/[ ]*:[ ]*/=\"/;s/$/\"/' \"$i\" >\"$TMP\"\n  . \"$TMP\"\n\n  RUN_UNIX=$((CUR_TIME - start_time))\n  RUN_DAYS=$((RUN_UNIX / 60 / 60 / 24))\n  RUN_HRS=$(((RUN_UNIX / 60 / 60) % 24))\n\n  if [ \"$SUMMARY_ONLY\" = \"\" ]; then\n\n    echo \">>> $afl_banner ($RUN_DAYS days, $RUN_HRS hrs) <<<\"\n    echo\n\n  fi\n\n  if ! kill -0 \"$fuzzer_pid\" 2>/dev/null; then\n\n    if [ \"$SUMMARY_ONLY\" = \"\" ]; then\n\n      echo \"  Instance is dead or running remotely, skipping.\"\n      echo\n\n    fi\n\n    DEAD_CNT=$((DEAD_CNT + 1))\n    continue\n\n  fi\n\n  ALIVE_CNT=$((ALIVE_CNT + 1))\n\n  TOTAL_TIME=$((TOTAL_TIME + RUN_UNIX))\n  TOTAL_EXECS=$((TOTAL_EXECS + execs_done))\n  TOTAL_CRASHES=$((TOTAL_CRASHES + unique_crashes))\n  TOTAL_PENDING=$((TOTAL_PENDING + pending_total))\n  TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))\n\n  EXEC_SEC=$((execs_done / RUN_UNIX))\n  PATH_PERC=$((cur_path * 100 / paths_total))\n\n  if [ \"$SUMMARY_ONLY\" = \"\" ]; then\n\n    echo \"  cycle $((cycles_done + 1)), lifetime speed $EXEC_SEC execs/sec, path $cur_path/$paths_total (${PATH_PERC}%)\"\n\n    if [ \"$unique_crashes\" = \"0\" ]; then\n      echo \"  pending $pending_favs/$pending_total, coverage $bitmap_cvg, no crashes yet\"\n    else\n      echo \"  pending $pending_favs/$pending_total, coverage $bitmap_cvg, crash count $unique_crashes (!)\"\n    fi\n\n    echo\n\n  fi\n\ndone\n\nrm -f \"$TMP\"\n\nTOTAL_DAYS=$((TOTAL_TIME / 60 / 60 / 24))\nTOTAL_HRS=$(((TOTAL_TIME / 60 / 60) % 24))\n\ntest \"$TOTAL_TIME\" = \"0\" && TOTAL_TIME=1\n\necho \"Summary stats\"\necho \"=============\"\necho\necho \"       Fuzzers alive : $ALIVE_CNT\"\n\nif [ ! \"$DEAD_CNT\" = \"0\" ]; then\n  echo \"      Dead or remote : $DEAD_CNT (excluded from stats)\"\nfi\n\necho \"      Total run time : $TOTAL_DAYS days, $TOTAL_HRS hours\"\necho \"         Total execs : $((TOTAL_EXECS / 1000 / 1000)) million\"\necho \"    Cumulative speed : $((TOTAL_EXECS * ALIVE_CNT / TOTAL_TIME)) execs/sec\"\necho \"       Pending paths : $TOTAL_PFAV faves, $TOTAL_PENDING total\"\n\nif [ \"$ALIVE_CNT\" -gt \"1\" ]; then\n  echo \"  Pending per fuzzer : $((TOTAL_PFAV/ALIVE_CNT)) faves, $((TOTAL_PENDING/ALIVE_CNT)) total (on average)\"\nfi\n\necho \"       Crashes found : $TOTAL_CRASHES locally unique\"\necho\n\nexit 0\n"
  },
  {
    "path": "alloc-inl.h",
    "content": "/*\n   american fuzzy lop - error-checking, memory-zeroing alloc routines\n   ------------------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This allocator is not designed to resist malicious attackers (the canaries\n   are small and predictable), but provides a robust and portable way to detect\n   use-after-free, off-by-one writes, stale pointers, and so on.\n\n */\n\n#ifndef _HAVE_ALLOC_INL_H\n#define _HAVE_ALLOC_INL_H\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"config.h\"\n#include \"types.h\"\n#include \"debug.h\"\n\n/* User-facing macro to sprintf() to a dynamically allocated buffer. */\n\n#define alloc_printf(_str...) ({ \\\n    u8* _tmp; \\\n    s32 _len = snprintf(NULL, 0, _str); \\\n    if (_len < 0) FATAL(\"Whoa, snprintf() fails?!\"); \\\n    _tmp = ck_alloc(_len + 1); \\\n    snprintf((char*)_tmp, _len + 1, _str); \\\n    _tmp; \\\n  })\n\n/* Macro to enforce allocation limits as a last-resort defense against\n   integer overflows. */\n\n#define ALLOC_CHECK_SIZE(_s) do { \\\n    if ((_s) > MAX_ALLOC) \\\n      ABORT(\"Bad alloc request: %u bytes\", (_s)); \\\n  } while (0)\n\n/* Macro to check malloc() failures and the like. */\n\n#define ALLOC_CHECK_RESULT(_r, _s) do { \\\n    if (!(_r)) \\\n      ABORT(\"Out of memory: can't allocate %u bytes\", (_s)); \\\n  } while (0)\n\n/* Magic tokens used to mark used / freed chunks. */\n\n#define ALLOC_MAGIC_C1  0xFF00FF00 /* Used head (dword)  */\n#define ALLOC_MAGIC_F   0xFE00FE00 /* Freed head (dword) */\n#define ALLOC_MAGIC_C2  0xF0       /* Used tail (byte)   */\n\n/* Positions of guard tokens in relation to the user-visible pointer. */\n\n#define ALLOC_C1(_ptr)  (((u32*)(_ptr))[-2])\n#define ALLOC_S(_ptr)   (((u32*)(_ptr))[-1])\n#define ALLOC_C2(_ptr)  (((u8*)(_ptr))[ALLOC_S(_ptr)])\n\n#define ALLOC_OFF_HEAD  8\n#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)\n\n/* Allocator increments for ck_realloc_block(). */\n\n#define ALLOC_BLK_INC    256\n\n/* Sanity-checking macros for pointers. */\n\n#define CHECK_PTR(_p) do { \\\n    if (_p) { \\\n      if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) {\\\n        if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \\\n          ABORT(\"Use after free.\"); \\\n        else ABORT(\"Corrupted head alloc canary.\"); \\\n      } \\\n      if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \\\n        ABORT(\"Corrupted tail alloc canary.\"); \\\n    } \\\n  } while (0)\n\n#define CHECK_PTR_EXPR(_p) ({ \\\n    typeof (_p) _tmp = (_p); \\\n    CHECK_PTR(_tmp); \\\n    _tmp; \\\n  })\n\n\n/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized\n   requests. */\n\nstatic inline void* DFL_ck_alloc_nozero(u32 size) {\n\n  void* ret;\n\n  if (!size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return ret;\n\n}\n\n\n/* Allocate a buffer, returning zeroed memory. */\n\nstatic inline void* DFL_ck_alloc(u32 size) {\n\n  void* mem;\n\n  if (!size) return NULL;\n  mem = DFL_ck_alloc_nozero(size);\n\n  return memset(mem, 0, size);\n\n}\n\n\n/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD\n   is set, the old memory will be also clobbered with 0xFF. */\n\nstatic inline void DFL_ck_free(void* mem) {\n\n  if (!mem) return;\n\n  CHECK_PTR(mem);\n\n#ifdef DEBUG_BUILD\n\n  /* Catch pointer issues sooner. */\n  memset(mem, 0xFF, ALLOC_S(mem));\n\n#endif /* DEBUG_BUILD */\n\n  ALLOC_C1(mem) = ALLOC_MAGIC_F;\n\n  free(mem - ALLOC_OFF_HEAD);\n\n}\n\n\n/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.\n   With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the\n   old memory is clobbered with 0xFF. */\n\nstatic inline void* DFL_ck_realloc(void* orig, u32 size) {\n\n  void* ret;\n  u32   old_size = 0;\n\n  if (!size) {\n\n    DFL_ck_free(orig);\n    return NULL;\n\n  }\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n#ifndef DEBUG_BUILD\n    ALLOC_C1(orig) = ALLOC_MAGIC_F;\n#endif /* !DEBUG_BUILD */\n\n    old_size  = ALLOC_S(orig);\n    orig     -= ALLOC_OFF_HEAD;\n\n    ALLOC_CHECK_SIZE(old_size);\n\n  }\n\n  ALLOC_CHECK_SIZE(size);\n\n#ifndef DEBUG_BUILD\n\n  ret = realloc(orig, size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n#else\n\n  /* Catch pointer issues sooner: force relocation and make sure that the\n     original buffer is wiped. */\n\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  if (orig) {\n\n    memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));\n    memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);\n\n    ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;\n\n    free(orig);\n\n  }\n\n#endif /* ^!DEBUG_BUILD */\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  if (size > old_size)\n    memset(ret + old_size, 0, size - old_size);\n\n  return ret;\n\n}\n\n\n/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up\n   repeated small reallocs without complicating the user code). */\n\nstatic inline void* DFL_ck_realloc_block(void* orig, u32 size) {\n\n#ifndef DEBUG_BUILD\n\n  if (orig) {\n\n    CHECK_PTR(orig);\n\n    if (ALLOC_S(orig) >= size) return orig;\n\n    size += ALLOC_BLK_INC;\n\n  }\n\n#endif /* !DEBUG_BUILD */\n\n  return DFL_ck_realloc(orig, size);\n\n}\n\n\n/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */\n\nstatic inline u8* DFL_ck_strdup(u8* str) {\n\n  void* ret;\n  u32   size;\n\n  if (!str) return NULL;\n\n  size = strlen((char*)str) + 1;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n\n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return memcpy(ret, str, size);\n\n}\n\n\n/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized\n   or NULL inputs. */\n\nstatic inline void* DFL_ck_memdup(void* mem, u32 size) {\n\n  void* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  return memcpy(ret, mem, size);\n\n}\n\n\n/* Create a buffer with a block of text, appending a NUL terminator at the end.\n   Returns NULL for zero-sized or NULL inputs. */\n\nstatic inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {\n\n  u8* ret;\n\n  if (!mem || !size) return NULL;\n\n  ALLOC_CHECK_SIZE(size);\n  ret = malloc(size + ALLOC_OFF_TOTAL + 1);\n  ALLOC_CHECK_RESULT(ret, size);\n  \n  ret += ALLOC_OFF_HEAD;\n\n  ALLOC_C1(ret) = ALLOC_MAGIC_C1;\n  ALLOC_S(ret)  = size;\n  ALLOC_C2(ret) = ALLOC_MAGIC_C2;\n\n  memcpy(ret, mem, size);\n  ret[size] = 0;\n\n  return ret;\n\n}\n\n\n#ifndef DEBUG_BUILD\n\n/* In non-debug mode, we just do straightforward aliasing of the above functions\n   to user-visible names such as ck_alloc(). */\n\n#define ck_alloc          DFL_ck_alloc\n#define ck_alloc_nozero   DFL_ck_alloc_nozero\n#define ck_realloc        DFL_ck_realloc\n#define ck_realloc_block  DFL_ck_realloc_block\n#define ck_strdup         DFL_ck_strdup\n#define ck_memdup         DFL_ck_memdup\n#define ck_memdup_str     DFL_ck_memdup_str\n#define ck_free           DFL_ck_free\n\n#define alloc_report()\n\n#else\n\n/* In debugging mode, we also track allocations to detect memory leaks, and the\n   flow goes through one more layer of indirection. */\n\n/* Alloc tracking data structures: */\n\n#define ALLOC_BUCKETS     4096\n\nstruct TRK_obj {\n  void *ptr;\n  char *file, *func;\n  u32  line;\n};\n\n#ifdef AFL_MAIN\n\nstruct TRK_obj* TRK[ALLOC_BUCKETS];\nu32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report() TRK_report()\n\n#else\n\nextern struct TRK_obj* TRK[ALLOC_BUCKETS];\nextern u32 TRK_cnt[ALLOC_BUCKETS];\n\n#  define alloc_report()\n\n#endif /* ^AFL_MAIN */\n\n/* Bucket-assigning function for a given pointer: */\n\n#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)\n\n\n/* Add a new entry to the list of allocated objects. */\n\nstatic inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,\n                                 u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find a free slot in the list of entries for that bucket. */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (!TRK[bucket][i].ptr) {\n\n      TRK[bucket][i].ptr  = ptr;\n      TRK[bucket][i].file = (char*)file;\n      TRK[bucket][i].func = (char*)func;\n      TRK[bucket][i].line = line;\n      return;\n\n    }\n\n  /* No space available - allocate more. */\n\n  TRK[bucket] = DFL_ck_realloc_block(TRK[bucket],\n    (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));\n\n  TRK[bucket][i].ptr  = ptr;\n  TRK[bucket][i].file = (char*)file;\n  TRK[bucket][i].func = (char*)func;\n  TRK[bucket][i].line = line;\n\n  TRK_cnt[bucket]++;\n\n}\n\n\n/* Remove entry from the list of allocated objects. */\n\nstatic inline void TRK_free_buf(void* ptr, const char* file, const char* func,\n                                u32 line) {\n\n  u32 i, bucket;\n\n  if (!ptr) return;\n\n  bucket = TRKH(ptr);\n\n  /* Find the element on the list... */\n\n  for (i = 0; i < TRK_cnt[bucket]; i++)\n\n    if (TRK[bucket][i].ptr == ptr) {\n\n      TRK[bucket][i].ptr = 0;\n      return;\n\n    }\n\n  WARNF(\"ALLOC: Attempt to free non-allocated memory in %s (%s:%u)\",\n        func, file, line);\n\n}\n\n\n/* Do a final report on all non-deallocated objects. */\n\nstatic inline void TRK_report(void) {\n\n  u32 i, bucket;\n\n  fflush(0);\n\n  for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)\n    for (i = 0; i < TRK_cnt[bucket]; i++)\n      if (TRK[bucket][i].ptr)\n        WARNF(\"ALLOC: Memory never freed, created in %s (%s:%u)\",\n              TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);\n\n}\n\n\n/* Simple wrappers for non-debugging functions: */\n\nstatic inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,\n                                 u32 line) {\n\n  void* ret = DFL_ck_alloc(size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,\n                                   const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,\n                                         const char* func, u32 line) {\n\n  void* ret = DFL_ck_realloc_block(orig, size);\n  TRK_free_buf(orig, file, func, line);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,\n                                  u32 line) {\n\n  void* ret = DFL_ck_strdup(str);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,\n                                  const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,\n                                      const char* func, u32 line) {\n\n  void* ret = DFL_ck_memdup_str(mem, size);\n  TRK_alloc_buf(ret, file, func, line);\n  return ret;\n\n}\n\n\nstatic inline void TRK_ck_free(void* ptr, const char* file,\n                                const char* func, u32 line) {\n\n  TRK_free_buf(ptr, file, func, line);\n  DFL_ck_free(ptr);\n\n}\n\n/* Aliasing user-facing names to tracking functions: */\n\n#define ck_alloc(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_alloc_nozero(_p1) \\\n  TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc(_p1, _p2) \\\n  TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_realloc_block(_p1, _p2) \\\n  TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_strdup(_p1) \\\n  TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup(_p1, _p2) \\\n  TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_memdup_str(_p1, _p2) \\\n  TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)\n\n#define ck_free(_p1) \\\n  TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)\n\n#endif /* ^!DEBUG_BUILD */\n\n#endif /* ! _HAVE_ALLOC_INL_H */\n"
  },
  {
    "path": "config.h",
    "content": "/*\n   american fuzzy lop - vaguely configurable bits\n   ----------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_CONFIG_H\n#define _HAVE_CONFIG_H\n\n#include \"types.h\"\n\n/******************************************************\n *                                                    *\n *  Settings that may be of interest to power users:  *\n *                                                    *\n ******************************************************/\n\n/* Comment out to disable terminal colors: */\n\n#define USE_COLOR\n\n/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */\n\n#define FANCY_BOXES\n\n/* Default timeout for fuzzed code (milliseconds): */\n\n#define EXEC_TIMEOUT        1000\n\n/* Timeout rounding factor when auto-scaling (milliseconds): */\n\n#define EXEC_TM_ROUND       20\n\n/* Default memory limit for child process (MB): */\n\n#ifndef __x86_64__ \n#  define MEM_LIMIT         25\n#else\n#  define MEM_LIMIT         50\n#endif /* ^!__x86_64__ */\n\n/* Default memory limit when running in QEMU mode (MB): */\n\n#define MEM_LIMIT_QEMU      200\n\n/* Number of calibration cycles per every new test case (and for test\n   cases that show variable behavior): */\n\n#define CAL_CYCLES          10\n#define CAL_CYCLES_LONG     40\n\n/* The same, but when AFL_NO_VAR_CHECK is set in the environment: */\n\n#define CAL_CYCLES_NO_VAR   4\n\n/* Number of subsequent hangs before abandoning an input file: */\n\n#define HANG_LIMIT          250\n\n/* Maximum number of unique hangs or crashes to record: */\n\n#define KEEP_UNIQUE_HANG    500\n#define KEEP_UNIQUE_CRASH   5000\n\n/* Baseline number of random tweaks during a single 'havoc' stage: */\n\n#define HAVOC_CYCLES        5000\n\n/* Maximum multiplier for the above (should be a power of two, beware\n   of 32-bit int overflows): */\n\n#define HAVOC_MAX_MULT      16\n\n/* Absolute minimum number of havoc cycles (after all adjustments): */\n\n#define HAVOC_MIN           10\n\n/* Maximum stacking for havoc-stage tweaks. The actual value is calculated\n   like this: \n\n   n = random between 1 and HAVOC_STACK_POW2\n   stacking = 2^n\n\n   In other words, the default (n = 7) produces 2, 4, 8, 16, 32, 64, or\n   128 stacked tweaks: */\n\n#define HAVOC_STACK_POW2    7\n\n/* Caps on block sizes for cloning and deletion operations. Each of these\n   ranges has a 33% probability of getting picked, except for the first\n   two cycles where smaller blocks are favored: */\n\n#define HAVOC_BLK_SMALL     32\n#define HAVOC_BLK_MEDIUM    128\n#define HAVOC_BLK_LARGE     1500\n\n/* Probabilities of skipping non-favored entries in the queue, expressed as\n   percentages: */\n\n#define SKIP_TO_NEW_PROB    99 /* ...when there are new, pending favorites */\n#define SKIP_NFAV_OLD_PROB  95 /* ...no new favs, cur entry already fuzzed */\n#define SKIP_NFAV_NEW_PROB  75 /* ...no new favs, cur entry not fuzzed yet */\n\n/* Splicing cycle count: */\n\n#define SPLICE_CYCLES       20\n\n/* Nominal per-splice havoc cycle length: */\n\n#define SPLICE_HAVOC        500\n\n/* Maximum offset for integer addition / subtraction stages: */\n\n#define ARITH_MAX           35\n\n/* Limits for the test case trimmer. The absolute minimum chunk size; and\n   the starting and ending divisors for chopping up the input file: */\n\n#define TRIM_MIN_BYTES      4\n#define TRIM_START_STEPS    16\n#define TRIM_END_STEPS      1024\n\n/* Maximum size of input file, in bytes (keep under 100MB): */\n\n#define MAX_FILE            (1 * 1024 * 1024)\n\n/* The same, for the test case minimizer: */\n\n#define TMIN_MAX_FILE       (10 * 1024 * 1024)\n\n/* Block normalization steps for afl-tmin: */\n\n#define TMIN_SET_MIN_SIZE   4\n#define TMIN_SET_STEPS      128\n\n/* Maximum dictionary token size (-x), in bytes: */\n\n#define MAX_DICT_FILE       128\n\n/* Length limits for auto-detected dictionary tokens: */\n\n#define MIN_AUTO_EXTRA      3\n#define MAX_AUTO_EXTRA      32\n\n/* Maximum number of user-specified dictionary tokens to use in deterministic\n   steps; past this point, the \"extras/user\" step will be still carried out,\n   but with proportionally lower odds: */\n\n#define MAX_DET_EXTRAS      200\n\n/* Maximum number of auto-extracted dictionary tokens to actually use in fuzzing\n   (first value), and to keep in memory as candidates. The latter should be much\n   higher than the former. */\n\n#define USE_AUTO_EXTRAS     50\n#define MAX_AUTO_EXTRAS     (USE_AUTO_EXTRAS * 10)\n\n/* Scaling factor for the effector map used to skip some of the more\n   expensive deterministic steps. The actual divisor is set to\n   2^EFF_MAP_SCALE2 bytes: */\n\n#define EFF_MAP_SCALE2      3\n\n/* Minimum input file length at which the effector logic kicks in: */\n\n#define EFF_MIN_LEN         128\n\n/* Maximum effector density past which everything is just fuzzed\n   unconditionally (%): */\n\n#define EFF_MAX_PERC        90\n\n/* UI refresh frequency (Hz): */\n\n#define UI_TARGET_HZ        5\n\n/* Fuzzer stats file and plot update intervals (sec): */\n\n#define STATS_UPDATE_SEC    60\n#define PLOT_UPDATE_SEC     5\n\n/* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */\n\n#define AVG_SMOOTHING       16\n\n/* Sync interval (every n havoc cycles): */\n\n#define SYNC_INTERVAL       5\n\n/* Output directory reuse grace period (minutes): */\n\n#define OUTPUT_GRACE        25\n\n/* Uncomment to use simple file names (id_NNNNNN): */\n\n// #define SIMPLE_FILES\n\n/* List of interesting values to use in fuzzing. */\n\n#define INTERESTING_8 \\\n  -128,          /* Overflow signed 8-bit when decremented  */ \\\n  -1,            /*                                         */ \\\n   0,            /*                                         */ \\\n   1,            /*                                         */ \\\n   16,           /* One-off with common buffer size         */ \\\n   32,           /* One-off with common buffer size         */ \\\n   64,           /* One-off with common buffer size         */ \\\n   100,          /* One-off with common buffer size         */ \\\n   127           /* Overflow signed 8-bit when incremented  */\n\n#define INTERESTING_16 \\\n  -32768,        /* Overflow signed 16-bit when decremented */ \\\n  -129,          /* Overflow signed 8-bit                   */ \\\n   128,          /* Overflow signed 8-bit                   */ \\\n   255,          /* Overflow unsig 8-bit when incremented   */ \\\n   256,          /* Overflow unsig 8-bit                    */ \\\n   512,          /* One-off with common buffer size         */ \\\n   1000,         /* One-off with common buffer size         */ \\\n   1024,         /* One-off with common buffer size         */ \\\n   4096,         /* One-off with common buffer size         */ \\\n   32767         /* Overflow signed 16-bit when incremented */\n\n#define INTERESTING_32 \\\n  -2147483648LL, /* Overflow signed 32-bit when decremented */ \\\n  -100663046,    /* Large negative number (endian-agnostic) */ \\\n  -32769,        /* Overflow signed 16-bit                  */ \\\n   32768,        /* Overflow signed 16-bit                  */ \\\n   65535,        /* Overflow unsig 16-bit when incremented  */ \\\n   65536,        /* Overflow unsig 16 bit                   */ \\\n   100663045,    /* Large positive number (endian-agnostic) */ \\\n   2147483647    /* Overflow signed 32-bit when incremented */\n\n/***********************************************************\n *                                                         *\n *  Really exotic stuff you probably don't want to touch:  *\n *                                                         *\n ***********************************************************/\n\n/* Call count interval between reseeding the libc PRNG from /dev/urandom: */\n\n#define RESEED_RNG          10000\n\n/* Maximum line length passed from GCC to 'as' and used for parsing\n   configuration files: */\n\n#define MAX_LINE            8192\n\n/* Environment variable used to pass SHM ID to the called program. */\n\n#define SHM_ENV_VAR         \"__AFL_SHM_ID\"\n\n/* Other less interesting, internal-only variables. */\n\n#define CLANG_ENV_VAR       \"__AFL_CLANG_MODE\"\n#define AS_LOOP_ENV_VAR     \"__AFL_AS_LOOPCHECK\"\n#define PERSIST_ENV_VAR     \"__AFL_PERSISTENT\"\n#define DEFER_ENV_VAR       \"__AFL_DEFER_FORKSRV\"\n\n/* In-code signatures for deferred and persistent mode. */\n\n#define PERSIST_SIG         \"##SIG_AFL_PERSISTENT##\"\n#define DEFER_SIG           \"##SIG_AFL_DEFER_FORKSRV##\"\n\n/* Distinctive bitmap signature used to indicate failed execution: */\n\n#define EXEC_FAIL_SIG       0xfee1dead\n\n/* Distinctive exit code used to indicate MSAN trip condition: */\n\n#define MSAN_ERROR          86\n\n/* Designated file descriptors for forkserver commands (the application will\n   use FORKSRV_FD and FORKSRV_FD + 1): */\n\n#define FORKSRV_FD          198\n\n/* Fork server init timeout multiplier: we'll wait the user-selected\n   timeout plus this much for the fork server to spin up. */\n\n#define FORK_WAIT_MULT      10\n\n/* Calibration timeout adjustments, to be a bit more generous when resuming\n   fuzzing sessions or trying to calibrate already-added internal finds.\n   The first value is a percentage, the other is in milliseconds: */\n\n#define CAL_TMOUT_PERC      125\n#define CAL_TMOUT_ADD       50\n\n/* Number of chances to calibrate a case before giving up: */\n\n#define CAL_CHANCES         3\n\n/* Map size for the traced binary (2^MAP_SIZE_POW2). Must be greater than\n   2; you probably want to keep it under 18 or so for performance reasons\n   (adjusting AFL_INST_RATIO when compiling is probably a better way to solve\n   problems with complex programs). You need to recompile the target binary\n   after changing this - otherwise, SEGVs may ensue. */\n\n#define MAP_SIZE_POW2       16\n#define MAP_SIZE            (1 << MAP_SIZE_POW2)\n\n/* Maximum allocator request size (keep well under INT_MAX): */\n\n#define MAX_ALLOC           0x40000000\n\n/* A made-up hashing seed: */\n\n#define HASH_CONST          0xa5b35705\n\n/* Constants for afl-gotcpu to control busy loop timing: */\n\n#define  CTEST_TARGET_MS    5000\n#define  CTEST_BUSY_CYCLES  (10 * 1000 * 1000)\n\n/* Uncomment this to use inferior block-coverage-based instrumentation. Note\n   that you need to recompile the target binary for this to have any effect: */\n\n// #define COVERAGE_ONLY\n\n/* Uncomment this to ignore hit counts and output just one bit per tuple.\n   As with the previous setting, you will need to recompile the target\n   binary: */\n\n// #define SKIP_COUNTS\n\n/* Uncomment this to use instrumentation data to record newly discovered paths,\n   but do not use them as seeds for fuzzing. This is useful for conveniently\n   measuring coverage that could be attained by a \"dumb\" fuzzing algorithm: */\n\n// #define IGNORE_FINDS\n\n#endif /* ! _HAVE_CONFIG_H */\n"
  },
  {
    "path": "debug.h",
    "content": "/*\n   american fuzzy lop - debug / error handling macros\n   --------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_DEBUG_H\n#define _HAVE_DEBUG_H\n\n#include <errno.h>\n\n#include \"types.h\"\n#include \"config.h\"\n\n/*******************\n * Terminal colors *\n *******************/\n\n#ifdef USE_COLOR\n\n#  define cBLK \"\\x1b[0;30m\"\n#  define cRED \"\\x1b[0;31m\"\n#  define cGRN \"\\x1b[0;32m\"\n#  define cBRN \"\\x1b[0;33m\"\n#  define cBLU \"\\x1b[0;34m\"\n#  define cMGN \"\\x1b[0;35m\"\n#  define cCYA \"\\x1b[0;36m\"\n#  define cNOR \"\\x1b[0;37m\"\n#  define cGRA \"\\x1b[1;30m\"\n#  define cLRD \"\\x1b[1;31m\"\n#  define cLGN \"\\x1b[1;32m\"\n#  define cYEL \"\\x1b[1;33m\"\n#  define cLBL \"\\x1b[1;34m\"\n#  define cPIN \"\\x1b[1;35m\"\n#  define cLCY \"\\x1b[1;36m\"\n#  define cBRI \"\\x1b[1;37m\"\n#  define cRST \"\\x1b[0m\"\n\n#else\n\n#  define cBLK \"\"\n#  define cRED \"\"\n#  define cGRN \"\"\n#  define cBRN \"\"\n#  define cBLU \"\"\n#  define cMGN \"\"\n#  define cCYA \"\"\n#  define cNOR \"\"\n#  define cGRA \"\"\n#  define cLRD \"\"\n#  define cLGN \"\"\n#  define cYEL \"\"\n#  define cLBL \"\"\n#  define cPIN \"\"\n#  define cLCY \"\"\n#  define cBRI \"\"\n#  define cRST \"\"\n\n#endif /* ^USE_COLOR */\n\n/*************************\n * Box drawing sequences *\n *************************/\n\n#ifdef FANCY_BOXES\n\n#  define SET_G1   \"\\x1b)0\"       /* Set G1 for box drawing    */\n#  define RESET_G1 \"\\x1b)B\"       /* Reset G1 to ASCII         */\n#  define bSTART   \"\\x0e\"         /* Enter G1 drawing mode     */\n#  define bSTOP    \"\\x0f\"         /* Leave G1 drawing mode     */\n#  define bH       \"q\"            /* Horizontal line           */\n#  define bV       \"x\"            /* Vertical line             */\n#  define bLT      \"l\"            /* Left top corner           */\n#  define bRT      \"k\"            /* Right top corner          */\n#  define bLB      \"m\"            /* Left bottom corner        */\n#  define bRB      \"j\"            /* Right bottom corner       */\n#  define bX       \"n\"            /* Cross                     */\n#  define bVR      \"t\"            /* Vertical, branch right    */\n#  define bVL      \"u\"            /* Vertical, branch left     */\n#  define bHT      \"v\"            /* Horizontal, branch top    */\n#  define bHB      \"w\"            /* Horizontal, branch bottom */\n\n#else\n\n#  define SET_G1   \"\"\n#  define RESET_G1 \"\"\n#  define bSTART   \"\"\n#  define bSTOP    \"\"\n#  define bH       \"-\"\n#  define bV       \"|\"\n#  define bLT      \"+\"\n#  define bRT      \"+\"\n#  define bLB      \"+\"\n#  define bRB      \"+\"\n#  define bX       \"+\"\n#  define bVR      \"+\"\n#  define bVL      \"+\"\n#  define bHT      \"+\"\n#  define bHB      \"+\"\n\n#endif /* ^FANCY_BOXES */\n\n/***********************\n * Misc terminal codes *\n ***********************/\n\n#define TERM_HOME     \"\\x1b[H\"\n#define TERM_CLEAR    TERM_HOME \"\\x1b[2J\"\n#define cEOL          \"\\x1b[0K\"\n#define CURSOR_HIDE   \"\\x1b[?25l\"\n#define CURSOR_SHOW   \"\\x1b[?25h\"\n\n/************************\n * Debug & error macros *\n ************************/\n\n/* Just print stuff to the appropriate stream. */\n\n#ifdef MESSAGES_TO_STDOUT\n#  define SAYF(x...)    printf(x)\n#else \n#  define SAYF(x...)    fprintf(stderr, x)\n#endif /* ^MESSAGES_TO_STDOUT */\n\n/* Show a prefixed warning. */\n\n#define WARNF(x...) do { \\\n    SAYF(cYEL \"[!] \" cBRI \"WARNING: \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"doing something\" message. */\n\n#define ACTF(x...) do { \\\n    SAYF(cLBL \"[*] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed \"success\" message. */\n\n#define OKF(x...) do { \\\n    SAYF(cLGN \"[+] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Show a prefixed fatal error message (not used in afl). */\n\n#define BADF(x...) do { \\\n    SAYF(cLRD \"\\n[-] \" cRST x); \\\n    SAYF(cRST \"\\n\"); \\\n  } while (0)\n\n/* Die with a verbose non-OS fatal error message. */\n\n#define FATAL(x...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-] PROGRAM ABORT : \" cBRI x); \\\n    SAYF(cLRD \"\\n         Location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    exit(1); \\\n  } while (0)\n\n/* Die by calling abort() to provide a core dump. */\n\n#define ABORT(x...) do { \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-] PROGRAM ABORT : \" cBRI x); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    abort(); \\\n  } while (0)\n\n/* Die while also including the output of perror(). */\n\n#define PFATAL(x...) do { \\\n    fflush(stdout); \\\n    SAYF(bSTOP RESET_G1 CURSOR_SHOW cLRD \"\\n[-]  SYSTEM ERROR : \" cBRI x); \\\n    SAYF(cLRD \"\\n    Stop location : \" cRST \"%s(), %s:%u\\n\", \\\n         __FUNCTION__, __FILE__, __LINE__); \\\n    SAYF(cLRD \"       OS message : \" cRST \"%s\\n\", strerror(errno)); \\\n    exit(1); \\\n  } while (0)\n\n/* Die with FAULT() or PFAULT() depending on the value of res (used to\n   interpret different failure modes for read(), write(), etc). */\n\n#define RPFATAL(res, x...) do { \\\n    if (res < 0) PFATAL(x); else FATAL(x); \\\n  } while (0)\n\n/* Error-checking versions of read() and write() that call RPFATAL() as\n   appropriate. */\n\n#define ck_write(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = write(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short write to %s\", fn); \\\n  } while (0)\n\n#define ck_read(fd, buf, len, fn) do { \\\n    u32 _len = (len); \\\n    s32 _res = read(fd, buf, _len); \\\n    if (_res != _len) RPFATAL(_res, \"Short read from %s\", fn); \\\n  } while (0)\n\n#endif /* ! _HAVE_DEBUG_H */\n"
  },
  {
    "path": "docs/COPYING",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "docs/ChangeLog",
    "content": "=========\nChangeLog\n=========\n\n  This is the list of all noteworthy changes made in every public release of\n  the tool. See README for the general instruction manual.\n\n----------------\nStaying informed\n----------------\n\nWant to stay in the loop on major new features? Join our mailing list by\nsending a mail to <afl-users+subscribe@googlegroups.com>.\n\nNot sure if you should upgrade? The lowest currently recommended version\nis 1.92b. If you're stuck on an earlier release, it's strongly advisable\nto get on with the times.\n\n--------------\nVersion 1.95b:\n--------------\n\n  - Fixed a harmless bug when handling -B. Spotted by Jacek Wielemborek.\n\n  - Made the exit message a bit more accurate when AFL_EXIT_WHEN_DONE is set.\n\n  - Added some error-checking for old-style forkserver syntax. Suggested by\n    Ben Nagy.\n\n  - Switched from exit() to _exit() in injected code to avoid snafus with\n    destructors in C++ code. Spotted by sunblate.\n\n  - Made a change to avoid spuriously setting __AFL_SHM_ID when \n    AFL_DUMB_FORKSRV is set in conjunction with -n. Spotted by Jakub Wilk.\n\n--------------\nVersion 1.94b:\n--------------\n\n  - Changed allocator alignment to improve support for non-x86 systems (now\n    that llvm_mode makes this more feasible).\n\n  - Fixed a minor typo in afl-cmin. Spotted by Jonathan Neuschafer.\n\n  - Fixed an obscure bug that would affect people trying to use afl-gcc\n    with $TMP set but $TMPDIR absent. Spotted by Jeremy Barnes.\n\n--------------\nVersion 1.93b:\n--------------\n\n  - Hopefully fixed a problem with MacOS X and persistent mode, spotted by\n    Leo Barnes.\n\n--------------\nVersion 1.92b:\n--------------\n\n  - Made yet another C++ fix (namespaces). Reported by Daniel Lockyer.\n\n--------------\nVersion 1.91b:\n--------------\n\n  - Made another fix to make 1.90b actually work properly with C++ (d'oh).\n    Problem spotted by Daniel Lockyer.\n\n--------------\nVersion 1.90b:\n--------------\n\n  - Fixed a minor typo spotted by Kai Zhao; and made several other minor updates\n    to docs.\n\n  - Updated the project URL for python-afl. Requested by Jakub Wilk.\n\n  - Fixed a potential problem with deferred mode signatures getting optimized\n    out by the linker (with --gc-sections).\n\n--------------\nVersion 1.89b:\n--------------\n\n  - Revamped the support for persistent and deferred forkserver modes.\n    Both now feature simpler syntax and do not require companion env\n    variables. Suggested by Jakub Wilk.\n\n  - Added a bit more info about afl-showmap. Suggested by Jacek Wielemborek.\n\n--------------\nVersion 1.88b:\n--------------\n\n  - Made AFL_EXIT_WHEN_DONE work in non-tty mode. Issue spotted by\n    Jacek Wielemborek.\n\n--------------\nVersion 1.87b:\n--------------\n\n  - Added QuickStartGuide.txt, a one-page quick start doc.\n\n  - Fixed several typos spotted by Dominique Pelle.\n\n  - Revamped several parts of README.\n\n--------------\nVersion 1.86b:\n--------------\n\n  - Added support for AFL_SKIP_CRASHES, which is a very hackish solution to\n    the problem of resuming sessions with intermittently crashing inputs.\n\n  - Removed the hard-fail terminal size check, replaced with a dynamic\n    warning shown in place of the UI. Based on feedback from Christian Holler.\n\n  - Fixed a minor typo in show_stats. Spotted by Dingbao Xie.\n\n--------------\nVersion 1.85b:\n--------------\n\n  - Fixed a garbled sentence in notes on parallel fuzzing. Thanks to Jakub Wilk.\n\n  - Fixed a minor glitch in afl-cmin. Spotted by Jonathan Foote.\n\n--------------\nVersion 1.84b:\n--------------\n\n  - Made SIMPLE_FILES behave as expected when naming backup directories for\n    crashes and hangs.\n\n  - Added the total number of favored paths to fuzzer_stats. Requested by\n    Ben Nagy.\n\n  - Made afl-tmin, afl-fuzz, and afl-cmin reject negative values passed to\n    -t and -m, since they generally won't work as expected.\n\n  - Made a fix for no lahf / sahf support on older versions of FreeBSD.\n    Patch contributed by Alex Moneger.\n\n--------------\nVersion 1.83b:\n--------------\n\n  - Fixed a problem with xargs -d on non-Linux systems in afl-cmin. Spotted by\n    teor2345 and Ben Nagy.\n\n  - Fixed an implicit declaration in LLVM mode on MacOS X. Reported by \n    Kai Zhao.\n\n--------------\nVersion 1.82b:\n--------------\n\n  - Fixed a harmless but annoying race condition in persistent mode - signal\n    delivery is a bit more finicky than I thought.\n\n  - Updated the documentation to explain persistent mode a bit better.\n\n  - Tweaked AFL_PERSISTENT to force AFL_NO_VAR_CHECK.\n\n--------------\nVersion 1.81b:\n--------------\n\n  - Added persistent mode for in-process fuzzing. See llvm_mode/README.llvm.\n    Inspired by Kostya Serebryany and Christian Holler.\n\n  - Changed the in-place resume code to preserve crashes/README.txt. Suggested\n    by Ben Nagy.\n\n  - Included a potential fix for LLVM mode issues on MacOS X, based on the\n    investigation done by teor2345.\n\n--------------\nVersion 1.80b:\n--------------\n\n  - Made afl-cmin tolerant of whitespaces in filenames. Suggested by \n    Jonathan Neuschafer and Ketil Froyn.\n\n  - Added support for AFL_EXIT_WHEN_DONE, as suggested by Michael Rash.\n\n--------------\nVersion 1.79b:\n--------------\n\n  - Added support for dictionary levels, see testcases/README.testcases.\n\n  - Reworked the SQL dictionary to use levels.\n\n  - Added a note about Preeny.\n\n--------------\nVersion 1.78b:\n--------------\n\n  - Added a dictionary for PDF, contributed by Ben Nagy.\n\n  - Added several references to afl-cov, a new tool by Michael Rash.\n\n  - Fixed a problem with crash reporter detection on MacOS X, as reported by\n    Louis Dassy.\n\n--------------\nVersion 1.77b:\n--------------\n\n  - Extended the -x option to support single-file dictionaries.\n\n  - Replaced factory-packaged dictionaries with file-based variants.\n\n  - Removed newlines from HTML keywords in testcases/_extras/html/.\n\n--------------\nVersion 1.76b:\n--------------\n\n  - Very significantly reduced the number of duplicate execs during\n    deterministic checks, chiefly in int16 and int32 stages. Confirmed\n    identical path yields. This should improve early-stage efficiency by\n    around 5-10%.\n\n  - Reduced the likelihood of duplicate non-deterministic execs by\n    bumping up lowest stacking factor from 1 to 2. Quickly confirmed\n    that this doesn't seem to have significant impact on coverage with\n    libpng.\n\n  - Added a note about integrating afl-fuzz with third-party tools.\n\n--------------\nVersion 1.75b:\n--------------\n\n  - Improved argv_fuzzing to allow it to emit empty args. Spotted by Jakub\n    Wilk.\n\n  - afl-clang-fast now defines __AFL_HAVE_MANUAL_INIT. Suggested by Jakub Wilk.\n\n  - Fixed a libtool-related bug with afl-clang-fast that would make some\n    ./configure invocations generate incorrect output. Spotted by Jakub Wilk.\n\n  - Removed flock() on Solaris. This means no locking on this platform,\n    but so be it. Problem reported by Martin Carpenter.\n\n  - Fixed a typo. Reported by Jakub Wilk.\n\n--------------\nVersion 1.74b:\n--------------\n\n  - Added an example argv[] fuzzing wrapper in experimental/argv_fuzzing.\n    Reworked the bash example to be faster, too.\n\n  - Clarified llvm_mode prerequisites for FreeBSD.\n\n  - Improved afl-tmin to use /tmp if cwd is not writeable.\n\n  - Removed redundant includes for sys/fcntl.h, which caused warnings with\n    some nitpicky versions of libc.\n\n  - Added a corpus of basic HTML tags that parsers are likely to pay attention\n    to (no attributes).\n\n  - Added EP_EnabledOnOptLevel0 to llvm_mode, so that the instrumentation is\n    inserted even when AFL_DONT_OPTIMIZE=1 is set.\n\n  - Switched qemu_mode to use the newly-released QEMU 2.3.0, which contains\n    a couple of minor bugfixes.\n\n--------------\nVersion 1.73b:\n--------------\n\n  - Fixed a pretty stupid bug in effector maps that could sometimes cause\n    AFL to fuzz slightly more than necessary; and in very rare circumstances,\n    could lead to SEGV if eff_map is aligned with page boundary and followed\n    by an unmapped page. Spotted by Jonathan Gray.\n\n--------------\nVersion 1.72b:\n--------------\n\n  - Fixed a glitch in non-x86 install, spotted by Tobias Ospelt.\n\n  - Added a minor safeguard to llvm_mode Makefile following a report from\n    Kai Zhao.\n\n--------------\nVersion 1.71b:\n--------------\n\n  - Fixed a bug with installed copies of AFL trying to use QEMU mode. Spotted\n    by G.M. Lime.\n\n  - Added last path / crash / hang times to fuzzer_stats, suggested by\n    Richard Hipp.\n\n  - Fixed a typo, thanks to Jakub Wilk.\n\n--------------\nVersion 1.70b:\n--------------\n\n  - Modified resumption code to reuse the original timeout value when resuming\n    a session if -t is not given. This prevents timeout creep in continuous\n    fuzzing.\n\n  - Added improved error messages for failed handshake when AFL_DEFER_FORKSRV\n    is set.\n\n  - Made a slight improvement to llvm_mode/Makefile based on feedback from\n    Jakub Wilk.\n\n  - Refreshed several bits of documentation.\n\n  - Added a more prominent note about the MacOS X trade-offs to Makefile.\n\n--------------\nVersion 1.69b:\n--------------\n\n  - Added support for deferred initialization in LLVM mode. Suggested by\n    Richard Godbee.\n\n--------------\nVersion 1.68b:\n--------------\n\n  - Fixed a minor PRNG glitch that would make the first seconds of a fuzzing\n    job deterministic. Thanks to Andreas Stieger.\n\n  - Made tmp[] static in the LLVM runtime to keep Valgrind happy (this had\n    no impact on anything else). Spotted by Richard Godbee.\n\n  - Clarified the footnote in README.\n\n--------------\nVersion 1.67b:\n--------------\n\n  - Made one more correction to llvm_mode Makefile, spotted by Jakub Wilk.\n\n--------------\nVersion 1.66b:\n--------------\n\n  - Added CC / CXX support to llvm_mode Makefile. Requested by Charlie Eriksen.\n\n  - Fixed 'make clean' with gmake. Suggested by Oliver Schneider.\n\n  - Fixed 'make -j n clean all'. Suggested by Oliver Schneider.\n\n  - Removed build date and time from banners to give people deterministic\n    builds. Requested by Jakub Wilk.\n\n--------------\nVersion 1.65b:\n--------------\n\n  - Fixed a snafu with some leftover code in afl-clang-fast.\n\n  - Corrected even moar typos.\n\n--------------\nVersion 1.64b:\n--------------\n\n  - Further simplified afl-clang-fast runtime by reverting .init_array to\n    __attribute__((constructor(0)). This should improve compatibility with\n    non-ELF platforms.\n\n  - Fixed a problem with afl-clang-fast and -shared libraries. Simplified\n    the code by getting rid of .preinit_array and replacing it with a .comm\n    object. Problem reported by Charlie Eriksen.\n\n  - Removed unnecessary instrumentation density adjustment for the LLVM mode.\n    Reported by Jonathan Neuschafer.\n\n--------------\nVersion 1.63b:\n--------------\n\n  - Updated cgroups_asan/ with a new version from Sam, made a couple changes\n    to streamline it and keep parallel afl instances in separate groups.\n\n  - Fixed typos, thanks to Jakub Wilk.\n\n--------------\nVersion 1.62b:\n--------------\n\n  - Improved the handling of -x in afl-clang-fast,\n\n  - Improved the handling of low AFL_INST_RATIO settings for QEMU and\n    LLVM modes.\n\n  - Fixed the llvm-config bug for good (thanks to Tobias Ospelt).\n\n--------------\nVersion 1.61b:\n--------------\n\n  - Fixed an obscure bug compiling OpenSSL with afl-clang-fast. Patch by\n    Laszlo Szekeres.\n\n  - Fixed a 'make install' bug on non-x86 systems, thanks to Tobias Ospelt.\n\n  - Fixed a problem with half-broken llvm-config on Odroid, thanks to\n    Tobias Ospelt. (There is another odd bug there that hasn't been fully\n    fixed - TBD).\n\n--------------\nVersion 1.60b:\n--------------\n\n  - Allowed experimental/llvm_instrumentation/ to graduate to llvm_mode/.\n\n  - Removed experimental/arm_support/, since it's completely broken and likely\n    unnecessary with LLVM support in place.\n\n  - Added ASAN cgroups script to experimental/asan_cgroups/, updated existing\n    docs. Courtesy Sam Hakim and David A. Wheeler.\n\n  - Refactored afl-tmin to reduce the number of execs in common use cases.\n    Ideas from Jonathan Neuschafer and Turo Lamminen.\n\n  - Added a note about CLAs at the bottom of README.\n\n  - Renamed testcases_readme.txt to README.testcases for some semblance of\n    consistency.\n\n  - Made assorted updates to docs.\n\n  - Added MEM_BARRIER() to afl-showmap and afl-tmin, just to be safe.\n\n--------------\nVersion 1.59b:\n--------------\n\n  - Imported Laszlo Szekeres' experimental LLVM instrumentation into\n    experimental/llvm_instrumentation. I'll work on including it in the \n    \"mainstream\" version soon.\n\n  - Fixed another typo, thanks to Jakub Wilk.\n\n--------------\nVersion 1.58b:\n--------------\n\n  - Added a workaround for abort() behavior in -lpthread programs in QEMU mode.\n    Spotted by Aidan Thornton.\n\n  - Made several documentation updates, including links to the static\n    instrumentation tool (sister_projects.txt).\n\n--------------\nVersion 1.57b:\n--------------\n\n  - Fixed a problem with exception handling on some versions of MacOS X.\n    Spotted by Samir Aguiar and Anders Wang Kristensen.\n\n  - Tweaked afl-gcc to use BIN_PATH instead of a fixed string in help\n    messages.\n\n--------------\nVersion 1.56b:\n--------------\n\n  - Renamed related_work.txt to historical_notes.txt.\n\n  - Made minor edits to the ASAN doc.\n\n  - Added docs/sister_projects.txt with a list of inspired or closely\n    related utilities.\n\n--------------\nVersion 1.55b:\n--------------\n\n  - Fixed a glitch with afl-showmap opening /dev/null with O_RDONLY when\n    running in quiet mode. Spotted by Tyler Nighswander.\n\n--------------\nVersion 1.54b:\n--------------\n\n  - Added another postprocessor example for PNG.\n\n  - Made a cosmetic fix to realloc() handling in experimental/post_library/,\n    suggested by Jakub Wilk.\n\n  - Improved -ldl handling. Suggested by Jakub Wilk.\n\n--------------\nVersion 1.53b:\n--------------\n\n  - Fixed an -l ordering issue that is apparently still a problem on Ubuntu.\n    Spotted by William Robinet.\n\n--------------\nVersion 1.52b:\n--------------\n\n  - Added support for file format postprocessors. Requested by Ben Nagy. This\n    feature is intentionally buried, since it's fairly easy to misuse and\n    useful only in some scenarios. See experimental/post_library/.\n\n--------------\nVersion 1.51b:\n--------------\n\n  - Made it possible to properly override LD_BIND_NOW after one very unusual\n    report of trouble.\n\n  - Cleaned up typos, thanks to Jakub Wilk.\n\n  - Fixed a bug in AFL_DUMB_FORKSRV.\n\n--------------\nVersion 1.50b:\n--------------\n\n  - Fixed a flock() bug that would prevent dir reuse errors from kicking\n    in every now and then.\n\n  - Renamed references to ppvm (the project is now called recidivm).\n\n  - Made improvements to file descriptor handling to avoid leaving some fds\n    unnecessarily open in the child process.\n\n  - Fixed a typo or two.\n\n--------------\nVersion 1.49b:\n--------------\n\n  - Added code to save original command line in fuzzer_stats and\n    crashes/README.txt. Also saves fuzzer version in fuzzer_stats.\n    Requested by Ben Nagy.\n\n--------------\nVersion 1.48b:\n--------------\n\n  - Fixed a bug with QEMU fork server crashes when translation is attempted\n    after a jump to an invalid pointer in the child process (i.e., after\n    bumping into a particularly nasty security bug in the tested binary).\n    Reported by Tyler Nighswander.\n\n--------------\nVersion 1.47b:\n--------------\n\n  - Fixed a bug with afl-cmin in -Q mode complaining about binary being not\n    instrumented. Thanks to Jonathan Neuschafer for the bug report.\n\n  - Fixed another bug with argv handling for afl-fuzz in -Q mode. Reported\n    by Jonathan Neuschafer.\n\n  - Improved the use of colors when showing crash counts in -C mode.\n\n--------------\nVersion 1.46b:\n--------------\n\n  - Improved instrumentation performance on 32-bit systems by getting rid of\n    xor-swap (oddly enough, xor-swap is still faster on 64-bit) and tweaking\n    alignment.\n\n  - Made path depth numbers more accurate with imported test cases.\n\n--------------\nVersion 1.45b:\n--------------\n\n  - Added support for SIMPLE_FILES in config.h for folks who don't like\n    descriptive file names. Generates very simple names without colons,\n    commas, plus signs, dashes, etc.\n\n  - Replaced zero-sized files with symlinks in the variable behavior state\n    dir to simplify examining the relevant test cases.\n\n  - Changed the period of limited-range block ops from 5 to 10 minutes based\n    on a couple of experiments. The basic goal of this delay timer behavior\n    is to better support jobs that are seeded with completely invalid files,\n    in which case, the first few queue cycles may be completed very quickly\n    without discovering new paths. Should have no effect on well-seeded jobs.\n\n  - Made several minor updates to docs.\n\n--------------\nVersion 1.44b:\n--------------\n\n  - Corrected two bungled attempts to get the -C mode work properly\n    with afl-cmin (accounting for the short-lived releases tagged 1.42 and\n    1.43b) - sorry.\n\n  - Removed AFL_ALLOW_CRASHES in favor of the -C mode in said tool.\n\n  - Said goodbye to Hello Kitty, as requested by Padraig Brady.\n\n--------------\nVersion 1.41b:\n--------------\n\n  - Added AFL_ALLOW_CRASHES=1 to afl-cmin. Allows crashing inputs in the\n    output corpus. Changed the default behavior to disallow it.\n\n  - Made the afl-cmin output dir default to 0700, not 0755, to be consistent\n    with afl-fuzz; documented the rationale for 0755 in afl-plot.\n\n  - Lowered the output dir reuse time limit to 25 minutes as a dice-roll\n    compromise after a discussion on afl-users@.\n\n  - Made afl-showmap accept -o /dev/null without borking out.\n\n  - Added support for crash / hang info in exit codes of afl-showmap.\n\n  - Tweaked block operation scaling to also factor in ballpark run time\n    in cases where queue passes take very little time.\n\n  - Fixed typos and made improvements to several docs.\n\n--------------\nVersion 1.40b:\n--------------\n\n  - Switched to smaller block op sizes during the first passes over the\n    queue. Helps keep test cases small.\n\n  - Added memory barrier for run_target(), just in case compilers get\n    smarter than they are today.\n\n  - Updated a bunch of docs.\n\n--------------\nVersion 1.39b:\n--------------\n\n  - Added the ability to skip inputs by sending SIGUSR1 to the fuzzer.\n\n  - Reworked several portions of the documentation.\n\n  - Changed the code to reset splicing perf scores between runs to keep\n    them closer to intended length.\n\n  - Reduced the minimum value of -t to 5 for afl-fuzz (~200 exec/sec)\n    and to 10 for auxiliary tools (due to the absence of a fork server).\n\n  - Switched to more aggressive default timeouts (rounded up to 25 ms\n    versus 50 ms - ~40 execs/sec) and made several other cosmetic changes\n    to the timeout code.\n\n--------------\nVersion 1.38b:\n--------------\n\n  - Fixed a bug in the QEMU build script, spotted by William Robinet.\n\n  - Improved the reporting of skipped bitflips to keep the UI counters a bit\n    more accurate.\n\n  - Cleaned up related_work.txt and added some non-goals.\n\n  - Fixed typos, thanks to Jakub Wilk.\n\n--------------\nVersion 1.37b:\n--------------\n\n  - Added effector maps, which detect regions that do not seem to respond\n    to bitflips and subsequently exclude them from more expensive steps\n    (arithmetics, known ints, etc). This should offer significant performance\n    improvements with quite a few types of text-based formats, reducing the\n    number of deterministic execs by a factor of 2 or so.\n\n  - Cleaned up mem limit handling in afl-cmin.\n\n  - Switched from uname -i to uname -m to work around Gentoo-specific\n    issues with coreutils when building QEMU. Reported by William Robinet.\n\n  - Switched from PID checking to flock() to detect running sessions.\n    Problem, against all odds, bumped into by Jakub Wilk.\n\n  - Added SKIP_COUNTS and changed the behavior of COVERAGE_ONLY in config.h.\n    Useful only for internal benchmarking.\n\n  - Made improvements to UI refresh rates and exec/sec stats to make them\n    more stable.\n\n  - Made assorted improvements to the documentation and to the QEMU build\n    script.\n\n  - Switched from perror() to strerror() in error macros, thanks to Jakub\n    Wilk for the nag.\n\n  - Moved afl-cmin back to bash, wasn't thinking straight. It has to stay\n    on bash because other shells may have restrictive limits on array sizes.\n\n--------------\nVersion 1.36b:\n--------------\n\n  - Switched afl-cmin over to /bin/sh. Thanks to Jonathan Gray.\n\n  - Fixed an off-by-one bug in queue limit check when resuming sessions\n    (could cause NULL ptr deref if you are *really* unlucky).\n\n  - Fixed the QEMU script to tolerate i686 if returned by uname -i. Based on\n    a problem report from Sebastien Duquette.\n\n  - Added multiple references to Jakub's ppvm tool.\n\n  - Made several minor improvements to the Makefile.\n\n  - Believe it or not, fixed some typos. Thanks to Jakub Wilk.\n\n--------------\nVersion 1.35b:\n--------------\n\n  - Cleaned up regular expressions in some of the scripts to avoid errors\n    on *BSD systems. Spotted by Jonathan Gray.\n\n--------------\nVersion 1.34b:\n--------------\n\n  - Performed a substantial documentation and program output cleanup to\n    better explain the QEMU feature.\n\n--------------\nVersion 1.33b:\n--------------\n\n  - Added support for AFL_INST_RATIO and AFL_INST_LIBS in the QEMU mode.\n\n  - Fixed a stack allocation crash in QEMU mode (bug in QEMU, fixed with\n    an extra patch applied to the downloaded release).\n\n  - Added code to test the QEMU instrumentation once the afl-qemu-trace\n    binary is built.\n\n  - Modified afl-tmin and afl-showmap to search $PATH for binaries and to\n    better handle QEMU support.\n\n  - Added a check for instrumented binaries when passing -Q to afl-fuzz.\n\n--------------\nVersion 1.32b:\n--------------\n\n  - Fixed 'make install' following the QEMU changes. Spotted by Hanno Boeck.\n\n  - Fixed EXTRA_PAR handling in afl-cmin.\n\n--------------\nVersion 1.31b:\n--------------\n\n  - Hallelujah! Thanks to Andrew Griffiths, we now support very fast, black-box\n    instrumentation of binary-only code. See qemu_mode/README.qemu.\n\n    To use this feature, you need to follow the instructions in that\n    directory and then run afl-fuzz with -Q.\n\n--------------\nVersion 1.30b:\n--------------\n\n  - Added -s (summary) option to afl-whatsup. Suggested by Jodie Cunningham.\n\n  - Added a sanity check in afl-tmin to detect minimization to zero len or\n    excess hangs.\n\n  - Fixed alphabet size counter in afl-tmin.\n\n  - Slightly improved the handling of -B in afl-fuzz.\n\n  - Fixed process crash messages with -m none.\n\n--------------\nVersion 1.29b:\n--------------\n\n  - Improved the naming of test cases when orig: is already present in the file\n    name.\n\n  - Made substantial improvements to technical_details.txt.\n\n--------------\nVersion 1.28b:\n--------------\n\n  - Made a minor tweak to the instrumentation to preserve the directionality\n    of tuples (i.e., A -> B != B -> A) and to maintain the identity of tight\n    loops (A -> A). You need to recompile targeted binaries to leverage this.\n\n  - Cleaned up some of the afl-whatsup stats.\n\n  - Added several sanity checks to afl-cmin.\n\n--------------\nVersion 1.27b:\n--------------\n\n  - Made afl-tmin recursive. Thanks to Hanno Boeck for the tip.\n\n  - Added docs/technical_details.txt.\n\n  - Changed afl-showmap search strategy in afl-cmap to just look into the\n    same place that afl-cmin is executed from. Thanks to Jakub Wilk.\n\n  - Removed current_todo.txt and cleaned up the remaining docs.\n\n--------------\nVersion 1.26b:\n--------------\n\n  - Added total execs/sec stat for afl-whatsup.\n\n  - afl-cmin now auto-selects between cp or ln. Based on feedback from\n    Even Huus.\n\n  - Fixed a typo. Thanks to Jakub Wilk.\n\n  - Made afl-gotcpu a bit more accurate by using getrusage instead of\n    times. Thanks to Jakub Wilk.\n\n  - Fixed a memory limit issue during the build process on NetBSD-current.\n    Reported by Thomas Klausner.\n\n--------------\nVersion 1.25b:\n--------------\n\n  - Introduced afl-whatsup, a simple tool for querying the status of\n    local synced instances of afl-fuzz.\n\n  - Added -x compiler to clang options on Darwin. Suggested by Filipe\n    Cabecinhas.\n\n  - Improved exit codes for afl-gotcpu.\n\n  - Improved the checks for -m and -t values in afl-cmin. Bug report\n    from Evan Huus.\n\n--------------\nVersion 1.24b:\n--------------\n\n  - Introduced afl-getcpu, an experimental tool to empirically measure\n    CPU preemption rates. Thanks to Jakub Wilk for the idea.\n\n--------------\nVersion 1.23b:\n--------------\n\n  - Reverted one change to afl-cmin that actually made it slower.\n\n--------------\nVersion 1.22b:\n--------------\n\n  - Reworked afl-showmap.c to support normal options, including -o, -q,\n    -e. Also added support for timeouts and memory limits.\n\n  - Made changes to afl-cmin and other scripts to accommodate the new\n    semantics.\n\n  - Officially retired AFL_EDGES_ONLY.\n\n  - Fixed another typo in afl-tmin, courtesy of Jakub Wilk.\n\n--------------\nVersion 1.21b:\n--------------\n\n  - Graduated minimize_corpus.sh to afl-cmin. It is now a first-class\n    utility bundled with the fuzzer. \n\n  - Made significant improvements to afl-cmin to make it faster, more\n    robust, and more versatile.\n\n  - Refactored some of afl-tmin code to make it a bit more readable.\n\n  - Made assorted changes to the doc to document afl-cmin and other stuff.\n\n--------------\nVersion 1.20b:\n--------------\n\n  - Added AFL_DUMB_FORKSRV, as requested by Jakub Wilk. This works only\n    in -n mode and allows afl-fuzz to run with \"dummy\" fork servers that\n    don't output any instrumentation, but follow the same protocol.\n\n  - Renamed AFL_SKIP_CHECKS to AFL_SKIP_BIN_CHECK to make it at least\n    somewhat descriptive.\n\n  - Switched to using clang as the default assembler on MacOS X to work\n    around Xcode issues with newer builds of clang. Testing and patch by\n    Nico Weber.\n\n  - Fixed a typo (via Jakub Wilk).\n\n--------------\nVersion 1.19b:\n--------------\n\n  - Improved exec failure detection in afl-fuzz and afl-showmap.\n\n  - Improved Ctrl-C handling in afl-showmap.\n\n  - Added afl-tmin, a handy instrumentation-enabled minimizer.\n\n--------------\nVersion 1.18b:\n--------------\n\n  - Fixed a serious but short-lived bug in the resumption behavior introduced\n    in version 1.16b.\n\n  - Added -t nn+ mode for soft-skipping timing-out paths.\n\n--------------\nVersion 1.17b:\n--------------\n\n  - Fixed a compiler warning introduced in 1.16b for newer versions of GCC.\n    Thanks to Jakub Wilk and Ilfak Guilfanov.\n\n  - Improved the consistency of saving fuzzer_stats, bitmap info, and\n    auto-dictionaries when aborting fuzzing sessions.\n\n  - Made several noticeable performance improvements to deterministic arith\n    and known int steps.\n\n--------------\nVersion 1.16b:\n--------------\n\n  - Added a bit of code to make resumption pick up from the last known\n    offset in the queue, rather than always rewinding to the start. Suggested\n    by Jakub Wilk.\n\n  - Switched to tighter timeout control for slow programs (3x rather than\n    5x average exec speed at init).\n\n--------------\nVersion 1.15b:\n--------------\n\n  - Added support for AFL_NO_VAR_CHECK to speed up resumption and inhibit\n    variable path warnings for some programs.\n\n  - Made the trimmer run even for variable paths, since there is no special\n    harm in doing so and it can be very beneficial if the trimming still\n    pans out.\n\n  - Made the UI a bit more descriptive by adding \"n/a\" instead of \"0\" in a\n    couple of corner cases.\n\n--------------\nVersion 1.14b:\n--------------\n\n  - Added a (partial) dictionary for JavaScript.\n\n  - Added AFL_NO_CPU_RED, as suggested by Jakub Wilk.\n\n  - Tweaked the havoc scaling logic added in 1.12b.\n\n--------------\nVersion 1.13b:\n--------------\n\n  - Improved the performance of minimize_corpus.sh by switching to a\n    sort-based approach.\n\n  - Made several minor revisions to the docs.\n\n--------------\nVersion 1.12b:\n--------------\n\n  - Made an improvement to dictionary generation to avoid runs of identical\n    bytes.\n\n  - Added havoc cycle scaling to help with slow binaries in -d mode. Based on\n    a thread with Sami Liedes.\n\n  - Added AFL_SYNC_FIRST for afl-fuzz. This is useful for those who obsess\n    over stats, no special purpose otherwise.\n\n  - Switched to more robust box drawing codes, suggested by Jakub Wilk.\n\n  - Created faster 64-bit variants of several critical-path bitmap functions\n    (sorry, no difference on 32 bits).\n\n  - Fixed moar typos, as reported by Jakub Wilk.\n\n--------------\nVersion 1.11b:\n--------------\n\n  - Added a bit more info about dictionary strategies to the status screen.\n\n--------------\nVersion 1.10b:\n--------------\n\n  - Revised the dictionary behavior to use insertion and overwrite in\n    deterministic steps, rather than just the latter. This improves coverage\n    with SQL and the like.\n\n  - Added a mention of \"*\" in status_screen.txt, as suggested by Jakub Wilk.\n\n--------------\nVersion 1.09b:\n--------------\n\n  - Corrected a cosmetic problem with 'extras' stage count not always being\n    accurate in the stage yields view.\n\n  - Fixed a typo reported by Jakub Wilk and made some minor documentation\n    improvements.\n\n--------------\nVersion 1.08b:\n--------------\n\n  - Fixed a div-by-zero bug in the newly-added code when using a dictionary.\n\n--------------\nVersion 1.07b:\n--------------\n\n  - Added code that automatically finds and extracts syntax tokens from the\n    input corpus.\n\n  - Fixed a problem with ld dead-code removal option on MacOS X, reported\n    by Filipe Cabecinhas.\n\n  - Corrected minor typos spotted by Jakub Wilk.\n\n  - Added a couple of more exotic archive format samples.\n\n--------------\nVersion 1.06b:\n--------------\n\n  - Switched to slightly more accurate (if still not very helpful) reporting\n    of short read and short write errors. These theoretically shouldn't happen\n    unless you kill the forkserver or run out of disk space. Suggested by\n    Jakub Wilk.\n\n  - Revamped some of the allocator and debug code, adding comments and\n    cleaning up other mess.\n\n  - Tweaked the odds of fuzzing non-favored test cases to make sure that\n    baseline coverage of all inputs is reached sooner.\n\n--------------\nVersion 1.05b:\n--------------\n\n  - Added a dictionary for WebP.\n\n  - Made some additional performance improvements to minimize_corpus.sh,\n    getting deeper into the bash woods.\n\n--------------\nVersion 1.04b:\n--------------\n\n  - Made substantial performance improvements to minimize_corpus.sh with\n    large datasets, albeit at the expense of having to switch back to bash\n    (other shells may have limits on array sizes, etc).\n\n  - Tweaked afl-showmap to support the format used by the new script.\n\n--------------\nVersion 1.03b:\n--------------\n\n  - Added code to skip README.txt in the input directory to make the crash\n    exploration mode work better. Suggested by Jakub Wilk.\n\n  - Added a dictionary for SQLite.\n\n--------------\nVersion 1.02b:\n--------------\n\n  - Reverted the ./ search path in minimize_corpus.sh because people did\n    not like it.\n\n  - Added very explicit warnings not to run various shell scripts that\n    read or write to /tmp/ (since this is generally a pretty bad idea on\n    multi-user systems).\n\n  - Added a check for /tmp binaries and -f locations in afl-fuzz.\n\n--------------\nVersion 1.01b:\n--------------\n\n  - Added dictionaries for XML and GIF.\n\n--------------\nVersion 1.00b:\n--------------\n\n  - Slightly improved the performance of minimize_corpus.sh, especially on\n    Linux.\n\n  - Made a couple of improvements to calibration timeouts for resumed scans.\n\n--------------\nVersion 0.99b:\n--------------\n\n  - Fixed minimize_corpus.sh to work with dash, as suggested by Jakub Wilk.\n\n  - Modified minimize_corpus.sh to try locate afl-showmap in $PATH and ./.\n    The first part requested by Jakub Wilk.\n\n  - Added support for afl-as --version, as required by one funky build\n    script. Reported by William Robinet.\n\n--------------\nVersion 0.98b:\n--------------\n\n  - Added a dictionary for TIFF.\n\n  - Fixed another cosmetic snafu with stage exec counts for -x.\n\n  - Switched afl-plot to /bin/sh, since it seems bashism-free. Also tried\n    to remove any obvious bashisms from other experimental/ scripts,\n    most notably including minimize_corpus.sh and triage_crashes.sh.\n    Requested by Jonathan Gray.\n\n--------------\nVersion 0.97b:\n--------------\n\n  - Fixed cosmetic issues around the naming of -x strategy files.\n\n  - Added a dictionary for JPEG.\n\n  - Fixed a very rare glitch when running instrumenting 64-bit code that makes\n    heavy use of xmm registers that are also touched by glibc.\n\n--------------\nVersion 0.96b:\n--------------\n\n  - Added support for extra dictionaries, provided testcases/_extras/png/\n    as a demo.\n\n  - Fixed a minor bug in number formatting routines used by the UI.\n\n  - Added several additional PNG test cases that are relatively unlikely\n    to be hit by chance.\n\n  - Fixed afl-plot syntax for gnuplot 5.x. Reported by David Necas.\n\n--------------\nVersion 0.95b:\n--------------\n\n  - Cleaned up the OSX ReportCrash code. Thanks to Tobias Ospelt for help.\n\n  - Added some extra tips for AFL_NO_FORKSERVER on OSX.\n\n  - Refreshed the INSTALL file.\n\n--------------\nVersion 0.94b:\n--------------\n\n  - Added in-place resume (-i-) to address a common user complaint.\n\n  - Added an awful workaround for ReportCrash on MacOS X. Problem\n    spotted by Joseph Gentle.\n\n--------------\nVersion 0.93b:\n--------------\n\n  - Fixed the link() workaround, as reported by Jakub Wilk.\n\n--------------\nVersion 0.92b:\n--------------\n\n  - Added support for reading test cases from another filesystem.\n    Requested by Jakub Wilk.\n\n  - Added pointers to the mailing list.\n\n  - Added a sample PDF document.\n\n--------------\nVersion 0.91b:\n--------------\n\n  - Refactored minimize_corpus.sh to make it a bit more user-friendly and to\n    select for smallest files, not largest bitmaps. Offers a modest corpus\n    size improvement in most cases.\n\n  - Slightly improved the performance of splicing code.\n\n--------------\nVersion 0.90b:\n--------------\n\n  - Moved to an algorithm where paths are marked as preferred primarily based\n    on size and speed, rather than bitmap coverage. This should offer\n    noticeable performance gains in many use cases.\n\n  - Refactored path calibration code; calibration now takes place as soon as a\n    test case is discovered, to facilitate better prioritization decisions later\n    on.\n\n  - Changed the way of marking variable paths to avoid .state metadata\n    inconsistencies.\n\n  - Made sure that calibration routines always create a new test case to avoid\n    hypothetical problems with utilities that modify the input file.\n\n  - Added bitmap saturation to fuzzer stats and plot data.\n\n  - Added a testcase for JPEG XR.\n\n  - Added a tty check for the colors warning in Makefile, to keep distro build\n    logs tidy. Suggested by Jakub Wilk.\n\n--------------\nVersion 0.89b:\n--------------\n\n  - Renamed afl-plot.sh to afl-plot, as requested by Padraig Brady.\n\n  - Improved the compatibility of afl-plot with older versions of gnuplot.\n\n  - Added banner information to fuzzer_stats, populated it to afl-plot.\n\n--------------\nVersion 0.88b:\n--------------\n\n  - Added support for plotting, with design and implementation based on a\n    prototype design proposed by Michael Rash. Huge thanks!\n\n  - Added afl-plot.sh, which allows you to, well, generate a nice plot using\n    this data.\n\n  - Refactored the code slightly to make more frequent updates to fuzzer_stats\n    and to provide more detail about synchronization.\n\n  - Added a fflush(stdout) call for non-tty operation, as requested by \n    Joonas Kuorilehto.\n\n  - Added some detail to fuzzer_stats for parity with plot_file.\n\n--------------\nVersion 0.87b:\n--------------\n\n  - Added support for MSAN, via AFL_USE_MSAN, same gotchas as for ASAN.\n\n--------------\nVersion 0.86b:\n--------------\n\n  - Added AFL_NO_FORKSRV, allowing the forkserver to be bypassed. Suggested\n    by Ryan Govostes.\n\n  - Simplified afl-showmap.c to make use of the no-forkserver mode.\n\n  - Made minor improvements to crash_triage.sh, as suggested by Jakub Wilk.\n\n--------------\nVersion 0.85b:\n--------------\n\n  - Fixed the CPU counting code - no sysctlbyname() on OpenBSD, d'oh. Bug\n    reported by Daniel Dickman.\n\n  - Made a slight correction to error messages - the advice on testing\n    with ulimit was a tiny bit off by a factor of 1024.\n\n--------------\nVersion 0.84b:\n--------------\n\n  - Added support for the CPU widget on some non-Linux platforms (I hope).\n    Based on feedback from Ryan Govostes.\n\n  - Cleaned up the changelog (very meta).\n\n--------------\nVersion 0.83b:\n--------------\n\n  - Added experimental/clang_asm_normalize/ and related notes in \n    env_variables.txt and afl-as.c. Thanks to Ryan Govostes for the idea.\n\n  - Added advice on hardware utilization in README.\n\n--------------\nVersion 0.82b:\n--------------\n\n  - Made additional fixes for Xcode support, juggling -Q and -q flags. Thanks to\n    Ryan Govostes.\n\n  - Added a check for __asm__ blocks and switches to .intel_syntax in assembly.\n    Based on feedback from Ryan Govostes.\n\n--------------\nVersion 0.81b:\n--------------\n\n  - A workaround for Xcode 6 as -Q flag glitch. Spotted by Ryan Govostes.\n\n  - Improved Solaris build instructions, as suggested by Martin Carpenter.\n\n  - Fix for a slightly busted path scoring conditional. Minor practical impact.\n\n--------------\nVersion 0.80b:\n--------------\n\n  - Added a check for $PATH-induced loops. Problem noticed by Kartik Agaram.\n\n  - Added AFL_KEEP_ASSEMBLY for easier troubleshooting.\n\n  - Added an override for AFL_USE_ASAN if set at afl compile time. Requested by\n    Hanno Boeck.\n\n--------------\nVersion 0.79b:\n--------------\n\n  - Made minor adjustments to path skipping logic.\n\n  - Made several documentation updates to reflect the path selection changes\n    made in 0.78b.\n\n--------------\nVersion 0.78b:\n--------------\n\n  - Added a CPU governor check. Bug report from Joe Zbiciak.\n\n  - Favored paths are now selected strictly based on new edges, not hit\n    counts. This speeds up the first pass by a factor of 3-6x without\n    significantly impacting ultimate coverage (tested with libgif, libpng,\n    libjpeg).\n\n    It also allows some performance & memory usage improvements by making\n    some of the in-memory bitmaps much smaller.\n\n  - Made multiple significant performance improvements to bitmap checking\n    functions, plus switched to a faster hash.\n\n  - Owing largely to these optimizations, bumped the size of the bitmap to\n    64k and added a warning to detect older binaries that rely on smaller\n    bitmaps.\n\n--------------\nVersion 0.77b:\n--------------\n\n  - Added AFL_SKIP_CHECKS to bypass binary checks when really warranted.\n    Feature requested by Jakub Wilk.\n\n  - Fixed a couple of typos.\n\n  - Added a warning for runs that are aborted early on.\n\n--------------\nVersion 0.76b:\n--------------\n\n  - Incorporated another signal handling fix for Solaris. Suggestion\n    submitted by Martin Carpenter.\n\n--------------\nVersion 0.75b:\n--------------\n\n  - Implemented a slightly more \"elegant\" kludge for the %llu glitch (see\n    types.h).\n\n  - Relaxed CPU load warnings to stay in sync with reality.\n\n--------------\nVersion 0.74b:\n--------------\n\n  - Switched to more responsive exec speed averages and better UI speed\n    scaling.\n\n  - Fixed a bug with interrupted reads on Solaris. Issue spotted by Martin\n    Carpenter.\n\n--------------\nVersion 0.73b:\n--------------\n\n  - Fixed a stray memcpy() instead of memmove() on overlapping buffers.\n    Mostly harmless but still dumb. Mistake spotted thanks to David Higgs.\n\n--------------\nVersion 0.72b:\n--------------\n\n  - Bumped map size up to 32k. You may want to recompile instrumented\n    binaries (but nothing horrible will happen if you don't).\n\n  - Made huge performance improvements for bit-counting functions.\n\n  - Default optimizations now include -funroll-loops. This should have\n    interesting effects on the instrumentation. Frankly, I'm just going to\n    ship it and see what happens next. I have a good feeling about this.\n\n  - Made a fix for stack alignment crash on MacOS X 10.10; looks like the \n    rhetorical question in the comments in afl-as.h has been answered.\n    Tracked down by Mudge Zatko.\n\n--------------\nVersion 0.71b:\n--------------\n\n  - Added a fix for the nonsensical MacOS ELF check. Spotted by Mudge Zatko.\n\n  - Made some improvements to ASAN checks.\n\n--------------\nVersion 0.70b:\n--------------\n\n  - Added explicit detection of ASANified binaries.\n\n  - Fixed compilation issues on Solaris. Reported by Martin Carpenter.\n\n--------------\nVersion 0.69b:\n--------------\n\n  - Improved the detection of non-instrumented binaries.\n\n  - Made the crash counter in -C mode accurate.\n\n  - Fixed an obscure install bug that made afl-as non-functional with the tool\n    installed to /usr/bin instead of /usr/local/bin. Found by Florian Kiersch.\n\n  - Fixed for a cosmetic SIGFPE when Ctrl-C is pressed while the fork server\n    is spinning up.\n\n--------------\nVersion 0.68b:\n--------------\n\n  - Added crash exploration mode! Woot!\n\n--------------\nVersion 0.67b:\n--------------\n\n  - Fixed several more typos, the project is now cartified 100% typo-free.\n    Thanks to Thomas Jarosch and Jakub Wilk.\n\n  - Made a change to write fuzzer_stats early on.\n\n  - Fixed a glitch when (not!) running on MacOS X as root. Spotted by Tobias\n    Ospelt.\n\n  - Made it possible to override -O3 in Makefile. Suggested by Jakub Wilk.\n\n--------------\nVersion 0.66b:\n--------------\n\n  - Fixed a very obscure issue with build systems that use gcc as an assembler\n    for hand-written .s files; this would confuse afl-as. Affected nss, reported\n    by Hanno Boeck.\n\n  - Fixed a bug when cleaning up synchronized fuzzer output dirs. Issue reported\n    by Thomas Jarosch.\n\n--------------\nVersion 0.65b:\n--------------\n\n  - Cleaned up shell printf escape codes in Makefile. Reported by Jakub Wilk.\n\n  - Added more color to fuzzer_stats, provided short documentation of the file\n    format, and made several other stats-related improvements.\n\n--------------\nVersion 0.64b:\n--------------\n\n  - Enabled GCC support on MacOS X.\n\n--------------\nVersion 0.63b:\n--------------\n\n  - Provided a new, simplified way to pass data in files (@@). See README.\n\n  - Made additional fixes for 64-bit MacOS X, working around a crashing bug in\n    their linker (umpf) and several other things. It's alive!\n\n  - Added a minor workaround for a bug in 64-bit FreeBSD (clang -m32 -g doesn't\n    work on that platform, but clang -m32 does, so we no longer insert -g).\n\n  - Added a build-time warning for inverse video terminals and better\n    instructions in status_screen.txt.\n\n--------------\nVersion 0.62b:\n--------------\n\n  - Made minor improvements to the allocator, as suggested by Tobias Ospelt.\n\n  - Added example instrumented memcmp() in experimental/instrumented_cmp.\n\n  - Added a speculative fix for MacOS X (clang detection, again).\n\n  - Fixed typos in parallel_fuzzing.txt. Problems spotted by Thomas Jarosch.\n\n--------------\nVersion 0.61b:\n--------------\n\n  - Fixed a minor issue with clang detection on systems with a clang cc\n    wrapper, so that afl-gcc doesn't confuse it with GCC.\n\n  - Made cosmetic improvements to docs and to the CPU load indicator.\n\n  - Fixed a glitch with crash removal (README.txt left behind, d'oh).\n\n--------------\nVersion 0.60b:\n--------------\n\n  - Fixed problems with jump tables generated by exotic versions of GCC. This\n    solves an outstanding problem on OpenBSD when using afl-gcc + PIE (not\n    present with afl-clang).\n\n  - Fixed permissions on one of the sample archives.\n\n  - Added a lahf / sahf workaround for OpenBSD (their assembler doesn't know\n    about these opcodes).\n\n  - Added docs/INSTALL.\n\n--------------\nVersion 0.59b:\n--------------\n\n  - Modified 'make install' to also install test cases.\n\n  - Provided better pointers to installed README in afl-fuzz.\n\n  - More work on RLIMIT_AS for OpenBSD.\n\n--------------\nVersion 0.58b:\n--------------\n\n  - Added a core count check on Linux.\n\n  - Refined the code for the lack-of-RLIMIT_AS case on OpenBSD.\n\n  - Added a rudimentary CPU utilization meter to help with optimal loading.\n\n--------------\nVersion 0.57b:\n--------------\n\n  - Made fixes to support FreeBSD and OpenBSD: use_64bit is now inferred if not\n    explicitly specified when calling afl-as, and RLIMIT_AS is behind an #ifdef.\n    Thanks to Fabian Keil and Jonathan Gray for helping troubleshoot this.\n\n  - Modified 'make install' to also install docs (in /usr/local/share/doc/afl).\n\n  - Fixed a typo in status_screen.txt.\n\n  - Made a couple of Makefile improvements as proposed by Jakub Wilk.\n\n--------------\nVersion 0.56b:\n--------------\n\n  - Added probabilistic instrumentation density reduction in ASAN mode. This\n    compensates for ASAN-specific branches in a crude but workable way.\n\n  - Updated notes_for_asan.txt.\n\n--------------\nVersion 0.55b:\n--------------\n\n  - Implemented smarter out_dir behavior, automatically deleting directories\n    that don't contain anything of special value. Requested by several folks,\n    including Hanno Boeck.\n\n  - Added more detail in fuzzer_stats (start time, run time, fuzzer PID).\n\n  - Implemented support for configurable install prefixes in Makefile\n    ($PREFIX), as requested by Luca Barbato.\n\n  - Made it possible to resume by doing -i <out_dir>, without having to specify\n    -i <out_dir>/queue/.\n\n--------------\nVersion 0.54b:\n--------------\n\n  - Added a fix for -Wformat warning messages (oops, I thought this had been in\n    place for a while).\n\n--------------\nVersion 0.53b:\n--------------\n\n  - Redesigned the crash & hang duplicate detection code to better deal with\n    fault conditions that can be reached in a multitude of ways.\n\n    The old approach could be compared to hashing stack traces to de-dupe\n    crashes, a method prone to crash count inflation. The alternative I\n    wanted to avoid would be equivalent to just looking at crash %eip,\n    which can have false negatives in common functions such as memcpy().\n\n    The middle ground currently used in afl-fuzz can be compared to looking\n    at every line item in the stack trace and tagging crashes as unique if\n    we see any function name that we haven't seen before (or if something that\n    we have *always* seen there suddenly disappears). We do the comparison\n    without paying any attention to ordering or hit counts. This can still\n    cause some crash inflation early on, but the problem will quickly taper\n    off. So, you may get 20 dupes instead of 5,000.\n    \n  - Added a fix for harmless but absurd trim ratios shown if the first exec in\n    the trimmer timed out. Spotted by @EspenGx.\n\n--------------\nVersion 0.52b:\n--------------\n\n  - Added a quick summary of the contents in experimental/.\n\n  - Made a fix to the process of writing fuzzer_stats.\n\n  - Slightly reorganized the .state/ directory, now recording redundant paths,\n    too. Note that this breaks the ability to properly resume older sessions \n    - sorry about that.\n\n    (To fix this, simply move <out_dir>/.state/* from an older run\n    to <out_dir>/.state/deterministic_done/*.)\n\n--------------\nVersion 0.51b:\n--------------\n\n  - Changed the search order for afl-as to avoid the problem with older copies\n    installed system-wide; this also means that I can remove the Makefile check\n    for that.\n\n  - Made it possible to set instrumentation ratio of 0%.\n\n  - Introduced some typos, fixed others.\n\n  - Fixed the test_prev target in Makefile, as reported by Ozzy Johnson.\n\n--------------\nVersion 0.50b:\n--------------\n\n  - Improved the 'make install' logic, as suggested by Padraig Brady.\n\n  - Revamped various bits of the documentation, especially around perf_tips.txt;\n    based on the feedback from Alexander Cherepanov.\n\n  - Added AFL_INST_RATIO to afl-as. The only case where this comes handy is\n    ffmpeg, at least as far as I can tell. (Trivia: the current version of \n    ffmpeg ./configure also ignores CC and --cc, probably unintentionally).\n\n  - Added documentation for all environmental variables (env_variables.txt).\n\n  - Implemented a visual warning for excessive or insufficient bitmap density.\n\n  - Changed afl-gcc to add -O3 by default; use AFL_DONT_OPTIMIZE if you don't\n    like that. Big speed gain for ffmpeg, so seems like a good idea.\n\n  - Made a regression fix to afl-as to ignore .LBB labels in gcc mode.\n\n--------------\nVersion 0.49b:\n--------------\n\n  - Fixed more typos, as found by Jakub Wilk.\n\n  - Added support for clang!\n\n  - Changed AFL_HARDEN to *not* include ASAN by default. Use AFL_USE_ASAN if\n    needed. The reasons for this are in notes_for_asan.txt.\n\n  - Switched from configure auto-detection to isatty() to keep afl-as and\n    afl-gcc quiet.\n\n  - Improved installation process to properly create symlinks, rather than\n    copies of binaries.\n\n--------------\nVersion 0.48b:\n--------------\n\n  - Improved afl-fuzz to force-set ASAN_OPTIONS=abort_on_error=1. Otherwise,\n    ASAN crashes wouldn't be caught at all. Reported by Hanno Boeck.\n\n  - Improved Makefile mkdir logic, as suggested by Hanno Boeck.\n\n  - Improved the 64-bit instrumentation to properly save r8-r11 registers in\n    the x86 setup code. The old behavior could cause rare problems running\n    *without* instrumentation when the first function called in a particular\n    .o file has 5+ parameters. No impact on code running under afl-fuzz or\n    afl-showmap. Issue spotted by Padraig Brady.\n\n--------------\nVersion 0.47b:\n--------------\n\n  - Fixed another Makefile bug for parallel builds of afl. Problem identified\n    by Richard W. M. Jones.\n\n  - Added support for suffixes for -m.\n\n  - Updated the documentation and added notes_for_asan.txt. Based on feedback\n    from Hanno Boeck, Ben Laurie, and others.\n\n  - Moved the project to http://lcamtuf.coredump.cx/afl/.\n\n--------------\nVersion 0.46b:\n--------------\n\n  - Cleaned up Makefile dependencies for parallel builds. Requested by \n    Richard W. M. Jones.\n\n  - Added support for DESTDIR in Makefile. Once again suggested by\n    Richard W. M. Jones :-)\n\n  - Removed all the USE_64BIT stuff; we now just auto-detect compilation mode.\n    As requested by many callers to the show.\n\n  - Fixed rare problems with programs that use snippets of assembly and\n    switch between .code32 and .code64. Addresses a glitch spotted by\n    Hanno Boeck with compiling ToT gdb.\n\n--------------\nVersion 0.45b:\n--------------\n\n  - Implemented a test case trimmer. Results in 20-30% size reduction for many\n    types of work loads, with very pronounced improvements in path discovery\n    speeds.\n\n  - Added better warnings for various problems with input directories.\n\n  - Added a Makefile warning for older copies, based on counterintuitive\n    behavior observed by Hovik Manucharyan.\n\n  - Added fuzzer_stats file for status monitoring. Suggested by @dronesec.\n\n  - Fixed moar typos, thanks to Alexander Cherepanov.\n\n  - Implemented better warnings for ASAN memory requirements, based on calls\n    from several angry listeners.\n\n  - Switched to saner behavior with non-tty stdout (less output generated,\n    no ANSI art).\n\n--------------\nVersion 0.44b:\n--------------\n\n  - Added support for AFL_CC and AFL_CXX, based on a patch from Ben Laurie.\n\n  - Replaced afl-fuzz -S -D with -M for simplicity.\n\n  - Added a check for .section .text; lack of this prevented main() from\n    getting instrumented for some users. Reported by Tom Ritter.\n\n  - Reorganized the testcases/ directory.\n\n  - Added an extra check to confirm that the build is operational.\n\n  - Made more consistent use of color reset codes, as suggested by Oliver\n    Kunz.\n\n--------------\nVersion 0.43b:\n--------------\n\n  - Fixed a bug with 64-bit gcc -shared relocs.\n\n  - Removed echo -e from Makefile for compatibility with dash. Suggested\n    by Jakub Wilk.\n\n  - Added status_screen.txt.\n\n  - Added experimental/canvas_harness.\n\n  - Made a minor change to the Makefile GCC check. Suggested by Hanno Boeck.\n\n--------------\nVersion 0.42b:\n--------------\n\n  - Fixed a bug with red zone handling for 64-bit (oops!). Problem reported by\n    Felix Groebert.\n\n  - Implemented horribly experimental ARM support in experimental/arm_support.\n\n  - Made several improvements to error messages.\n\n  - Added AFL_QUIET to silence afl-gcc and afl-as when using wonky build\n    systems. Reported by Hanno Boeck.\n\n  - Improved check for 64-bit compilation, plus several sanity checks\n    in Makefile.\n\n--------------\nVersion 0.41b:\n--------------\n\n  - Fixed a fork served bug for processes that call execve().\n\n  - Made minor compatibility fixes to Makefile, afl-gcc; suggested by Jakub\n    Wilk.\n\n  - Fixed triage_crashes.sh to work with the new layout of output directories.\n    Suggested by Jakub Wilk.\n\n  - Made multiple performance-related improvements to the injected\n    instrumentation.\n\n  - Added visual indication of the number of imported paths.\n\n  - Fixed afl-showmap to make it work well with new instrumentation.\n\n  - Added much better error messages for crashes when importing test cases\n    or otherwise calibrating the binary.\n\n--------------\nVersion 0.40b:\n--------------\n\n  - Added support for parallelized fuzzing. Inspired by earlier patch\n    from Sebastian Roschke.\n\n  - Added an example in experimental/distributed_fuzzing/.\n\n--------------\nVersion 0.39b:\n--------------\n\n  - Redesigned status screen, now 90% more spiffy.\n\n  - Added more verbose and user-friendly messages for some common problems.\n\n  - Modified the resumption code to reconstruct path depth.\n\n  - Changed the code to inhibit core dumps and improve the ability to detect\n    SEGVs.\n\n  - Added a check for redirection of core dumps to programs.\n\n  - Made a minor improvement to the handling of variable paths.\n\n  - Made additional performance tweaks to afl-fuzz, chiefly around mem limits.\n\n  - Added performance_tips.txt.\n\n--------------\nVersion 0.38b:\n--------------\n\n  - Fixed an fd leak and +cov tracking bug resulting from changes in 0.37b.\n\n  - Implemented auto-scaling for screen update speed.\n\n  - Added a visual indication when running in non-instrumented mode.\n\n--------------\nVersion 0.37b:\n--------------\n\n  - Added fuzz state tracking for more seamless resumption of aborted\n    fuzzing sessions.\n\n  - Removed the -D option, as it's no longer necessary.\n\n  - Refactored calibration code and improved startup reporting.\n\n  - Implemented dynamically scaled timeouts, so that you don't need to\n    play with -t except in some very rare cases.\n\n  - Added visual notification for slow binaries.\n\n  - Improved instrumentation to explicitly cover the other leg of every\n    branch.\n\n--------------\nVersion 0.36b:\n--------------\n\n  - Implemented fork server support to avoid the overhead of execve(). A\n    nearly-verbatim design from Jann Horn; still pending part 2 that would\n    also skip initial setup steps (thinking about reliable heuristics now).\n\n  - Added a check for shell scripts used as fuzz targets.\n\n  - Added a check for fuzz jobs that don't seem to be finding anything.\n\n  - Fixed the way IGNORE_FINDS works (was a bit broken after adding splicing\n    and path skip heuristics).\n\n--------------\nVersion 0.35b:\n--------------\n\n  - Properly integrated 64-bit instrumentation into afl-as.\n\n--------------\nVersion 0.34b:\n--------------\n\n  - Added a new exec count classifier (the working theory is that it gets\n    meaningful coverage with fewer test cases spewed out).\n\n--------------\nVersion 0.33b:\n--------------\n\n  - Switched to new, somewhat experimental instrumentation that tries to\n    target only arcs, rather than every line. May be fragile, but is a lot\n    faster (2x+).\n\n  - Made several other cosmetic fixes and typo corrections, thanks to\n    Jakub Wilk.\n\n--------------\nVersion 0.32b:\n--------------\n\n  - Another take at fixing the C++ exception thing. Reported by Jakub Wilk.\n\n--------------\nVersion 0.31b:\n--------------\n\n  - Made another fix to afl-as to address a potential problem with newer\n    versions of GCC (introduced in 0.28b). Thanks to Jann Horn.\n\n--------------\nVersion 0.30b:\n--------------\n\n  - Added more detail about the underlying operations in file names.\n\n--------------\nVersion 0.29b:\n--------------\n\n  - Made some general improvements to chunk operations.\n\n--------------\nVersion 0.28b:\n--------------\n\n  - Fixed C++ exception handling in newer versions of GCC. Problem diagnosed\n    by Eberhard Mattes.\n\n  - Fixed the handling of the overflow flag. Once again, thanks to\n    Eberhard Mattes.\n\n--------------\nVersion 0.27b:\n--------------\n\n  - Added prioritization of new paths over the already-fuzzed ones.\n\n  - Included spliced test case ID in the output file name.\n\n  - Fixed a rare, cosmetic null ptr deref after Ctrl-C.\n\n  - Refactored the code to make copies of test cases in the output directory.\n\n  - Switched to better output file names, keeping track of stage and splicing\n    sources.\n\n--------------\nVersion 0.26b:\n--------------\n\n  - Revamped storage of testcases, -u option removed,\n\n  - Added a built-in effort minimizer to get rid of potentially redundant\n    inputs,\n\n  - Provided a testcase count minimization script in experimental/,\n\n  - Made miscellaneous improvements to directory and file handling.\n\n  - Fixed a bug in timeout detection.\n\n--------------\nVersion 0.25b:\n--------------\n\n  - Improved count-based instrumentation.\n\n  - Improved the hang deduplication logic.\n\n  - Added -cov prefixes for test cases.\n\n  - Switched from readdir() to scandir() + alphasort() to preserve ordering of\n    test cases.\n\n  - Added a splicing strategy.\n\n  - Made various minor UI improvements and several other bugfixes.\n\n--------------\nVersion 0.24b:\n--------------\n\n  - Added program name to the status screen, plus the -T parameter to go with\n    it.\n\n--------------\nVersion 0.23b:\n--------------\n\n  - Improved the detection of variable behaviors.\n\n  - Added path depth tracking,\n\n  - Improved the UI a bit,\n\n  - Switched to simplified (XOR-based) tuple instrumentation.\n\n--------------\nVersion 0.22b:\n--------------\n\n  - Refactored the handling of long bitflips and some swaps.\n\n  - Fixed the handling of gcc -pipe, thanks to anonymous reporter.\n\n--------------\nVersion 0.21b:\n--------------\n\n  - Initial public release.\n"
  },
  {
    "path": "docs/INSTALL",
    "content": "=========================\nInstallation instructions\n=========================\n\n  This document provides basic installation instructions and discusses known\n  issues for a variety of platforms. See README for the general instruction\n  manual.\n\n1) Linux on x86\n---------------\n\nThis platform is expected to work well. Compile the program with:\n\n$ make\n\nYou can start using the fuzzer without installation, but it is also possible to\ninstall it with:\n\n# make install\n\nThere are no special dependencies to speak of; you will need GNU make and a\nworking compiler (gcc or clang). Some of the optional scripts bundled with the\nprogram may depend on bash, gdb, and similar basic tools.\n\nIf you are using clang, please review llvm_mode/README.llvm; the LLVM\nintegration mode can offer substantial performance gains compared to the\ntraditional approach.\n\nYou may have to change several settings to get optimal results (most notably,\ndisable crash reporting utilities and switch to a different CPU governor), but\nafl-fuzz will guide you through that if necessary.\n\n2) OpenBSD, FreeBSD, NetBSD on x86\n----------------------------------\n\nSimilarly to Linux, these platforms are expected to work well and are\nregularly tested. Compile everything with GNU make:\n\n$ gmake\n\nNote that BSD make will *not* work; if you do not have gmake on your system,\nplease install it first. As on Linux, you can use the fuzzer itself without\ninstallation, or install it with:\n\n# gmake install\n\nKeep in mind that if you are using csh as your shell, the syntax of some of the\nshell commands given in the README and other docs will be different.\n\nThe llvm_mode requires a dynamically linked, fully-operational installation of\nclang. At least on FreeBSD, the clang binaries are static and do not include\nsome of the essential tools, so if you want to make it work, you may need to\nfollow the instructions in llvm_mode/README.llvm.\n\nBeyond that, everything should work as advertised.\n\nThe QEMU mode is currently supported only on Linux. I think it's just a QEMU\nproblem, I couldn't get a vanilla copy of user-mode emulation support working\ncorrectly on BSD at all.\n\n3) MacOS X on x86\n-----------------\n\nMacOS X should work, but there are some gotchas due to the idiosyncrasies of\nthe platform. On top of this, I have limited release testing capabilities\nand depend mostly on user feedback.\n\nTo build AFL, install Xcode and follow the general instructions for Linux.\n\nThe Xcode 'gcc' tool is just a wrapper for clang, so be sure to use afl-clang\nto compile any instrumented binaries; afl-gcc will fail unless you have GCC\ninstalled from another source (in which case, please specify AFL_CC and\nAFL_CXX to point to the \"real\" GCC binaries).\n\nOnly 64-bit compilation will work on the platform; porting the 32-bit\ninstrumentation would require a fair amount of work due to the way OS X\nhandles relocations, and today, virtually all MacOS X boxes are 64-bit.\n\nThe crash reporting daemon that comes by default with MacOS X will cause\nproblems with fuzzing. You need to turn it off by following the instructions\nprovided here: http://goo.gl/CCcd5u\n\nThe fork() semantics on OS X are a bit unusual compared to other unix systems\nand definitely don't look POSIX-compliant. This means two things:\n\n  - Fuzzing will be probably slower than on Linux. In fact, some folks report\n    considerable performance gains by running the jobs inside a Linux VM on\n    MacOS X.\n\n  - Some non-portable, platform-specific code may be incompatible with the\n    AFL forkserver. If you run into any problems, set AFL_NO_FORKSRV=1 in the\n    environment before starting afl-fuzz.\n\nUser emulation mode of QEMU does not appear to be supported on MacOS X, so\nblack-box instrumentation mode (-Q) will not work.\n\nThe llvm_mode requires a fully-operational installation of clang. The one that\ncomes with Xcode is missing some of the essential headers and helper tools.\nSee llvm_mode/README.llvm for advice on how to build the compiler from scratch.\n\n4) Linux or *BSD on non-x86 systems\n-----------------------------------\n\nStandard build will fail on non-x86 systems, but you should be able to\nleverage two other options:\n\n  - The LLVM mode (see llvm_mode/README.llvm), which does not rely on\n    x86-specific assembly shims,\n\n  - The QEMU mode (see qemu_mode/README.qemu), which can be also used for\n    fuzzing cross-platform binaries.\n\nIn both cases, you will need to set AFL_NOX86=1 before running make or gmake.\n\n5) Solaris on x86\n-----------------\n\nThe fuzzer reportedly works on Solaris, but I have not tested this first-hand,\nand the user base is fairly small, so I don't have a lot of feedback.\n\nTo get the ball rolling, you will need to use GNU make and GCC or clang. I'm\nbeing told that the stock version of GCC that comes with the platform does not\nwork properly due to its reliance on a hardcoded location for 'as' (completely\nignoring the -B parameter or $PATH).\n\nTo fix this, you may want to build stock GCC from the source, like so:\n\n$ ./configure --prefix=$HOME/gcc --with-gnu-as --with-gnu-ld \\\n  --with-gmp-include=/usr/include/gmp --with-mpfr-include=/usr/include/mpfr\n$ make\n$ sudo make install\n\nDo *not* specify --with-as=/usr/gnu/bin/as - this will produce a GCC binary that\nignores the -B flag and you will be back to square one.\n\nIf you have system-wide crash reporting enabled, you may run into problems\nsimilar to the gotchas for Linux and MacOS X, but I have not verified this.\nMore information about AppCrash can be found here:\n\n  http://www.oracle.com/technetwork/server-storage/solaris10/app-crash-142906.html\n\nUser emulation mode of QEMU is not available on Solaris, so black-box\ninstrumentation mode (-Q) will not work.\n\n6) Everything else\n------------------\n\nYou're on your own. On POSIX-compliant systems, you may be able to compile and\nrun the fuzzer; and the LLVM mode may offer a way to instrument non-x86 code.\n\nThe fuzzer will not run on Windows. It will also not work under Cygwin. It\ncould be ported to the latter platform fairly easily, but it's a pretty bad\nidea, because Cygwin is extremely slow. It makes much more sense to use\nVirtualBox or so to run a hardware-accelerated Linux VM; it will run around\n20x faster or so. If you have a *really* compelling use case for Cygwin, let\nme know.\n\nAlthough Android on x86 should theoretically work, the stock kernel has SHM\nsupport compiled out, so you will need to address this issue first. It's\npossible that all you need is this:\n\n  https://github.com/pelya/android-shmem\n"
  },
  {
    "path": "docs/QuickStartGuide.txt",
    "content": "=====================\nAFL quick start guide\n=====================\n\nYou should read docs/README. It's pretty short. If you really can't, here's\nhow to hit the ground running:\n\n1) Compile AFL with 'make'. If build fails, see docs/INSTALL for tips.\n\n2) Find or write a reasonably fast and simple program that takes data from\n   a file or stdin, processes it in a test-worthy way, then exits cleanly.\n   If testing a network service, modify it to run in the foreground and read\n   from stdin. When fuzzing a format that uses checksums, comment out the\n   checksum verification code, too.\n\n   The program must crash properly when a fault is encountered. Watch out for\n   custom SIGSEGV or SIGABRT handlers and background processes.\n\n3) Compile the program / library to be fuzzed using afl-gcc. A common way to\n   do this would be:\n\n   CC=/path/to/afl-gcc CXX=/path/to/afl-g++ ./configure --disable-shared\n   make clean all\n\n   If program build fails, ping <afl-users@googlegroups.com>.\n\n4) Get a small but valid input file that makes sense to the program. When\n   fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described in\n   testcases/README.testcases, too.\n\n5) If the program reads from stdin, run 'afl-fuzz' like so:\n\n   ./afl-fuzz -i testcase_dir -o findings_dir -- \\\n     /path/to/tested/program [...program's cmdline...]\n\n   If the program takes input from a file, you can put @@ in the program's\n   command line; AFL will put an auto-generated file name in there for you.\n\n6) Investigate anything shown in red in the fuzzer UI by promptly consulting\n   docs/status_screen.txt.\n\nThat's it. Sit back, relax, and - time permitting - try to skim through the\nfollowing files:\n\n  - docs/README               - A general introduction to AFL,\n  - docs/perf_tips.txt        - Simple tips on how to fuzz more quickly,\n  - docs/status_screen.txt    - An explanation of the tidbits shown in the UI,\n  - docs/parallel_fuzzing.txt - Advice on running AFL on multiple cores.\n"
  },
  {
    "path": "docs/README",
    "content": "==================\namerican fuzzy lop\n==================\n\n  Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n  Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n  Released under terms and conditions of Apache License, Version 2.0.\n\n  For new versions and additional information, check out:\n  http://lcamtuf.coredump.cx/afl/\n\n  To compare notes with other users or get notified about major new features,\n  send a mail to <afl-users+subscribe@googlegroups.com>.\n\n  ** See QuickStartGuide.txt if you don't have time to read this file. **\n\n1) Challenges of guided fuzzing\n-------------------------------\n\nFuzzing is one of the most powerful and proven strategies for identifying\nsecurity issues in real-world software; it is responsible for the vast\nmajority of remote code execution and privilege escalation bugs found to date\nin security-critical software.\n\nUnfortunately, fuzzing is also relatively shallow; blind, random mutations\nmake it very unlikely to reach certain code paths in the tested code, leaving\nsome vulnerabilities firmly outside the reach of this technique.\n\nThere have been numerous attempts to solve this problem. One of the early\napproaches - pioneered by Tavis Ormandy - is corpus distillation. The method\nrelies on coverage signals to select a subset of interesting seeds from a\nmassive, high-quality corpus of candidate files, and then fuzz them by\ntraditional means. The approach works exceptionally well, but requires such\na corpus to be readily available. In addition, block coverage measurements\nprovide only a very simplistic understanding of program state, and are less\nuseful for guiding the fuzzing effort in the long haul.\n\nOther, more sophisticated research has focused on techniques such as program\nflow analysis (\"concolic execution\"), symbolic execution, or static analysis.\nAll these methods are extremely promising in experimental settings, but tend\nto suffer from reliability and performance problems in practical uses - and\ncurrently do not offer a viable alternative to \"dumb\" fuzzing techniques.\n\n2) The afl-fuzz approach\n------------------------\n\nAmerican Fuzzy Lop is a brute-force fuzzer coupled with an exceedingly simple\nbut rock-solid instrumentation-guided genetic algorithm. It uses a modified\nform of edge coverage to effortlessly pick up subtle, local-scale changes to\nprogram control flow.\n\nSimplifying a bit, the overall algorithm can be summed up as:\n\n  1) Load user-supplied initial test cases into the queue,\n\n  2) Take next input file from the queue,\n\n  3) Attempt to trim the test case to the smallest size that doesn't alter\n     the measured behavior of the program,\n\n  4) Repeatedly mutate the file using a balanced and well-researched variety\n     of traditional fuzzing strategies,\n\n  5) If any of the generated mutations resulted in a new state transition\n     recorded by the instrumentation, add mutated output as a new entry in the\n     queue.\n\n  6) Go to 2.\n\nThe discovered test cases are also periodically culled to eliminate ones that\nhave been obsoleted by newer, higher-coverage finds; and undergo several other\ninstrumentation-driven effort minimization steps.\n\nAs a side result of the fuzzing process, the tool creates a small,\nself-contained corpus of interesting test cases. These are extremely useful\nfor seeding other, labor- or resource-intensive testing regimes - for example,\nfor stress-testing browsers, office applications, graphics suites, or\nclosed-source tools.\n\nThe fuzzer is thoroughly tested to deliver out-of-the-box performance far\nsuperior to blind fuzzing or coverage-only tools.\n\n3) Instrumenting programs for use with AFL\n------------------------------------------\n\nWhen source code is available, instrumentation can be injected by a companion\ntool that works as a drop-in replacement for gcc or clang in any standard build\nprocess for third-party code.\n\nThe instrumentation has a fairly modest performance impact; in conjunction with\nother optimizations implemented by afl-fuzz, most programs can be fuzzed as fast\nor even faster than possible with traditional tools.\n\nThe correct way to recompile the target program may vary depending on the\nspecifics of the build process, but a nearly-universal approach would be:\n\n$ CC=/path/to/afl/afl-gcc ./configure\n$ make clean all\n\nFor C++ programs, you'd would also want to set CXX=/path/to/afl/afl-g++.\n\nThe clang wrappers (afl-clang and afl-clang++) can be used in the same way;\nclang users may also opt to leverage a higher-performance instrumentation mode,\nas described in llvm_mode/README.llvm.\n\nWhen testing libraries, you need to find or write a simple program that reads\ndata from stdin or from a file and passes it to the tested library. In such a\ncase, it is essential to link this executable against a static version of the\ninstrumented library, or to make sure that the correct .so file is loaded at\nruntime (usually by setting LD_LIBRARY_PATH). The simplest option is a static\nbuild, usually possible via:\n\n$ CC=/path/to/afl/afl-gcc ./configure --disable-shared\n\nSetting AFL_HARDEN=1 when calling 'make' will cause the CC wrapper to\nautomatically enable code hardening options that make it easier to detect\nsimple memory bugs.\n\nPS. ASAN users are advised to review notes_for_asan.txt file for important\ncaveats.\n\n4) Instrumenting binary-only apps\n---------------------------------\n\nWhen source code is *NOT* available, the fuzzer offers experimental support for\nfast, on-the-fly instrumentation of black-box binaries. This is accomplished\nwith a version of QEMU running in the lesser-known \"user space emulation\" mode.\n\nQEMU is a project separate from AFL, but you can conveniently build the\nfeature by doing:\n\n$ cd qemu_mode\n$ ./build_qemu_support.sh\n\nFor additional instructions and caveats, see qemu_mode/README.qemu.\n\nThe mode is approximately 2-5x slower than compile-time instrumentation, is\nless conductive to parallelization, and may have some other quirks.\n\n5) Choosing initial test cases\n------------------------------\n\nTo operate correctly, the fuzzer requires one or more starting file that\ncontains a good example of the input data normally expected by the targeted\napplication. There are two basic rules:\n\n  - Keep the files small. Under 1 kB is ideal, although not strictly necessary.\n    For a discussion of why size matters, see perf_tips.txt.\n\n  - Use multiple test cases only if they are functionally different from\n    each other. There is no point in using fifty different vacation photos\n    to fuzz an image library.\n\nYou can find many good examples of starting files in the testcases/ subdirectory\nthat comes with this tool.\n\nPS. If a large corpus of data is available for screening, you may want to use\nthe afl-cmin utility to identify a subset of functionally distinct files that\nexercise different code paths in the target binary.\n\n6) Fuzzing binaries\n-------------------\n\nThe fuzzing process itself is carried out by the afl-fuzz utility. This program\nrequires a read-only directory with initial test cases, a separate place to\nstore its findings, plus a path to the binary to test.\n\nFor target binaries that accept input directly from stdin, the usual syntax is:\n\n$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]\n\nFor programs that take input from a file, use '@@' to mark the location in\nthe target's command line where the input file name should be placed. The\nfuzzer will substitute this for you:\n\n$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@\n\nYou can also use the -f option to have the mutated data written to a specific\nfile. This is useful if the program expects a particular file extension or so.\n\nFor programs that accept input via a network, use:\n\n$ ./afl-fuzz -i testcase_dir -o findings_dir [-D delay_before_write] \\\n             [-t timeout_delay] [-L ] -N network_specification /path/to/program \\\n\t     [...params...]\n\nwhere -L is specified only if the target program acts as a client to a network\nserver (sends data to the server before receiving input in return).  Otherwise,\nafl-fuzz assumes the target program acts as a server or daemon and expects to\nreceive data from network clients and respond.  The network_specification\nand the delay parameters are discussed below in (12).\n\nNon-instrumented binaries can be fuzzed in the QEMU mode (add -Q in the command\nline) or in a traditional, blind-fuzzer mode (specify -n).\n\nYou can use -t and -m to override the default timeout and memory limit for the\nexecuted process; rare examples of targets that may need these settings touched\ninclude compilers and video decoders.\n\nTips for optimizing fuzzing performance are discussed in perf_tips.txt.\n\nNote that afl-fuzz starts by performing an array of deterministic fuzzing\nsteps, which can take several days. If you want quick & dirty results right\naway, akin to zzuf or honggfuzz, add the -d option to the command line.\n\n7) Interpreting output\n----------------------\n\nSee the status_screen.txt file for information on how to interpret the\ndisplayed stats and monitor the health of the process. Be sure to consult this\nfile especially if any UI elements are highlighted in red.\n\nThe fuzzing process will continue until you press Ctrl-C. At minimum, you want\nto allow the fuzzer to complete one queue cycle, which may take anywhere from a\ncouple of hours to a week or so.\n\nThere are three subdirectories created within the output directory and updated\nin real time:\n\n  - queue/   - test cases for every distinctive execution path, plus all the\n               starting files given by the user. This is the synthesized corpus\n               mentioned in section 2.\n\n               Before using this corpus for any other purposes, you can shrink\n               it to a smaller size using the afl-cmin tool. The tool will find\n               a smaller subset of files offering equivalent edge coverage.\n\n  - crashes/ - unique test cases that cause the tested program to receive a\n               fatal signal (e.g., SIGSEGV, SIGILL, SIGABRT). The entries are \n               grouped by the received signal.\n\n  - hangs/   - unique test cases that cause the tested program to time out. Note\n               that when default (aggressive) timeout settings are in effect,\n               this can be slightly noisy due to latency spikes and other\n               natural phenomena.\n\nCrashes and hangs are considered \"unique\" if the associated execution paths\ninvolve any state transitions not seen in previously-recorded faults. If a\nsingle bug can be reached in multiple ways, there will be some count inflation\nearly in the process, but this should quickly taper off.\n\nThe file names for crashes and hangs are correlated with parent, non-faulting\nqueue entries. This should help with debugging.\n\nWhen you can't reproduce a crash found by afl-fuzz, the most likely cause is\nthat you are not setting the same memory limit as used by the tool. Try:\n\n$ LIMIT_MB=50\n$ ( ulimit -Sv $[LIMIT_MB << 10]; /path/to/tested_binary ... )\n\nChange LIMIT_MB to match the -m parameter passed to afl-fuzz. On OpenBSD,\nalso change -Sv to -Sd.\n\nAny existing output directory can be also used to resume aborted jobs; try:\n\n$ ./afl-fuzz -i- -o existing_output_dir [...etc...]\n\nIf you have gnuplot installed, you can also generate some pretty graphs for any\nactive fuzzing task using afl-plot. For an example of how this looks like,\nsee http://lcamtuf.coredump.cx/afl/plot/.\n\n8) Parallelized fuzzing\n-----------------------\n\nEvery instance of afl-fuzz takes up roughly one core. This means that on\nmulti-core systems, parallelization is necessary to fully utilize the hardware.\nFor tips on how to fuzz a common target on multiple cores or multiple networked\nmachines, please refer to parallel_fuzzing.txt.\n\nNote the limitations to multi-core execution for fuzzing network services under\n(12).\n\n9) Fuzzer dictionaries\n----------------------\n\nBy default, afl-fuzz mutation engine is optimized for compact data formats -\nsay, images, multimedia, compressed data, regular expression syntax, or shell\nscripts. It is somewhat less suited for languages with particularly verbose and\nredundant verbiage - notably including HTML, SQL, or JavaScript.\n\nTo avoid the hassle of building syntax-aware tools, afl-fuzz provides a way to\nseed the fuzzing process with an optional dictionary of language keywords,\nmagic headers, or other special tokens associated with the targeted data type\n- and use that to reconstruct the underlying grammar on the go:\n\n  http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html\n\nTo use this feature, you first need to create a dictionary in one of the two\nformats discussed in testcases/README.testcases; and then point the fuzzer to\nit via the -x option in the command line.\n\nThere is no way to provide more structured descriptions of the underlying\nsyntax, but the fuzzer will likely figure out some of this based on the\ninstrumentation feedback alone. This actually works in practice, say:\n\n  http://lcamtuf.blogspot.com/2015/04/finding-bugs-in-sqlite-easy-way.html\n\nPS. Even when no explicit dictionary is given, afl-fuzz will try to extract\nexisting syntax tokens in the input corpus by watching the instrumentation\nvery closely during deterministic byte flips. This works for some types of\nparsers and grammars, but isn't nearly as good as the -x mode.\n\n10) Crash triage\n----------------\n\nThe coverage-based grouping of crashes usually produces a small data set that\ncan be quickly triaged manually or with a very simple GDB or Valgrind script.\nEvery crash is also traceable to its parent non-crashing test case in the\nqueue, making it easier to diagnose faults.\n\nHaving said that, it's important to acknowledge that some fuzzing crashes can be\ndifficult quickly evaluate for exploitability without a lot of debugging and\ncode analysis work. To assist with this task, afl-fuzz supports a very unique\n\"crash exploration\" mode enabled with the -C flag.\n\nIn this mode, the fuzzer takes one or more crashing test cases as the input,\nand uses its feedback-driven fuzzing strategies to very quickly enumerate all\ncode paths that can be reached in the program while keeping it in the\ncrashing state.\n\nMutations that do not result in a crash are rejected; so are any changes that\ndo not affect the execution path.\n\nThe output is a small corpus of files that can be very rapidly examined to see\nwhat degree of control the attacker has over the faulting address, or whether\nit is possible to get past an initial out-of-bounds read - and see what lies\nbeneath.\n\nOh, one more thing: for test case minimization, give afl-tmin a try. The tool\ncan be operated in a very simple way:\n\n$ ./afl-tmin -i test_case -o minimized_result -- /path/to/program [...]\n\nThe tool works with crashing and non-crashing test cases alike. In the crash\nmode, it will happily accept instrumented and non-instrumented binaries. In the\nnon-crashing mode, the minimizer relies on standard AFL instrumentation to make\nthe file simpler without altering the execution path.\n\nThe minimizer accepts the -m, -t, -f and @@ syntax in a manner compatible with\nafl-fuzz.\n\n11) Common-sense risks\n----------------------\n\nPlease keep in mind that, similarly to many other computationally-intensive\ntasks, fuzzing may put strain on your hardware and on the OS. In particular:\n\n  - Your CPU will run hot and will need adequate cooling. In most cases, if\n    cooling is insufficient or stops working properly, CPU speeds will be\n    automatically throttled. That said, especially when fuzzing on less\n    suitable hardware (laptops, smartphones, etc), it's not entirely impossible\n    for something to blow up.\n\n  - Targeted programs may end up erratically grabbing gigabytes of memory or\n    filling up disk space with junk files. AFL tries to enforce basic memory\n    limits, but can't prevent each and every possible mishap. The bottom line\n    is that you shouldn't be fuzzing on systems where the prospect of data loss\n    is not an acceptable risk.\n\n  - Fuzzing involves billions of reads and writes to the filesystem. On modern\n    systems, this will be usually heavily cached, resulting in fairly modest\n    \"physical\" I/O - but there are many factors that may alter this equation.\n    It is your responsibility to monitor for potential trouble; with very heavy\n    I/O, the lifespan of many HDDs and SSDs may be reduced.\n\n    A good way to monitor disk I/O on Linux is the 'iostat' command:\n\n    $ iostat -d 3 -x -k [...optional disk ID...]\n\n12) Fuzzing network services\n----------------------------\n\nBoth client and server (daemon) programs that communicate using an \nIP network (IPv4 or IPv6) can be fuzzed using the command line\n\n$ ./afl-fuzz -i testcase_dir -o findings_dir [-D delay_before_write] \\\n             [-t timeout_delay] [-L] -N network_specification /path/to/program \\\n\t     [...params...]\n\nwhere the network_specification has a form similar to a URL:\n\n    [tcp|udp]://hostspec:port\n\nAfl-fuzz has two network fuzzing modes, where it acts as a client to a\nnetwork server that expects input via a socket (no -L option), and where it\nacts as a server to a network client that sends data to afl-fuzz before\nreceiving input (using the -L option).  In the first case, afl-fuzz sends data\nto the port specified by the URL.  In the second case, afl-fuzz receives data\non that port and sends a (fuzzed) response to the port the target (client) used\nto send its data.\n\nNote that when afl-fuzz acts as a server (the -L option), there is no control\nover how the target client manages its use of sockets - and in particular, a\nclient that uses ephemeral sockets (the usual case) will rapidly consume the\nnetwork stack's pool of available sockets.  Some operating systems are able to\nreclaim used ephemeral sockets to keep the pool from being exhausted; others\nmay experience difficulties.\n\nWhile the -D and -t command line arguments are optional, they are almost\nalways necessary when fuzzing a program using network protocols, as\ndescribed below.\n\nCase is irrelevant in the network specification.  For programs that\nuse a stream (connection-based) protocol, use TCP, and for programs\nthat use a datagram (connectionless) protocol, use UDP.  The hostspec\nmust be one of ::1 (forcing IPv6 networking), 127.0.0.1 (forcing IPv4\nnetworking), and localhost (which is typically configured as IPv4 but\nmay suppport IPv6 on some systems).  Only loopback networking (local\nto the host) is supported.  The port must be either a port number in\nthe range 1..65535 or a service name known to the system being used.\nYou can test programs that use privileged ports, but you then have to\nprovide afl-fuzz with those additional privileges (e.g., root).  It is\nusually better to reconfigure the program being tested so that it will\nuse a non-privileged port during fuzzing.\n\nPrograms that implement network services, also called daemons, are\ntypically transaction-based: They wait for a request and send a\nresponse, and some expect a sequence of request/response transactions.\nAfl-fuzz implements fuzzing only for the first write to the target\nprogram and ignores all responses from the target.  Most network\nservices expect to run as background processes and process requests\nfrom many processes -- they do not normally exit.  A timeout delay is\nrequired in order to terminate these processes, and the default\ntimeout delay used in afl-fuzz is usually too long.  The user needs to\nexperimentally determine a timeout delay (in milliseconds) that\nproduces a sufficiently low percentage of hangs (exits forced by\nexpiration of the delay) while allowing the input to the target from\nafl-fuzz to be completely processed.  (Note that afl-fuzz will usually\ncount these hangs as a single unique hang.) Since a network service\ndoes not normally exit, the initial timing performed by afl-fuzz will\nfail unless a '+' character is appended to the timeout_delay\nparameter, indicating that afl-fuzz is to ignore these timeouts.\n\nNetwork services programs also require some time to perform start-up\nprocessing, create and bind a socket to an address and port, and begin\nlistening for traffic on that socket.  Connection requests (TCP) and\nsends (UDP) generated by afl-fuzz will fail if made before the network\nservice is ready.  Afl-fuzz implements a delay and retry procedure to\navoid this problem, where the delay is specified by the\ndelay_before_write parameter (in milliseconds).  The first connection\nattempt (for TCP) or write (for UDP) is not made until after this\ndelay, and the delay also specifies the wait time before each\nsubsequent attempt.  Afl-fuzz will attempt to connect or send to the\nsame each target process a maximum of three times.\n\nThe delay_before_write parameter, in particular, and to a lesser\nextent the timeout_delay parameter limit the maximum achievable rate\nof target program executions and therefore need to be small. A rule of\nthumb is the timeout_delay value should be slightly longer than three\ntimes the delay_before_write value, and the delay_before_write value\nshould be as small as possible while consistent with an acceptable\nfraction of target process executions that time out (for example,\naround 0.1%).\n\nNetwork client program have similar characteristics that require the use of\nthe delay parameter, but they write to their expected server (afl-fuzz in this\ncase) before reading from their network socket.  This makes coordination between\nafl-fuzz and (client) target somewhat more challenging.  While the delay and\ntimeout parameters can usually be adjusted to obtain execution rates similar\nto those for server programs, when afl-fuzz exits (due to a ^C interrupt) it\nmay hang.  In this case, use (on UNIX or Linux) the ps command to find the\nprocess id (PID) of the afl-fuzz process, and use the kill command to terminate\nit (typically, \"kill -9 PID\").  This will also terminate (or scavenge) the\nnetwork client program's process, which may be in a zombie state that can not\notherwise be removed (without rebooting the system).\n\nA note concerning network fuzzing on multi-core systems:\n\nIt is not possible to run two processes under a single operating\nsystem kernel that bind to (listen to) the same port on the same\naddress. Thus, either a special wrapper (such as could be implemented\nusing LD_PRELOAD) can be used to remap each target's port to a\ndifferent value, or only one target process can be executed per kernel\n(not per core). Parallel fuzzing of network services can be done using\nseveral independent hosts (a cluster), or by reconfiguring the code\nrunning on each core to use a different port.\n\n13) Known limitations & areas for improvement\n---------------------------------------------\n\nHere are some of the most important caveats for AFL:\n\n  - AFL detects faults by checking for the first spawned process dying due to\n    a signal (SIGSEGV, SIGABRT, etc). Programs that install custom handlers for\n    these signals may need to have the relevant code commented out. In the same\n    vein, faults in child processed spawned by the fuzzed target may evade\n    detection unless you manually add some code to catch that.\n\n  - As with any other brute-force tool, the fuzzer offers limited coverage if\n    encryption, checksums, cryptographic signatures, or compression are used to\n    wholly wrap the actual data format to be tested.\n\n    To work around this, you can comment out the relevant checks (see\n    experimental/libpng_no_checksum/ for inspiration); if this is not possible,\n    you can also write a postprocessor, as explained in\n    experimental/post_library/.\n\n  - There are some unfortunate trade-offs with ASAN and 64-bit binaries. This\n    isn't due to any specific fault of afl-fuzz; see notes_for_asan.txt for\n    tips.\n\n  - The supplied method for fuzzing network services or background daemons\n    is limited to fuzzing the first packet received by the service or daemon.\n    Since many of these processes are transactional, it may be desirable to\n    provide a deterministic sequence of transactions with the target,\n    followed by fuzzing. This is not supported and would be a nice topic\n    for future work. Interactive apps that require UI interaction to work\n    are also not supported. You may need to make simple code changes to\n    make them behave in a more traditional way. Preeny may offer a relatively\n    simple option, too - see: https://github.com/zardus/preeny\n\n    Some useful tips for modifying network-based services can be also found at:\n    https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop\n\n  - AFL doesn't output human-readable coverage data. If you want to monitor\n    coverage, use afl-cov from Michael Rash: https://github.com/mrash/afl-cov\n\n  - Only afl-fuzz implements network fuzzing capabilities at this time.  In\n    particular, afl-cmin (a script), afl-tmin, and afl-showmap, all of which\n    execute the target program, do not.\n\n\nBeyond this, see INSTALL for platform-specific tips.\n\n14) Special thanks\n------------------\n\nMany of the improvements to afl-fuzz wouldn't be possible without feedback,\nbug reports, or patches from:\n\n  Jann Horn                             Hanno Boeck\n  Felix Groebert                        Jakub Wilk\n  Richard W. M. Jones                   Alexander Cherepanov\n  Tom Ritter                            Hovik Manucharyan\n  Sebastian Roschke                     Eberhard Mattes\n  Padraig Brady                         Ben Laurie\n  @dronesec                             Luca Barbato\n  Tobias Ospelt                         Thomas Jarosch\n  Martin Carpenter                      Mudge Zatko\n  Joe Zbiciak                           Ryan Govostes\n  Michael Rash                          William Robinet\n  Jonathan Gray                         Filipe Cabecinhas\n  Nico Weber                            Jodie Cunningham\n  Andrew Griffiths                      Parker Thompson\n  Jonathan Neuschfer                    Tyler Nighswander\n  Ben Nagy                              Samir Aguiar\n  Aidan Thornton                        Aleksandar Nikolich\n  Sam Hakim                             Laszlo Szekeres\n  David A. Wheeler                      Turo Lamminen\n  Andreas Stieger                       Richard Godbee\n  Louis Dassy                           teor2345\n  Alex Moneger                          Dmitry Vyukov\n  Keegan McAllister                     Kostya Serebryany\n  Richo Healey                          Martijn Bogaard\n  rc0r                                  Jonathan Foote\n  Christian Holler                      Dominique Pelle\n  Jacek Wielemborek                     Leo Barnes\n  Jeremy Barnes                         Doug Birdwell\n\nThank you!\n\n15) Contact\n-----------\n\nQuestions? Concerns? Bug reports? The author can be usually reached at\n<lcamtuf@google.com>.\n\nThere is also a mailing list for the project; to join, send a mail to\n<afl-users+subscribe@googlegroups.com>. Or, if you prefer to browse\narchives first, try:\n\n  https://groups.google.com/group/afl-users\n\nPS. If you wish to submit raw code to be incorporated into the project, please\nbe aware that the copyright on most of AFL is claimed by Google. While you do\nretain copyright on your contributions, they do ask people to agree to a simple\nCLA first:\n\n  https://cla.developers.google.com/clas\n\nSorry about the hassle. Of course, no CLA is required for feature requests or\nbug reports.\n"
  },
  {
    "path": "docs/env_variables.txt",
    "content": "=======================\nEnvironmental variables\n=======================\n\n  This document discusses the environment variables used by American Fuzzy Lop\n  to expose various exotic functions that may be (rarely) useful for power\n  users or for some types of custom fuzzing setups. See README for the general\n  instruction manual.\n\n1) Settings for afl-gcc, afl-clang, and afl-as\n----------------------------------------------\n\nBecause they can't directly accept command-line options, the compile-time\ntools make fairly broad use of environmental variables:\n\n  - Setting AFL_HARDEN automatically adds code hardening options when invoking\n    the downstream compiler. This currently includes -D_FORTIFY_SOURCE=2 and\n    -fstack-protector-all. The setting is useful for catching non-crashing\n    memory bugs at the expense of a very slight (sub-5%) performance loss.\n\n  - By default, the wrapper appends -O3 to optimize builds. Very rarely, this\n    will cause problems in programs built with -Werror, simply because -O3\n    enables more thorough code analysis and can spew out additional warnings.\n    To disable optimizations, set AFL_DONT_OPTIMIZE.\n\n  - Setting AFL_USE_ASAN automatically enables ASAN, provided that your\n    compiler supports that. Note that fuzzing with ASAN is mildly challenging\n    - see notes_for_asan.txt.\n\n    (You can also enable MSAN via AFL_USE_MSAN; ASAN and MSAN come with the\n    same gotchas; the modes are mutually exclusive. UBSAN and other exotic\n    sanitizers are not officially supported yet, but are easy to get to work\n    by hand.)\n\n  - Setting AFL_CC, AFL_CXX, and AFL_AS lets you use alternate downstream\n    compilation tools, rather than the default 'clang', 'gcc', or 'as' binaries\n    in your $PATH.\n\n  - AFL_PATH can be used to point afl-gcc to an alternate location of afl-as.\n    One possible use of this is experimental/clang_asm_normalize/, which lets\n    you instrument hand-written assembly when compiling clang code by plugging\n    a normalizer into the chain. (There is no equivalent feature for GCC.)\n\n  - Setting AFL_INST_RATIO to a percentage between 0 and 100% controls the\n    probability of instrumenting every branch. This is (very rarely) useful\n    when dealing with exceptionally complex programs that saturate the output\n    bitmap. Examples include v8, ffmpeg, and perl.\n\n    (If this ever happens, afl-fuzz will warn you ahead of the time by\n    displaying the \"bitmap density\" field in fiery red.)\n\n    Setting AFL_INST_RATIO to 0 is a valid choice. This will instrument only\n    the transitions between function entry points, but not individual branches.\n\n  - TMPDIR is used by afl-as for temporary files; if this variable is not set,\n    the tool defaults to /tmp.\n\n  - Setting AFL_KEEP_ASSEMBLY prevents afl-as from deleting instrumented\n    assembly files. Useful for troubleshooting problems or understanding how\n    the tool works. To get them in a predictable place, try something like:\n\n    mkdir assembly_here\n    TMPDIR=$PWD/assembly_here AFL_KEEP_ASSEMBLY=1 make clean all\n\n  - Setting AFL_QUIET will prevent afl-cc and afl-as banners from being\n    displayed during compilation, in case you find them distracting.\n\n2) Settings for afl-clang-fast\n------------------------------\n\nThe native LLVM instrumentation helper accepts a subset of the settings\ndiscussed in section #1, with the exception of:\n\n  - AFL_AS, since this toolchain does not directly invoke GNU as.\n\n  - TMPDIR and AFL_KEEP_ASSEMBLY, since no temporary assembly files are\n    created.\n\nNote that AFL_INST_RATIO will behave a bit differently than for afl-gcc,\nbecause functions are *not* instrumented unconditionally - so low values\nwill have a more striking effect. For this tool, 0 is not a valid choice.\n\n3) Settings for afl-fuzz\n------------------------\n\nThe main fuzzer binary accepts several options that disable a couple of sanity\nchecks or alter some of the more exotic semantics of the tool:\n\n  - Setting AFL_SKIP_CPUFREQ skips the check for CPU scaling policy. This is\n    useful if you can't change the defaults (e.g., no root access to the\n    system) and are OK with some performance loss.\n\n  - Setting AFL_NO_FORKSRV disables the forkserver optimization, reverting to\n    fork + execve() call for every tested input. This is useful mostly when\n    working with unruly libraries that create threads or do other crazy\n    things when initializing (before the instrumentation has a chance to run).\n\n    Note that this setting inhibits some of the user-friendly diagnostics\n    normally done when starting up the forkserver and causes a pretty\n    significant performance drop.\n\n  - Setting AFL_NO_VAR_CHECK skips the detection of variable test cases,\n    greatly speeding up session resumption and path discovery for complex\n    multi-threaded apps (but depriving you of a potentially useful signal\n    in more orderly programs).\n\n  - AFL_EXIT_WHEN_DONE causes afl-fuzz to terminate when all existing paths\n    have been fuzzed and there were no new finds for a while. This would be\n    normally indicated by the cycle counter in the UI turning green. May be\n    convenient for some types of automated jobs.\n\n  - AFL_SKIP_CRASHES causes AFL to tolerate crashing files in the input\n    queue. This can help with rare situations where a program crashes only\n    intermittently, but it's not really recommended under normal operating\n    conditions.\n\n  - When developing custom instrumentation on top of afl-fuzz, you can use\n    AFL_SKIP_BIN_CHECK to inhibit the checks for non-instrumented binaries\n    and shell scripts; and AFL_DUMB_FORKSRV in conjunction with the -n\n    setting to instruct afl-fuzz to still follow the fork server protocol\n    without expecting any instrumentation data in return.\n\n  - When running in the -M or -S mode, setting AFL_IMPORT_FIRST causes the\n    fuzzer to import test cases from other instances before doing anything\n    else. This makes the \"own finds\" counter in the UI more accurate\n    Beyond counter aesthetics, not much else should change.\n\n  - Setting AFL_POST_LIBRARY allows you to configure a postprocessor for\n    mutated files - say, to fix up checksums. See experimental/post_library/\n    for more.\n\n  - The CPU widget shown at the bottom of the screen is fairly simplistic and\n    may complain of high load prematurely, especially on systems with low core\n    counts. To avoid the alarming red color, you can set AFL_NO_CPU_RED.\n\n  - In QEMU mode (-Q), AFL_PATH will be searched for afl-qemu-trace.\n\n  - If you are Jakub, you may need AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES.\n    Others need not apply.\n\n4) Settings for afl-qemu-trace\n------------------------------\n\nThe QEMU wrapper used to instrument binary-only code supports several settings:\n\n  - It is possible to set AFL_INST_RATIO to skip the instrumentation on some\n    of the basic blocks, which can be useful when dealing with very complex\n    binaries.\n\n  - Setting AFL_INST_LIBS causes the translator to also instrument the code\n    inside any dynamically linked libraries (notably including glibc).\n\n  - The underlying QEMU binary will recognize any standard \"user space\n    emulation\" variables (e.g., QEMU_STACK_SIZE), but there should be no\n    reason to touch them.\n\n5) Settings for afl-cmin\n------------------------\n\nThe corpus minimization script offers very little customization:\n\n  - Setting AFL_PATH offers a way to specify the location of afl-showmap\n    and afl-qemu-trace (the latter only in -Q mode).\n\n  - AFL_KEEP_TRACES makes the tool keep traces and other metadata used for\n    minimization and normally deleted at exit. The files can be found in the\n    <out_dir>/.traces/*.\n\n6) Settings for afl-tmin\n------------------------\n\nVirtually nothing to play with. Well, in QEMU mode (-Q), AFL_PATH will be\nsearched for afl-qemu-trace. In addition to this, TMPDIR may be used if a\ntemporary file can't be created in the current working directory.\n\n7) Third-party variables set by afl-fuzz & other tools\n------------------------------------------------------\n\nSeveral variables are not directly interpreted by afl-fuzz, but are set to\noptimal values if not already present in the environment:\n\n  - By default, LD_BIND_NOW is set to speed up fuzzing by forcing the\n    linker to do all the work before the fork server kicks in. You can\n    override this by setting LD_BIND_LAZY beforehand, but it is almost\n    certainly pointless.\n\n  - By default, ASAN_OPTIONS are set to:\n\n    abort_on_error=1\n    detect_leaks=0\n    allocator_may_return_null=1\n\n    If you want to set your own options, be sure to include abort_on_error=1 -\n    otherwise, the fuzzer will not be able to detect crashes in the tested\n    app.\n\n  - In the same vein, by default, MSAN_OPTIONS are set to:\n\n    exit_code=86\n    msan_track_origins=0\n\n    Be sure to include the first one when customizing anything, since MSAN\n    doesn't call abort() on error, and we need a way to detect faults.\n"
  },
  {
    "path": "docs/historical_notes.txt",
    "content": "================\nHistorical notes\n================\n\n  This doc talks about the rationale of some of the high-level design decisions\n  for American Fuzzy Lop. It's adopted from a discussion with Rob Graham.\n  See README for the general instruction manual, and technical_details.txt for\n  additional implementation-level insights.\n\n1) Influences\n-------------\n\nIn short, afl-fuzz is inspired chiefly by the work done by Tavis Ormandy back\nin 2007. Tavis did some very persuasive experiments using gcov block coverage\nto select optimal test cases out of a large corpus of data, and then using\nthem as a starting point for traditional fuzzing workflows.\n\n(By \"persuasive\", I mean: netting a significant number of interesting\nvulnerabilities.)\n\nIn parallel to this, both Tavis and I were interested in evolutionary fuzzing.\nTavis had his experiments, and I was working on a tool called bunny-the-fuzzer,\nreleased somewhere in 2007.\n\nBunny used a generational algorithm not much different from afl-fuzz, but\nalso tried to reason about the relationship between various input bits and\nthe internal state of the program, with hopes of deriving some additional value\nfrom that. The reasoning / correlation part was probably in part inspired by\nother projects done around the same time by Will Drewry and Chris Evans.\n\nThe state correlation approach sounded very sexy on paper, but ultimately, made\nthe fuzzer complicated, brittle, and cumbersome to use; every other target\nprogram would require a tweak or two. Because Bunny didn't fare a whole lot\nbetter than less sophisticated brute-force tools, I eventually decided to write\nit off. You can still find its original documentation at:\n\n  https://code.google.com/p/bunny-the-fuzzer/wiki/BunnyDoc\n\nThere has been a fair amount of independent work, too. Most notably, a few\nweeks earlier that year, Jared DeMott had a Defcon presentation about a\ncoverage-driven fuzzer that relied on coverage as a fitness function.\n\nJared's approach was by no means identical to what afl-fuzz does, but it was in\nthe same ballpark. His fuzzer tried to explicitly solve for the maximum coverage\nwith a single input file; in comparison, afl simply selects for cases that do\nsomething new (which yields better results - see technical_details.txt).\n\nA few years later, Gabriel Campana released fuzzgrind, a tool that relied purely\non Valgrind and a constraint solver to maximize coverage without any brute-force\nbits; and Microsoft Research folks talked extensively about their still\nnon-public, solver-based SAGE framework.\n\nIn the past six years or so, I've also seen a fair number of academic papers\nthat dealt with smart fuzzing (focusing chiefly on symbolic execution) and a\ncouple papers that discussed proof-of-concept applications of genetic\nalgorithms with the same goals in mind. I'm unconvinced how practical most of\nthese experiments were; I suspect that many of them suffer from the\nbunny-the-fuzzer's curse of being cool on paper and in carefully designed\nexperiments, but failing the ultimate test of being able to find new,\nworthwhile security bugs in otherwise well-fuzzed, real-world software.\n\nIn some ways, the baseline that the \"cool\" solutions have to compete against is\na lot more impressive than it may seem, making it difficult for competitors to\nstand out. For a singular example, check out the work by Gynvael and Mateusz\nJurczyk, applying \"dumb\" fuzzing to ffmpeg, a prominent and security-critical\ncomponent of modern browsers and media players:\n\n  http://googleonlinesecurity.blogspot.com/2014/01/ffmpeg-and-thousand-fixes.html\n\nEffortlessly getting comparable results with state-of-the-art symbolic execution\nin equally complex software still seems fairly unlikely, and hasn't been\ndemonstrated in practice so far.\n\nBut I digress; ultimately, attribution is hard, and glorying the fundamental\nconcepts behind AFL is probably a waste of time. The devil is very much in the\noften-overlooked details, which brings us to...\n\n2) Design goals for afl-fuzz\n----------------------------\n\nIn short, I believe that the current implementation of afl-fuzz takes care of\nseveral itches that seemed impossible to scratch with other tools:\n\n1) Speed. It's genuinely hard to compete with brute force when your \"smart\"\n   approach is resource-intensive. If your instrumentation makes it 10x more\n   likely to find a bug, but runs 100x slower, your users are getting a bad\n   deal.\n\n   To avoid starting with a handicap, afl-fuzz is meant to let you fuzz most of\n   the intended targets at roughly their native speed - so even if it doesn't\n   add value, you do not lose much.\n\n   On top of this, the tool leverages instrumentation to actually reduce the\n   amount of work in a couple of ways: for example, by carefully trimming the\n   corpus or skipping non-functional but non-trimmable regions in the input\n   files.\n\n2) Rock-solid reliability. It's hard to compete with brute force if your\n   approach is brittle and fails unexpectedly. Automated testing is attractive\n   because it's simple to use and scalable; anything that goes against these\n   principles is an unwelcome trade-off and means that your tool will be used\n   less often and with less consistent results.\n\n   Most of the approaches based on symbolic execution, taint tracking, or\n   complex syntax-aware instrumentation are currently fairly unreliable with\n   real-world targets. Perhaps more importantly, their failure modes can render\n   them strictly worse than \"dumb\" tools, and such degradation can be difficult\n   for less experienced users to notice and correct.\n\n   In contrast, afl-fuzz is designed to be rock solid, chiefly by keeping it\n   simple. In fact, at its core, it's designed to be just a very good\n   traditional fuzzer with a wide range of interesting, well-researched\n   strategies to go by. The fancy parts just help it focus the effort in\n   places where it matters the most.\n\n3) Simplicity. The author of a testing framework is probably the only person\n   who truly understands the impact of all the settings offered by the tool -\n   and who can dial them in just right. Yet, even the most rudimentary fuzzer\n   frameworks often come with countless knobs and fuzzing ratios that need to\n   be guessed by the operator ahead of the time. This can do more harm than \n   good.\n\n   AFL is designed to avoid this as much as possible. The three knobs you\n   can play with are the output file, the memory limit, and the ability to\n   override the default, auto-calibrated timeout. The rest is just supposed to\n   work. When it doesn't, user-friendly error messages outline the probable\n   causes and workarounds, and get you back on track right away.\n\n4) Chainability. Most general-purpose fuzzers can't be easily employed\n   against resource-hungry or interaction-heavy tools, necessitating the\n   creation of custom in-process fuzzers or the investment of massive CPU\n   power (most of which is wasted on tasks not directly related to the code\n   we actually want to test).\n\n   AFL tries to scratch this itch by allowing users to use more lightweight\n   targets (e.g., standalone image parsing libraries) to create small\n   corpora of interesting test cases that can be fed into a manual testing\n   process or a UI harness later on.\n\nAs mentioned in technical_details.txt, AFL does all this not by systematically\napplying a single overarching CS concept, but by experimenting with a variety\nof small, complementary methods that were shown to reliably yields results\nbetter than chance. The use of instrumentation is a part of that toolkit, but is\nfar from being the most important one.\n\nUltimately, what matters is that afl-fuzz is designed to find cool bugs - and\nhas a pretty robust track record of doing just that.\n"
  },
  {
    "path": "docs/notes_for_asan.txt",
    "content": "==================================\nNotes for using ASAN with afl-fuzz\n==================================\n\n  This file discusses some of the caveats for fuzzing under ASAN, and suggests\n  a handful of alternatives. See README for the general instruction manual.\n\n1) Short version\n----------------\n\nASAN on 64-bit systems requests a lot of memory in a way that can't be easily\ndistinguished from a misbehaving program bent on crashing your system.\n\nBecause of this, fuzzing with ASAN is recommended only in four scenarios:\n\n  - On 32-bit systems, where we can always enforce a reasonable memory limit\n    (-m 800 or so is a good starting point),\n\n  - On 64-bit systems only if you can do one of the following:\n\n    - Compile the binary in 32-bit mode (gcc -m32),\n\n    - Precisely gauge memory needs using http://jwilk.net/software/recidivm .\n\n    - Limit the memory available to process using cgroups on Linux (see\n      experimental/asan_cgroups).\n\nTo compile with ASAN, set AFL_USE_ASAN=1 before calling 'make clean all'. The\nafl-gcc / afl-clang wrappers will pick that up and add the appropriate flags.\nNote that ASAN is incompatible with -static, so be mindful of that.\n\n(You can also use AFL_USE_MSAN=1 to enable MSAN instead.)\n\nThere is also the option of generating a corpus using a non-ASAN binary, and\nthen feeding it to an ASAN-instrumented one to check for bugs. This is faster,\nand can give you somewhat comparable results.\n\n2) Long version\n---------------\n\nASAN allocates a huge region of virtual address space for bookkeeping purposes.\nMost of this is never actually accessed, so the OS never has to allocate any\nreal pages of memory for the process, and the VM grabbed by ASAN is essentially\n\"free\" - but the mapping counts against the standard OS-enforced limit\n(RLIMIT_AS, aka ulimit -v).\n\nOn our end, afl-fuzz tries to protect you from processes that go off-rails\nand start consuming all the available memory in a vain attempt to parse a\nmalformed input file. This happens surprisingly often, so enforcing such a limit\nis important for almost any fuzzer: the alternative is for the kernel OOM\nhandler to step in and start killing random processes to free up resources.\nNeedless to say, that's not a very nice prospect to live with.\n\nUnfortunately, un*x systems offer no portable way to limit the amount of\npages actually given to a process in a way that distinguishes between that\nand the harmless \"land grab\" done by ASAN. In principle, there are three standard\nways to limit the size of the heap:\n\n  - The RLIMIT_AS mechanism (ulimit -v) caps the size of the virtual space -\n    but as noted, this pays no attention to the number of pages actually\n    in use by the process, and doesn't help us here.\n\n  - The RLIMIT_DATA mechanism (ulimit -d) seems like a good fit, but it applies\n    only to the traditional sbrk() / brk() methods of requesting heap space;\n    modern allocators, including the one in glibc, routinely rely on mmap()\n    instead, and circumvent this limit completely.\n\n  - Finally, the RLIMIT_RSS limit (ulimit -m) sounds like what we need, but\n    doesn't work on Linux - mostly because nobody felt like implementing it.\n\nThere are also cgroups, but they are Linux-specific, not universally available\neven on Linux systems, and they require root permissions to set up; I'm a bit\nhesitant to make afl-fuzz require root permissions just for that. That said,\nif you are on Linux and want to use cgroups, check out the contributed script\nthat ships in experimental/asan_cgroups/.\n\nIn settings where cgroups aren't available, we have no nice, portable way to\navoid counting the ASAN allocation toward the limit. On 32-bit systems, or for\nbinaries compiled in 32-bit mode (-m32), this is not a big deal: ASAN needs\naround 600-800 MB or so, depending on the compiler - so all you need to do is\nto specify -m that is a bit higher than that.\n\nOn 64-bit systems, the situation is more murky, because the ASAN allocation\nis completely outlandish - around 17.5 TB in older versions, and closer to\n20 TB with newest ones. The actual amount of memory on your system is\n(probably!) just a tiny fraction of that - so unless you dial the limit\nwith surgical precision, you will get no protection from OOM bugs.\n\nOn my system, the amount of memory grabbed by ASAN with a slightly older\nversion of gcc is around 17,825,850 MB; for newest clang, it's 20,971,600.\nBut there is no guarantee that these numbers are stable, and if you get them\nwrong by \"just\" a couple gigs or so, you will be at risk.\n\nTo get the precise number, you can use the recidivm tool developed by Jakub\nWilk (http://jwilk.net/software/recidivm). In absence of this, ASAN is *not*\nrecommended when fuzzing 64-bit binaries, unless you are confident that they\nare robust and enforce reasonable memory limits (in which case, you can\nspecify '-m none' when calling afl-fuzz).\n\nUsing recidivm or running with no limits aside, there are two other decent\nalternatives: build a corpus of test cases using a non-ASAN binary, and then\nexamine them with ASAN, Valgrind, or other heavy-duty tools in a more\ncontrolled setting; or compile the target program with -m32 (32-bit mode)\nif your system supports that.\n\n3) Interactions with the QEMU mode\n----------------------------------\n\nASAN, MSAN, and other sanitizers appear to be incompatible with QEMU user\nemulation, so please do not try to use them with the -Q option; QEMU doesn't\nseem to appreciate the shadow VM trick used by these tools, and will likely\njust allocate all your physical memory, then crash.\n\n4) What about UBSAN?\n--------------------\n\nSome folks expressed interest in fuzzing with UBSAN. This isn't officially\nsupported, because many installations of UBSAN don't offer a consistent way\nto abort() on fault conditions or to terminate with a distinctive exit code.\n\nThat said, some versions of the library can be binary-patched to address this\nissue, while newer releases support explicit compile-time flags - see this\nmailing list thread for tips:\n\n  https://groups.google.com/forum/#!topic/afl-users/GyeSBJt4M38\n"
  },
  {
    "path": "docs/parallel_fuzzing.txt",
    "content": "=========================\nTips for parallel fuzzing\n=========================\n\n  This document talks about synchronizing afl-fuzz jobs on a single machine\n  or across a fleet of systems. See README for the general instruction manual.\n\n1) Introduction\n---------------\n\nEvery copy of afl-fuzz will take up one CPU core. This means that on an\nn-core system, you can almost always run around n concurrent fuzzing jobs with\nvirtually no performance hit (you can use the afl-gotcpu tool to make sure).\n\nIn fact, if you rely on just a single job on a multi-core system, you will\nbe underutilizing the hardware. So, parallelization is usually the right\nway to go.\n\nWhen targeting multiple unrelated binaries or using the tool in \"dumb\" (-n)\nmode, it is perfectly fine to just start up several fully separate instances\nof afl-fuzz. The picture gets more complicated when you want to have multiple\nfuzzers hammering a common target: if a hard-to-hit but interesting test case\nis synthesized by one fuzzer, the remaining instances will not be able to use\nthat input to guide their work.\n\nTo help with this problem, afl-fuzz offers a simple way to synchronize test\ncases on the fly.\n\n2) Single-system parallelization\n--------------------------------\n\nIf you wish to parallelize a single job across multiple cores on a local\nsystem, simply create a new, empty output directory (\"sync dir\") that will be\nshared by all the instances of afl-fuzz; and then come up with a naming scheme\nfor every instance - say, \"fuzzer01\", \"fuzzer02\", etc. \n\nRun the first one (\"master\", -M) like this:\n\n$ ./afl-fuzz -i testcase_dir -o sync_dir -M fuzzer01 [...other stuff...]\n\n...and then, start up secondary (-S) instances like this:\n\n$ ./afl-fuzz -i testcase_dir -o sync_dir -S fuzzer02 [...other stuff...]\n$ ./afl-fuzz -i testcase_dir -o sync_dir -S fuzzer03 [...other stuff...]\n\nEach fuzzer will keep its state in a separate subdirectory, like so:\n\n  /path/to/sync_dir/fuzzer01/\n\nEach instance will also periodically rescan the top-level sync directory\nfor any test cases found by other fuzzers - and will incorporate them into\nits own fuzzing when they are deemed interesting enough.\n\nThe only difference between the -M and -S modes is that the master instance\nwill still perform deterministic checks; while the slaves will proceed straight\nto random tweaks. If you don't want to do deterministic fuzzing at all, it's OK\nto run all instances with -S. With very slow or complex targets, or when running\nheavily parallelized jobs, this is usually a good plan.\n\nYou can monitor the progress of your jobs from the command line with the\nprovided afl-whatsup tool. When the instances are no longer finding new paths,\nit's probably time to stop.\n\nWARNING: Exercise caution when explicitly specifying the -f option. Each fuzzer\nmust use a separate temporary file; otherwise, things will go south. One safe\nexample may be:\n\n$ ./afl-fuzz [...] -S fuzzer10 -f file10.txt ./fuzzed/binary @@\n$ ./afl-fuzz [...] -S fuzzer11 -f file11.txt ./fuzzed/binary @@\n$ ./afl-fuzz [...] -S fuzzer12 -f file12.txt ./fuzzed/binary @@\n\nThis is not a concern if you use @@ without -f and let afl-fuzz come up with the\nfile name.\n\n3) Multi-system parallelization\n-------------------------------\n\nThe basic operating principle for multi-system parallelization is similar to\nthe mechanism explained in section 2. The key difference is that you need to\nwrite a simple script that performs two actions:\n\n  - Uses SSH with authorized_keys to connect to every machine and retrieve\n    a tar archive of the /path/to/sync_dir/<fuzzer_id>/queue/ directories for\n    every <fuzzer_id> local to the machine. It's best to use a naming scheme\n    that includes host name in the fuzzer ID, so that you can do something\n    like:\n\n    for s in {1..10}; do\n      ssh user@host${s} \"tar -czf - sync/host${s}_fuzzid*/[qf]*\" >host${s}.tgz\n    done\n\n  - Distributes and unpacks these files on all the remaining machines, e.g.:\n\n    for s in {1..10}; do\n      for d in {1..10}; do\n        test \"$s\" = \"$d\" && continue\n        ssh user@host${d} 'tar -kxzf -' <host${s}.tgz\n      done\n    done\n\nThere is an example of such a script in experimental/distributed_fuzzing/;\nyou can also find a more featured, experimental tool developed by\nMartijn Bogaard at:\n\n  https://github.com/MartijnB/disfuzz-afl\n\nAnother client-server implementation from Richo Healey is:\n\n  https://github.com/richo/roving\n\nNote that these third-party tools are unsafe to run on systems exposed to the\nInternet or to untrusted users.\n\nWhen developing custom test case sync code, there are several optimizations\nto keep in mind:\n\n  - The synchronization does not have to happen very often; running the\n    task every 30 minutes or so may be perfectly fine.\n\n  - There is no need to synchronize crashes/ or hangs/; you only need to\n    copy over queue/* (and ideally, also fuzzer_stats).\n\n  - It is not necessary (and not advisable!) to overwrite existing files;\n    the -k option in tar is a good way to avoid that.\n\n  - There is no need to fetch directories for fuzzers that are not running\n    locally on a particular machine, and were simply copied over onto that\n    system during earlier runs.\n\n  - For large fleets, you will want to consolidate tarballs for each host,\n    as this will let you use n SSH connections for sync, rather than n*(n-1).\n\n    You may also want to implement staged synchronization. For example, you\n    could have 10 groups of systems, with group 1 pushing test cases only\n    to group 2; group 2 pushing them only to group 3; and so on, with group\n    eventually 10 feeding back to group 1.\n\n    This arrangement would allow test interesting cases to propagate across\n    the fleet without having to copy every fuzzer queue to every single host.\n\n  - You do not want a \"master\" instance of afl-fuzz on every system; you should\n    run them all with -S, and just designate a single process somewhere within\n    the fleet to run with -M.\n\nIt is *not* advisable to skip the synchronization script and run the fuzzers\ndirectly on a network filesystem; unexpected latency and unkillable processes\nin I/O wait state can mess things up.\n\n4) Remote monitoring and data collection\n----------------------------------------\n\nYou can use screen, nohup, tmux, or something equivalent to run remote\ninstances of afl-fuzz. If you redirect the program's output to a file, it will\nautomatically switch from a fancy UI to more limited status reports. There is\nalso basic machine-readable information always written to the fuzzer_stats file\nin the output directory. Locally, that information can be interpreted with\nafl-whatsup.\n\nIn principle, you can use the status screen of the master (-M) instance to\nmonitor the overall fuzzing progress and decide when to stop. In this\nmode, the most important signal is just that no new paths are being found\nfor a longer while. If you do not have a master instance, just pick any\nsingle slave and go by that.\n\nYou can also rely on that instance's output directory to collect the\nsynthesized corpus that covers all the noteworthy paths discovered anywhere\nwithin the fleet. The slave (-S) instances do not require any special\nmonitoring, other than just making sure that they are up.\n\nKeep in mind that crashing inputs are *not* automatically propagated to the\nmaster instance, so you may still want to monitor for crashes fleet-wide\nfrom within your synchronization or health checking scripts (see afl-whatsup).\n\n5) Asymmetric setups\n--------------------\n\nIt is perhaps worth noting that all of the following is permitted:\n\n  - Running afl-fuzz with conjunction with other guided tools that can extend\n    coverage (e.g., via concolic execution). Third-party tools simply need to\n    follow the protocol described above for pulling new test cases from\n    out_dir/<fuzzer_id>/queue/* and writing their own finds to sequentially\n    numbered id:nnnnnn files in out_dir/<ext_tool_id>/queue/*.\n\n  - Running some of the synchronized fuzzers with different (but related)\n    target binaries. For example, simultaneously stress-testing several\n    different JPEG parsers (say, IJG jpeg and libjpeg-turbo) while sharing\n    the discovered test cases can have synergistic effects and improve the\n    overall coverage.\n\n    (In this case, running one -M instance per each binary is a good plan.)\n\n  - Having some of the fuzzers invoke the binary in different ways.\n    For example, 'djpeg' supports several DCT modes, configurable with\n    a command-line flag, while 'dwebp' supports incremental and one-shot\n    decoding. In some scenarios, going after multiple distinct modes and then\n    pooling test cases will improve coverage.\n\n  - Much less convincingly, running the synchronized fuzzers with different\n    starting test cases (e.g., progressive and standard JPEG) or dictionaries.\n    The synchronization mechanism ensures that the test sets will get fairly\n    homogeneous over time, but it introduces some initial variability.\n"
  },
  {
    "path": "docs/perf_tips.txt",
    "content": "=================================\nTips for performance optimization\n=================================\n\n  This file provides tips for troubleshooting slow or wasteful fuzzing jobs.\n  See README for the general instruction manual.\n\n1) Keep your test cases small\n-----------------------------\n\nThis is probably the single most important step to take! Large test cases do\nnot merely take more time and memory to be parsed by the tested binary, but\nalso make the fuzzing process dramatically less efficient in several other\nways.\n\nTo illustrate, let's say that you're randomly flipping bits in a file, one bit\nat a time. Let's assume that if you flip bit #47, you will hit a security bug;\nflipping any other bit just results in an invalid document.\n\nNow, if your starting test case is 100 bytes long, you will have a 71% chance of\ntriggering the bug within the first 1,000 execs - not bad! But if the test case\nis 1 kB long, the probability that we will randomly hit the right pattern in\nthe same timeframe goes down to 11%. And if it has 10 kB of non-essential\ncruft, the odds plunge to 1%.\n\nOn top of that, with larger inputs, the binary may be now running 5-10x times\nslower than before - so the overall drop in fuzzing efficiency may be easily\nas high as 500x or so.\n\nIn practice, this means that you shouldn't fuzz image parsers with your\nvacation photos. Generate a tiny 16x16 picture instead, and run it through\njpegtran or pngcrunch for good measure. The same goes for most other types\nof documents.\n\nThere's plenty of small starting test cases in ../testcases/* - try them out\nor submit new ones!\n\nIf you want to start with a larger, third-party corpus, run afl-cmin with an\naggressive timeout on that data set first.\n\n2) Use a simpler target\n-----------------------\n\nConsider using a simpler target binary in your fuzzing work. For example, for\nimage formats, bundled utilities such as djpeg, readpng, or gifhisto are\nconsiderably (10-20x) faster than the convert tool from ImageMagick - all while\nexercising roughly the same library-level image parsing code.\n\nEven if you don't have a lightweight harness for a particular target, remember\nthat you can always use another, related library to generate a corpus that will\nbe then manually fed to a more resource-hungry program later on.\n\n3) Use LLVM instrumentation\n---------------------------\n\nWhen fuzzing slow targets, you can gain 2x performance improvement by using\nthe LLVM-based instrumentation mode described in llvm_mode/README.llvm. Note\nthat this mode requires the use of clang and will not work with GCC.\n\nThe LLVM mode also offers a \"persistent\", in-process fuzzing mode that can\nwork well for certain types of self-contained libraries, and for fast targets,\ncan offer performance gains up to 5-10x; and a \"deferred fork server\" mode\nthat can offer huge benefits for programs with high startup overhead. Both\nmodes require you to edit the source code of the fuzzed program, but the\nchanges often amount to just strategically placing a single line or two.\n\n4) Profile and optimize the binary\n----------------------------------\n\nCheck for any parameters or settings that obviously improve performance. For\nexample, the djpeg utility that comes with IJG jpeg and libjpeg-turbo can be\ncalled with:\n\n  -dct fast -nosmooth -onepass -dither none -scale 1/4\n\n...and that will speed things up. There is a corresponding drop in the quality\nof decoded images, but it's probably not something you care about.\n\nIn some programs, it is possible to disable output altogether, or at least use\nan output format that is computationally inexpensive. For example, with image\ntranscoding tools, converting to a BMP file will be a lot faster than to PNG.\n\nWith some laid-back parsers, enabling \"strict\" mode (i.e., bailing out after\nfirst error) may result in smaller files and improved run time without\nsacrificing coverage; for example, for sqlite, you may want to specify -bail.\n\nIf the program is still too slow, you can use strace -tt or an equivalent\nprofiling tool to see if the targeted binary is doing anything silly.\nSometimes, you can speed things up simply by specifying /dev/null as the\nconfig file, or disabling some compile-time features that aren't really needed\nfor the job (try ./configure --help). One of the notoriously resource-consuming\nthings would be calling other utilities via exec*(), popen(), system(), or\nequivalent calls; for example, tar can invoke external decompression tools\nwhen it decides that the input file is a compressed archive.\n\nSome programs may also intentionally call sleep(), usleep(), or nanosleep();\nvim is a good example of that.\n\nIn programs that are slow due to unavoidable initialization overhead, you may\nwant to try the LLVM deferred forkserver mode (see llvm_mode/README.llvm),\nwhich can give you speed gains up to 10x, as mentioned above.\n\nLast but not least, if you are using ASAN and the performance is unacceptable,\nconsider turning it off for now, and manually examining the generated corpus\nwith an ASAN-enabled binary later on.\n\n5) Instrument just what you need\n--------------------------------\n\nInstrument just the libraries you actually want to stress-test right now, one\nat a time. Let the program use system-wide, non-instrumented libraries for\nany functionality you don't actually want to fuzz. For example, in most\ncases, it doesn't make to instrument libgmp just because you're testing a\ncrypto app that relies on it for bignum math.\n\nBeware of programs that come with oddball third-party libraries bundled with\ntheir source code (Spidermonkey is a good example of this). Check ./configure\noptions to use non-instrumented system-wide copies instead.\n\n6) Parallelize your fuzzers\n---------------------------\n\nThe fuzzer is designed to need ~1 core per job. This means that on a, say,\n4-core system, you can easily run four parallel fuzzing jobs with relatively\nlittle performance hit. For tips on how to do that, see parallel_fuzzing.txt.\n\nThe afl-gotcpu utility can help you understand if you still have idle CPU\ncapacity on your system. (It won't tell you about memory bandwidth, cache\nmisses, or similar factors, but they are less likely to be a concern.)\n\n7) Keep memory use and timeouts in check\n----------------------------------------\n\nIf you have increased the -m or -t limits more than truly necessary, consider\ndialing them back down.\n\nFor programs that are nominally very fast, but get sluggish for some inputs,\nyou can also try setting -t values that are more punishing than what afl-fuzz\ndares to use on its own. On fast and idle machines, going down to -t 5 may be\na viable plan.\n\nThe -m parameter is worth looking at, too. Some programs can end up spending\na fair amount of time allocating and initializing megabytes of memory when\npresented with pathological inputs. Low -m values can make them give up sooner\nand not waste CPU time.\n\n8) Check OS configuration\n-------------------------\n\nThere are several OS-level factors that may affect fuzzing speed:\n\n  - High system load. Use idle machines where possible. Kill any non-essential\n    CPU hogs (idle browser windows, media players, complex screensavers, etc).\n\n  - Network filesystems, either used for fuzzer input / output, or accessed by\n    the fuzzed binary to read configuration files (pay special attention to the\n    home directory - many programs search it for dot-files).\n\n  - On-demand CPU scaling. The Linux 'ondemand' governor performs its analysis\n    on a particular schedule and is known to underestimate the needs of\n    short-lived processes spawned by afl-fuzz (or any other fuzzer). On Linux,\n    this can be fixed with:\n\n    cd /sys/devices/system/cpu\n    echo performance | tee cpu*/cpufreq/scaling_governor\n\n    On other systems, the impact of CPU scaling will be different; when fuzzing,\n    use OS-specific tools to find out if all cores are running at full speed.\n\n  - Suboptimal scheduling strategies. The significance of this will vary from\n    one target to another, but on Linux, you may want to make sure that the\n    following options are set:\n\n    echo 1 >/proc/sys/kernel/sched_child_runs_first\n    echo 1 >/proc/sys/kernel/sched_autogroup_enabled\n\n    Setting a different scheduling policy for the fuzzer process - say\n    SCHED_RR - can usually speed things up, too, but needs to be done with\n    care.\n\n9) If all other options fail, use -d\n------------------------------------\n\nFor programs that are genuinely slow, in cases where you really can't escape\nusing huge input files, or when you simply want to get quick and dirty results\nearly on, you can always resort to the -d mode.\n\nThe mode causes afl-fuzz to skip all the deterministic fuzzing steps, which\nmakes output a lot less neat and makes the testing a bit less in-depth, but\nit will give you an experience more familiar from other fuzzing tools.\n"
  },
  {
    "path": "docs/sister_projects.txt",
    "content": "===============\nSister projects\n===============\n\n  This doc lists some of the projects that are inspired by, derived from,\n  designed for, or meant to integrate with AFL. See README for the general\n  instruction manual.\n\n----------------------------\nSupport for other languages:\n----------------------------\n\nPython AFL (Jakub Wilk)\n-----------------------\n\n  Allows fuzz-testing of Python programs. Uses custom instrumentation and its\n  own forkserver.\n\n  http://jwilk.net/software/python-afl\n\nGo-fuzz (Dmitry Vyukov)\n-----------------------\n\n  AFL-inspired guided fuzzing approach for Go targets:\n\n  https://github.com/dvyukov/go-fuzz\n\nafl.rs (Keegan McAllister)\n--------------------------\n\n  Allows Rust features to be easily fuzzed with AFL (using the LLVM mode).\n\n  https://github.com/kmcallister/afl.rs\n\nAFL for GCJ Java and other GCC frontends (-)\n--------------------------------------------\n\n  GCC Java programs are actually supported out of the box - simply rename\n  afl-gcc to afl-gcj. Unfortunately, by default, unhandled exceptions in GCJ do\n  not result in abort() being called, so you will need to manually add a\n  top-level exception handler that exits with SIGABRT or something equivalent.\n\n  Other GCC-supported languages should be fairly easy to get working, but may\n  face similar problems. See https://gcc.gnu.org/frontends.html for a list of\n  options.\n\nAFL-style in-process fuzzer for LLVM (Kostya Serebryany)\n--------------------------------------------------------\n\n  Provides an evolutionary instrumentation-guided fuzzing harness that allows\n  some programs to be fuzzed without the fork / execve overhead. (Similar\n  functionality is now available as the \"persistent\" feature described in\n  ../llvm_mode/README.llvm.)\n\n  http://llvm.org/docs/LibFuzzer.html\n\nAFL fixup shim (Ben Nagy)\n-------------------------\n\n  Allows AFL_POST_LIBRARY postprocessors to be written in arbitrary languages\n  that don't have C / .so bindings. Includes examples in Go.\n\n  https://github.com/bnagy/aflfix\n\n----------------\nNetwork fuzzing:\n----------------\n\nPreeny (Yan Shoshitaishvili)\n----------------------------\n\n  Provides a fairly simple way to convince dynamically linked network-centric\n  programs to read from a file or not fork. Not AFL-specific, but described as\n  useful by many users. Some assembly required.\n\n  https://github.com/zardus/preeny\n\n-------------------------------------------\nDistributed fuzzing and related automation:\n-------------------------------------------\n\nroving (Richo Healey)\n---------------------\n\n  A client-server architecture for effortlessly orchestrating AFL runs across\n  a fleet of machines. You don't want to use this on systems that face the\n  Internet or live in other untrusted environments.\n\n  https://github.com/richo/roving\n\nDistfuzz-AFL (Martijn Bogaard)\n------------------------------\n\n  Simplifies the management of afl-fuzz instances on remote machines. The\n  author notes that the current implementation isn't secure and should not\n  be exposed on the Internet.\n\n  https://github.com/MartijnB/disfuzz-afl\n\nafl-launch (Ben Nagy)\n---------------------\n\n  Batch AFL launcher utility with a simple CLI.\n\n  https://github.com/bnagy/afl-launch\n\nAFL Utils (rc0r)\n----------------\n\n  Simplifies the triage of discovered crashes, start parallel instances, etc.\n\n  https://github.com/rc0r/afl-utils\n\nafl-fuzzing-scripts (Tobias Ospelt)\n-----------------------------------\n\n  Simplifies starting up multiple parallel AFL jobs.\n\n  https://github.com/floyd-fuh/afl-fuzzing-scripts/\n\nafl-sid (Jacek Wielemborek)\n---------------------------\n\n  Allows users to more conveniently build and deploy AFL via Docker.\n\n  https://github.com/d33tah/afl-sid\n\n-------------------------------------\nCrash triage, coverage analysis, etc:\n-------------------------------------\n\nafl-crash-analyzer (Tobias Ospelt)\n----------------------------------\n\n  Makes it easier to navigate and annotate crashing test cases.\n\n  https://github.com/floyd-fuh/afl-crash-analyzer/\n\nCrashwalk (Ben Nagy)\n--------------------\n\n  AFL-aware tool to annotate and sort through crashing test cases.\n\n  https://github.com/bnagy/crashwalk\n\nafl-cov (Michael Rash)\n----------------------\n\n  Produces human-readable coverage data based on the output queue of afl-fuzz.\n\n  https://github.com/mrash/afl-cov\n\nRecidiVM (Jakub Wilk)\n---------------------\n\n  Makes it easy to estimate memory usage limits when fuzzing with ASAN or MSAN.\n\n  http://jwilk.net/software/recidivm\n\n-------------------------------\nNarrow-purpose or experimental:\n-------------------------------\n\nPause and resume scripts (Ben Nagy)\n-----------------------------------\n\n  Simple automation to suspend and resume groups of fuzzing jobs.\n\n  https://gist.github.com/bnagy/8f0eb29eb125653f73fd\n\nStatic binary-only instrumentation (Aleksandar Nikolich)\n--------------------------------------------------------\n\n  Allows black-box binaries to be instrumented statically (i.e., by modifying\n  the binary ahead of the time, rather than translating it on the run). Author\n  reports better performance compared to QEMU, but occasional translation\n  errors with stripped binaries.\n\n  https://github.com/vrtadmin/moflow/tree/master/afl-dyninst\n\nAFL PIN (Parker Thompson)\n-------------------------\n\n  Early-stage Intel PIN instrumentation support (from before we settled on\n  faster-running QEMU).\n\n  https://github.com/mothran/aflpin\n\nAFL-style instrumentation in llvm (Kostya Serebryany)\n-----------------------------------------------------\n\n  Allows AFL-equivalent instrumentation to be injected at compiler level.\n  This is currently not supported by AFL as-is, but may be useful in other\n  projects.\n\n  https://code.google.com/p/address-sanitizer/wiki/AsanCoverage#Coverage_counters\n\nAFL JS (Han Choongwoo)\n----------------------\n\n  One-off optimizations to speed up the fuzzing of JavaScriptCore (now likely\n  superseded by LLVM deferred forkserver init - see llvm_mode/README.llvm).\n\n  https://github.com/tunz/afl-fuzz-js\n\nAFL harness for fwknop (Michael Rash)\n-------------------------------------\n\n  An example of a fairly involved integration with AFL.\n\n  https://github.com/mrash/fwknop/tree/master/test/afl\n\nBuilding harnesses for DNS servers (Jonathan Foote, Ron Bowes)\n--------------------------------------------------------------\n\n  Two articles outlining the general principles and showing some example code.\n\n  https://www.fastly.com/blog/how-to-fuzz-server-american-fuzzy-lop\n  https://goo.gl/j9EgFf\n\nFuzzer shell for SQLite (Richard Hipp)\n--------------------------------------\n\n  A simple SQL shell designed specifically for fuzzing the underlying library.\n\n  http://www.sqlite.org/src/artifact/9e7e273da2030371\n\n"
  },
  {
    "path": "docs/status_screen.txt",
    "content": "===============================\nUnderstanding the status screen\n===============================\n\n  This document provides an overview of the status screen - plus tips for\n  troubleshooting any warnings and red text shown in the UI. See README for\n  the general instruction manual.\n\n0) A note about colors\n----------------------\n\nThe status screen and error messages use colors to keep things readable and\nattract your attention to the most important details. For example, red almost\nalways means \"consult this doc\" :-)\n\nUnfortunately, the UI will render correctly only if your terminal is using\ntraditional un*x palette (white text on black background) or something close\nto that.\n\nIf you are using inverse video, you may want to change your settings, say:\n\n  - For GNOME Terminal, go to Edit > Profile preferences, select the \"colors\"\n    tab, and from the list of built-in schemes, choose \"white on black\".\n\n  - For the MacOS X Terminal app, go to Preferences > Settings, click on\n    the \"Pro\" color scheme, and select \"Use bright colors for bold text\".\n    Then, open a new window using the \"Pro\" scheme via the Shell > New Window\n    menu (or make \"Pro\" your default).\n\nAlternatively, if you really like your current colors, you can edit config.h\nto comment out USE_COLORS, then do 'make clean all'.\n\nI'm not aware of any other simple way to make this work without causing\nother side effects - sorry about that.\n\nWith that out of the way, let's talk about what's actually on the screen...\n\n1) Process timing\n-----------------\n\n  +----------------------------------------------------+\n  |        run time : 0 days, 8 hrs, 32 min, 43 sec    |\n  |   last new path : 0 days, 0 hrs, 6 min, 40 sec     |\n  | last uniq crash : none seen yet                    |\n  |  last uniq hang : 0 days, 1 hrs, 24 min, 32 sec    |\n  +----------------------------------------------------+\n\nThis section is fairly self-explanatory: it tells you how long the fuzzer has\nbeen running and how much time has elapsed since its most recent finds. This is\nbroken down into \"paths\" (a shorthand for test cases that trigger new execution\npatterns), crashes, and hangs.\n\nWhen it comes to timing: there is no hard rule, but most fuzzing jobs should be\nexpected to run for days or weeks; in fact, for a moderately complex project, the\nfirst pass will probably take a day or so. Every now and then, some jobs\nwill be allowed to run for months.\n\nThere's one important thing to watch out for: if the tool is not finding new\npaths within several minutes of starting, you're probably not invoking the\ntarget binary correctly and it never gets to parse the input files we're\nthrowing at it; another possible explanations are that the default memory limit\n(-m) is too restrictive, and the program exits after failing to allocate a\nbuffer very early on; or that the input files are patently invalid and always\nfail a basic header check.\n\nIf there are no new paths showing up for a while, you will eventually see a big\nred warning in this section, too :-)\n\n2) Overall results\n------------------\n\n  +-----------------------+\n  |  cycles done : 0      |\n  |  total paths : 2095   |\n  | uniq crashes : 0      |\n  |   uniq hangs : 19     |\n  +-----------------------+\n\nThe first field in this section gives you the count of queue passes done so far\n- that is, the number of times the fuzzer went over all the interesting test\ncases discovered so far, fuzzed them, and looped back to the very beginning.\nEvery fuzzing session should be allowed to complete at least one cycle; and\nideally, should run much longer than that.\n\nAs noted earlier, the first pass can take a day or longer, so sit back and\nrelax. If you want to get broader but more shallow coverage right away, try\nthe -d option - it gives you a more familiar experience by skipping the\ndeterministic fuzzing steps. It is, however, inferior to the standard mode in\na couple of subtle ways.\n\nTo help make the call on when to hit Ctrl-C, the cycle counter is color-coded.\nIt is shown in magenta during the first pass, progresses to yellow if new finds\nare still being made in subsequent rounds, then blue when that ends - and\nfinally, turns green after the fuzzer hasn't been seeing any action for a\nlonger while.\n\nThe remaining fields in this part of the screen should be pretty obvious:\nthere's the number of test cases (\"paths\") discovered so far, and the number of\nunique faults. The test cases, crashes, and hangs can be explored in real-time\nby browsing the output directory, as discussed in the README.\n\n3) Cycle progress\n-----------------\n\n  +-------------------------------------+\n  |  now processing : 1296 (61.86%)     |\n  | paths timed out : 0 (0.00%)         |\n  +-------------------------------------+\n\nThis box tells you how far along the fuzzer is with the current queue cycle: it\nshows the ID of the test case it is currently working on, plus the number of\ninputs it decided to ditch because they were persistently timing out.\n\nThe \"*\" suffix sometimes shown in the first line means that the currently\nprocessed path is not \"favored\" (a property discussed later on, in section 6).\n\nIf you feel that the fuzzer is progressing too slowly, see the note about the\n-d option in section 2 of this doc.\n\n4) Map coverage\n---------------\n\n  +--------------------------------------+\n  |    map density : 4763 (29.07%)       |\n  | count coverage : 4.03 bits/tuple     |\n  +--------------------------------------+\n\nThe section provides some trivia about the coverage observed by the\ninstrumentation embedded in the target binary.\n\nThe first line in the box tells you how many branch tuples we have already\nhit, in proportion to how much the bitmap can hold. Be wary of extremes:\n\n  - Absolute numbers below 200 or so suggest one of three things: that the\n    program is extremely simple; that it is not instrumented properly (e.g.,\n    due to being linked against a non-instrumented copy of the target\n    library); or that it is bailing out prematurely on your input test cases.\n    The fuzzer will try to mark this in pink, just to make you aware.\n\n  - Percentages over 70% may very rarely happen with very complex programs\n    that make heavy use of template-generated code.\n\n    Because high bitmap density makes it harder for the fuzzer to reliably\n    discern new program states, I recommend recompiling the binary with\n    AFL_INST_RATIO=10 or so and trying again (see env_variables.txt).\n\n    The fuzzer will flag high percentages in red. Chances are, you will never\n    see that unless you're fuzzing extremely hairy software (say, v8, perl,\n    ffmpeg).\n\nThe other line deals with the variability in tuple hit counts seen in the\nbinary. In essence, if every taken branch is always taken a fixed number of\ntimes for all the inputs we have tried, this will read \"1.00\". As we manage\nto trigger other hit counts for every branch, the needle will start to move\ntoward \"8.00\" (every bit in the 8-bit map hit), but will probably never\nreach that extreme.\n\nTogether, the values can be useful for comparing the coverage of several\ndifferent fuzzing jobs that rely on the same instrumented binary.\n\n5) Stage progress\n-----------------\n\n  +-------------------------------------+\n  |  now trying : interest 32/8         |\n  | stage execs : 3996/34.4k (11.62%)   |\n  | total execs : 27.4M                 |\n  |  exec speed : 891.7/sec             |\n  +-------------------------------------+\n\nThis part gives you an in-depth peek at what the fuzzer is actually doing right\nnow. It tells you about the current stage, which can be any of:\n\n  - calibration - a pre-fuzzing stage where the execution path is examined\n    to detect anomalies, establish baseline execution speed, and so on. Executed\n    very briefly whenever a new find is being made.\n\n  - trim L/S - another pre-fuzzing stage where the test case is trimmed to the\n    shortest form that still produces the same execution path. The length (L)\n    and stepover (S) are chosen in general relationship to file size.\n\n  - bitflip L/S - deterministic bit flips. There are L bits toggled at any given\n    time, walking the input file with S-bit increments. The current L/S variants\n    are: 1/1, 2/1, 4/1, 8/8, 16/8, 32/8.\n\n  - arith L/8 - deterministic arithmetics. The fuzzer tries to subtract or add\n    small integers to 8-, 16-, and 32-bit values. The stepover is always 8 bits.\n\n  - interest L/8 - deterministic value overwrite. The fuzzer has a list of known\n    \"interesting\" 8-, 16-, and 32-bit values to try. The stepover is 8 bits.\n\n  - extras - deterministic injection of dictionary terms. This can be shown as\n    \"user\" or \"auto\", depending on whether the fuzzer is using a user-supplied\n    dictionary (-x) or an auto-created one. You will also see \"over\" or \"insert\",\n    depending on whether the dictionary words overwrite existing data or are\n    inserted by offsetting the remaining data to accommodate their length.\n\n  - havoc - a sort-of-fixed-length cycle with stacked random tweaks. The\n    operations attempted during this stage include bit flips, overwrites with\n    random and \"interesting\" integers, block deletion, block duplication, plus\n    assorted dictionary-related operations (if a dictionary is supplied in the\n    first place).\n\n  - splice - a last-resort strategy that kicks in after the first full queue\n    cycle with no new paths. It is equivalent to 'havoc', except that it first\n    splices together two random inputs from the queue at some arbitrarily\n    selected midpoint.\n\n  - sync - a stage used only when -M or -S is set (see parallel_fuzzing.txt).\n    No real fuzzing is involved, but the tool scans the output from other\n    fuzzers and imports test cases as necessary. The first time this is done,\n    it may take several minutes or so.\n\nThe remaining fields should be fairly self-evident: there's the exec count\nprogress indicator for the current stage, a global exec counter, and a\nbenchmark for the current program execution speed. This may fluctuate from\none test case to another, but the benchmark should be ideally over 500 execs/sec\nmost of the time - and if it stays below 100, the job will probably take very\nlong.\n\nThe fuzzer will explicitly warn you about slow targets, too. If this happens,\nsee the perf_tips.txt file included with the fuzzer for ideas on how to speed\nthings up.\n\n6) Findings in depth\n--------------------\n\n  +--------------------------------------+\n  | favored paths : 879 (41.96%)         |\n  |  new edges on : 423 (20.19%)         |\n  | total crashes : 0 (0 unique)         |\n  |   total hangs : 24 (19 unique)       |\n  +--------------------------------------+\n\nThis gives you several metrics that are of interest mostly to complete nerds.\nThe section includes the number of paths that the fuzzer likes the most based\non a minimization algorithm baked into the code (these will get considerably\nmore air time), and the number of test cases that actually resulted in better\nedge coverage (versus just pushing the branch hit counters up). There are also\nadditional, more detailed counters for crashes and hangs.\n\n7) Fuzzing strategy yields\n--------------------------\n\n  +-----------------------------------------------------+\n  |   bit flips : 57/289k, 18/289k, 18/288k             |\n  |  byte flips : 0/36.2k, 4/35.7k, 7/34.6k             |\n  | arithmetics : 53/2.54M, 0/537k, 0/55.2k             |\n  |  known ints : 8/322k, 12/1.32M, 10/1.70M            |\n  |  dictionary : 9/52k, 1/53k, 1/24k                   |\n  |       havoc : 1903/20.0M, 0/0                       |\n  |        trim : 20.31%/9201, 17.05%                   |\n  +-----------------------------------------------------+\n\nThis is just another nerd-targeted section keeping track of how many paths we\nhave netted, in proportion to the number of execs attempted, for each of the\nfuzzing strategies discussed earlier on. This serves to convincingly validate\nassumptions about the usefulness of the various approaches taken by afl-fuzz.\n\nThe trim strategy stats in this section are a bit different than the rest.\nThe first number in this line shows the ratio of bytes removed from the input\nfiles; the second one corresponds to the number of execs needed to achieve this\ngoal. Finally, the third number shows the proportion of bytes that, although\nnot possible to remove, were deemed to have no effect and were excluded from\nsome of the more expensive deterministic fuzzing steps.\n\n8) Path geometry\n----------------\n\n  +---------------------+\n  |    levels : 5       |\n  |   pending : 1570    |\n  |  pend fav : 583     |\n  | own finds : 0       |\n  |  imported : 0       |\n  |  variable : 0       |\n  +---------------------+\n\nThe first field in this section tracks the path depth reached through the\nguided fuzzing process. In essence: the initial test cases supplied by the\nuser are considered \"level 1\". The test cases that can be derived from that\nthrough traditional fuzzing are considered \"level 2\"; the ones derived by\nusing these as inputs to subsequent fuzzing rounds are \"level 3\"; and so forth.\nThe maximum depth is therefore a rough proxy for how much value you're getting\nout of the instrumentation-guided approach taken by afl-fuzz.\n\nThe next field shows you the number of inputs that have not gone through any\nfuzzing yet. The same stat is also given for \"favored\" entries that the fuzzer\nreally wants to get to in this queue cycle (the non-favored entries may have to\nwait a couple of cycles to get their chance).\n\nNext, we have the number of new paths found during this fuzzing section and\nimported from other fuzzer instances when doing parallelized fuzzing; and the\nnumber of inputs that produce seemingly variable behavior in the tested binary.\n\nThat last bit is actually fairly interesting. There are four quasi-common\nexplanations for variable behavior of the tested program:\n\n  - Use of uninitialized memory in conjunction with some intrinsic sources of\n    entropy in the tested binary. This can be indicative of a security bug.\n\n  - Multiple threads executing at once in semi-random order. Not a big deal,\n    but to avoid hiccups, it's best to restrict instrumented programs to a\n    single thread. Check compile-time options or run-time flags. For example,\n    for ImageMagick, you can try --without-threads --disable-openmp; for\n    ffmpeg, look for --disable-pthreads instead.\n\n  - Attempts to create files that were already created during previous runs, or\n    otherwise interact with some form of persistent state. This is harmless,\n    but you may want to instruct the targeted program to write to stdout or to\n    /dev/null to avoid surprises (and disable the creation of temporary files\n    and similar artifacts, if applicable).\n\n  - Hitting functionality that is actually designed to behave randomly. For\n    example, when fuzzing sqlite, the fuzzer will dutifully detect variable\n    behavior once the mutation engine generates something like:\n\n    select random();\n\nLess likely causes may include running out of disk space, SHM handles, or other\nglobally limited resources.\n\nThe paths where variable behavior is detected are marked with a matching entry\nin the <out_dir>/queue/.state/variable_behavior/ directory, so you can look\nthem up easily.\n\nIf you can't suppress variable behavior and don't want to see these warnings,\nsimply set AFL_NO_VAR_CHECK=1 in the environment before running afl-fuzz. This\nwill also dramatically speed up session resumption.\n\n9) CPU load\n-----------\n\n  [cpu: 25%]\n\nThis tiny widget shows the apparent CPU utilization on the local system. It is\ncalculated by taking the number of processes in the \"runnable\" state, and then\ncomparing it to the number of logical cores on the system.\n\nIf the value is shown in green, you are using fewer CPU cores than available on\nyour system and can probably parallelize to improve performance; for tips on\nhow to do that, see parallel_fuzzing.txt.\n\nIf the value is shown in red, your CPU is *possibly* oversubscribed, and\nrunning additional fuzzers may not give you any benefits.\n\nOf course, this benchmark is very simplistic; it tells you how many processes\nare ready to run, but not how resource-hungry they may be. It also doesn't\ndistinguish between physical cores, logical cores, and virtualized CPUs; the\nperformance characteristics of each of these will differ quite a bit.\n\nIf you want a more accurate measurement, you can run the afl-gotcpu utility\nfrom the command line.\n\n10) Addendum: status and plot files\n-----------------------------------\n\nFor unattended operation, some of the key status screen information can be also\nfound in a machine-readable format in the fuzzer_stats file in the output\ndirectory. This includes:\n\n  - start_time     - unix time indicating the start time of afl-fuzz\n  - last_update    - unix time corresponding to the last update of this file\n  - fuzzer_pid     - PID of the fuzzer process\n  - cycles_done    - queue cycles completed so far\n  - execs_done     - number of execve() calls attempted\n  - execs_per_sec  - current number of execs per second\n  - paths_total    - total number of entries in the queue\n  - paths_found    - number of entries discovered through local fuzzing\n  - paths_imported - number of entries imported from other instances\n  - max_depth      - number of levels in the generated data set\n  - cur_path       - currently processed entry number\n  - pending_favs   - number of favored entries still waiting to be fuzzed\n  - pending_total  - number of all entries waiting to be fuzzed\n  - variable_paths - number of test cases showing variable behavior\n  - unique_crashes - number of unique crashes recorded\n  - unique_hangs   - number of unique hangs encountered\n\nMost of these map directly to the UI elements discussed earlier on.\n\nOn top of that, you can also find an entry called 'plot_data', containing a\nplottable history for most of these fields. If you have gnuplot installed, you\ncan turn this into a nice progress report with the included 'afl-plot' tool.\n"
  },
  {
    "path": "docs/technical_details.txt",
    "content": "===================================\nTechnical \"whitepaper\" for afl-fuzz\n===================================\n\n  This document provides a quick overview of the guts of American Fuzzy Lop.\n  See README for the general instruction manual; and for a discussion of\n  motivations and design goals behind AFL, see historical_notes.txt.\n\n0) Design statement\n-------------------\n\nAmerican Fuzzy Lop does its best not to focus on any singular principle of\noperation and not be a proof-of-concept for any specific theory. The tool can\nbe thought of as a collection of hacks that have been tested in practice,\nfound to be surprisingly effective, and have been implemented in the simplest,\nmost robust way I could think of at the time.\n\nMany of the resulting features are made possible thanks to the availability of\nlightweight instrumentation that served as a foundation for the tool, but this\nmechanism should be thought of merely as a means to an end. The only true\ngoverning principles are speed, reliability, and ease of use.\n\n1) Coverage measurements\n------------------------\n\nThe instrumentation injected into compiled programs captures branch (edge)\ncoverage, along with coarse branch-taken hit counts. The code injected at\nbranch points is essentially equivalent to:\n\n  cur_location = <COMPILE_TIME_RANDOM>;\n  shared_mem[cur_location ^ prev_location]++; \n  prev_location = cur_location >> 1;\n\nThe cur_location value is generated randomly to simplify the process of\nlinking complex projects and keep the XOR output distributed uniformly.\n\nThe shared_mem[] array is a 64 kB SHM region passed to the instrumented binary\nby the caller. Every byte set in the output map can be thought of as a hit for\na particular (branch_src, branch_dst) tuple in the instrumented code.\n\nThe size of the map is chosen so that collisions are sporadic with almost all\nof the intended targets, which usually sport between 2k and 10k discoverable\nbranch points:\n\n   Branch cnt | Colliding tuples | Example targets\n  ------------+------------------+-----------------\n        1,000 | 0.75%            | giflib, lzo\n        2,000 | 1.5%             | zlib, tar, xz\n        5,000 | 3.5%             | libpng, libwebp\n       10,000 | 7%               | libxml\n       20,000 | 14%              | sqlite\n       50,000 | 30%              | -\n\nAt the same time, its size is small enough to allow the map to be analyzed\nin a matter of microseconds on the receiving end, and to effortlessly fit\nwithin L2 cache.\n\nThis form of coverage provides considerably more insight into the execution\npath of the program than simple block coverage. In particular, it trivially\ndistinguishes between the following execution traces:\n\n  A -> B -> C -> D -> E (tuples: AB, BC, CD, DE)\n  A -> B -> D -> C -> E (tuples: AB, BD, DC, CE)\n\nThis aids the discovery of subtle fault conditions in the underlying code,\nbecause security vulnerabilities are more often associated with unexpected\nor incorrect state transitions than with merely reaching a new basic block.\n\nThe reason for the shift operation in the last line of the pseudocode shown\nearlier in this section is to preserve the directionality of tuples (without\nthis, A ^ B would be indistinguishable from B ^ A) and to retain the identity\nof tight loops (otherwise, A ^ A would be obviously equal to B ^ B).\n\nThe absence of simple saturating arithmetic opcodes on Intel CPUs means that\nthe hit counters can sometimes wrap around to zero. Since this is a fairly\nunlikely and localized event, it's seen as an acceptable performance trade-off.\n\n2) Detecting new behaviors\n--------------------------\n\nThe fuzzer maintains a global map of tuples seen in previous executions; this\ndata can be rapidly compared with individual traces and updated in just a couple\nof dword- or qword-wide instructions and a simple loop.\n\nWhen a mutated input produces an execution trace containing new tuples, the\ncorresponding input file is preserved and routed for additional processing\nlater on (see section #3). Inputs that do not trigger new local-scale state\ntransitions in the execution trace are discarded, even if their overall\ninstrumentation output pattern is unique.\n\nThis approach allows for a very fine-grained and long-term exploration of\nprogram state while not having to perform any computationally intensive and\nfragile global comparisons of complex execution traces, and while avoiding the\nscourge of path explosion.\n\nTo illustrate the properties of the algorithm, consider that the second trace\nshown below would be considered substantially new because of the presence of\nnew tuples (CA, AE):\n\n  #1: A -> B -> C -> D -> E\n  #2: A -> B -> C -> A -> E\n\nAt the same time, with #2 processed, the following pattern will not be seen\nas unique, despite having a markedly different execution path:\n\n  #3: A -> B -> C -> A -> B -> C -> A -> B -> C -> D -> E\n\nIn addition to detecting new tuples, the fuzzer also considers coarse tuple\nhit counts. These are divided into several buckets:\n\n  1, 2, 3, 4-7, 8-15, 16-31, 32-127, 128+\n\nTo some extent, the number of buckets is an implementation artifact: it allows\nan in-place mapping of an 8-bit counter generated by the instrumentation to\nan 8-position bitmap relied on by the fuzzer executable to keep track of the\nalready-seen execution counts for each tuple.\n\nChanges within the range of a single bucket are ignored; transition from one\nbucket to another is flagged as an interesting change in program control flow,\nand is routed to the evolutionary process outlined in the section below.\n\nThe hit count behavior provides a way to distinguish between potentially\ninteresting control flow changes, such as a block of code being executed\ntwice when it was normally hit only once. At the same time, it is fairly\ninsensitive to empirically less notable changes, such as a loop going from\n47 cycles to 48. The counters also provide some degree of \"accidental\"\nimmunity against tuple collisions in dense trace maps.\n\nThe execution is policed fairly heavily through memory and execution time\nlimits; by default, the timeout is set at 5x the initially-calibrated\nexecution speed, rounded up to 20 ms. The aggressive timeouts are meant to\nprevent dramatic fuzzer performance degradation by descending into tarpits\nthat, say, improve coverage by 1% while being 100x slower; we pragmatically\nreject them and hope that the fuzzer will find a less expensive way to reach\nthe same code. Empirical testing strongly suggests that more generous time\nlimits are not worth the cost.\n\n3) Evolving the input queue\n---------------------------\n\nMutated test cases that produced new state transitions within the program are\nadded to the input queue and used as a starting point for future rounds of\nfuzzing. They supplement, but do not automatically replace, existing finds.\n\nThis approach allows the tool to progressively explore various disjoint and\npossibly mutually incompatible features of the underlying data format, as\nshown in this image:\n\n  http://lcamtuf.coredump.cx/afl/afl_gzip.png\n\nSeveral practical examples of the results of this algorithm are discussed\nhere:\n\n  http://lcamtuf.blogspot.com/2014/11/pulling-jpegs-out-of-thin-air.html\n  http://lcamtuf.blogspot.com/2014/11/afl-fuzz-nobody-expects-cdata-sections.html\n\nThe synthetic corpus produced by this process is essentially a compact\ncollection of \"hmm, this does something new!\" input files, and can be used to\nseed any other testing processes down the line (for example, to manually\nstress-test resource-intensive desktop apps).\n\nWith this approach, the queue for most targets grows to somewhere between 1k\nand 10k entries; approximately 10-30% of this is attributable to the discovery\nof new tuples, and the remainder is associated with changes in hit counts.\n\nThe following table compares the relative ability to discover file syntax and\nexplore program states when using several different approaches to guided\nfuzzing. The instrumented target was GNU patch 2.7.3 compiled with -O3 and\nseeded with a dummy text file; the session consisted of a single pass over the\ninput queue with afl-fuzz:\n\n    Fuzzer guidance | Blocks  | Edges   | Edge hit | Highest-coverage\n      strategy used | reached | reached | cnt var  | test case generated\n  ------------------+---------+---------+----------+---------------------------\n     (Initial file) | 156     | 163     | 1.00     | (none)\n                    |         |         |          |\n    Blind fuzzing S | 182     | 205     | 2.23     | First 2 B of RCS diff\n    Blind fuzzing L | 228     | 265     | 2.23     | First 4 B of -c mode diff\n     Block coverage | 855     | 1,130   | 1.57     | Almost-valid RCS diff\n      Edge coverage | 1,452   | 2,070   | 2.18     | One-chunk -c mode diff\n          AFL model | 1,765   | 2,597   | 4.99     | Four-chunk -c mode diff\n\nThe first entry for blind fuzzing (\"S\") corresponds to executing just a single\nround of testing; the second set of figures (\"L\") shows the fuzzer running in a\nloop for a number of execution cycles comparable with that of the instrumented\nruns, which required more time to fully process the growing queue.\n\nRoughly similar results have been obtained in a separate experiment where the\nfuzzer was modified to compile out all the random fuzzing stages and leave just\na series of rudimentary, sequential operations such as walking bit flips.\nBecause this mode would be incapable of altering the size of the input file,\nthe sessions were seeded with a valid unified diff:\n\n    Queue extension | Blocks  | Edges   | Edge hit | Number of unique\n      strategy used | reached | reached | cnt var  | crashes found\n  ------------------+---------+---------+----------+------------------\n     (Initial file) | 624     | 717     | 1.00     | -\n                    |         |         |          |\n      Blind fuzzing | 1,101   | 1,409   | 1.60     | 0\n     Block coverage | 1,255   | 1,649   | 1.48     | 0\n      Edge coverage | 1,259   | 1,734   | 1.72     | 0\n          AFL model | 1,452   | 2,040   | 3.16     | 1\n\nSome of the earlier work on evolutionary fuzzing suggested maintaining just a\nsingle test case and selecting for mutations that improve coverage. At least\nin the tests described above, this \"greedy\" method appeared to offer no\nsubstantial benefits over blind fuzzing.\n\n4) Culling the corpus\n---------------------\n\nThe progressive state exploration approach outlined above means that some of\nthe test cases synthesized later on in the game may have edge coverage that\nis a strict superset of the coverage provided by their ancestors.\n\nTo optimize the fuzzing effort, AFL periodically re-evaluates the queue using a\nfast algorithm that selects a smaller subset of test cases that still cover\nevery tuple seen so far, and whose characteristics make them particularly\nfavorable to the tool.\n\nThe algorithm works by assigning every queue entry a score proportional to its\nexecution latency and file size; and then selecting lowest-scoring candidates\nfor each tuple.\n\nThe tuples are then processed sequentially using a simple workflow:\n\n  1) Find next tuple not yet in the temporary working set,\n\n  2) Locate the winning queue entry for this tuple,\n\n  3) Register *all* tuples present in that entry's trace in the working set,\n\n  4) Go to #1 if there are any missing tuples in the set.\n\nThe generated corpus of \"favored\" entries is usually 5-10x smaller than the\nstarting data set. Non-favored entries are not discarded, but they are skipped\nwith varying probabilities when encountered in the queue:\n\n  - If there are new, yet-to-be-fuzzed favorites present in the queue, 99%\n    of non-favored entries will be skipped to get to the favored ones.\n\n  - If there are no new favorites:\n\n    - If the current non-favored entry was fuzzed before, it will be skipped\n      95% of the time.\n\n    - If it hasn't gone through any fuzzing rounds yet, the odds of skipping\n      drop down to 75%.\n\nBased on empirical testing, this provides a reasonable balance between queue\ncycling speed and test case diversity.\n\nSlightly more sophisticated but much slower culling can be performed on input\nor output corpora with afl-cmin. This tool permanently discards the redundant\nentries and produces a smaller corpus suitable for use with afl-fuzz or\nexternal tools.\n\n5) Trimming input files\n-----------------------\n\nFile size has a dramatic impact on fuzzing performance, both because large\nfiles make the target binary slower, and because they reduce the likelihood\nthat a mutation would touch important format control structures, rather than\nredundant data blocks. This is discussed in more detail in perf_tips.txt.\n\nThe possibility of a bad starting corpus provided by the user aside, some\ntypes of mutations can have the effect of iteratively increasing the size of\nthe generated files, so it is important to counter this trend.\n\nLuckily, the instrumentation feedback provides a simple way to automatically\ntrim down input files while ensuring that the changes made to the files have no\nimpact on the execution path.\n\nThe built-in trimmer in afl-fuzz attempts to sequentially remove blocks of data\nwith variable length and stepover; any deletion that doesn't affect the checksum\nof the trace map is committed to disk. The trimmer is not designed to be\nparticularly thorough; instead, it tries to strike a balance between precision\nand the number of execve() calls spent on the process. The average per-file\ngains are around 5-20%.\n\nThe standalone afl-tmin tool uses a more exhaustive, iterative algorithm, and\nalso attempts to perform alphabet normalization on the trimmed files.\n\n6) Fuzzing strategies\n---------------------\n\nThe feedback provided by the instrumentation makes it easy to understand the\nvalue of various fuzzing strategies and optimize their parameters so that they\nwork equally well across a wide range of file types. The strategies used by\nafl-fuzz are generally format-agnostic and are discussed in more detail here:\n\n  http://lcamtuf.blogspot.com/2014/08/binary-fuzzing-strategies-what-works.html\n\nIt is somewhat notable that especially early on, most of the work done by\nafl-fuzz is actually highly deterministic, and progresses to random stacked\nmodifications and test case splicing only at a later stage. The deterministic\nstrategies include:\n\n  - Sequential bit flips with varying lengths and stepovers,\n\n  - Sequential addition and subtraction of small integers,\n\n  - Sequential insertion of known interesting integers (0, 1, INT_MAX, etc),\n\nThe non-deterministic steps include stacked bit flips, insertions, deletions,\narithmetics, and splicing of different test cases.\n\nTheir relative yields and execve() costs have been investigated and are\ndiscussed in the aforementioned blog post.\n\nFor the reasons discussed in historical_notes.txt (chiefly, performance,\nsimplicity, and reliability), AFL generally does not try to reason about the\nrelationship between specific mutations and program states; the fuzzing steps\nare nominally blind, and are guided only by the evolutionary design of the\ninput queue.\n\nThat said, there is one (trivial) exception to this rule: when a new queue\nentry goes through the initial set of deterministic fuzzing steps, and some\nregions in the file are observed to have no effect on the checksum of the\nexecution path, they may be excluded from the remaining phases of\ndeterministic fuzzing - and proceed straight to random tweaks. Especially for\nverbose, human-readable data formats, this can reduce the number of execs by\n10-40% or so without an appreciable drop in coverage. In extreme cases, such\nas normally block-aligned tar archives, the gains can be as high as 90%.\n\nBecause the underlying \"effector maps\" are local every queue entry and remain\nin force only during deterministic stages that do not alter the size or the\ngeneral layout of the underlying file, this mechanism appears to work very\nreliably and proved to be simple to implement.\n\n7) Dictionaries\n---------------\n\nThe feedback provided by the instrumentation makes it easy to automatically\nidentify syntax tokens in some types of input files, and to detect that certain\ncombinations of predefined or auto-detected dictionary terms constitute a\nvalid grammar for the tested parser.\n\nA discussion of how these features are implemented within afl-fuzz can be found\nhere:\n\n  http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html\n\nIn essence, when basic, typically easily-obtained syntax tokens are combined\ntogether in a purely random manner, the instrumentation and the evolutionary\ndesign of the queue together provide a feedback mechanism to differentiate\nbetween meaningless mutations and ones that trigger new behaviors in the\ninstrumented code - and to incrementally build more complex syntax on top of\nthis discovery.\n\nThe dictionaries have been shown to enable the fuzzer to rapidly reconstruct\nthe grammar of highly verbose and complex languages such as JavaScript, SQL,\nor XML; several examples of generated SQL statements are given in the blog\npost mentioned above.\n\n8) De-duping crashes\n--------------------\n\nDe-duplication of crashes is one of the more important problems for any\ncompetent fuzzing tool. Many of the naive approaches run into problems; in\nparticular, looking just at the faulting address may lead to completely\nunrelated issues being clustered together if the fault happens in a common\nlibrary function (say, strcmp, strcpy); while checksumming call stack\nbacktraces can lead to extreme crash count inflation if the fault can be\nreached through a number of different, possibly recursive code paths.\n\nThe solution implemented in afl-fuzz considers a crash unique if any of two\nconditions are met:\n\n  - The crash trace includes a tuple not seen in any of the previous crashes,\n\n  - The crash trace is missing a tuple that was always present in earlier\n    faults.\n\nThe approach is vulnerable to some path count inflation early on, but exhibits\na very strong self-limiting effect, similar to the execution path analysis\nlogic that is the cornerstone of afl-fuzz.\n\n9) Investigating crashes\n------------------------\n\nThe exploitability of many types of crashes can be ambiguous; afl-fuzz tries\nto address this by providing a crash exploration mode where a known-faulting\ntest case is fuzzed in a manner very similar to the normal operation of the\nfuzzer, but with a constraint that causes any non-crashing mutations to be\nthrown away.\n\nA detailed discussion of the value of this approach can be found here:\n\n  http://lcamtuf.blogspot.com/2014/11/afl-fuzz-crash-exploration-mode.html\n\nThe method uses instrumentation feedback to explore the state of the crashing\nprogram to get past the ambiguous faulting condition and then isolate the\nnewly-found inputs for human review.\n\nOn the subject of crashes, it is worth noting that in contrast to normal\nqueue entries, crashing inputs are *not* trimmed; they are kept exactly as\ndiscovered to make it easier to compare them to the parent, non-crashing entry\nin the queue. That said, afl-tmin can be used to shrink them at will.\n\n10) The fork server\n-------------------\n\nTo improve performance, afl-fuzz uses a \"fork server\", where the fuzzed process\ngoes through execve(), linking, and libc initialization only once, and is then\ncloned from a stopped process image by leveraging copy-on-write. The\nimplementation is described in more detail here:\n\n  http://lcamtuf.blogspot.com/2014/10/fuzzing-binaries-without-execve.html\n\nThe fork server is an integral aspect of the injected instrumentation and\nsimply stops at the first instrumented function to await commands from\nafl-fuzz.\n\nWith fast targets, the fork server can offer considerable performance gains,\nusually between 1.5x and 2x. It is also possible to:\n\n  - Use the fork server in manual (\"deferred\") mode, skipping over larger,\n    user-selected chunks of initialization code. With some targets, this can\n    produce 10x+ performance gains.\n\n  - Enable \"persistent\" mode, where a single process is used to try out\n    multiple inputs, greatly limiting the overhead of repetitive fork()\n    calls. As with the previous mode, this requires custom modifications,\n    but can improve the performance of fast targets by a factor of 5 or more\n    - approximating the benefits of in-process fuzzing jobs.\n\n11) Parallelization\n-------------------\n\nThe parallelization mechanism relies on periodically examining the queues\nproduced by independently-running instances on other CPU cores or on remote\nmachines, and then selectively pulling in the test cases that produce behaviors\nnot yet seen by the fuzzer at hand.\n\nThis allows for extreme flexibility in fuzzer setup, including running synced\ninstances against different parsers of a common data format, often with\nsynergistic effects.\n\nFor more information about this design, see parallel_fuzzing.txt.\n\n12) Binary-only instrumentation\n-------------------------------\n\nInstrumentation of black-box, binary-only targets is accomplished with the\nhelp of a separately-built version of QEMU in \"user emulation\" mode. This also\nallows the execution of cross-architecture code - say, ARM binaries on x86.\n\nQEMU uses basic blocks as translation units; the instrumentation is implemented\non top of this and uses a model roughly analogous to the compile-time hooks:\n\n  if (block_address > elf_text_start && block_address < elf_text_end) {\n\n    cur_location = (block_address >> 4) ^ (block_address << 8);\n    shared_mem[cur_location ^ prev_location]++; \n    prev_location = cur_location >> 1;\n\n  }\n\nThe shift-and-XOR-based scrambling in the second line is used to mask the\neffects of instruction alignment.\n\nThe start-up of binary translators such as QEMU, DynamoRIO, and PIN is fairly\nslow; to counter this, the QEMU mode leverages a fork server similar to that\nused for compiler-instrumented code, effectively spawning copies of an\nalready-initialized process paused at _start.\n\nFirst-time translation of a new basic block also incurs substantial latency. To\neliminate this problem, the AFL fork server is extended by providing a channel\nbetween the running emulator and the parent process. The channel is used\nto notify the parent about the addresses of any newly-encountered blocks and to\nadd them to the translation cache that will be replicated for future child\nprocesses.\n\nAs a result of these two optimizations, the overhead of the QEMU mode is\nroughly 2-5x, compared to 100x+ for PIN.\n"
  },
  {
    "path": "docs/vuln_samples/bash-cmd-exec.var",
    "content": "() { _; } >_[$($())] { id; }"
  },
  {
    "path": "docs/vuln_samples/bash-uninit-mem.var",
    "content": "() { x() { _; }; x() { _; } <<a; }"
  },
  {
    "path": "docs/vuln_samples/libxml2-bad-read.xml",
    "content": "<!DOCTYPEd[<!ENTITY\nS\t\"\"><!ENTITY %\nN\t\"<!ELEMENT<![INCLUDE0\"<!ENTITYL%N;"
  },
  {
    "path": "docs/vuln_samples/sqlite-bad-free.sql",
    "content": "create table t0(o CHar(0)CHECK(0&O>O));insert into t0\nselect randomblob(0)-trim(0);\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-bad-ptr.sql",
    "content": "SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE\"\"\"\"\"\"\"\";\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-bad-ptr2.sql",
    "content": "PRAGMA foreign_keys=1;CREATE TABLE t1(\"\"\"0\"PRIMARY KEy REFERENCES t1 ON DELETE SET NULL);REPLACE INTO t1 SELECT(0);\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-heap-overflow.sql",
    "content": "DROP TABLE IF EXISTS t;CREATE VIRTUAL TABLE t0 USING fts4();insert into t0 select zeroblob(0);SAVEPOINT O;insert into t0\nselect(0);SAVEPOINT E;insert into t0 SELECT 0 UNION SELECT 0'x'ORDER BY x;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-heap-overwrite.sql",
    "content": "ATTACH \"file:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA?mode=memory&cache=shared\" AS x;"
  },
  {
    "path": "docs/vuln_samples/sqlite-negative-memset.sql",
    "content": "SELECT*from(select\"\",zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(150000000),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0)),(select\"\",zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),(0),zeroblob(150000000),(0),zeroblob(0),(0)EXCEPT select zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0));\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr1.sql",
    "content": "create table t0(t);insert into t0\nselect strftime();\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr10.sql",
    "content": "SELECT fts3_tokenizer(@0());\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr11.sql",
    "content": "select''like''like''like#0;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr12.sql",
    "content": "PRAGMA e;select lower(0);select lower(0)\"a\",\"\"GROUP BY a ORDER BY a;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr13.sql",
    "content": "WITH x AS(SELECT*FROM t)SELECT\"\"EXCEPT SELECT 0 ORDER BY 0 COLLATE\"\";\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr14.sql",
    "content": "CREATE VIRTUAL TABLE x USING fts4();VALUES(0,0),(0,0),(0,0),(0,0);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql=''WHERE name='';UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';SAVEPOINT K;SAVEPOINT T;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr15.sql",
    "content": "CREATE VIRTUAL TABLE t4 USING fts4(0,b,c,notindexed=0);INSERT INTO t4 VALUES('','','0');BEGIN;INSERT INTO t4 VALUES('','','0');INSERT INTO t4(t4)VALUES('integrity-check');\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr2.sql",
    "content": "DETACH(select group_concat(q));\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr3.sql",
    "content": "select(select strftime());\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr4.sql",
    "content": "select n()AND+#00;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr5.sql",
    "content": "select e.*,0 from(s,(L))e;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr6.sql",
    "content": "PRAGMA encoding='UTF16';CREATE VIRTUAL TABLE  USING s;"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr7.sql",
    "content": "CREATE VIRTUAL TABLE t USING fts4(tokenize=);\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr8.sql",
    "content": "CREATE TABLE p(a UNIQUE,PRIMARY KEY('a'))WITHOUT rowid;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-null-ptr9.sql",
    "content": "CREATE TABLE t0(z);WITH d(x)AS(SELECT*UNION SELECT 0)INSERT INTO t0 SELECT 0 FROM d;\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-oob-read.sql",
    "content": "create table t0( DEFAULT(0=0)NOT/**/NULL);REPLACE into t0 select'';"
  },
  {
    "path": "docs/vuln_samples/sqlite-oob-write.sql",
    "content": "CREATE VIRTUAL TABLE t0 USING fts4(x,order=DESC);\nINSERT INTO t0(docid,x)VALUES(-1E0,'0(o');\nINSERT INTO t0 VALUES('');\nINSERT INTO t0 VALUES('');\nINSeRT INTO t0 VALUES('o');\nSELECT docid FROM t0 WHERE t0 MATCH'\"0*o\"';\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-stack-buf-overflow.sql",
    "content": "SELECT printf('%*.*f',90000||006000000&6600000000,00000000000000000909000000000000.0000000000000000)\"\"WHERE\"\">\"\";\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-stack-exhaustion.sql",
    "content": "CREATE VIRTUAL TABLE t0 USING fts4(content=t0);\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-unint-mem.sql",
    "content": "REATE VIRTUAL TABLE t0 USING fts4(prefix=0);INSERT INTO t0 VALUES(0);\n"
  },
  {
    "path": "docs/vuln_samples/sqlite-use-after-free.sql",
    "content": "create table t(s);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql='ANALYZE;CREATE VIRTUAL TABLE t USING fts3;DROP TABLE t;DROP TABLE EXISTS t';PRAGMA r;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t;\n"
  },
  {
    "path": "docs/vuln_samples/strings-stack-overflow",
    "content": "$$@$$$@$o\nSo\nS"
  },
  {
    "path": "experimental/README.experiments",
    "content": "Here's a quick overview of the stuff you can find in this directory:\n\n  - argv_fuzzing         - a simple wrapper to allow cmdline to be fuzzed\n                           (e.g., to test setuid programs).\n\n  - asan_cgroups         - a contributed script to simplify fuzzing ASAN\n                           binaries with robust memory limits on Linux.\n\n  - bash_shellshock      - a simple hack used to find a bunch of\n                           post-Shellshock bugs in bash.\n\n  - canvas_harness       - a test harness used to find browser bugs with a \n                           corpus generated using simple image parsing \n                           binaries & afl-fuzz.\n\n  - clang_asm_normalize  - a script that makes it easy to instrument\n                           hand-written assembly, provided that you have clang.\n\n  - crash_triage         - a very rudimentary example of how to annotate crashes\n                           with additional gdb metadata.\n\n  - distributed_fuzzing  - a sample script for synchronizing fuzzer instances\n                           across multiple machines (see parallel_fuzzing.txt).\n\n  - instrumented_cmp     - an experiment showing how a custom memcmp() or\n                           strcmp() can be used to work around one of the\n                           limitations of afl-fuzz.\n\n  - libpng_no_checksum   - a sample patch for removing CRC checks in libpng.\n\n  - persistent_demo      - an example of how to use the LLVM persistent process\n                           mode to speed up certain fuzzing jobs.\n\n  - post_library         - an example of how to build postprocessors for AFL.\n\nNote that the minimize_corpus.sh tool has graduated from the experimental/\ndirectory and is now available as ../afl-cmin. The LLVM mode has likewise\ngraduated to ../llvm_mode/*.\n\nMost of the tools in this directory are meant chiefly as examples that need to\nbe tweaked for your specific needs. They come with some basic documentation,\nbut are not necessarily production-grade.\n"
  },
  {
    "path": "experimental/argv_fuzzing/argv-fuzz-inl.h",
    "content": "/*\n   american fuzzy lop - sample argv fuzzing wrapper\n   ------------------------------------------------\n\n   Written by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file shows a simple way to fuzz command-line parameters with stock\n   afl-fuzz. To use, add:\n\n   #include \"/path/to/argv-fuzz-inl.h\"\n\n   ...to the file containing main(), ideally placing it after all the \n   standard includes. Next, put AFL_INIT_ARGV(); near the very beginning of\n   main().\n\n   This will cause the program to read NUL-delimited input from stdin and\n   put it in argv[]. Two subsequent NULs terminate the array. Empty\n   params are encoded as a lone 0x02. Lone 0x02 can't be generated, but\n   that shouldn't matter in real life.\n\n   If you would like to always preserve argv[0], use this instead:\n   AFL_INIT_SET0(\"prog_name\");\n\n*/\n\n#ifndef _HAVE_ARGV_FUZZ_INL\n#define _HAVE_ARGV_FUZZ_INL\n\n#include <unistd.h>\n\n#define AFL_INIT_ARGV() do { argv = afl_init_argv(&argc); } while (0)\n\n#define AFL_INIT_SET0(_p) do { \\\n    argv = afl_init_argv(&argc); \\\n    argv[0] = (_p); \\\n    if (!argc) argc = 1; \\\n  } while (0)\n\n#define MAX_CMDLINE_LEN 100000\n#define MAX_CMDLINE_PAR 1000\n\nstatic char** afl_init_argv(int* argc) {\n\n  static char  in_buf[MAX_CMDLINE_LEN];\n  static char* ret[MAX_CMDLINE_PAR];\n\n  char* ptr = in_buf;\n  int   rc  = 0;\n\n  if (read(0, in_buf, MAX_CMDLINE_LEN - 2) < 0);\n\n  while (*ptr) {\n\n    ret[rc] = ptr;\n    if (ret[rc][0] == 0x02 && !ret[rc][1]) ret[rc]++;\n    rc++;\n\n    while (*ptr) ptr++;\n    ptr++;\n\n  }\n\n  *argc = rc;\n\n  return ret;\n\n}\n\n#undef MAX_CMDLINE_LEN\n#undef MAX_CMDLINE_PAR\n\n#endif /* !_HAVE_ARGV_FUZZ_INL */\n"
  },
  {
    "path": "experimental/asan_cgroups/limit_memory.sh",
    "content": "#!/usr/bin/env bash\n#\n# american fuzzy lop - limit memory using cgroups\n# -----------------------------------------------\n#\n# Written by Samir Khakimov <samir.hakim@nyu.edu> and\n#            David A. Wheeler <dwheeler@ida.org>\n#\n# Edits to bring the script in line with afl-cmin and other companion scripts\n# by Michal Zalewski <lcamtuf@google.com>. All bugs are my fault.\n#\n# Copyright 2015 Institute for Defense Analyses.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This tool allows the amount of actual memory allocated to a program\n# to be limited on Linux systems using cgroups, instead of the traditional\n# setrlimit() API. This helps avoid the address space problems discussed in\n# docs/notes_for_asan.txt.\n#\n# Important: the limit covers *both* afl-fuzz and the fuzzed binary. In some\n# hopefully rare circumstances, afl-fuzz could be killed before the fuzzed\n# task.\n#\n\necho \"cgroup tool for afl-fuzz by <samir.hakim@nyu.edu> and <dwheeler@ida.org>\"\necho\n\nunset NEW_USER\nMEM_LIMIT=\"50\"\n\nwhile getopts \"+u:m:\" opt; do\n\n  case \"$opt\" in\n\n    \"u\")\n         NEW_USER=\"$OPTARG\"\n         ;;\n\n    \"m\")\n         MEM_LIMIT=\"$[OPTARG]\"\n         ;;\n\n    \"?\")\n         exit 1\n         ;;\n\n   esac\n\ndone\n\nif [ \"$MEM_LIMIT\" -lt \"5\" ]; then\n  echo \"[-] Error: malformed or dangerously low value of -m.\" 1>&2\n  exit 1\nfi\n\nshift $((OPTIND-1))\n\nTARGET_BIN=\"$1\"\n\nif [ \"$TARGET_BIN\" = \"\" -o \"$NEW_USER\" = \"\" ]; then\n\n  cat 1>&2 <<_EOF_\nUsage: $0 [ options ] -- /path/to/afl-fuzz [ ...afl options... ]\n\nRequired parameters:\n\n  -u user   - run the fuzzer as a specific user after setting up limits\n\nOptional parameters:\n\n  -m megs   - set memory limit to a specified value ($MEM_LIMIT MB)\n\nThis tool configures cgroups-based memory limits for a fuzzing job to simplify\nthe task of fuzzing ASAN or MSAN binaries. You would normally want to use it in\nconjunction with '-m none' passed to the afl-fuzz binary itself, say:\n\n  $0 -u joe ./afl-fuzz -i input -o output -m none /path/to/target\n\n_EOF_\n\n  exit 1\n\nfi\n\n# Basic sanity checks\n\nif [ ! \"`uname -s`\" = \"Linux\" ]; then\n echo \"[-] Error: this tool does not support non-Linux systems.\" 1>&2\n exit 1\nfi\n\nif [ ! \"`id -u`\" = \"0\" ]; then\n echo \"[-] Error: you need to run this script as root (sorry!).\" 1>&2\n exit 1\nfi\n\nif ! type cgcreate 2>/dev/null 1>&2; then\n\n  echo \"[-] Error: you need to install cgroup tools first.\" 1>&2\n\n  if type apt-get 2>/dev/null 1>&2; then\n    echo \"    (Perhaps 'apt-get install cgroup-bin' will work.)\" 1>&2\n  elif type yum 2>/dev/null 1>&2; then\n    echo \"    (Perhaps 'yum install libcgroup-tools' will work.)\" 1>&2\n  fi\n\n  exit 1\n\nfi\n\nif ! id -u \"$NEW_USER\" 2>/dev/null 1>&2; then\n  echo \"[-] Error: user '$NEW_USER' does not seem to exist.\" 1>&2\n  exit 1\nfi\n\n# Create a new cgroup path if necessary... We used PID-keyed groups to keep\n# parallel afl-fuzz tasks separate from each other.\n\nCID=\"afl-$NEW_USER-$$\"\n\nCPATH=\"/sys/fs/cgroup/memory/$CID\"\n\nif [ ! -d \"$CPATH\" ]; then\n\n  cgcreate -a \"$NEW_USER\" -g memory:\"$CID\" || exit 1\n\nfi\n\n# Set the appropriate limit...\n\nif [ -f \"$CPATH/memory.memsw.limit_in_bytes\" ]; then\n\n  echo \"${MEM_LIMIT}M\" > \"$CPATH/memory.limit_in_bytes\" 2>/dev/null\n  echo \"${MEM_LIMIT}M\" > \"$CPATH/memory.memsw.limit_in_bytes\" || exit 1\n  echo \"${MEM_LIMIT}M\" > \"$CPATH/memory.limit_in_bytes\" || exit 1\n\nelif grep -qE 'partition|file' /proc/swaps; then\n\n  echo \"[-] Error: your system requires swap to be disabled first (swapoff -a).\" 1>&2\n  exit 1\n\nelse\n\n  echo \"${MEM_LIMIT}M\" > \"$CPATH/memory.limit_in_bytes\" || exit 1\n\nfi\n\n# All right. At this point, we can just run the command.\n\ncgexec -g \"memory:$CID\" su -c \"$*\" \"$NEW_USER\"\n\ncgdelete -g \"memory:$CID\"\n"
  },
  {
    "path": "experimental/bash_shellshock/shellshock-fuzz.diff",
    "content": "This patch shows a very simple way to find post-Shellshock bugs in bash, as\ndiscussed here:\n\n  http://lcamtuf.blogspot.com/2014/10/bash-bug-how-we-finally-cracked.html\n\nIn essence, it shows a way to fuzz environmental variables. Instructions:\n\n1) Download bash 4.3, apply this patch, compile with:\n\n   CC=/path/to/afl-gcc ./configure\n   make clean all\n\n   Note that the harness puts the fuzzed output in $TEST_VARIABLE. With\n   Florian's Shellshock patch (bash43-028), this is no longer passed down\n   to the parser.\n\n2) Create and cd to an empty directory, put the compiled bash binary in\n   there, and run these commands:\n\n   mkdir in_dir\n   echo -n '() { a() { a; }; : >b; }' >in_dir/script.txt\n\n3) Run the fuzzer with:\n\n   /path/to/afl-fuzz -d -i in_dir -o out_dir ./bash -c :\n\n   The -d parameter is advisable only if the tested shell is fairly slow\n   or if you are in a hurry; will cover more ground faster, but\n   less systematically.\n\n4) Watch for crashes in out_dir/crashes/. Also watch for any new files\n   created in cwd if you're interested in non-crash RCEs (files will be\n   created whenever the shell executes \"foo>bar\" or something like\n   that). You can correlate their creation date with new entries in\n   out_dir/queue/.\n\n   You can also modify the bash binary to directly check for more subtle\n   fault conditions, or use the synthesized entries in out_dir/queue/\n   as a seed for other, possibly slower or more involved testing regimes.\n\n   Expect several hours to get decent coverage.\n\n--- bash-4.3/shell.c.orig\t2014-01-14 14:04:32.000000000 +0100\n+++ bash-4.3/shell.c\t2015-04-30 05:56:46.000000000 +0200\n@@ -371,6 +371,14 @@\n   env = environ;\n #endif /* __OPENNT */\n \n+  {\n+\n+    static char val[1024 * 16];\n+    read(0, val, sizeof(val) - 1);\n+    setenv(\"TEST_VARIABLE\", val, 1);\n+\n+  }\n+\n   USE_VAR(argc);\n   USE_VAR(argv);\n   USE_VAR(env);\n"
  },
  {
    "path": "experimental/canvas_harness/canvas_harness.html",
    "content": "<html>\n<!--\n\n  american fuzzy lop - <canvas> harness\n  -------------------------------------\n \n  Written and maintained by Michal Zalewski <lcamtuf@google.com>\n \n  Copyright 2013, 2014 Google Inc. All rights reserved.\n \n  Licensed under the Apache License, Version 2.0 (the \"License\");\n  you may not use this file except in compliance with the License.\n  You may obtain a copy of the License at:\n \n    http://www.apache.org/licenses/LICENSE-2.0\n \n  A simple harness for going through afl-generated test cases, rendering them in\n  the browser environment, and discovering the use of uninitialized memory and\n  similar bugs. This code led to the discovery of a fair number of library and\n  browser security bugs!\n\n  The url_list[] array is a placeholder; for this to work properly, it needs to\n  be initialized with web-reachable paths to individual test cases. This can\n  be done manually or with a simple script.\n\n-->\n\n<body onload=\"set_images()\">\n\n<div id=\"status\"></div>\n\n<div id=\"image_div\"></div>\n\n<canvas height=64 width=64 id=cvs></canvas>\n\n<h2>Results</h2>\n\n<ul id=\"output\"></ul>\n\n<script>\n\nvar c = document.getElementById('cvs');\nvar ctx = c.getContext('2d');\n\nvar url_list = [\n  \"images/id:000000,[...].jpg\",\n  \"images/id:000001,[...].jpg\",\n  /* ... */\n  null\n];\n\nvar USE_IMAGES = 50;\nvar cur_image = 0;\n\nif (location.hash) cur_image = parseInt(location.hash.substr(1));\n\nvar loaded = 0;\nvar image_obj = [];\n\nvar msie_cleanup;\n\nfunction check_results() {\n\n  var uniques = [];\n\n  clearTimeout(msie_cleanup);\n\n  ctx.clearRect(0, 0, 64, 64);\n\n  uniques.push(image_obj[0].imgdata);\n\n  for (var i = 1; i < USE_IMAGES; i++) {\n\n    if (!image_obj[i].imgdata) continue;\n\n    if (image_obj[0].imgdata != image_obj[i].imgdata) {\n\n      for (var j = 1; j < uniques.length; j++)\n        if (uniques[j] == image_obj[i].imgdata) break;\n\n      if (j == uniques.length) uniques.push(image_obj[i].imgdata);\n\n\n    }\n\n  }\n\n  if (uniques.length > 1) {\n\n    var str = '<li> Image ' + url_list[cur_image] + ' has ' + uniques.length + ' variants: ';\n\n    for (var i = 0; i < uniques.length; i++)\n      str += '<img src=\"' + uniques[i] + '\">';\n\n    document.getElementById('output').innerHTML += str;\n\n  }\n\n  cur_image++;\n  set_images();\n}\n\n\nfunction count_image() {\n\n  if (!this.complete || this.counted) return;\n\n  this.counted = true;\n\n  loaded++;\n\n  ctx.clearRect(0, 0, 64, 64);\n\n  try {\n    ctx.drawImage(this, 0, 0, 64, 64);\n  } catch (e) { }\n\n  this.imgdata = c.toDataURL();\n\n  if (loaded == USE_IMAGES) check_results();\n}\n\n\nfunction set_images() {\n\n  loaded = 0;\n\n  document.getElementById('status').innerHTML = 'Now processing ' + cur_image + '...';\n  location.hash = '#' + cur_image;\n\n  if (url_list[cur_image] == null) {\n    alert('Done!');\n    return;\n  }\n\n  restart_images();\n\n  msie_cleanup = setTimeout(check_results, 5000);\n\n  for (var i = 0; i < USE_IMAGES; i++)\n    image_obj[i].src = url_list[cur_image] + '?' + Math.random();\n\n}\n\n\nfunction restart_images() {\n\n  for (var i = 0; i < USE_IMAGES; i++) \n    if (image_obj[i]) image_obj[i].counted = true;\n\n  document.getElementById('image_div').innerHTML = '';\n  image_obj = [];\n\n  for (var i = 0; i < USE_IMAGES; i++) {\n\n    image_obj[i] = new Image();\n    image_obj[i].height = 64;\n    image_obj[i].width = 64;\n    image_obj[i].onerror = count_image;\n    image_obj[i].onload = count_image;\n\n    document.getElementById('image_div').appendChild(image_obj[i]);\n\n  }\n\n}\n\n</script>\n\n<iframe src='http://www.cnn.com/'></iframe>\n"
  },
  {
    "path": "experimental/clang_asm_normalize/as",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - clang assembly normalizer\n# ----------------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n# The idea for this wrapper comes from Ryan Govostes.\n#\n# Copyright 2013, 2014 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This 'as' wrapper should allow you to instrument unruly, hand-written\n# assembly with afl-as.\n#\n# Usage:\n#\n# export AFL_REAL_PATH=/path/to/directory/with/afl-as/\n# AFL_PATH=/path/to/this/directory/ make clean all\n\nif [ \"$#\" -lt \"2\" ]; then\n  echo \"[-] Error: this utility can't be called directly.\" 1>&2\n  exit 1\nfi\n\nif [ \"$AFL_REAL_PATH\" = \"\" ]; then\n  echo \"[-] Error: AFL_REAL_PATH not set!\" 1>&2\n  exit 1\nfi\n\nif [ ! -x \"$AFL_REAL_PATH/afl-as\" ]; then\n  echo \"[-] Error: AFL_REAL_PATH does not contain the 'afl-as' binary.\" 1>&2\n  exit 1\nfi\n\nunset __AFL_AS_CMDLINE __AFL_FNAME\n\nwhile [ ! \"$#\" = \"0\" ]; do\n\n  if [ \"$#\" = \"1\" ]; then\n    __AFL_FNAME=\"$1\"\n  else\n    __AFL_AS_CMDLINE=\"${__AFL_AS_CMDLINE} $1\"\n  fi\n\n  shift\n\ndone\n\ntest \"$TMPDIR\" = \"\" && TMPDIR=/tmp\n\nTMPFILE=`mktemp $TMPDIR/.afl-XXXXXXXXXX.s`\n\ntest \"$TMPFILE\" = \"\" && exit 1\n\nclang -cc1as -filetype asm -output-asm-variant 0 \"${__AFL_FNAME}\" >\"$TMPFILE\"\n\nERR=\"$?\"\n\nif [ ! \"$ERR\" = \"0\" ]; then\n  rm -f \"$TMPFILE\"\n  exit $ERR\nfi\n\n\"$AFL_REAL_PATH/afl-as\" ${__AFL_AS_CMDLINE} \"$TMPFILE\"\n\nERR=\"$?\"\n\nrm -f \"$TMPFILE\"\n\nexit \"$ERR\"\n"
  },
  {
    "path": "experimental/crash_triage/triage_crashes.sh",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - crash triage utility\n# -----------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2013, 2014 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# Note that this assumes that the targeted application reads from stdin\n# and requires no other cmdline parameters. Modify as needed if this is\n# not the case.\n#\n# Note that on OpenBSD, you may need to install a newer version of gdb\n# (e.g., from ports). You can set GDB=/some/path to point to it if\n# necessary.\n#\n\necho \"crash triage utility for afl-fuzz by <lcamtuf@google.com>\"\necho\n\nulimit -v 100000 2>/dev/null\nulimit -d 100000 2>/dev/null\n\nif [ ! \"$#\" = \"2\" ]; then\n  echo \"Usage: $0 /path/to/afl_output_dir /path/to/tested_binary\" 1>&2\n  echo 1>&2\n  echo \"Note: the tested binary must accept input on stdin and require no additional\" 1>&2\n  echo \"parameters. For more complex use cases, you need to edit this script.\" 1>&2\n  echo 1>&2\n  exit 1\nfi\n\nDIR=\"$1\"\nBIN=\"$2\"\n\necho \"$DIR\" | grep -qE '^(/var)?/tmp/'\nT1=\"$?\"\n\necho \"$BIN\" | grep -qE '^(/var)?/tmp/'\nT2=\"$?\"\n\nif [ \"$T1\" = \"0\" -o \"$T2\" = \"0\" ]; then\n  echo \"[-] Error: do not use shared /tmp or /var/tmp directories with this script.\" 1>&2\n  exit 1\nfi\n\nif [ \"$GDB\" = \"\" ]; then\n  GDB=gdb\nfi\n\nif [ ! -f \"$BIN\" -o ! -x \"$BIN\" ]; then\n  echo \"[-] Error: binary '$2' not found or is not executable.\" 1>&2\n  exit 1\nfi\n\nif [ ! -d \"$DIR/queue\" ]; then\n  echo \"[-] Error: directory '$1' not found or not created by afl-fuzz.\" 1>&2\n  exit 1\nfi\n\nCCOUNT=$((`ls -- \"$DIR/crashes\" 2>/dev/null | wc -l`))\n\nif [ \"$CCOUNT\" = \"0\" ]; then\n  echo \"No crashes recorded in the target directory - nothing to be done.\"\n  exit 0\nfi\n\necho\n\nfor crash in $DIR/crashes/id:*; do\n\n  id=`basename -- \"$crash\" | cut -d, -f1 | cut -d: -f2`\n  sig=`basename -- \"$crash\" | cut -d, -f2 | cut -d: -f2`\n\n  echo \"+++ ID $id, SIGNAL $sig +++\"\n  echo\n\n  $GDB --batch -q --ex \"r <$crash\" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' \"$BIN\" 0</dev/null\n  echo\n\ndone\n\n"
  },
  {
    "path": "experimental/distributed_fuzzing/sync_script.sh",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - path minimization tool\n# -------------------------------------------\n#\n# Written and maintained by Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2014 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# To make this script work:\n#\n# - Edit FUZZ_HOSTS, FUZZ_DOMAIN, FUZZ_USER, and SYNC_DIR to reflect your\n#   environment.\n#\n# - Make sure that the system you are running this on can log into FUZZ_HOSTS\n#   without a password (authorized_keys or otherwise).\n#\n# - Make sure that every fuzzer is running with -o pointing to SYNC_DIR and -S\n#   that consists of its local host name, followed by an underscore, and then\n#   by some host-local fuzzer ID.\n#\n\n# Hosts to synchronize the data across.\nFUZZ_HOSTS='host1 host2 host3 host4'\n\n# Domain for all hosts\nFUZZ_DOMAIN='example.com'\n\n# Remote user for SSH\nFUZZ_USER=bob\n\n# Directory to synchronize\nSYNC_DIR='/home/bob/sync_dir'\n\n# Interval (seconds) between sync attempts\nSYNC_INTERVAL=$((30 * 60))\n\nif [ \"$PWD\" = \"/tmp\" -o \"$PWD\" = \"/var/tmp\" ]; then\n  echo \"[-] Error: do not use shared /tmp or /var/tmp directories with this script.\" 1>&2\n  exit 1\nfi\n\nrm -rf .sync_tmp 2>/dev/null\nmkdir .sync_tmp || exit 1\n\nwhile :; do\n\n  # Pull data in...\n\n  for host in $FUZZ_HOSTS; do\n\n    echo \"[*] Retrieving data from ${host}.${FUZZ_DOMAIN}...\"\n\n    ssh -o 'passwordauthentication no' ${FUZZ_USER}@${host}.$FUZZ_DOMAIN \\\n      \"cd '$SYNC_DIR' && tar -czf - ${host}_*/[qf]*\" >\".sync_tmp/${host}.tgz\"\n\n  done\n\n  # Distribute data. For large fleets, see tips in the docs/ directory.\n\n  for dst_host in $FUZZ_HOSTS; do\n\n    echo \"[*] Distributing data to ${dst_host}.${FUZZ_DOMAIN}...\"\n\n    for src_host in $FUZZ_HOSTS; do\n\n      test \"$src_host\" = \"$dst_host\" && continue\n\n      echo \"    Sending fuzzer data from ${src_host}.${FUZZ_DOMAIN}...\"\n\n      ssh -o 'passwordauthentication no' ${FUZZ_USER}@$dst_host \\\n        \"cd '$SYNC_DIR' && tar -xkzf -\" <\".sync_tmp/${src_host}.tgz\"\n\n    done\n\n  done\n\n  echo \"[+] Done. Sleeping for $SYNC_INTERVAL seconds (Ctrl-C to quit).\"\n\n  sleep $SYNC_INTERVAL\n\ndone\n\n"
  },
  {
    "path": "experimental/instrumented_cmp/instrumented_cmp.c",
    "content": "/*\n\n   A simple proof-of-concept for instrumented strcpy() or memcpy().\n\n   Normally, afl-fuzz will have difficulty ever reaching the code behind\n   something like:\n\n     if (!strcmp(password, \"s3cr3t!\")) ...\n\n   This is because the strcmp() operation is completely opaque to the tool.\n   A simple and non-invasive workaround that doesn't require complex code\n   analysis is to replace strcpy(), memcpy(), and equivalents with\n   inlined, non-optimized code.\n\n   I am still evaluating the value of doing this, but for time being, here's\n   a quick demo of how it may work. To test:\n\n     $ ./afl-gcc instrumented_cmp.c\n     $ mkdir test_in\n     $ printf xxxxxxxxxxxxxxxx >test_in/input\n     $ ./afl-fuzz -i test_in -o test_out ./a.out\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n/* Naive instrumented memcmp(). */\n\ninline int my_memcmp(char* ptr1, char* ptr2, int len)\n  __attribute__((always_inline));\n\ninline int my_memcmp(char* ptr1, char* ptr2, int len) {\n\n  while (len--) if (*(ptr1++) ^ *(ptr2++)) return 1;\n  return 0;\n\n}\n\n#define memcmp my_memcmp\n\n/* Normal program. */\n\nchar tmp[16];\n\nint main(int argc, char** argv) {\n\n  int len = read(0, tmp, sizeof(tmp));\n\n  if (len != sizeof(tmp)) {\n\n    printf(\"Truncated file!\\n\");\n    exit(1);\n\n  }\n\n  if (!memcmp(tmp + 5, \"sesame\", 6)) {\n\n    /* Simulated \"faulty\" code path. */\n\n    int* x = (int*)0x12345678;\n    *x = 1;\n\n  } else printf(\"Bad password.\\n\");\n\n  return 0;\n\n}\n"
  },
  {
    "path": "experimental/libpng_no_checksum/libpng-nocrc.patch",
    "content": "--- pngrutil.c.orig\t2014-06-12 03:35:16.000000000 +0200\n+++ pngrutil.c\t2014-07-01 05:08:31.000000000 +0200\n@@ -268,7 +268,11 @@\n    if (need_crc != 0)\n    {\n       crc = png_get_uint_32(crc_bytes);\n-      return ((int)(crc != png_ptr->crc));\n+\n+      if (crc != png_ptr->crc)\n+        fprintf(stderr, \"NOTE: CRC in the file is 0x%08x, change to 0x%08x\\n\", crc, png_ptr->crc);\n+\n+      return ((int)(1 != 1));\n    }\n \n    else\n"
  },
  {
    "path": "experimental/persistent_demo/persistent_demo.c",
    "content": "/*\n   american fuzzy lop - persistent mode example\n   --------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This file demonstrates the high-performance \"persistent mode\" that may be\n   suitable for fuzzing certain fast and well-behaved libraries, provided that\n   they are stateless or that their internal state can be easily reset\n   across runs.\n\n   To make this work, the library and this shim need to be compiled in LLVM\n   mode using afl-clang-fast (other compiler wrappers will *not* work).\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <signal.h>\n#include <string.h>\n\n\n/* Main entry point. */\n\nint main(int argc, char** argv) {\n\n  char buf[100]; /* Example-only buffer, you'd replace it with other global or\n                    local variables appropriate for your use case. */\n\n  /* The number passed to __AFL_LOOP() controls the maximum number of\n     iterations before the loop exits and the program is allowed to\n     terminate normally. This limits the impact of accidental memory leaks\n     and similar hiccups. */\n\n  while (__AFL_LOOP(1000)) {\n\n    /*** PLACEHOLDER CODE ***/\n\n    /* STEP 1: Fully re-initialize all critical variables. In our example, this\n               involves zeroing buf[], our input buffer. */\n\n    memset(buf, 0, 100);\n\n    /* STEP 2: Read input data. When reading from stdin, no special preparation\n               is required. When reading from a named file, you need to close\n               the old descriptor and reopen the file first!\n\n               Beware of reading from buffered FILE* objects such as stdin. Use\n               raw file descriptors or call fopen() / fdopen() in every pass. */\n\n    read(0, buf, 100);\n\n    /* STEP 3: This is where we'd call the tested library on the read data.\n               We just have some trivial inline code that faults on 'foo!'. */\n\n    if (buf[0] == 'f') {\n      printf(\"one\\n\");\n      if (buf[1] == 'o') {\n        printf(\"two\\n\");\n        if (buf[2] == 'o') {\n          printf(\"three\\n\");\n          if (buf[3] == '!') {\n            printf(\"four\\n\");\n            abort();\n          }\n        }\n      }\n    }\n\n    /*** END PLACEHOLDER CODE ***/\n\n  }\n\n  /* Once the loop is exited, terminate normally - AFL will restart the process\n     when this happens, with a clean slate when it comes to allocated memory,\n     leftover file descriptors, etc. */\n\n  return 0;\n\n}\n"
  },
  {
    "path": "experimental/post_library/post_library.so.c",
    "content": "/*\n   american fuzzy lop - postprocessor library example\n   --------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   Postprocessor libraries can be passed to afl-fuzz to perform final cleanup\n   of any mutated test cases - for example, to fix up checksums in PNG files.\n\n   Please heed the following warnings:\n\n   1) In almost all cases, it is more productive to comment out checksum logic\n      in the targeted binary (as shown in ../libpng_no_checksum/). One possible\n      exception is the process of fuzzing binary-only software in QEMU mode.\n\n   2) Use of postprocessors for anything other than checksums is questionable\n      and may cause more harm than good. AFL is normally pretty good about\n      dealing with length fields, magic values, etc.\n\n   3) Post-processors that do anything non-trivial must be extremely robust to\n      gracefully handle malformed data and other error conditions - otherwise,\n      they will crash and take afl-fuzz down with them. Be wary of reading past\n      *len and of integer overflows when calculating file offsets.\n\n   In other words, THIS IS PROBABLY NOT WHAT YOU WANT - unless you really,\n   honestly know what you're doing =)\n\n   With that out of the way: the postprocessor library is passed to afl-fuzz\n   via AFL_POST_LIBRARY. The library must be compiled with:\n\n     gcc -shared -Wall -O3 post_library.so.c -o post_library.so\n\n   AFL will call the afl_postprocess() function for every mutated output buffer.\n   From there, you have three choices:\n\n   1) If you don't want to modify the test case, simply return the original\n      buffer pointer ('in_buf').\n\n   2) If you want to skip this test case altogether and have AFL generate a\n      new one, return NULL. Use this sparingly - it's faster than running\n      the target program with patently useless inputs, but still wastes CPU\n      time.\n\n   3) If you want to modify the test case, allocate an appropriately-sized\n      buffer, move the data into that buffer, make the necessary changes, and\n      then return the new pointer. You can update *len if necessary, too.\n\n      Note that the buffer will *not* be freed for you. To avoid memory leaks,\n      you need to free it or reuse it on subsequent calls (as shown below).\n\n      *** DO NOT MODIFY THE ORIGINAL 'in_buf' BUFFER. ***\n\n    Aight. The example below shows a simple postprocessor that tries to make\n    sure that all input files start with \"GIF89a\".\n\n    PS. If you don't like C, you can try out the unix-based wrapper from\n    Ben Nagy instead: https://github.com/bnagy/aflfix\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n/* Header that must be present at the beginning of every test case: */\n\n#define HEADER \"GIF89a\"\n\n/* The actual postprocessor routine called by afl-fuzz: */\n\nconst unsigned char* afl_postprocess(const unsigned char* in_buf,\n                                     unsigned int* len) {\n\n  static unsigned char* saved_buf;\n  unsigned char* new_buf;\n\n  /* Skip execution altogether for buffers shorter than 6 bytes (just to\n     show how it's done). We can trust *len to be sane. */\n\n  if (*len < strlen(HEADER)) return NULL;\n\n  /* Do nothing for buffers that already start with the expected header. */\n\n  if (!memcmp(in_buf, HEADER, strlen(HEADER))) return in_buf;\n\n  /* Allocate memory for new buffer, reusing previous allocation if\n     possible. */\n\n  new_buf = realloc(saved_buf, *len);\n\n  /* If we're out of memory, the most graceful thing to do is to return the\n     original buffer and give up on modifying it. Let AFL handle OOM on its\n     own later on. */\n\n  if (!new_buf) return in_buf;\n  saved_buf = new_buf;\n\n  /* Copy the original data to the new location. */\n\n  memcpy(new_buf, in_buf, *len);\n\n  /* Insert the new header. */\n\n  memcpy(new_buf, HEADER, strlen(HEADER));\n\n  /* Return modified buffer. No need to update *len in this particular case,\n     as we're not changing it. */\n\n  return new_buf;\n\n}\n"
  },
  {
    "path": "experimental/post_library/post_library_png.so.c",
    "content": "/*\n   american fuzzy lop - postprocessor for PNG\n   ------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   See post_library.so.c for a general discussion of how to implement\n   postprocessors. This specific postprocessor attempts to fix up PNG\n   checksums, providing a slightly more complicated example than found\n   in post_library.so.c.\n\n   Compile with:\n\n     gcc -shared -Wall -O3 post_library_png.so.c -o post_library_png.so -lz\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n#include <zlib.h>\n\n#include <arpa/inet.h>\n\n/* A macro to round an integer up to 4 kB. */\n\n#define UP4K(_i) ((((_i) >> 12) + 1) << 12)\n\nconst unsigned char* afl_postprocess(const unsigned char* in_buf,\n                                     unsigned int* len) {\n\n  static unsigned char* saved_buf;\n  static unsigned int   saved_len;\n\n  unsigned char* new_buf = (unsigned char*)in_buf;\n  unsigned int pos = 8;\n\n  /* Don't do anything if there's not enough room for the PNG header\n     (8 bytes). */\n\n  if (*len < 8) return in_buf;\n\n  /* Minimum size of a zero-length PNG chunk is 12 bytes; if we\n     don't have that, we can bail out. */\n\n  while (pos + 12 <= *len) {\n\n    unsigned int chunk_len, real_cksum, file_cksum;\n\n    /* Chunk length is the first big-endian dword in the chunk. */\n\n    chunk_len = ntohl(*(uint32_t*)(in_buf + pos));\n\n    /* Bail out if chunk size is too big or goes past EOF. */\n\n    if (chunk_len > 1024 * 1024 || pos + 12 + chunk_len > *len) break;\n\n    /* Chunk checksum is calculated for chunk ID (dword) and the actual\n       payload. */\n\n    real_cksum = ntohl(crc32(0, in_buf + pos + 4, chunk_len + 4));\n\n    /* The in-file checksum is the last dword past the chunk data. */\n\n    file_cksum = *(uint32_t*)(in_buf + pos + 8 + chunk_len);\n\n    /* If the checksums do not match, we need to fix the file. */\n\n    if (real_cksum != file_cksum) {\n\n      /* First modification? Make a copy of the input buffer. Round size\n         up to 4 kB to minimize the number of reallocs needed. */\n\n      if (new_buf == in_buf) {\n\n        if (*len <= saved_len) {\n\n          new_buf = saved_buf;\n\n        } else {\n\n          new_buf = realloc(saved_buf, UP4K(*len));\n          if (!new_buf) return in_buf;\n          saved_buf = new_buf;\n          saved_len = UP4K(*len);\n          memcpy(new_buf, in_buf, *len);\n\n        }\n\n      }\n\n      *(uint32_t*)(new_buf + pos + 8 + chunk_len) = real_cksum;\n\n    }\n\n    /* Skip the entire chunk and move to the next one. */\n\n    pos += 12 + chunk_len;\n\n  }\n\n  return new_buf;\n\n}\n"
  },
  {
    "path": "hash.h",
    "content": "/*\n   american fuzzy lop - hashing function\n   -------------------------------------\n\n   The hash32() function is a variant of MurmurHash3, a good\n   non-cryptosafe hashing function developed by Austin Appleby.\n\n   For simplicity, this variant does *NOT* accept buffer lengths\n   that are not divisible by 8 bytes. The 32-bit version is otherwise\n   similar to the original; the 64-bit one is a custom hack with\n   mostly-unproven properties.\n\n   Austin's original code is public domain.\n\n */\n\n#ifndef _HAVE_HASH_H\n#define _HAVE_HASH_H\n\n#include \"types.h\"\n\n#ifdef __x86_64__\n\n#define ROL64(_x, _r)  ((((u64)(_x)) << (_r)) | (((u64)(_x)) >> (64 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u64* data = (u64*)key;\n  u64 h1 = seed ^ len;\n\n  len >>= 3;\n\n  while (len--) {\n\n    u64 k1 = *data++;\n\n    k1 *= 0x87c37b91114253d5ULL;\n    k1  = ROL64(k1, 31);\n    k1 *= 0x4cf5ad432745937fULL;\n\n    h1 ^= k1;\n    h1  = ROL64(h1, 27);\n    h1  = h1 * 5 + 0x52dce729;\n\n  }\n\n  h1 ^= h1 >> 33;\n  h1 *= 0xff51afd7ed558ccdULL;\n  h1 ^= h1 >> 33;\n  h1 *= 0xc4ceb9fe1a85ec53ULL;\n  h1 ^= h1 >> 33;\n\n  return h1;\n\n}\n\n#else \n\n#define ROL32(_x, _r)  ((((u32)(_x)) << (_r)) | (((u32)(_x)) >> (32 - (_r))))\n\nstatic inline u32 hash32(const void* key, u32 len, u32 seed) {\n\n  const u32* data  = (u32*)key;\n  u32 h1 = seed ^ len;\n\n  len >>= 2;\n\n  while (len--) {\n\n    u32 k1 = *data++;\n\n    k1 *= 0xcc9e2d51;\n    k1  = ROL32(k1, 15);\n    k1 *= 0x1b873593;\n\n    h1 ^= k1;\n    h1  = ROL32(h1, 13);\n    h1  = h1 * 5 + 0xe6546b64;\n\n  }\n\n  h1 ^= h1 >> 16;\n  h1 *= 0x85ebca6b;\n  h1 ^= h1 >> 13;\n  h1 *= 0xc2b2ae35;\n  h1 ^= h1 >> 16;\n\n  return h1;\n\n}\n\n#endif /* ^__x86_64__ */\n\n#endif /* !_HAVE_HASH_H */\n"
  },
  {
    "path": "llvm_mode/Makefile",
    "content": "#\n# american fuzzy lop - LLVM instrumentation\n# -----------------------------------------\n#\n# Written by Laszlo Szekeres <lszekeres@google.com> and\n#            Michal Zalewski <lcamtuf@google.com>\n#\n# LLVM integration design comes from Laszlo Szekeres.\n#\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n\nPREFIX      ?= /usr/local\nHELPER_PATH  = $(PREFIX)/lib/afl\nBIN_PATH     = $(PREFIX)/bin\n\nVERSION      = $(shell grep ^VERSION ../Makefile | cut -d= -f2 | sed 's/ //')\n\nLLVM_CONFIG ?= llvm-config\n\nCFLAGS      ?= -O3 -funroll-loops\nCFLAGS      += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n               -DAFL_PATH=\\\"$(HELPER_PATH)\\\" -DBIN_PATH=\\\"$(BIN_PATH)\\\" \\\n               -DVERSION=\\\"$(VERSION)\\\"\n\nCXXFLAGS    ?= -O3 -funroll-loops\nCXXFLAGS    += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \\\n               -DVERSION=\\\"$(VERSION)\\\"\n\nCLANG_CFL    = `$(LLVM_CONFIG) --cxxflags` -fno-rtti $(CXXFLAGS)\nCLANG_LFL    = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)\n\n# User teor2345 reports that this is required to make things work on MacOS X.\n\nifeq \"$(shell uname)\" \"Darwin\"\n\nCLANG_LFL   += -Wl,-flat_namespace -Wl,-undefined,suppress\n\nendif\n\n# We were using llvm-config --bindir to get the location of clang, but\n# this seems to be busted on some distros, so using the one in $PATH is\n# probably better.\n\nifeq \"$(origin CC)\" \"default\"\n\nCC           = clang\nCXX          = clang++\n\nendif\n\nPROGS        = ../afl-clang-fast ../afl-llvm-pass.so ../afl-llvm-rt.o\n\nall: test_deps $(PROGS) test_build all_done\n\ntest_deps:\n\t@echo \"[*] Checking for working 'llvm-config'...\"\n\t@which $(LLVM_CONFIG) >/dev/null 2>&1 || ( echo \"[-] Oops, can't find 'llvm-config'. Install clang or set \\$$LLVM_CONFIG or \\$$PATH beforehand.\"; echo \"    (Sometimes, the binary will be named llvm-config-3.5 or something like that.)\"; exit 1 )\n\t@echo \"[*] Checking for working '$(CC)'...\"\n\t@which $(CC) >/dev/null 2>&1 || ( echo \"[-] Oops, can't find '$(CC)'. Make sure that it's in your \\$$PATH (or set \\$$CC and \\$$CXX).\"; exit 1 )\n\t@echo \"[*] Checking for '../afl-showmap'...\"\n\t@test -f ../afl-showmap || ( echo \"[-] Oops, can't find '../afl-showmap'. Be sure to compile AFL first.\"; exit 1 )\n\t@echo \"[+] All set and ready to build.\"\n\n../afl-clang-fast: afl-clang-fast.c | test_deps\n\t$(CC) $(CFLAGS) $< -o $@ $(LDFLAGS)\n\tln -sf afl-clang-fast ../afl-clang-fast++\n\n../afl-llvm-pass.so: afl-llvm-pass.so.cc | test_deps\n\t$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)\n\n../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps\n\t$(CC) $(CFLAGS) -fPIC -c $< -o $@\n\ntest_build: $(PROGS)\n\t@echo \"[*] Testing the CC wrapper and instrumentation output...\"\n\tunset AFL_USE_ASAN AFL_USE_MSAN; AFL_QUIET=1 AFL_INST_RATIO=100 AFL_PATH=. AFL_CC=$(CC) ../afl-clang-fast $(CFLAGS) ../test-instr.c -o test-instr $(LDFLAGS)\n\techo 0 | ../afl-showmap -m none -q -o .test-instr0 ./test-instr\n\techo 1 | ../afl-showmap -m none -q -o .test-instr1 ./test-instr\n\t@rm -f test-instr\n\t@cmp -s .test-instr0 .test-instr1; DR=\"$$?\"; rm -f .test-instr0 .test-instr1; if [ \"$$DR\" = \"0\" ]; then echo; echo \"Oops, the instrumentation does not seem to be behaving correctly!\"; echo; echo \"Please ping <lcamtuf@google.com> to troubleshoot the issue.\"; echo; exit 1; fi\n\t@echo \"[+] All right, the instrumentation seems to be working!\"\n\nall_done: test_build\n\t@echo \"[+] All done! You can now use '../afl-clang-fast' to compile programs.\"\n\n.NOTPARALLEL: clean\n\nclean:\n\trm -f *.o *.so *~ a.out core core.[1-9][0-9]* test-instr .test-instr0 .test-instr1 \n\trm -f $(PROGS) ../afl-clang-fast++\n"
  },
  {
    "path": "llvm_mode/README.llvm",
    "content": "============================================\nFast LLVM-based instrumentation for afl-fuzz\n============================================\n\n  (See ../docs/README for the general instruction manual.)\n\n1) Introduction\n---------------\n\nThe code in this directory allows you to instrument programs for AFL using\ntrue compiler-level instrumentation, instead of the more crude\nassembly-level rewriting approach taken by afl-gcc and afl-clang. This has\nseveral interesting properties:\n\n  - The compiler can make many optimizations that are hard to pull off when\n    manually inserting assembly. As a result, some slow, CPU-bound programs will\n    run up to around 2x faster.\n\n    The gains are less pronounced for fast binaries, where the speed is limited\n    chiefly by the cost of creating new processes. In such cases, the gain will\n    probably stay within 10%.\n\n  - The instrumentation is CPU-independent. At least in principle, you should\n    be able to rely on it to fuzz programs on non-x86 architectures (after\n    building afl-fuzz with AFL_NOX86=1).\n\n  - Because the feature relies on the internals of LLVM, it is clang-specific\n    and will *not* work with GCC.\n\nOnce this implementation is shown to be sufficiently robust and portable, it\nwill probably replace afl-clang. For now, it can be built separately and\nco-exists with the original code.\n\nThe idea and much of the implementation comes from Laszlo Szekeres.\n\n2) How to use\n-------------\n\nIn order to leverage this mechanism, you need to have clang installed on your\nsystem. You should also make sure that the llvm-config tool is in your path\n(or pointed to via LLVM_CONFIG in the environment).\n\nUnfortunately, some systems that do have clang come without llvm-config or the\nLLVM development headers; one example of this is FreeBSD. FreeBSD users will\nalso run into problems with clang being built statically and not being able to\nload modules (you'll see \"Service unavailable\" when loading afl-llvm-pass.so).\n\nTo solve all your problems, you can grab pre-built binaries for your OS from:\n\n  http://llvm.org/releases/download.html\n\n...and then put the bin/ directory from the tarball at the beginning of your\n$PATH when compiling the feature and building packages later on. You don't need\nto be root for that.\n\nTo build the instrumentation itself, type 'make'. This will generate binaries\ncalled afl-clang-fast and afl-clang-fast++ in the parent directory. Once this\nis done, you can instrument third-party code in a way similar to the standard\noperating mode of AFL, e.g.:\n\n  CC=/path/to/afl/afl-clang-fast ./configure [...options...]\n  make\n\nBe sure to also include CXX set to afl-clang-fast++ for C++ code.\n\nThe tool honors roughly the same environmental variables as afl-gcc (see\n../docs/env_variables.txt). This includes AFL_INST_RATIO, AFL_USE_ASAN,\nAFL_HARDEN, and AFL_DONT_OPTIMIZE.\n\nNote: if you want the LLVM helper to be installed on your system for all\nusers, you need to build it before issuing 'make install' in the parent\ndirectory.\n\n3) Gotchas, feedback, bugs\n--------------------------\n\nThis is an early-stage mechanism, so field reports are welcome. You can send bug\nreports to <afl-users@googlegroups.com>.\n\n4) Bonus feature #1: deferred instrumentation\n---------------------------------------------\n\nAFL tries to optimize performance by executing the targeted binary just once,\nstopping it just before main(), and then cloning this \"master\" process to get\na steady supply of targets to fuzz.\n\nAlthough this approach eliminates much of the OS-, linker- and libc-level\ncosts of executing the program, it does not always help with binaries that\nperform other time-consuming initialization steps - say, parsing a large config\nfile before getting to the fuzzed data.\n\nIn such cases, it's beneficial to initialize the forkserver a bit later, once\nmost of the initialization work is already done, but before the binary attempts\nto read the fuzzed input and parse it; in some cases, this can offer a 10x+\nperformance gain. You can implement delayed initialization in LLVM mode in a\nfairly simple way.\n\nFirst, find a suitable location in the code where the delayed cloning can \ntake place. This needs to be done with *extreme* care to avoid breaking the\nbinary. In particular, the program will probably malfunction if you select\na location after:\n\n  - The creation of any vital threads or child processes - since the forkserver\n    can't clone them easily.\n\n  - The initialization of timers via setitimer() or equivalent calls.\n\n  - The creation of temporary files, network sockets, offset-sensitive file\n    descriptors, and similar shared-state resources - but only provided that\n    their state meaningfully influences the behavior of the program later on.\n\n  - Any access to the fuzzed input, including reading the metadata about its\n    size.\n\nWith the location selected, add this code in the appropriate spot:\n\n#ifdef __AFL_HAVE_MANUAL_CONTROL\n  __AFL_INIT();\n#endif\n\nYou don't need the #ifdef guards, but including them ensures that the program\nwill keep working normally when compiled with a tool other than afl-clang-fast.\n\nFinally, recompile the pogram with afl-clang-fast (afl-gcc or afl-clang will\n*not* generate a deferred-initialization binary) - and you should be all set!\n\n5) Bonus feature #2: persistent mode\n------------------------------------\n\nSome libraries provide APIs that are stateless, or whose state can be reset in\nbetween processing different input files. When such a reset is performed, a\nsingle long-lived process can be reused to try out multiple test cases,\neliminating the need for repeated fork() calls and the associated OS overhead.\n\nThe basic structure of the program that does this would be:\n\n  while (__AFL_LOOP(1000)) {\n\n    /* Read input data. */\n    /* Call library code to be fuzzed. */\n    /* Reset state. */\n\n  }\n\n  /* Exit normally */\n\nThe numerical value specified within the loop controls the maximum number\nof iterations before AFL will restart the process from scratch. This minimizes\nthe impact of memory leaks and similar glitches; 1000 is a good starting point.\n\nA more detailed template is shown in ../experimental/persistent_demo/.\nSimilarly to the previous mode, the feature works only with afl-clang-fast;\n#ifdef guards can be used to suppress it when using other compilers.\n\nNote that as with the previous mode, the feature is easy to misuse; if you\ndo not fully reset the critical state, you may end up with false positives or\nwaste a whole lot of CPU power doing nothing useful at all. Be particularly\nwary of memory leaks and of the state of file descriptors.\n\nWhen running in this mode, the execution paths will inherently vary a bit\ndepending on whether the input loop is being entered for the first time or\nexecuted again. To avoid spurious warnings, the feature implies \nAFL_NO_VAR_CHECK and hides the \"variable path\" warnings in the UI.\n\nPS. Because there are task switches still involved, the mode isn't as fast as\n\"pure\" in-process fuzzing offered, say, by LLVM's LibFuzzer; but it is a lot\nfaster than the normal fork() model, and compared to in-process fuzzing,\nshould be a lot more robust.\n"
  },
  {
    "path": "llvm_mode/afl-clang-fast.c",
    "content": "/*\n   american fuzzy lop - LLVM-mode wrapper for clang\n   ------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres.\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This program is a drop-in replacement for clang, similar in most respects\n   to ../afl-gcc. It tries to figure out compilation mode, adds a bunch\n   of flags, and then calls the real compiler.\n\n */\n\n#define AFL_MAIN\n\n#include \"../config.h\"\n#include \"../types.h\"\n#include \"../debug.h\"\n#include \"../alloc-inl.h\"\n\n#include <stdio.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <string.h>\n\nstatic u8*  obj_path;               /* Path to runtime libraries         */\nstatic u8** cc_params;              /* Parameters passed to the real CC  */\nstatic u32  cc_par_cnt = 1;         /* Param count, including argv0      */\n\n\n/* Try to find the runtime libraries. If that fails, abort. */\n\nstatic void find_obj(u8* argv0) {\n\n  u8 *afl_path = getenv(\"AFL_PATH\");\n  u8 *slash, *tmp;\n\n  if (afl_path) {\n\n    tmp = alloc_printf(\"%s/afl-llvm-rt.o\", afl_path);\n\n    if (!access(tmp, R_OK)) {\n      obj_path = afl_path;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n\n  }\n\n  slash = strrchr(argv0, '/');\n\n  if (slash) {\n\n    u8 *dir;\n\n    *slash = 0;\n    dir = ck_strdup(argv0);\n    *slash = '/';\n\n    tmp = alloc_printf(\"%s/afl-llvm-rt.o\", dir);\n\n    if (!access(tmp, R_OK)) {\n      obj_path = dir;\n      ck_free(tmp);\n      return;\n    }\n\n    ck_free(tmp);\n    ck_free(dir);\n\n  }\n\n  if (!access(AFL_PATH \"/afl-llvm-rt.o\", R_OK)) {\n    obj_path = AFL_PATH;\n    return;\n  }\n\n  FATAL(\"Unable to find 'afl-llvm-rt.o' or 'afl-llvm-pass.so'. Please set AFL_PATH\");\n \n}\n\n\n/* Copy argv to cc_params, making the necessary edits. */\n\nstatic void edit_params(u32 argc, char** argv) {\n\n  u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1;\n  u8 *name;\n\n  cc_params = ck_alloc((argc + 64) * sizeof(u8*));\n\n  name = strrchr(argv[0], '/');\n  if (!name) name = argv[0]; else name++;\n\n  if (!strcmp(name, \"afl-clang-fast++\")) {\n    u8* alt_cxx = getenv(\"AFL_CXX\");\n    cc_params[0] = alt_cxx ? alt_cxx : (u8*)\"clang++\";\n  } else {\n    u8* alt_cc = getenv(\"AFL_CC\");\n    cc_params[0] = alt_cc ? alt_cc : (u8*)\"clang\";\n  }\n\n  cc_params[cc_par_cnt++] = \"-Xclang\";\n  cc_params[cc_par_cnt++] = \"-load\";\n  cc_params[cc_par_cnt++] = \"-Xclang\";\n  cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-pass.so\", obj_path);\n  cc_params[cc_par_cnt++] = \"-Qunused-arguments\";\n\n  while (--argc) {\n    u8* cur = *(++argv);\n\n#if defined(__x86_64__)\n    if (!strcmp(cur, \"-m32\")) FATAL(\"-m32 is not supported\");\n#endif\n\n    if (!strcmp(cur, \"-x\")) x_set = 1;\n\n    if (!strcmp(cur, \"-c\") || !strcmp(cur, \"-S\") || !strcmp(cur, \"-E\") ||\n        !strcmp(cur, \"-v\")) maybe_linking = 0;\n\n    if (!strcmp(cur, \"-fsanitize=address\") ||\n        !strcmp(cur, \"-fsanitize=memory\")) asan_set = 1;\n\n    if (strstr(cur, \"FORTIFY_SOURCE\")) fortify_set = 1;\n\n    cc_params[cc_par_cnt++] = cur;\n\n  }\n\n  if (getenv(\"AFL_HARDEN\")) {\n\n    cc_params[cc_par_cnt++] = \"-fstack-protector-all\";\n\n    if (!fortify_set)\n      cc_params[cc_par_cnt++] = \"-D_FORTIFY_SOURCE=2\";\n\n  }\n\n  if (!asan_set) {\n\n    if (getenv(\"AFL_USE_ASAN\")) {\n\n      cc_params[cc_par_cnt++] = \"-fsanitize=address\";\n\n      if (getenv(\"AFL_USE_MSAN\"))\n        FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n    } else if (getenv(\"AFL_USE_MSAN\")) {\n\n      cc_params[cc_par_cnt++] = \"-fsanitize=memory\";\n\n      if (getenv(\"AFL_USE_ASAN\"))\n        FATAL(\"ASAN and MSAN are mutually exclusive\");\n\n    }\n\n  }\n\n  if (!getenv(\"AFL_DONT_OPTIMIZE\")) {\n\n    cc_params[cc_par_cnt++] = \"-g\";\n    cc_params[cc_par_cnt++] = \"-O3\";\n    cc_params[cc_par_cnt++] = \"-funroll-loops\";\n\n  }\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_HAVE_MANUAL_CONTROL=1\";\n\n  /* When the user tries to use persistent or deferred forkserver modes by\n     appending a single line to the program, we want to reliably inject a\n     signature into the binary (to be picked up by afl-fuzz) and we want\n     to call a function from the runtime .o file. This is unnecessarily\n     painful for three reasons:\n\n     1) We need to convince the compiler not to optimize out the signature.\n        This is done with __attribute__((used)).\n\n     2) We need to convince the linker, when called with -Wl,--gc-sections,\n        not to do the same. This is done by forcing an assignment to a\n        'volatile' pointer.\n\n     3) We need to declare __afl_persistent_loop() in the global namespace,\n        but doing this within a method in a class is hard - :: and extern \"C\"\n        are forbidden and __attribute__((alias(...))) doesn't work. Hence the\n        __asm__ aliasing trick.\n\n   */\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_LOOP(_A)=\"\n    \"({ static volatile char *_B __attribute__((used)); \"\n    \" _B = (char*)\\\"\" PERSIST_SIG \"\\\"; \"\n#ifdef __APPLE__\n    \"int _L(unsigned int) __asm__(\\\"___afl_persistent_loop\\\"); \"\n#else\n    \"int _L(unsigned int) __asm__(\\\"__afl_persistent_loop\\\"); \"\n#endif /* ^__APPLE__ */\n    \"_L(_A); })\";\n\n  cc_params[cc_par_cnt++] = \"-D__AFL_INIT()=\"\n    \"do { static volatile char *_A __attribute__((used)); \"\n    \" _A = (char*)\\\"\" DEFER_SIG \"\\\"; \"\n#ifdef __APPLE__\n    \"void _I(void) __asm__(\\\"___afl_manual_init\\\"); \"\n#else\n    \"void _I(void) __asm__(\\\"__afl_manual_init\\\"); \"\n#endif /* ^__APPLE__ */\n    \"_I(); } while (0)\";\n\n  if (maybe_linking) {\n\n    if (x_set) {\n      cc_params[cc_par_cnt++] = \"-x\";\n      cc_params[cc_par_cnt++] = \"none\";\n    }\n\n    cc_params[cc_par_cnt++] = alloc_printf(\"%s/afl-llvm-rt.o\", obj_path);\n\n  }\n\n  cc_params[cc_par_cnt] = NULL;\n\n}\n\n\n/* Main entry point */\n\nint main(int argc, char** argv) {\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-clang-fast \" cBRI VERSION  cRST \" by <lszekeres@google.com>\\n\");\n\n  }\n\n  if (argc < 2) {\n\n    SAYF(\"\\n\"\n         \"This is a helper application for afl-fuzz. It serves as a drop-in replacement\\n\"\n         \"for clang, letting you recompile third-party code with the required runtime\\n\"\n         \"instrumentation. A common use pattern would be one of the following:\\n\\n\"\n\n         \"  CC=%s/afl-clang-fast ./configure\\n\"\n         \"  CXX=%s/afl-clang-fast++ ./configure\\n\\n\"\n\n         \"In contrast to the traditional afl-clang tool, this version is implemented as\\n\"\n         \"an LLVM pass and tends to offer improved performance with slow programs.\\n\\n\"\n\n         \"You can specify custom next-stage toolchain via AFL_CC and AFL_CXX. Setting\\n\"\n         \"AFL_HARDEN enables hardening optimizations in the compiled code.\\n\\n\",\n         BIN_PATH, BIN_PATH);\n\n    exit(1);\n\n  }\n\n\n  find_obj(argv[0]);\n\n  edit_params(argc, argv);\n\n  execvp(cc_params[0], (char**)cc_params);\n\n  FATAL(\"Oops, failed to execute '%s' - check your PATH\", cc_params[0]);\n\n  return 0;\n\n}\n"
  },
  {
    "path": "llvm_mode/afl-llvm-pass.so.cc",
    "content": "/*\n   american fuzzy lop - LLVM-mode instrumentation pass\n   ---------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres. C bits copied-and-pasted\n   from afl-as.c are Michal's fault.\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This library is plugged into LLVM when invoking clang through afl-clang-fast.\n   It tells the compiler to add code roughly equivalent to the bits discussed\n   in ../afl-as.h.\n\n */\n\n#include \"../config.h\"\n#include \"../debug.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"llvm/ADT/Statistic.h\"\n#include \"llvm/IR/IRBuilder.h\"\n#include \"llvm/IR/LegacyPassManager.h\"\n#include \"llvm/IR/Module.h\"\n#include \"llvm/Support/Debug.h\"\n#include \"llvm/Transforms/IPO/PassManagerBuilder.h\"\n\nusing namespace llvm;\n\nnamespace {\n\n  class AFLCoverage : public ModulePass {\n\n    public:\n\n      static char ID;\n      AFLCoverage() : ModulePass(ID) { }\n\n      bool runOnModule(Module &M) override;\n\n      const char *getPassName() const override {\n        return \"American Fuzzy Lop Instrumentation\";\n      }\n\n  };\n\n}\n\n\nchar AFLCoverage::ID = 0;\n\n\nbool AFLCoverage::runOnModule(Module &M) {\n\n  LLVMContext &C = M.getContext();\n\n  IntegerType *Int8Ty  = IntegerType::getInt8Ty(C);\n  IntegerType *Int16Ty = IntegerType::getInt16Ty(C);\n  IntegerType *Int64Ty = IntegerType::getInt64Ty(C);\n\n  /* Show a banner */\n\n  char be_quiet = 0;\n\n  if (isatty(2) && !getenv(\"AFL_QUIET\")) {\n\n    SAYF(cCYA \"afl-llvm-pass \" cBRI VERSION cRST \" by <lszekeres@google.com>\\n\");\n\n  } else be_quiet = 1;\n\n  /* Decide instrumentation ratio */\n\n  char* inst_ratio_str = getenv(\"AFL_INST_RATIO\");\n  unsigned int inst_ratio = 100;\n\n  if (inst_ratio_str) {\n\n    if (sscanf(inst_ratio_str, \"%u\", &inst_ratio) != 1 || !inst_ratio ||\n        inst_ratio > 100)\n      FATAL(\"Bad value of AFL_INST_RATIO (must be between 1 and 100)\");\n\n  }\n\n  /* Get globals for the SHM region and the previous location. */\n\n  GlobalVariable *AFLMapPtr =\n      new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,\n                         GlobalValue::ExternalLinkage, 0, \"__afl_area_ptr\");\n\n  GlobalVariable *AFLPrevLoc = new GlobalVariable(\n      M, Int16Ty, false, GlobalValue::ExternalLinkage, 0, \"__afl_prev_loc\");\n\n  /* Instrument all the things! */\n\n  int inst_blocks = 0;\n\n  for (auto &F : M)\n    for (auto &BB : F) {\n\n      BasicBlock::iterator IP = BB.getFirstInsertionPt();\n      IRBuilder<> IRB(IP);\n\n      if (R(100) >= inst_ratio) continue;\n\n      /* Make up cur_loc */\n\n      unsigned int cur_loc = R(MAP_SIZE);\n      ConstantInt *CurLoc = ConstantInt::get(Int64Ty, cur_loc);\n\n      /* Load prev_loc */\n\n      LoadInst *PrevLoc = IRB.CreateLoad(AFLPrevLoc);\n      PrevLoc->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *PrevLocCasted = IRB.CreateZExt(PrevLoc, IRB.getInt64Ty());\n\n      /* Load SHM pointer */\n\n      LoadInst *MapPtr = IRB.CreateLoad(AFLMapPtr);\n      MapPtr->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *MapPtrIdx =\n          IRB.CreateGEP(MapPtr, IRB.CreateXor(PrevLocCasted, CurLoc));\n\n      /* Update bitmap */\n\n      LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);\n      Counter->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n      Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));\n      IRB.CreateStore(Incr, MapPtrIdx)\n          ->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n\n      /* Set prev_loc to cur_loc >> 1 */\n\n      StoreInst *Store =\n          IRB.CreateStore(ConstantInt::get(Int16Ty, cur_loc >> 1), AFLPrevLoc);\n      Store->setMetadata(M.getMDKindID(\"nosanitize\"), MDNode::get(C, None));\n\n      inst_blocks++;\n\n    }\n\n  /* Say something nice. */\n\n  if (!be_quiet) {\n\n    if (!inst_blocks) WARNF(\"No instrumentation targets found.\");\n    else OKF(\"Instrumented %u locations (%s mode, ratio %u%%).\",\n             inst_blocks,\n             getenv(\"AFL_HARDEN\") ? \"hardened\" : \"non-hardened\",\n             inst_ratio);\n\n  }\n\n  return true;\n\n}\n\n\nstatic void registerAFLPass(const PassManagerBuilder &,\n                            legacy::PassManagerBase &PM) {\n\n  PM.add(new AFLCoverage());\n\n}\n\n\nstatic RegisterStandardPasses RegisterAFLPass(\n    PassManagerBuilder::EP_OptimizerLast, registerAFLPass);\n\nstatic RegisterStandardPasses RegisterAFLPass0(\n    PassManagerBuilder::EP_EnabledOnOptLevel0, registerAFLPass);\n"
  },
  {
    "path": "llvm_mode/afl-llvm-rt.o.c",
    "content": "/*\n   american fuzzy lop - LLVM instrumentation bootstrap\n   ---------------------------------------------------\n\n   Written by Laszlo Szekeres <lszekeres@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   LLVM integration design comes from Laszlo Szekeres.\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This code is the rewrite of afl-as.h's main_payload.\n\n*/\n\n#include \"../config.h\"\n#include \"../types.h\"\n\n#include <stdlib.h>\n#include <signal.h>\n#include <unistd.h>\n#include <assert.h>\n\n#include <sys/mman.h>\n#include <sys/shm.h>\n#include <sys/wait.h>\n#include <sys/types.h>\n\n\n/* Globals needed by the injected instrumentation. The __afl_area_initial region\n   is used for instrumentation output before __afl_map_shm() has a chance to run.\n   It will end up as .comm, so it shouldn't be too wasteful. */\n\nu8  __afl_area_initial[MAP_SIZE];\nu8* __afl_area_ptr = __afl_area_initial;\nu16 __afl_prev_loc;\n\n\n/* Running in persistent mode? */\n\nstatic u8 is_persistent;\n\n\n/* SHM setup. */\n\nstatic void __afl_map_shm(void) {\n\n  u8 *id_str = getenv(SHM_ENV_VAR);\n\n  /* If we're running under AFL, attach to the appropriate region, replacing the\n     early-stage __afl_area_initial region that is needed to allow some really\n     hacky .init code to work correctly in projects such as OpenSSL. */\n\n  if (id_str) {\n\n    u32 shm_id = atoi(id_str);\n\n    __afl_area_ptr = shmat(shm_id, NULL, 0);\n\n    /* Whooooops. */\n\n    if (__afl_area_ptr == (void *)-1) _exit(1);\n\n    /* Write something into the bitmap so that even with low AFL_INST_RATIO,\n       our parent doesn't give up on us. */\n\n    __afl_area_ptr[0] = 1;\n\n  }\n\n}\n\n\n/* Fork server logic. */\n\nstatic void __afl_start_forkserver(void) {\n\n  static u8 tmp[4];\n  s32 child_pid;\n\n  u8  child_stopped = 0;\n\n  /* Phone home and tell the parent that we're OK. If parent isn't there,\n     assume we're not running in forkserver mode and just execute program. */\n\n  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;\n\n  while (1) {\n\n    u32 was_killed;\n    int status;\n\n    /* Wait for parent by reading from the pipe. Abort if read fails. */\n\n    if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);\n\n    /* If we stopped the child in persistent mode, but there was a race\n       condition and afl-fuzz already issued SIGKILL, write off the old\n       process. */\n\n    if (child_stopped && was_killed) {\n      child_stopped = 0;\n      if (waitpid(child_pid, &status, 0) < 0) _exit(1);\n    }\n\n    if (!child_stopped) {\n\n      /* Once woken up, create a clone of our process. */\n\n      child_pid = fork();\n      if (child_pid < 0) _exit(1);\n\n      /* In child process: close fds, resume execution. */\n\n      if (!child_pid) {\n\n        close(FORKSRV_FD);\n        close(FORKSRV_FD + 1);\n        return;\n  \n      }\n\n    } else {\n\n      /* Special handling for persistent mode: if the child is alive but\n         currently stopped, simply restart it with SIGCONT. */\n\n      kill(child_pid, SIGCONT);\n      child_stopped = 0;\n\n    }\n\n    /* In parent process: write PID to pipe, then wait for child. */\n\n    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) _exit(1);\n\n    if (waitpid(child_pid, &status, is_persistent ? WUNTRACED : 0) < 0)\n      _exit(1);\n\n    /* In persistent mode, the child stops itself with SIGSTOP to indicate\n       a successful run. In this case, we want to wake it up without forking\n       again. */\n\n    if (WIFSTOPPED(status)) child_stopped = 1;\n\n    /* Relay wait status to pipe, then loop back. */\n\n    if (write(FORKSRV_FD + 1, &status, 4) != 4) _exit(1);\n\n  }\n\n}\n\n\n/* A simplified persistent mode handler, used as explained in README.llvm. */\n\nint __afl_persistent_loop(unsigned int max_cnt) {\n\n  static u8  first_pass = 1;\n  static u32 cycle_cnt;\n\n  if (first_pass) {\n\n    cycle_cnt  = max_cnt;\n    first_pass = 0;\n    return 1;\n\n  }\n\n  if (is_persistent && --cycle_cnt) {\n\n    raise(SIGSTOP);\n    return 1;\n\n  } else return 0;\n\n}\n\n\n/* This one can be called from user code when deferred forkserver mode\n    is enabled. */\n\nvoid __afl_manual_init(void) {\n\n  static u8 init_done;\n\n  if (!init_done) {\n\n    __afl_map_shm();\n    __afl_start_forkserver();\n    init_done = 1;\n\n  }\n\n}\n\n\n/* Proper initialization routine. */\n\n__attribute__((constructor(0))) void __afl_auto_init(void) {\n\n  is_persistent = !!getenv(PERSIST_ENV_VAR);\n\n  if (getenv(DEFER_ENV_VAR)) return;\n\n  __afl_manual_init();\n\n}\n\n\n"
  },
  {
    "path": "qemu_mode/README.qemu",
    "content": "=========================================================\nHigh-performance binary-only instrumentation for afl-fuzz\n=========================================================\n\n  (See ../docs/README for the general instruction manual.)\n\n1) Introduction\n---------------\n\nThe code in this directory allows you to build a standalone feature that\nleverages the QEMU \"user emulation\" mode and allows callers to obtain\ninstrumentation output for black-box, closed-source binaries. This mechanism\ncan be then used by afl-fuzz to stress-test targets that couldn't be built\nwith afl-gcc.\n\nThe usual performance cost is 2-5x, which is considerably better than\nseen so far in experiments with tools such as DynamoRIO and PIN.\n\nThe idea and much of the implementation comes from Andrew Griffiths.\n\n2) How to use\n-------------\n\nThe feature is implemented with a fairly simple patch to QEMU 2.3.0. The\nsimplest way to build it is to run ./build_qemu_support.sh. The script will\ndownload, configure, and compile the QEMU binary for you.\n\nQEMU is a big project, so this will take a while, and you may have to\nresolve a couple of dependencies (most notably, you will definitely need\nlibtool and glib2-devel).\n\nOnce the binaries are compiled, you can leverage the QEMU tool by calling\nafl-fuzz and all the related utilities with -Q in the command line.\n\nNote that QEMU requires a generous memory limit to run; somewhere around\n200 MB is a good starting point, but considerably more may be needed for\nmore complex programs. The default -m limit will be automatically bumped up\nto 200 MB when specifying -Q to afl-fuzz; be careful when overriding this.\n\nIn principle, if you set CPU_TARGET before calling ./build_qemu_support.sh,\nyou should get a build capable of running non-native binaries (say, you\ncan try CPU_TARGET=arm). This is also necessary for running 32-bit binaries\non a 64-bit system (CPU_TARGET=i386).\n\nNote: if you want the QEMU helper to be installed on your system for all\nusers, you need to build it before issuing 'make install' in the parent\ndirectory.\n\n3) Notes on linking\n-------------------\n\nThe feature is supported only on Linux. Supporting BSD may amount to porting\nthe changes made to linux-user/elfload.c and applying them to\nbsd-user/elfload.c, but I have not looked into this yet.\n\nThe instrumentation follows only the .text section of the first ELF binary\nencountered in the linking process. It does not trace shared libraries. In\npractice, this means two things:\n\n  - Any libraries you want to analyze *must* be linked statically into the\n    executed ELF file (this will usually be the case for closed-source\n    apps).\n\n  - Standard C libraries and other stuff that is wasteful to instrument\n    should be linked dynamically - otherwise, AFL will have no way to avoid\n    peeking into them.\n\nSetting AFL_INST_LIBS=1 can be used to circumvent the .text detection logic\nand instrument every basic block encountered.\n\n4) Benchmarking\n---------------\n\nIf you want to compare the performance of the QEMU instrumentation with that of\nafl-gcc compiled code against the same target, you need to build the\nnon-instrumented binary with the same optimization flags that are normally\ninjected by afl-gcc, and make sure that the bits to be tested are statically\nlinked into the binary. A common way to do this would be:\n\n$ CFLAGS=\"-O3 -funroll-loops\" ./configure --disable-shared\n$ make clean all\n\nComparative measurements of execution speed or instrumentation coverage will be\nfairly meaningless if the optimization levels or instrumentation scopes don't\nmatch.\n\n5) Gotchas, feedback, bugs\n--------------------------\n\nIf you need to fix up checksums or do other cleanup on mutated test cases, see\nexperimental/post_library/ for a viable solution.\n\nDo not mix QEMU mode with ASAN, MSAN, or the likes; QEMU doesn't appreciate\nthe \"shadow VM\" trick employed by the sanitizers and will probably just\nrun out of memory.\n\nCompared to fully-fledged virtualization, the user emulation mode is *NOT* a\nsecurity boundary. The binaries can freely interact with the host OS. If you\nsomehow need to fuzz an untrusted binary, put everything in a sandbox first.\n\nBeyond that, this is an early-stage mechanism, so fields reports are welcome.\nYou can send them to <afl-users@googlegroups.com>.\n\n6) Alternatives: static rewriting\n---------------------------------\n\nStatically rewriting binaries just once, instead of attempting to translate\nthem at run time, can be a faster alternative. That said, static rewriting is\nfraught with peril, because it depends on being able to properly and fully model\nprogram control flow without actually executing each and every code path.\n\nIf you want to experiment with this mode of operation, there is a module\ncontributed by Aleksandar Nikolich:\n\n  https://github.com/vrtadmin/moflow/tree/master/afl-dyninst\n  https://groups.google.com/forum/#!topic/afl-users/HlSQdbOTlpg\n\nAt this point, the author reports the possibility of hiccups with stripped\nbinaries. That said, if we can get it to be comparably reliable to QEMU, we may\ndecide to switch to this mode, but I had no time to play with it yet.\n"
  },
  {
    "path": "qemu_mode/build_qemu_support.sh",
    "content": "#!/bin/sh\n#\n# american fuzzy lop - QEMU build script\n# --------------------------------------\n#\n# Written by Andrew Griffiths <agriffiths@google.com> and\n#            Michal Zalewski <lcamtuf@google.com>\n#\n# Copyright 2015 Google Inc. All rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at:\n#\n#   http://www.apache.org/licenses/LICENSE-2.0\n#\n# This script downloads, patches, and builds a version of QEMU with\n# minor tweaks to allow non-instrumented binaries to be run under\n# afl-fuzz. \n#\n# The modifications reside in patches/*. The standalone QEMU binary\n# will be written to ../afl-qemu-trace.\n#\n\nQEMU_URL=\"http://wiki.qemu-project.org/download/qemu-2.3.0.tar.bz2\"\nQEMU_SHA384=\"7a0f0c900f7e2048463cc32ff3e904965ab466c8428847400a0f2dcfe458108a68012c4fddb2a7e7c822b4fd1a49639b\"\n\necho \"=================================================\"\necho \"AFL binary-only instrumentation QEMU build script\"\necho \"=================================================\"\necho\n\necho \"[*] Performing basic sanity checks...\"\n\nif [ ! \"`uname -s`\" = \"Linux\" ]; then\n\n  echo \"[-] Error: QEMU instrumentation is supported only on Linux.\"\n  exit 1\n\nfi\n\nif [ ! -f \"patches/afl-qemu-cpu-inl.h\" -o ! -f \"../config.h\" ]; then\n\n  echo \"[-] Error: key files not found - wrong working directory?\"\n  exit 1\n\nfi\n\nif [ ! -f \"../afl-showmap\" ]; then\n\n  echo \"[-] Error: ../afl-showmap not found - compile AFL first!\"\n  exit 1\n\nfi\n\n\nfor i in libtool wget python automake autoconf sha384sum bison iconv; do\n\n  T=`which \"$i\" 2>/dev/null`\n\n  if [ \"$T\" = \"\" ]; then\n\n    echo \"[-] Error: '$i' not found, please install first.\"\n    exit 1\n\n  fi\n\ndone\n\nif [ ! -d \"/usr/include/glib-2.0/\" -a ! -d \"/usr/local/include/glib-2.0/\" ]; then\n\n  echo \"[-] Error: devel version of 'glib2' not found, please install first.\"\n  exit 1\n\nfi\n\nif echo \"$CC\" | grep -qF /afl-; then\n\n  echo \"[-] Error: do not use afl-gcc or afl-clang to compile this tool.\"\n  exit 1\n\nfi\n\necho \"[+] All checks passed!\"\n\nARCHIVE=\"`basename -- \"$QEMU_URL\"`\"\n\nCKSUM=`sha384sum -- \"$ARCHIVE\" 2>/dev/null | cut -d' ' -f1`\n\nif [ ! \"$CKSUM\" = \"$QEMU_SHA384\" ]; then\n\n  echo \"[*] Downloading QEMU 2.3.0 from the web...\"\n  rm -f \"$ARCHIVE\"\n  wget -O \"$ARCHIVE\" -- \"$QEMU_URL\" || exit 1\n\n  CKSUM=`sha384sum -- \"$ARCHIVE\" 2>/dev/null | cut -d' ' -f1`\n\nfi\n\nif [ \"$CKSUM\" = \"$QEMU_SHA384\" ]; then\n\n  echo \"[+] Cryptographic signature on $ARCHIVE checks out.\"\n\nelse\n\n  echo \"[-] Error: signature mismatch on $ARCHIVE (perhaps download error?).\"\n  exit 1\n\nfi\n\necho \"[*] Uncompressing archive (this will take a while)...\"\n\nrm -rf \"qemu-2.3.0\" || exit 1\ntar xf \"$ARCHIVE\" || exit 1\n\necho \"[+] Unpacking successful.\"\n\necho \"[*] Applying patches...\"\n\npatch -p0 <patches/elfload.diff || exit 1\npatch -p0 <patches/cpu-exec.diff || exit 1\npatch -p0 <patches/translate-all.diff || exit 1\npatch -p0 <patches/syscall.diff || exit 1\n\necho \"[+] Patching done.\"\n\ntest \"$CPU_TARGET\" = \"\" && CPU_TARGET=\"`uname -m`\"\ntest \"$CPU_TARGET\" = \"i686\" && CPU_TARGET=\"i386\"\n\necho \"[*] Configuring QEMU for $CPU_TARGET...\"\n\ncd qemu-2.3.0 || exit 1\n\nCFLAGS=\"-O3\" ./configure --disable-system --enable-linux-user \\\n  --enable-guest-base --disable-gtk --disable-sdl --disable-vnc \\\n  --target-list=\"${CPU_TARGET}-linux-user\" || exit 1\n\necho \"[+] Configuration complete.\"\n\necho \"[*] Attempting to build QEMU (fingers crossed!)...\"\n\nmake || exit 1\n\necho \"[+] Build process successful!\"\n\necho \"[*] Copying binary...\"\n\ncp -f \"${CPU_TARGET}-linux-user/qemu-${CPU_TARGET}\" \"../../afl-qemu-trace\" || exit 1\n\ncd ..\nls -l ../afl-qemu-trace || exit 1\n\necho \"[+] Successfully created '../afl-qemu-trace'.\"\n\necho \"[*] Testing the build...\"\n\ncd ..\n\nmake >/dev/null || exit 1\n\ngcc test-instr.c -o test-instr || exit 1\n\nunset AFL_INST_RATIO\n\necho 0 | ./afl-showmap -m none -Q -q -o .test-instr0 ./test-instr || exit 1\necho 1 | ./afl-showmap -m none -Q -q -o .test-instr1 ./test-instr || exit 1\n\nrm -f test-instr\n\ncmp -s .test-instr0 .test-instr1\nDR=\"$?\"\n\nrm -f .test-instr0 .test-instr1\n\nif [ \"$DR\" = \"0\" ]; then\n\n  echo \"[-] Error: afl-qemu-trace instrumentation doesn't seem to work!\"\n  exit 1\n\nfi\n\necho \"[+] Instrumentation tests passed. \"\n\necho \"[+] All set, you can now use the -Q mode in afl-fuzz!\"\n\nexit 0\n"
  },
  {
    "path": "qemu_mode/patches/afl-qemu-cpu-inl.h",
    "content": "/*\n   american fuzzy lop - high-performance binary-only instrumentation\n   -----------------------------------------------------------------\n\n   Written by Andrew Griffiths <agriffiths@google.com> and\n              Michal Zalewski <lcamtuf@google.com>\n\n   Idea & design very much by Andrew Griffiths.\n\n   Copyright 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n   This code is a shim patched into the separately-distributed source\n   code of QEMU 2.2.0. It leverages the built-in QEMU tracing functionality\n   to implement AFL-style instrumentation and to take care of the remaining\n   parts of the AFL fork server logic.\n\n   The resulting QEMU binary is essentially a standalone instrumentation\n   tool; for an example of how to leverage it for other purposes, you can\n   have a look at afl-showmap.c.\n\n */\n\n#include <sys/shm.h>\n#include \"../../config.h\"\n\n/***************************\n * VARIOUS AUXILIARY STUFF *\n ***************************/\n\n/* A snippet patched into tb_find_slow to inform the parent process that\n   we have hit a new block that hasn't been translated yet, and to tell\n   it to translate within its own context, too (this avoids translation\n   overhead in the next forked-off copy). */\n\n#define AFL_QEMU_CPU_SNIPPET1 do { \\\n    afl_request_tsl(pc, cs_base, flags); \\\n  } while (0)\n\n/* This snippet kicks in when the instruction pointer is positioned at\n   _start and does the usual forkserver stuff, not very different from\n   regular instrumentation injected via afl-as.h. */\n\n#define AFL_QEMU_CPU_SNIPPET2 do { \\\n    if(tb->pc == afl_entry_point) { \\\n      afl_setup(); \\\n      afl_forkserver(env); \\\n    } \\\n    afl_maybe_log(tb->pc); \\\n  } while (0)\n\n/* We use one additional file descriptor to relay \"needs translation\"\n   messages between the child and the fork server. */\n\n#define TSL_FD (FORKSRV_FD - 1)\n\n/* This is equivalent to afl-as.h: */\n\nstatic unsigned char *afl_area_ptr;\n\n/* Exported variables populated by the code patched into elfload.c: */\n\nabi_ulong afl_entry_point, /* ELF entry point (_start) */\n          afl_start_code,  /* .text start pointer      */\n          afl_end_code;    /* .text end pointer        */\n\n/* Set in the child process in forkserver mode: */\n\nstatic unsigned char afl_fork_child;\nunsigned int afl_forksrv_pid;\n\n/* Instrumentation ratio: */\n\nstatic unsigned int afl_inst_rms = MAP_SIZE;\n\n/* Function declarations. */\n\nstatic void afl_setup(void);\nstatic void afl_forkserver(CPUArchState*);\nstatic inline void afl_maybe_log(abi_ulong);\n\nstatic void afl_wait_tsl(CPUArchState*, int);\nstatic void afl_request_tsl(target_ulong, target_ulong, uint64_t);\n\nstatic TranslationBlock *tb_find_slow(CPUArchState*, target_ulong,\n                                      target_ulong, uint64_t);\n\n\n/* Data structure passed around by the translate handlers: */\n\nstruct afl_tsl {\n  target_ulong pc;\n  target_ulong cs_base;\n  uint64_t flags;\n};\n\n\n/*************************\n * ACTUAL IMPLEMENTATION *\n *************************/\n\n\n/* Set up SHM region and initialize other stuff. */\n\nstatic void afl_setup(void) {\n\n  char *id_str = getenv(SHM_ENV_VAR),\n       *inst_r = getenv(\"AFL_INST_RATIO\");\n\n  int shm_id;\n\n  if (inst_r) {\n\n    unsigned int r;\n\n    r = atoi(inst_r);\n\n    if (r > 100) r = 100;\n    if (!r) r = 1;\n\n    afl_inst_rms = MAP_SIZE * r / 100;\n\n  }\n\n  if (id_str) {\n\n    shm_id = atoi(id_str);\n    afl_area_ptr = shmat(shm_id, NULL, 0);\n\n    if (afl_area_ptr == (void*)-1) exit(1);\n\n    /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap\n       so that the parent doesn't give up on us. */\n\n    if (inst_r) afl_area_ptr[0] = 1;\n\n\n  }\n\n  if (getenv(\"AFL_INST_LIBS\")) {\n\n    afl_start_code = 0;\n    afl_end_code   = (abi_ulong)-1;\n\n  }\n\n}\n\n\n/* Fork server logic, invoked once we hit _start. */\n\nstatic void afl_forkserver(CPUArchState *env) {\n\n  static unsigned char tmp[4];\n\n  if (!afl_area_ptr) return;\n\n  /* Tell the parent that we're alive. If the parent doesn't want\n     to talk, assume that we're not running in forkserver mode. */\n\n  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;\n\n  afl_forksrv_pid = getpid();\n\n  /* All right, let's await orders... */\n\n  while (1) {\n\n    pid_t child_pid;\n    int status, t_fd[2];\n\n    /* Whoops, parent dead? */\n\n    if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);\n\n    /* Establish a channel with child to grab translation commands. We'll \n       read from t_fd[0], child will write to TSL_FD. */\n\n    if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);\n    close(t_fd[1]);\n\n    child_pid = fork();\n    if (child_pid < 0) exit(4);\n\n    if (!child_pid) {\n\n      /* Child process. Close descriptors and run free. */\n\n      afl_fork_child = 1;\n      close(FORKSRV_FD);\n      close(FORKSRV_FD + 1);\n      close(t_fd[0]);\n      return;\n\n    }\n\n    /* Parent. */\n\n    close(TSL_FD);\n\n    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);\n\n    /* Collect translation requests until child dies and closes the pipe. */\n\n    afl_wait_tsl(env, t_fd[0]);\n\n    /* Get and relay exit status to parent. */\n\n    if (waitpid(child_pid, &status, 0) < 0) exit(6);\n    if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);\n\n  }\n\n}\n\n\n/* The equivalent of the tuple logging routine from afl-as.h. */\n\nstatic inline void afl_maybe_log(abi_ulong cur_loc) {\n\n  static abi_ulong prev_loc;\n\n  /* Optimize for cur_loc > afl_end_code, which is the most likely case on\n     Linux systems. */\n\n  if (cur_loc > afl_end_code || cur_loc < afl_start_code || !afl_area_ptr)\n    return;\n\n  /* Looks like QEMU always maps to fixed locations, so we can skip this:\n     cur_loc -= afl_start_code; */\n\n  /* Instruction addresses may be aligned. Let's mangle the value to get\n     something quasi-uniform. */\n\n  cur_loc  = (cur_loc >> 4) ^ (cur_loc << 8);\n  cur_loc &= MAP_SIZE - 1;\n\n  /* Implement probabilistic instrumentation by looking at scrambled block\n     address. This keeps the instrumented locations stable across runs. */\n\n  if (cur_loc >= afl_inst_rms) return;\n\n  afl_area_ptr[cur_loc ^ prev_loc]++;\n  prev_loc = cur_loc >> 1;\n\n}\n\n\n/* This code is invoked whenever QEMU decides that it doesn't have a\n   translation of a particular block and needs to compute it. When this happens,\n   we tell the parent to mirror the operation, so that the next fork() has a\n   cached copy. */\n\nstatic void afl_request_tsl(target_ulong pc, target_ulong cb, uint64_t flags) {\n\n  struct afl_tsl t;\n\n  if (!afl_fork_child) return;\n\n  t.pc      = pc;\n  t.cs_base = cb;\n  t.flags   = flags;\n\n  if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))\n    return;\n\n}\n\n\n/* This is the other side of the same channel. Since timeouts are handled by\n   afl-fuzz simply killing the child, we can just wait until the pipe breaks. */\n\nstatic void afl_wait_tsl(CPUArchState *env, int fd) {\n\n  struct afl_tsl t;\n\n  while (1) {\n\n    /* Broken pipe means it's time to return to the fork server routine. */\n\n    if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))\n      break;\n\n    tb_find_slow(env, t.pc, t.cs_base, t.flags);\n\n  }\n\n  close(fd);\n\n}\n\n"
  },
  {
    "path": "qemu_mode/patches/cpu-exec.diff",
    "content": "--- qemu-2.3.0/cpu-exec.c.orig     2014-12-09 14:45:40.000000000 +0000\n+++ qemu-2.3.0/cpu-exec.c  2015-02-20 22:07:02.966000000 +0000\n@@ -28,6 +28,8 @@\n #include \"exec/memory-internal.h\"\n #include \"qemu/rcu.h\"\n\n+#include \"../patches/afl-qemu-cpu-inl.h\"\n+\n /* -icount align implementation. */\n\n typedef struct SyncClocks {\n@@ -296,8 +298,11 @@\n     }\n  not_found:\n    /* if no translated code available, then translate it now */\n+\n     tb = tb_gen_code(cpu, pc, cs_base, flags, 0);\n\n+    AFL_QEMU_CPU_SNIPPET1;\n+\n  found:\n     /* Move the last found TB to the head of the list */\n     if (likely(*ptb1)) {\n@@ -492,6 +497,9 @@\n                     next_tb = 0;\n                     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;\n                 }\n+\n+                AFL_QEMU_CPU_SNIPPET2;\n+\n                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {\n                     qemu_log(\"Trace %p [\" TARGET_FMT_lx \"] %s\\n\",\n                              tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));\n"
  },
  {
    "path": "qemu_mode/patches/elfload.diff",
    "content": "--- qemu-2.3.0/linux-user/elfload.c.orig\t2014-12-09 14:45:42.000000000 +0000\n+++ qemu-2.3.0/linux-user/elfload.c\t2015-01-28 02:51:23.719000000 +0000\n@@ -28,6 +28,8 @@\n \n #define ELF_OSABI   ELFOSABI_SYSV\n \n+extern abi_ulong afl_entry_point, afl_start_code, afl_end_code;\n+\n /* from personality.h */\n \n /*\n@@ -1889,6 +1891,8 @@\n     info->brk = 0;\n     info->elf_flags = ehdr->e_flags;\n \n+    if (!afl_entry_point) afl_entry_point = info->entry;\n+\n     for (i = 0; i < ehdr->e_phnum; i++) {\n         struct elf_phdr *eppnt = phdr + i;\n         if (eppnt->p_type == PT_LOAD) {\n@@ -1922,9 +1926,11 @@\n             if (elf_prot & PROT_EXEC) {\n                 if (vaddr < info->start_code) {\n                     info->start_code = vaddr;\n+                    if (!afl_start_code) afl_start_code = vaddr;\n                 }\n                 if (vaddr_ef > info->end_code) {\n                     info->end_code = vaddr_ef;\n+                    if (!afl_end_code) afl_end_code = vaddr_ef;\n                 }\n             }\n             if (elf_prot & PROT_WRITE) {\n"
  },
  {
    "path": "qemu_mode/patches/syscall.diff",
    "content": "--- qemu-2.3.0/linux-user/syscall.c.orig\t2014-12-09 14:45:43.000000000 +0000\n+++ qemu-2.3.0/linux-user/syscall.c\t2015-03-27 06:33:00.736000000 +0000\n@@ -227,7 +227,21 @@\n _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)\n _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)\n #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)\n-_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)\n+\n+extern unsigned int afl_forksrv_pid;\n+\n+static int sys_tgkill(int tgid, int pid, int sig) {\n+\n+  /* Workaround for -lpthread to make abort() work properly, without\n+     killing the forkserver due to a prematurely cached PID. */\n+\n+  if (afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT)\n+    pid = tgid = getpid();\n+\n+  return syscall(__NR_sys_tgkill, pid, tgid, sig);\n+\n+}\n+\n #endif\n #if defined(TARGET_NR_tkill) && defined(__NR_tkill)\n _syscall2(int,sys_tkill,int,tid,int,sig)\n"
  },
  {
    "path": "qemu_mode/patches/translate-all.diff",
    "content": "--- qemu-2.3.0/translate-all.c.orig     2014-12-09 14:45:46.000000000 +0000\n+++ qemu-2.3.0/translate-all.c  2015-01-28 22:37:42.383000000 +0000\n@@ -393,8 +393,13 @@\n     /* We can't use g_malloc because it may recurse into a locked mutex. */\n # define ALLOC(P, SIZE)                                 \\\n     do {                                                \\\n-        P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,    \\\n-                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);   \\\n+      void* _tmp = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, \\\n+                        MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \\\n+      if (_tmp == (void*)-1) { \\\n+        qemu_log(\">>> Out of memory for stack, bailing out. <<<\\n\"); \\\n+        exit(1); \\\n+      } \\\n+      (P) = _tmp; \\\n     } while (0)\n #else\n # define ALLOC(P, SIZE) \\\n"
  },
  {
    "path": "test-instr.c",
    "content": "/*\n   american fuzzy lop - a trivial program to test the build\n   --------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2014 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\nint main(int argc, char** argv) {\n\n  char buf[8];\n\n  if (read(0, buf, 8) < 1) {\n    printf(\"Hum?\\n\");\n    exit(1);\n  }\n\n  if (buf[0] == '0')\n    printf(\"Looks like a zero to me!\\n\");\n  else\n    printf(\"A non-zero value? How quaint!\\n\");\n\n  exit(0);\n\n}\n"
  },
  {
    "path": "testcases/README.testcases",
    "content": "===============================\nAFL test cases and dictionaries\n===============================\n\n  (See ../docs/README for the general instruction manual.)\n\n1) Starting test cases\n----------------------\n\nThe archives/, images/, multimedia/, and others/ subdirectories contain small,\nstandalone files that can be used to seed afl-fuzz when testing parsers for a\nvariety of common data formats.\n\nThere is probably not much to be said about these files, except that they were\noptimized for size and stripped of any non-essential fluff. Some directories\ncontain several examples that exercise various features of the underlying format.\nFor example, there is a PNG file with and without a color profile.\n\nAdditional test cases are always welcome; the current \"most wanted\" list\nincludes:\n\n  - JBIG,\n  - Ogg Vorbis,\n  - Ogg Theora,\n  - MP3,\n  - AAC,\n  - WebM,\n  - Small JPEG with a color profile,\n  - Small fonts.\n\n2) Dictionaries\n---------------\n\nThe _extras/ subdirectory contains a set of dictionaries that can be used in\nconjunction with the -x option to allow the fuzzer to effortlessly explore the\ngrammar of some of the more verbose data formats or languages. The basic\nprinciple behind the operation of fuzzer dictionaries is outlined in section 9\nof the \"main\" README for the project.\n\nCustom dictionaries can be added at will. They should consist of a\nreasonably-sized set of rudimentary syntax units that the fuzzer will then try\nto clobber together in various ways. Snippets between 2 and 16 bytes are usually\nthe sweet spot.\n\nCustom dictionaries can be created in two ways:\n\n  - By creating a new directory and placing each token in a separate file, in\n    which case, there is no need to escape or otherwise format the data.\n\n  - By creating a flat text file where tokens are listed one per line in the\n    format of name=\"value\". The alphanumeric name is ignored and can be omitted,\n    although it is a convenient way to document the meaning of a particular\n    token. The value must appear in quotes, with hex escaping (\\xNN) applied to\n    all non-printable, high-bit, or otherwise problematic characters (\\\\ and \\\"\n    shorthands are recognized, too).\n\nThe fuzzer auto-selects the appropriate mode depending on whether the -x\nparameter is a file or a directory.\n\nIn the file mode, every name field can be optionally followed by @<num>, e.g.:\n\n  keyword_foo@1 = \"foo\"\n\nSuch entries will be loaded only if the requested dictionary level is equal or\nhigher than this number. The default level is zero; a higher value can be set\nby appending @<num> to the dictionary file name, like so:\n\n  -x path/to/dictionary.dct@2\n\nGood examples of dictionaries can be found in _extras/xml.dict and\n_extras/png.dict.\n"
  },
  {
    "path": "testcases/_extras/gif.dict",
    "content": "#\n# AFL dictionary for GIF images\n# -----------------------------\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nheader_87a=\"87a\"\nheader_89a=\"89a\"\nheader_gif=\"GIF\"\n\nmarker_2c=\",\"\nmarker_3b=\";\"\n\nsection_2101=\"!\\x01\\x12\"\nsection_21f9=\"!\\xf9\\x04\"\nsection_21fe=\"!\\xfe\"\nsection_21ff=\"!\\xff\\x11\"\n"
  },
  {
    "path": "testcases/_extras/html_tags.dict",
    "content": "#\n# AFL dictionary for HTML parsers (tags only)\n# -------------------------------------------\n#\n# A basic collection of HTML tags likely to matter to HTML parsers. Does *not*\n# include any attributes or attribute values.\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\ntag_a=\"<a>\"\ntag_abbr=\"<abbr>\"\ntag_acronym=\"<acronym>\"\ntag_address=\"<address>\"\ntag_annotation_xml=\"<annotation-xml>\"\ntag_applet=\"<applet>\"\ntag_area=\"<area>\"\ntag_article=\"<article>\"\ntag_aside=\"<aside>\"\ntag_audio=\"<audio>\"\ntag_b=\"<b>\"\ntag_base=\"<base>\"\ntag_basefont=\"<basefont>\"\ntag_bdi=\"<bdi>\"\ntag_bdo=\"<bdo>\"\ntag_bgsound=\"<bgsound>\"\ntag_big=\"<big>\"\ntag_blink=\"<blink>\"\ntag_blockquote=\"<blockquote>\"\ntag_body=\"<body>\"\ntag_br=\"<br>\"\ntag_button=\"<button>\"\ntag_canvas=\"<canvas>\"\ntag_caption=\"<caption>\"\ntag_center=\"<center>\"\ntag_cite=\"<cite>\"\ntag_code=\"<code>\"\ntag_col=\"<col>\"\ntag_colgroup=\"<colgroup>\"\ntag_data=\"<data>\"\ntag_datalist=\"<datalist>\"\ntag_dd=\"<dd>\"\ntag_del=\"<del>\"\ntag_desc=\"<desc>\"\ntag_details=\"<details>\"\ntag_dfn=\"<dfn>\"\ntag_dir=\"<dir>\"\ntag_div=\"<div>\"\ntag_dl=\"<dl>\"\ntag_dt=\"<dt>\"\ntag_em=\"<em>\"\ntag_embed=\"<embed>\"\ntag_fieldset=\"<fieldset>\"\ntag_figcaption=\"<figcaption>\"\ntag_figure=\"<figure>\"\ntag_font=\"<font>\"\ntag_footer=\"<footer>\"\ntag_foreignobject=\"<foreignobject>\"\ntag_form=\"<form>\"\ntag_frame=\"<frame>\"\ntag_frameset=\"<frameset>\"\ntag_h1=\"<h1>\"\ntag_h2=\"<h2>\"\ntag_h3=\"<h3>\"\ntag_h4=\"<h4>\"\ntag_h5=\"<h5>\"\ntag_h6=\"<h6>\"\ntag_head=\"<head>\"\ntag_header=\"<header>\"\ntag_hgroup=\"<hgroup>\"\ntag_hr=\"<hr>\"\ntag_html=\"<html>\"\ntag_i=\"<i>\"\ntag_iframe=\"<iframe>\"\ntag_image=\"<image>\"\ntag_img=\"<img>\"\ntag_input=\"<input>\"\ntag_ins=\"<ins>\"\ntag_isindex=\"<isindex>\"\ntag_kbd=\"<kbd>\"\ntag_keygen=\"<keygen>\"\ntag_label=\"<label>\"\ntag_legend=\"<legend>\"\ntag_li=\"<li>\"\ntag_link=\"<link>\"\ntag_listing=\"<listing>\"\ntag_main=\"<main>\"\ntag_malignmark=\"<malignmark>\"\ntag_map=\"<map>\"\ntag_mark=\"<mark>\"\ntag_marquee=\"<marquee>\"\ntag_math=\"<math>\"\ntag_menu=\"<menu>\"\ntag_menuitem=\"<menuitem>\"\ntag_meta=\"<meta>\"\ntag_meter=\"<meter>\"\ntag_mglyph=\"<mglyph>\"\ntag_mi=\"<mi>\"\ntag_mn=\"<mn>\"\ntag_mo=\"<mo>\"\ntag_ms=\"<ms>\"\ntag_mtext=\"<mtext>\"\ntag_multicol=\"<multicol>\"\ntag_nav=\"<nav>\"\ntag_nextid=\"<nextid>\"\ntag_nobr=\"<nobr>\"\ntag_noembed=\"<noembed>\"\ntag_noframes=\"<noframes>\"\ntag_noscript=\"<noscript>\"\ntag_object=\"<object>\"\ntag_ol=\"<ol>\"\ntag_optgroup=\"<optgroup>\"\ntag_option=\"<option>\"\ntag_output=\"<output>\"\ntag_p=\"<p>\"\ntag_param=\"<param>\"\ntag_plaintext=\"<plaintext>\"\ntag_pre=\"<pre>\"\ntag_progress=\"<progress>\"\ntag_q=\"<q>\"\ntag_rb=\"<rb>\"\ntag_rp=\"<rp>\"\ntag_rt=\"<rt>\"\ntag_rtc=\"<rtc>\"\ntag_ruby=\"<ruby>\"\ntag_s=\"<s>\"\ntag_samp=\"<samp>\"\ntag_script=\"<script>\"\ntag_section=\"<section>\"\ntag_select=\"<select>\"\ntag_small=\"<small>\"\ntag_source=\"<source>\"\ntag_spacer=\"<spacer>\"\ntag_span=\"<span>\"\ntag_strike=\"<strike>\"\ntag_strong=\"<strong>\"\ntag_style=\"<style>\"\ntag_sub=\"<sub>\"\ntag_summary=\"<summary>\"\ntag_sup=\"<sup>\"\ntag_svg=\"<svg>\"\ntag_table=\"<table>\"\ntag_tbody=\"<tbody>\"\ntag_td=\"<td>\"\ntag_template=\"<template>\"\ntag_textarea=\"<textarea>\"\ntag_tfoot=\"<tfoot>\"\ntag_th=\"<th>\"\ntag_thead=\"<thead>\"\ntag_time=\"<time>\"\ntag_title=\"<title>\"\ntag_tr=\"<tr>\"\ntag_track=\"<track>\"\ntag_tt=\"<tt>\"\ntag_u=\"<u>\"\ntag_ul=\"<ul>\"\ntag_var=\"<var>\"\ntag_video=\"<video>\"\ntag_wbr=\"<wbr>\"\ntag_xmp=\"<xmp>\"\n"
  },
  {
    "path": "testcases/_extras/jpeg.dict",
    "content": "#\n# AFL dictionary for JPEG images\n# ------------------------------\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nheader_jfif=\"JFIF\\x00\"\nheader_jfxx=\"JFXX\\x00\"\n\nsection_ffc0=\"\\xff\\xc0\"\nsection_ffc2=\"\\xff\\xc2\"\nsection_ffc4=\"\\xff\\xc4\"\nsection_ffd0=\"\\xff\\xd0\"\nsection_ffd8=\"\\xff\\xd8\"\nsection_ffd9=\"\\xff\\xd9\"\nsection_ffda=\"\\xff\\xda\"\nsection_ffdb=\"\\xff\\xdb\"\nsection_ffdd=\"\\xff\\xdd\"\nsection_ffe0=\"\\xff\\xe0\"\nsection_ffe1=\"\\xff\\xe1\"\nsection_fffe=\"\\xff\\xfe\"\n"
  },
  {
    "path": "testcases/_extras/js.dict",
    "content": "#\n# AFL dictionary for JavaScript\n# -----------------------------\n#\n# Contains basic reserved keywords and syntax building blocks.\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nkeyword_arguments=\"arguments\"\nkeyword_break=\"break\"\nkeyword_case=\"case\"\nkeyword_catch=\"catch\"\nkeyword_const=\"const\"\nkeyword_continue=\"continue\"\nkeyword_debugger=\"debugger\"\nkeyword_decodeURI=\"decodeURI\"\nkeyword_default=\"default\"\nkeyword_delete=\"delete\"\nkeyword_do=\"do\"\nkeyword_else=\"else\"\nkeyword_escape=\"escape\"\nkeyword_eval=\"eval\"\nkeyword_export=\"export\"\nkeyword_finally=\"finally\"\nkeyword_for=\"for (a=0;a<2;a++)\"\nkeyword_function=\"function\"\nkeyword_if=\"if\"\nkeyword_in=\"in\"\nkeyword_instanceof=\"instanceof\"\nkeyword_isNaN=\"isNaN\"\nkeyword_let=\"let\"\nkeyword_new=\"new\"\nkeyword_parseInt=\"parseInt\"\nkeyword_return=\"return\"\nkeyword_switch=\"switch\"\nkeyword_this=\"this\"\nkeyword_throw=\"throw\"\nkeyword_try=\"try\"\nkeyword_typeof=\"typeof\"\nkeyword_var=\"var\"\nkeyword_void=\"void\"\nkeyword_while=\"while\"\nkeyword_with=\"with\"\n\nmisc_1=\" 1\"\nmisc_a=\"a\"\nmisc_array=\" [1]\"\nmisc_assign=\" a=1\"\nmisc_code_block=\" {1}\"\nmisc_colon_num=\" 1:\"\nmisc_colon_string=\" 'a':\"\nmisc_comma=\" ,\"\nmisc_comment_block=\" /* */\"\nmisc_comment_line=\" //\"\nmisc_cond=\" 1?2:3\"\nmisc_dec=\" --\"\nmisc_div=\" /\"\nmisc_equals=\" =\"\nmisc_fn=\" a()\"\nmisc_identical=\" ===\"\nmisc_inc=\" ++\"\nmisc_minus=\" -\"\nmisc_modulo=\" %\"\nmisc_parentheses=\" ()\"\nmisc_parentheses_1=\" (1)\"\nmisc_parentheses_1x4=\" (1,1,1,1)\"\nmisc_parentheses_a=\" (a)\"\nmisc_period=\".\"\nmisc_plus=\" +\"\nmisc_plus_assign=\" +=\"\nmisc_regex=\" /a/g\"\nmisc_rol=\" <<<\"\nmisc_semicolon=\" ;\"\nmisc_serialized_object=\" {'a': 1}\"\nmisc_string=\" 'a'\"\nmisc_unicode=\" '\\\\u0001'\"\n\nobject_Array=\" Array\"\nobject_Boolean=\" Boolean\"\nobject_Date=\" Date\"\nobject_Function=\" Function\"\nobject_Infinity=\" Infinity\"\nobject_Int8Array=\" Int8Array\"\nobject_Math=\" Math\"\nobject_NaN=\" NaN\"\nobject_Number=\" Number\"\nobject_Object=\" Object\"\nobject_RegExp=\" RegExp\"\nobject_String=\" String\"\nobject_Symbol=\" Symbol\"\nobject_false=\" false\"\nobject_null=\" null\"\nobject_true=\" true\"\n\nprop_charAt=\".charAt\"\nprop_concat=\".concat\"\nprop_constructor=\".constructor\"\nprop_destructor=\".destructor\"\nprop_length=\".length\"\nprop_match=\".match\"\nprop_proto=\".__proto__\"\nprop_prototype=\".prototype\"\nprop_slice=\".slice\"\nprop_toCode=\".toCode\"\nprop_toString=\".toString\"\nprop_valueOf=\".valueOf\"\n"
  },
  {
    "path": "testcases/_extras/pdf.dict",
    "content": "#\n# AFL dictionary for PDF\n# ----------------------\n#\n# This is a pretty big PDF dictionary constructed by Ben by manually reviewing\n# the spec and combining that with the data pulled out of a corpus of sample\n# PDFs.\n#\n# Contributed by Ben Nagy <ben@iagu.net>\n#\n\n\"#\"\n\"%\"\n\"%%\"\n\"%%EOF\"\n\"%FDF-1.7\"\n\"%PDF-1.7\"\n\"(\"\n\"(/xdp:xdp)\"\n\"(\\\\001)\"\n\"(config)\"\n\"(datasets)\"\n\"(template)\"\n\"(xdp:xdp)\"\n\")\"\n\"-1\"\n\"-1.0\"\n\"..\"\n\"/\"\n\"/#23clipboard\"\n\"/.notdef\"\n\"/1\"\n\"/1.0\"\n\"/1.3\"\n\"/3D\"\n\"/3DA\"\n\"/3DAnimationStyle\"\n\"/3DB\"\n\"/3DD\"\n\"/3DI\"\n\"/3DLightingScheme\"\n\"/3DRenderMode\"\n\"/3DV\"\n\"/3DView\"\n\"/90pv-RKSJ-H\"\n\"/A\"\n\"/A0\"\n\"/A85\"\n\"/AA\"\n\"/AAIC\"\n\"/AAPL\"\n\"/ABCDEF+ACaslonPro-Regular\"\n\"/ABCDEF+AJensonPro-LtIt\"\n\"/ABCDEF+AdobeCorpID-MinionRg\"\n\"/ABCDEF+Arial,Bold\"\n\"/ABCDEF+BankGothicMdBT\"\n\"/ABCDEF+Bauhaus-Heavy\"\n\"/ABCDEF+BluesClues\"\n\"/ABCDEF+BodegaSans\"\n\"/ABCDEF+BodoniMTCondensed\"\n\"/ABCDEF+BookAntiqua\"\n\"/ABCDEF+CMBX10\"\n\"/ABCDEF+CaflischScriptPro-Regular\"\n\"/ABCDEF+CityBlueprint\"\n\"/ABCDEF+CourierNewPSMT\"\n\"/ABCDEF+FixedsysExcelsior2.00\"\n\"/ABCDEF+MSTT31854bd45bo188067S00\"\n\"/ABCDEF+MinionPro-BoldCnIt\"\n\"/ABCDEF+MyriadMM-It_400_300_\"\n\"/ABCDEF+Wingdings\"\n\"/ABCDEF+ZapfDingbats\"\n\"/AC\"\n\"/ADBE\"\n\"/ADB_DEVICE_DEFAULT_STYLE\"\n\"/ADB_DefaultStyle\"\n\"/ADB_NO_TRAP_STYLE\"\n\"/AE\"\n\"/AESV2\"\n\"/AGaramond\"\n\"/AH\"\n\"/AI8DstIndex\"\n\"/AI8SrcIndex\"\n\"/AIMetaData\"\n\"/AIPDFPrivateData1\"\n\"/AIS\"\n\"/AL\"\n\"/AN\"\n\"/AP\"\n\"/AS\"\n\"/ASCII85Decode\"\n\"/ASCIIHexDecode\"\n\"/ASomewhatLongerName\"\n\"/AU\"\n\"/Aacute\"\n\"/Acc.#20Prod.#202501#20#2F2#20#20\"\n\"/Accounts#20payable\"\n\"/AccurateScreens\"\n\"/Acircumflex\"\n\"/AcroForm\"\n\"/Action\"\n\"/Actual\"\n\"/Add\"\n\"/Adieresis\"\n\"/Adobe\"\n\"/Adobe#20PDF#20Library\"\n\"/Adobe.PPKLite\"\n\"/AdobeCorpID-Acrobat\"\n\"/AdobeCorpID-MinionRg\"\n\"/AdobePhotoshop\"\n\"/Agrave\"\n\"/All\"\n\"/AllKO\"\n\"/AllOn\"\n\"/Alt\"\n\"/Alternate\"\n\"/AlternatePresentations\"\n\"/Alternates\"\n\"/Amex\"\n\"/And\"\n\"/Angle\"\n\"/Annot\"\n\"/Annots\"\n\"/AntiAlias\"\n\"/AnyOn\"\n\"/Apag_PDFX_Checkup\"\n\"/App\"\n\"/Architecture-Normal\"\n\"/Arial\"\n\"/Aring\"\n\"/Art\"\n\"/ArtBox\"\n\"/Article\"\n\"/Artifact\"\n\"/Artwork\"\n\"/Ascent\"\n\"/Aspect\"\n\"/Assistant\"\n\"/Atilde\"\n\"/AuthEvent\"\n\"/Author\"\n\"/Avenir-Heavy\"\n\"/Avenir-MediumOblique\"\n\"/AvgWidth\"\n\"/BBox\"\n\"/BC\"\n\"/BCL\"\n\"/BDC\"\n\"/BDL\"\n\"/BE\"\n\"/BFSOL\"\n\"/BG\"\n\"/BG2\"\n\"/BM\"\n\"/BMC\"\n\"/BS\"\n\"/BW\"\n\"/Bank\"\n\"/BaseEncoding\"\n\"/BaseFont\"\n\"/BaseState\"\n\"/BaseVersion\"\n\"/Birch\"\n\"/BitsPerComponent\"\n\"/BitsPerCoordinate\"\n\"/BitsPerFlag\"\n\"/BitsPerSample\"\n\"/Bl\"\n\"/BlCDel\"\n\"/BlMiNu\"\n\"/Black\"\n\"/BlackIs1\"\n\"/BlackOP\"\n\"/BlackPoint\"\n\"/BleedBox\"\n\"/Blend\"\n\"/Block\"\n\"/Blue\"\n\"/BluesClues\"\n\"/Bookshelf\"\n\"/Border\"\n\"/Bounds\"\n\"/BoxColorInfo\"\n\"/Btn\"\n\"/BulmerMT-BoldDisplay\"\n\"/ByteRange\"\n\"/C\"\n\"/C0\"\n\"/C0_0\"\n\"/C1\"\n\"/C2W\"\n\"/C3\"\n\"/CALS_AIS\"\n\"/CALS_BM\"\n\"/CALS_HT\"\n\"/CALS_SMASK\"\n\"/CALS_ca\"\n\"/CAM\"\n\"/CB\"\n\"/CC\"\n\"/CCH\"\n\"/CCITTFaxDecode\"\n\"/CD\"\n\"/CDL\"\n\"/CEN\"\n\"/CF\"\n\"/CFM\"\n\"/CI\"\n\"/CIDFontType0\"\n\"/CIDFontType0C\"\n\"/CIDFontType2\"\n\"/CIDInit\"\n\"/CIDSet\"\n\"/CIDSystemInfo\"\n\"/CIDToGIDMap\"\n\"/CMV_LabBar\"\n\"/CMV_LabControl\"\n\"/CMYK\"\n\"/CMYK#20#2880,#208,#2034,#200#29\"\n\"/CMap\"\n\"/CMapName\"\n\"/CMapType\"\n\"/CMapVersion\"\n\"/CO\"\n\"/CP\"\n\"/CS\"\n\"/CS0\"\n\"/CT\"\n\"/CV\"\n\"/CalGray\"\n\"/CalRGB\"\n\"/CapHeight\"\n\"/Caption\"\n\"/Caslon540BT-Roman\"\n\"/CaslonBT-Bold\"\n\"/CaslonBT-BoldItalic\"\n\"/Catalog\"\n\"/Category\"\n\"/Ccedilla\"\n\"/CenturySchoolbookBT-Roman\"\n\"/Ch\"\n\"/Chair\"\n\"/Chap\"\n\"/Chaparral-Display\"\n\"/CharProcs\"\n\"/CharSet\"\n\"/CheckSum\"\n\"/Circle\"\n\"/ClarendonBT-Black\"\n\"/ClassMap\"\n\"/Clearface-Black\"\n\"/Clip\"\n\"/ClippedText\"\n\"/Cn\"\n\"/Collection\"\n\"/CollectionItem\"\n\"/CollectionSchema\"\n\"/CollectionSubitem\"\n\"/Color\"\n\"/ColorBurn\"\n\"/ColorDodge\"\n\"/ColorMatch\"\n\"/ColorSpace\"\n\"/ColorTransform\"\n\"/ColorType\"\n\"/Colorants\"\n\"/Colors\"\n\"/Columns\"\n\"/ComicSansMS,Bold\"\n\"/Comment\"\n\"/Comments\"\n\"/Company\"\n\"/Compatibility\"\n\"/Compatible\"\n\"/Components\"\n\"/CompressArt\"\n\"/Condensed\"\n\"/Configs\"\n\"/Consultant\"\n\"/ContainerVersion\"\n\"/Contents\"\n\"/Coords\"\n\"/Copy\"\n\"/Copy#20center\"\n\"/Cor\"\n\"/Corner#20surface\"\n\"/CosineDot\"\n\"/Count\"\n\"/Cour\"\n\"/Courier\"\n\"/Create\"\n\"/CreationDate\"\n\"/Creator\"\n\"/CreatorInfo\"\n\"/CreatorVersion\"\n\"/CropBox\"\n\"/CropFixed\"\n\"/CropRect\"\n\"/Crypt\"\n\"/CryptFilter\"\n\"/CryptFilterDecodeParms\"\n\"/Cs12\"\n\"/Cs3\"\n\"/Cyan\"\n\"/D\"\n\"/DA\"\n\"/DCTDecode\"\n\"/DIC#202525p*\"\n\"/DIS\"\n\"/DL\"\n\"/DOS\"\n\"/DP\"\n\"/DR\"\n\"/DS\"\n\"/DSz\"\n\"/DV\"\n\"/DW\"\n\"/DamagedRowsBeforeError\"\n\"/Darken\"\n\"/Data\"\n\"/Date\"\n\"/Decode\"\n\"/DecodeParms\"\n\"/DefEmbeddedFile\"\n\"/Default\"\n\"/DefaultCryptFilter\"\n\"/DefaultForPrinting\"\n\"/DefaultRGB\"\n\"/Delete\"\n\"/Delta\"\n\"/DescendantFonts\"\n\"/Descent\"\n\"/Description\"\n\"/Design\"\n\"/Dest\"\n\"/DestOutputProfile\"\n\"/DestOutputProfileRef\"\n\"/Dests\"\n\"/DeviceCMYK\"\n\"/DeviceGray\"\n\"/DeviceN\"\n\"/DeviceRGB\"\n\"/Difference\"\n\"/Differences\"\n\"/DigestLocation\"\n\"/DigestMethod\"\n\"/DigestValue\"\n\"/Dimmed\"\n\"/Direction\"\n\"/DisplayDocTitle\"\n\"/Dissolve\"\n\"/Div\"\n\"/Dm\"\n\"/DocMDP\"\n\"/DocOpen\"\n\"/Document\"\n\"/Documents\"\n\"/Domain\"\n\"/Door\"\n\"/DotGain\"\n\"/Draw\"\n\"/Dt\"\n\"/Dur\"\n\"/Dynamic#20connector\"\n\"/E\"\n\"/EF\"\n\"/EFF\"\n\"/EMC\"\n\"/Eacute\"\n\"/EarlyChange\"\n\"/Ecircumflex\"\n\"/Edieresis\"\n\"/Editable\"\n\"/Egrave\"\n\"/EmbedFonts\"\n\"/EmbedICCProfile\"\n\"/Embedded\"\n\"/EmbeddedFile\"\n\"/EmbeddedFiles\"\n\"/Encode\"\n\"/EncodedByteAlign\"\n\"/Encoding\"\n\"/Encrypt\"\n\"/EncryptMetadata\"\n\"/EndIndent\"\n\"/EndOfBlock\"\n\"/EndOfLine\"\n\"/Euro\"\n\"/Euro.037\"\n\"/Event\"\n\"/ExData\"\n\"/Exchange-Pro\"\n\"/Exclude\"\n\"/Exclusion\"\n\"/Executive\"\n\"/Export\"\n\"/ExportCrispy\"\n\"/ExportState\"\n\"/ExtGState\"\n\"/Extend\"\n\"/Extends\"\n\"/ExtensionLevel\"\n\"/Extensions\"\n\"/F1\"\n\"/F1.0\"\n\"/F12\"\n\"/F13\"\n\"/F3\"\n\"/F5\"\n\"/F6\"\n\"/F7\"\n\"/F8\"\n\"/FB\"\n\"/FD\"\n\"/FDecodeParms\"\n\"/FFilter\"\n\"/FICL\"\n\"/FM\"\n\"/FOV\"\n\"/FRM\"\n\"/FS\"\n\"/FT\"\n\"/Facilities\"\n\"/Fade\"\n\"/False\"\n\"/Feature\"\n\"/FedEx#20Orange\"\n\"/FedEx#20Purple\"\n\"/Field\"\n\"/Fields\"\n\"/Figure\"\n\"/File\"\n\"/Files\"\n\"/Filespec\"\n\"/FillIn\"\n\"/Filter\"\n\"/First\"\n\"/FirstChar\"\n\"/FirstPage\"\n\"/Fit\"\n\"/FitB\"\n\"/FitBH\"\n\"/FitBV\"\n\"/FitH\"\n\"/FitR\"\n\"/FitV\"\n\"/FitWindow\"\n\"/FixedPrint\"\n\"/Flags\"\n\"/FlateDecode\"\n\"/Fm0\"\n\"/Fm4\"\n\"/Fo\"\n\"/Focoltone#201047\"\n\"/Font\"\n\"/FontBBox\"\n\"/FontDescriptor\"\n\"/FontFamily\"\n\"/FontFile\"\n\"/FontFile2\"\n\"/FontMatrix\"\n\"/FontName\"\n\"/FontStretch\"\n\"/FontWeight\"\n\"/Form\"\n\"/FormEx\"\n\"/FormType\"\n\"/FreeText\"\n\"/FreeTextCallout\"\n\"/Frequency\"\n\"/FullSave\"\n\"/FullScreen\"\n\"/Function\"\n\"/FunctionType\"\n\"/Functions\"\n\"/Futura-Bold\"\n\"/Futura-CondensedExtraBold\"\n\"/G\"\n\"/G02\"\n\"/GLGR\"\n\"/GS0\"\n\"/GS1\"\n\"/GS2\"\n\"/GTS\"\n\"/GTS_PDFA1\"\n\"/GTS_PDFX\"\n\"/GTS_PDFXConformance\"\n\"/GTS_PDFXVersion\"\n\"/GWG#20Green\"\n\"/Gamma\"\n\"/Garamond\"\n\"/Georgia,Bold\"\n\"/GoTo\"\n\"/GoTo3DView\"\n\"/GoToE\"\n\"/GoToR\"\n\"/Gold\"\n\"/Goudy\"\n\"/Gray\"\n\"/Green\"\n\"/GreymantleMVB\"\n\"/GrotesqueMT\"\n\"/Group\"\n\"/H\"\n\"/HDAG_Tools\"\n\"/HKana\"\n\"/HT\"\n\"/HT2\"\n\"/Halftone\"\n\"/HalftoneName\"\n\"/HalftoneType\"\n\"/HardLight\"\n\"/HeBo\"\n\"/Head1\"\n\"/Headlamp\"\n\"/Height\"\n\"/HeiseiMin\"\n\"/Helv\"\n\"/Helvetica\"\n\"/Helvetica-Bold\"\n\"/Helvetica-BoldOblique\"\n\"/Helvetica-Condensed\"\n\"/HelveticaNeue-Black\"\n\"/Hide\"\n\"/HonMincho-M\"\n\"/Horizontal\"\n\"/Hue\"\n\"/I\"\n\"/I0\"\n\"/IC\"\n\"/ICCBased\"\n\"/ICCVersion\"\n\"/ID\"\n\"/IDS\"\n\"/IDTree\"\n\"/IEC\"\n\"/IF\"\n\"/IN\"\n\"/ISO32000Registry\"\n\"/ISO_PDFE1\"\n\"/ISO_PDFEVersion\"\n\"/IT\"\n\"/ITO\"\n\"/ITP\"\n\"/IV\"\n\"/IX\"\n\"/Icircumflex\"\n\"/Icon\"\n\"/Identity\"\n\"/Identity-H\"\n\"/IgnEP\"\n\"/Illustrator\"\n\"/Illustrator8.0\"\n\"/Im0\"\n\"/Im1\"\n\"/Im2\"\n\"/Im3\"\n\"/Im4\"\n\"/Image\"\n\"/Image1\"\n\"/ImageB\"\n\"/ImageC\"\n\"/ImageI\"\n\"/ImageMask\"\n\"/ImageResources\"\n\"/ImageType\"\n\"/Import\"\n\"/ImportData\"\n\"/ImpressBT-Regular\"\n\"/Index\"\n\"/Indexed\"\n\"/Info\"\n\"/Information#20services\"\n\"/Ink\"\n\"/InkList\"\n\"/InsertPages\"\n\"/Insignia\"\n\"/IntegerItem\"\n\"/Intent\"\n\"/Interpolate\"\n\"/ItalicAngle\"\n\"/ItcKabel-Ultra\"\n\"/Item1\"\n\"/Item2\"\n\"/JBIG2Decode\"\n\"/JBIG2Globals\"\n\"/JPXDecode\"\n\"/JS\"\n\"/JT\"\n\"/JTC\"\n\"/JTF\"\n\"/JTFile\"\n\"/JTM\"\n\"/JavaScript\"\n\"/JobTicketContents\"\n\"/Justify\"\n\"/Keywords\"\n\"/Kids\"\n\"/L\"\n\"/L1\"\n\"/L1a\"\n\"/L1b\"\n\"/L2R\"\n\"/L50188\"\n\"/LBody\"\n\"/LI\"\n\"/LL\"\n\"/LLE\"\n\"/LLO\"\n\"/LS\"\n\"/LSP\"\n\"/LZW\"\n\"/LZWDecode\"\n\"/Lab\"\n\"/Lang\"\n\"/Last\"\n\"/LastChar\"\n\"/LastItem\"\n\"/LastModified\"\n\"/Lateral#20file\"\n\"/Launch\"\n\"/Layout\"\n\"/Lbl\"\n\"/Leading\"\n\"/Legal\"\n\"/Length\"\n\"/Length1\"\n\"/Length2\"\n\"/Length3\"\n\"/LetterspaceFlags\"\n\"/Lighten\"\n\"/Limits\"\n\"/Line\"\n\"/LineDimension\"\n\"/LineHeight\"\n\"/Linear\"\n\"/Linearized\"\n\"/Link\"\n\"/Locked\"\n\"/LogoGreen\"\n\"/LrTb\"\n\"/Lslash\"\n\"/Luminosity\"\n\"/M\"\n\"/MB\"\n\"/MC\"\n\"/MC0\"\n\"/MCD\"\n\"/MCID\"\n\"/MCR\"\n\"/MD5\"\n\"/MH\"\n\"/MIT\"\n\"/MK\"\n\"/MMType1\"\n\"/MP\"\n\"/MR\"\n\"/MS\"\n\"/MUX#20#2F#20DEMUX\"\n\"/Mac\"\n\"/MacRomanEncoding\"\n\"/Magenta\"\n\"/Manager\"\n\"/MarkInfo\"\n\"/Marked\"\n\"/MarkedPDF\"\n\"/Marker#20board\"\n\"/Markup3D\"\n\"/Mask\"\n\"/Mastercard\"\n\"/Matrix\"\n\"/Max\"\n\"/MaxLen\"\n\"/MaxWidth\"\n\"/Me\"\n\"/Measure\"\n\"/MediaBox\"\n\"/MetaData\"\n\"/Min\"\n\"/MinionMM\"\n\"/MissingWidth\"\n\"/MixedContainer\"\n\"/MixingHints\"\n\"/ModDate\"\n\"/Mode\"\n\"/Modify\"\n\"/Movie\"\n\"/Msg\"\n\"/MurrayHillBT-Bold\"\n\"/MxGeom\"\n\"/MxLaNu\"\n\"/MxPts\"\n\"/MyriadPro-Black\"\n\"/NA\"\n\"/NChannel\"\n\"/ND\"\n\"/NL\"\n\"/NM\"\n\"/NR\"\n\"/Name\"\n\"/Name1\"\n\"/Named\"\n\"/Names\"\n\"/NeedsRendering\"\n\"/NewCenturySchlbk-Italic\"\n\"/NewWindow\"\n\"/Next\"\n\"/NextPage\"\n\"/No\"\n\"/NonEFontNoWarn\"\n\"/NonStruct\"\n\"/None\"\n\"/Normal\"\n\"/Not\"\n\"/NotDefSpecial\"\n\"/NumBlock\"\n\"/Nums\"\n\"/OB\"\n\"/OBJR\"\n\"/OC\"\n\"/OC2\"\n\"/OC3\"\n\"/OC4\"\n\"/OCG\"\n\"/OCGs\"\n\"/OCL\"\n\"/OCMD\"\n\"/OCProperties\"\n\"/OE\"\n\"/OFF\"\n\"/OLN\"\n\"/ON\"\n\"/OOL\"\n\"/OPBG\"\n\"/OPBS\"\n\"/OPI\"\n\"/OPM\"\n\"/OS\"\n\"/OT\"\n\"/Oacute\"\n\"/Obj\"\n\"/ObjStm\"\n\"/Ocircumflex\"\n\"/Odieresis\"\n\"/Ograve\"\n\"/Omega\"\n\"/OneColumn\"\n\"/Online\"\n\"/Open\"\n\"/OpenAction\"\n\"/Operation\"\n\"/Opt\"\n\"/OptionSet\"\n\"/Options\"\n\"/Or\"\n\"/Orange\"\n\"/Order\"\n\"/Ordering\"\n\"/OriginalLayerName\"\n\"/Oslash\"\n\"/Otilde\"\n\"/Outlines\"\n\"/OutputCondition\"\n\"/OutputConditionIdentifier\"\n\"/OutputIntent\"\n\"/OutputIntents\"\n\"/Overlay\"\n\"/P0\"\n\"/P1\"\n\"/P2\"\n\"/P2,#2300ff007900000000,PANTONE#20151#20C\"\n\"/PANTONE\"\n\"/PANTONE#20158-5#20CVS\"\n\"/PANTONE#20221#20CVU\"\n\"/PANTONE#203405#20C\"\n\"/PANTONE#20399#20CVC\"\n\"/PANTONE#20Blue#20072#20C\"\n\"/PANTONE#20Orange#20021#20C\"\n\"/PANTONE#20Orange#20021#20CVC\"\n\"/PANTONE#20Yellow#20C\"\n\"/PC\"\n\"/PDFDocEncoding\"\n\"/PIX\"\n\"/PO\"\n\"/PS\"\n\"/PUBLISHER\"\n\"/PZ\"\n\"/Pa0\"\n\"/Page\"\n\"/PageElement\"\n\"/PageLabels\"\n\"/PageLayout\"\n\"/PageMode\"\n\"/PageRange\"\n\"/Pages\"\n\"/PaintType\"\n\"/Palatino,Bold\"\n\"/Pale#20Brown.c\"\n\"/Panose\"\n\"/Paper#20tray\"\n\"/Para\"\n\"/Params\"\n\"/Parent\"\n\"/ParentTree\"\n\"/ParentTreeNextKey\"\n\"/Part\"\n\"/Pattern\"\n\"/PatternType\"\n\"/PcZ\"\n\"/Perceptual\"\n\"/Perms\"\n\"/Pg\"\n\"/Pgf\"\n\"/PieceInfo\"\n\"/PitStop\"\n\"/Placement\"\n\"/Play\"\n\"/Polygon\"\n\"/PolygonCloud\"\n\"/Popup\"\n\"/Position\"\n\"/PowerUpPDF\"\n\"/PrOut\"\n\"/PrRGBGra\"\n\"/PrRGBIma\"\n\"/Predictor\"\n\"/PresSteps\"\n\"/PreserveRB\"\n\"/Prev\"\n\"/PrevPage\"\n\"/Preview\"\n\"/Print\"\n\"/PrintRecord\"\n\"/PrintScaling\"\n\"/PrintState\"\n\"/PrintStyle\"\n\"/Printed\"\n\"/PrintingOrder\"\n\"/Private\"\n\"/ProcSet\"\n\"/Process\"\n\"/ProcessBlue\"\n\"/ProcessGreen\"\n\"/ProcessRed\"\n\"/Producer\"\n\"/ProfileCS\"\n\"/ProfileName\"\n\"/Prop_Build\"\n\"/Properties\"\n\"/Proportional\"\n\"/PubSec\"\n\"/Q\"\n\"/QuadPoints\"\n\"/R1\"\n\"/RBGroups\"\n\"/RC\"\n\"/RD\"\n\"/REC\"\n\"/REx\"\n\"/RF\"\n\"/RGB\"\n\"/RI\"\n\"/RICMYKGra\"\n\"/RICMYKIma\"\n\"/RICalGra\"\n\"/RICalIma\"\n\"/RIDefault\"\n\"/RIDevNGra\"\n\"/RIDevNIma\"\n\"/RIRGBGra\"\n\"/RIRGBIma\"\n\"/RL\"\n\"/RM\"\n\"/RV\"\n\"/Range\"\n\"/Rect\"\n\"/Red\"\n\"/Redact\"\n\"/Ref\"\n\"/Reference\"\n\"/Registry\"\n\"/RegistryName\"\n\"/RelativeColorimetric\"\n\"/Rendition\"\n\"/Renditions\"\n\"/Requirements\"\n\"/ResetForm\"\n\"/Resolution\"\n\"/Resources\"\n\"/ReversedChars\"\n\"/RoleMap\"\n\"/Root\"\n\"/Rotate\"\n\"/Round\"\n\"/RoundTrip\"\n\"/RoundtripVersion\"\n\"/Router\"\n\"/Rows\"\n\"/RunLengthDecode\"\n\"/Ryumin\"\n\"/SA\"\n\"/SBDraft\"\n\"/SC\"\n\"/SE\"\n\"/SFSSL\"\n\"/SFTWS\"\n\"/SI\"\n\"/SL\"\n\"/SLA\"\n\"/SM\"\n\"/SMask\"\n\"/SMaskInData\"\n\"/SP\"\n\"/SPS\"\n\"/STL\"\n\"/SU\"\n\"/SW\"\n\"/Saturation\"\n\"/SaveAs\"\n\"/SaveContents\"\n\"/SaveResource\"\n\"/SavedBy\"\n\"/Scaron\"\n\"/Schema\"\n\"/Screen\"\n\"/Sect\"\n\"/SemiCondensed\"\n\"/SemiExpanded\"\n\"/Separation\"\n\"/SeparationInfo\"\n\"/SetOCGState\"\n\"/SettingsFileName\"\n\"/Sh0\"\n\"/Sh1\"\n\"/Shading\"\n\"/ShadingType\"\n\"/Shape\"\n\"/Sig\"\n\"/SigFlags\"\n\"/SigRef\"\n\"/Signature\"\n\"/Signed\"\n\"/SinglePage\"\n\"/Size\"\n\"/SlideShow\"\n\"/SoftLight\"\n\"/Solid\"\n\"/Solidities\"\n\"/SomeName\"\n\"/Sort\"\n\"/Sound\"\n\"/Space\"\n\"/SpaceAfter\"\n\"/SpaceBefore\"\n\"/Span\"\n\"/SpawnTemplate\"\n\"/SpdrArt\"\n\"/SpiderInfo\"\n\"/Split\"\n\"/Spot\"\n\"/Spot1\"\n\"/Spot2\"\n\"/SpotFunction\"\n\"/SpotMap\"\n\"/St\"\n\"/Stamp\"\n\"/StandardImageFileData\"\n\"/Star\"\n\"/Start\"\n\"/StartIndent\"\n\"/StartResource\"\n\"/State\"\n\"/StdCF\"\n\"/StemH\"\n\"/StemV\"\n\"/Stm\"\n\"/StmF\"\n\"/Stop\"\n\"/Story\"\n\"/StrF\"\n\"/StrikeOut\"\n\"/StringItem\"\n\"/StructElem\"\n\"/StructParent\"\n\"/StructParents\"\n\"/StructTreeRoot\"\n\"/Style\"\n\"/SubFilter\"\n\"/SubType\"\n\"/Subdictionary\"\n\"/Subform\"\n\"/Subj\"\n\"/Subject\"\n\"/SubmitForm\"\n\"/SubmitStandalone\"\n\"/SubsetFontsBelow\"\n\"/SubsetFontsRatio\"\n\"/Supplement\"\n\"/Swiss721BT-Black\"\n\"/Switch\"\n\"/T\"\n\"/T1\"\n\"/T1_0\"\n\"/TB\"\n\"/TC\"\n\"/TCS\"\n\"/TF\"\n\"/TID\"\n\"/TK\"\n\"/TM\"\n\"/TO\"\n\"/TOC\"\n\"/TOCI\"\n\"/TOYO#200004pc\"\n\"/TP\"\n\"/TR\"\n\"/TR2\"\n\"/TRUMATCH#206-e\"\n\"/TS\"\n\"/TSV\"\n\"/TT\"\n\"/TT0\"\n\"/TTRefMan\"\n\"/TU\"\n\"/TV\"\n\"/TW\"\n\"/TWS\"\n\"/TWY\"\n\"/Tabs\"\n\"/TagSuspect\"\n\"/TargetCS\"\n\"/Technical\"\n\"/Template\"\n\"/TemplateInstantiated\"\n\"/Templates\"\n\"/Text\"\n\"/TextAlign\"\n\"/TextBox\"\n\"/TextIndent\"\n\"/The\"\n\"/This\"\n\"/Thorn\"\n\"/Thread\"\n\"/Threads\"\n\"/Thumb\"\n\"/Thumbnail\"\n\"/Thumbs\"\n\"/Ti\"\n\"/TiBI\"\n\"/TilingType\"\n\"/Times-BoldItalic\"\n\"/Times-Roman\"\n\"/Title\"\n\"/ToUnicode\"\n\"/Toggle\"\n\"/Trans\"\n\"/TransferFunction\"\n\"/TransformMethod\"\n\"/TransformParams\"\n\"/Transparency\"\n\"/TrapInfo\"\n\"/TrapMagicNumber\"\n\"/TrapRegions\"\n\"/TrapSet\"\n\"/Trapped\"\n\"/Trapping\"\n\"/TrappingDetails\"\n\"/TrappingParameters\"\n\"/TrimBox\"\n\"/True\"\n\"/TrueType\"\n\"/TrustedMode\"\n\"/TwoColumnLeft\"\n\"/Tx\"\n\"/Type\"\n\"/Type0\"\n\"/U3D\"\n\"/UA\"\n\"/UCR\"\n\"/UCR2\"\n\"/UIDOffset\"\n\"/UR\"\n\"/UR3\"\n\"/URI\"\n\"/URL\"\n\"/URLs\"\n\"/Uacute\"\n\"/Ucircumflex\"\n\"/Udieresis\"\n\"/Ugrave\"\n\"/Univers-BoldExt\"\n\"/Unix\"\n\"/Unknown\"\n\"/Usage\"\n\"/UseAttachments\"\n\"/UseNone\"\n\"/UseOC\"\n\"/UseOutlines\"\n\"/UseThumbs\"\n\"/UsedCMYK\"\n\"/UserProperties\"\n\"/UserUnit\"\n\"/V2\"\n\"/VA\"\n\"/VE\"\n\"/VP\"\n\"/Verdana,Bold\"\n\"/Version\"\n\"/Vertical\"\n\"/VeryLastItem\"\n\"/View\"\n\"/ViewerPreferences\"\n\"/Visa\"\n\"/Visible\"\n\"/Volume\"\n\"/W2\"\n\"/WAI\"\n\"/WAN\"\n\"/WMode\"\n\"/WP\"\n\"/WarnockPro-BoldIt\"\n\"/Watermark\"\n\"/WebCapture\"\n\"/Which\"\n\"/WhiteBG\"\n\"/WhitePoint\"\n\"/Widget\"\n\"/Width\"\n\"/Widths\"\n\"/Win\"\n\"/WinAnsiEncoding\"\n\"/Window\"\n\"/Windows\"\n\"/Work#20surface\"\n\"/Workbook\"\n\"/Worksheet\"\n\"/WritingMode\"\n\"/X\"\n\"/X1\"\n\"/XFA\"\n\"/XHeight\"\n\"/XML\"\n\"/XN\"\n\"/XObject\"\n\"/XRef\"\n\"/XRefStm\"\n\"/XStep\"\n\"/XUID\"\n\"/XYZ\"\n\"/Y\"\n\"/YStep\"\n\"/Yacute\"\n\"/Ydieresis\"\n\"/Yellow\"\n\"/Z\"\n\"/Z7KNXbN\"\n\"/ZaDb\"\n\"/ZapfDingbats\"\n\"/Zcaron\"\n\"/Zoom\"\n\"/_No_paragraph_style_\"\n\"/a1\"\n\"/acute\"\n\"/adbe.pkcs7.detached\"\n\"/ampersand\"\n\"/apple\"\n\"/approxequal\"\n\"/asciicircum\"\n\"/asciitilde\"\n\"/asterisk\"\n\"/at\"\n\"/audio#2Fmpeg\"\n\"/b\"\n\"/backslash\"\n\"/bar\"\n\"/blank\"\n\"/braceleft\"\n\"/braceright\"\n\"/bracketleft\"\n\"/bracketright\"\n\"/breve\"\n\"/brokenbar\"\n\"/bullet\"\n\"/c108\"\n\"/cCompKind\"\n\"/cCompQuality\"\n\"/cCompression\"\n\"/cRes\"\n\"/cResolution\"\n\"/ca\"\n\"/caron\"\n\"/cedilla\"\n\"/cent\"\n\"/circumflex\"\n\"/colon\"\n\"/comma\"\n\"/copyright\"\n\"/currency\"\n\"/dagger\"\n\"/daggerdbl\"\n\"/degree\"\n\"/deviceNumber\"\n\"/dieresis\"\n\"/divide\"\n\"/dollar\"\n\"/dotaccent\"\n\"/dotlessi\"\n\"/dotlessj\"\n\"/eight\"\n\"/ellipsis\"\n\"/emdash\"\n\"/endash\"\n\"/equal\"\n\"/eth\"\n\"/exclam\"\n\"/exclamdown\"\n\"/f\"\n\"/ff\"\n\"/ffi\"\n\"/ffl\"\n\"/fi\"\n\"/five\"\n\"/fl\"\n\"/florin\"\n\"/four\"\n\"/fraction\"\n\"/gCompKind\"\n\"/gCompQuality\"\n\"/gCompression\"\n\"/gRes\"\n\"/gResolution\"\n\"/germandbls\"\n\"/go1\"\n\"/grave\"\n\"/greater\"\n\"/greaterequal\"\n\"/guillemotleft\"\n\"/guillemotright\"\n\"/guilsinglleft\"\n\"/guilsinglright\"\n\"/hungarumlaut\"\n\"/hyphen\"\n\"/iacute\"\n\"/idieresis\"\n\"/igrave\"\n\"/infinity\"\n\"/integral\"\n\"/j\"\n\"/k\"\n\"/less\"\n\"/lessequal\"\n\"/logicalnot\"\n\"/lozenge\"\n\"/lt#20blue\"\n\"/mCompKind\"\n\"/mCompression\"\n\"/mRes\"\n\"/mResolution\"\n\"/macron\"\n\"/minus\"\n\"/mu\"\n\"/multiply\"\n\"/n\"\n\"/n0\"\n\"/nine\"\n\"/notequal\"\n\"/ntilde\"\n\"/numbersign\"\n\"/o\"\n\"/ogonek\"\n\"/one\"\n\"/onehalf\"\n\"/onequarter\"\n\"/onesuperior\"\n\"/op\"\n\"/ordfeminine\"\n\"/ordmasculine\"\n\"/p\"\n\"/pageH\"\n\"/pageV\"\n\"/paragraph\"\n\"/parenleft\"\n\"/parenright\"\n\"/partialdiff\"\n\"/pdf\"\n\"/pdfx\"\n\"/percent\"\n\"/period\"\n\"/periodcentered\"\n\"/perthousand\"\n\"/pi\"\n\"/plus\"\n\"/plusminus\"\n\"/pms#208400\"\n\"/printX\"\n\"/product\"\n\"/question\"\n\"/questiondown\"\n\"/quotedbl\"\n\"/quotedblbase\"\n\"/quotedblleft\"\n\"/quotedblright\"\n\"/quoteleft\"\n\"/quoteright\"\n\"/quotesinglbase\"\n\"/quotesingle\"\n\"/r\"\n\"/radical\"\n\"/registered\"\n\"/ring\"\n\"/s\"\n\"/s1\"\n\"/sd1\"\n\"/sd2\"\n\"/section\"\n\"/semicolon\"\n\"/seven\"\n\"/six\"\n\"/slash\"\n\"/sterling\"\n\"/summation\"\n\"/thinspace\"\n\"/three\"\n\"/threequarters\"\n\"/threesuperior\"\n\"/tilde\"\n\"/trademark\"\n\"/two\"\n\"/twosuperior\"\n\"/u\"\n\"/underscore\"\n\"/v\"\n\"/w\"\n\"/y1\"\n\"/yen\"\n\"/yes\"\n\"/zero\"\n\"0 R\"\n\"1\"\n\"1.0\"\n\"<\"\n\"<<\"\n\">\"\n\">>\"\n\"Adobe.PPKLite\"\n\"Adobe.PubSec\"\n\"B*\"\n\"BDC\"\n\"BI\"\n\"BMC\"\n\"BT\"\n\"BX\"\n\"CS\"\n\"DP\"\n\"Do\"\n\"EI\"\n\"EMC\"\n\"ET\"\n\"EX\"\n\"Entrust.PPKEF\"\n\"ID\"\n\"MP\"\n\"R\"\n\"T*\"\n\"TJ\"\n\"TL\"\n\"Tc\"\n\"Td\"\n\"Tf\"\n\"Tj\"\n\"Tm\"\n\"Tr\"\n\"Ts\"\n\"Tw\"\n\"W*\"\n\"[\"\n\"[0.0 0.0 0.0 0.0 0.0 0.0]\"\n\"[1 1 1]\"\n\"[1.0 -1.0 1.0 -1.0]\"\n\"[1.0 -1.0]\"\n\"\\\\\"\n\"]\"\n\"abs\"\n\"adbe.pkcs7.s3\"\n\"adbe.pkcs7.s4\"\n\"adbe.pkcs7.s5\"\n\"add\"\n\"and\"\n\"atan\"\n\"begin\"\n\"beginarrangedfont\"\n\"beginbfchar\"\n\"begincidrange\"\n\"begincmap\"\n\"begincodespacerange\"\n\"beginnotdefchar\"\n\"beginnotdefrange\"\n\"beginusematrix\"\n\"bitshift\"\n\"ceiling\"\n\"cm\"\n\"copy\"\n\"cos\"\n\"cvi\"\n\"cvr\"\n\"d0\"\n\"d1\"\n\"div\"\n\"dup\"\n\"end\"\n\"endarrangedfont\"\n\"endbfchar\"\n\"endcidrange\"\n\"endcmap\"\n\"endcodespacerange\"\n\"endnotdefchar\"\n\"endnotdefrange\"\n\"endobj\"\n\"endstream\"\n\"endusematrix\"\n\"eq\"\n\"exch\"\n\"exp\"\n\"f*\"\n\"false\"\n\"findresource\"\n\"floor\"\n\"ge\"\n\"gs\"\n\"gt\"\n\"idiv\"\n\"if\"\n\"ifelse\"\n\"index\"\n\"le\"\n\"ln\"\n\"log\"\n\"lt\"\n\"mod\"\n\"mul\"\n\"ne\"\n\"neg\"\n\"not\"\n\"null\"\n\"obj\"\n\"or\"\n\"page\"\n\"pop\"\n\"re\"\n\"rg\"\n\"ri\"\n\"roll\"\n\"round\"\n\"sin\"\n\"sqrt\"\n\"startxref\"\n\"stream\"\n\"sub\"\n\"trailer\"\n\"true\"\n\"truncate\"\n\"usecmap\"\n\"usefont\"\n\"xor\"\n\"xref\"\n\"{\"\n\"}\"\n"
  },
  {
    "path": "testcases/_extras/png.dict",
    "content": "#\n# AFL dictionary for PNG images\n# -----------------------------\n#\n# Just the basic, standard-originating sections; does not include vendor\n# extensions.\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nheader_png=\"\\x89PNG\\x0d\\x0a\\x1a\\x0a\"\n\nsection_IDAT=\"IDAT\"\nsection_IEND=\"IEND\"\nsection_IHDR=\"IHDR\"\nsection_PLTE=\"PLTE\"\nsection_bKGD=\"bKGD\"\nsection_cHRM=\"cHRM\"\nsection_fRAc=\"fRAc\"\nsection_gAMA=\"gAMA\"\nsection_gIFg=\"gIFg\"\nsection_gIFt=\"gIFt\"\nsection_gIFx=\"gIFx\"\nsection_hIST=\"hIST\"\nsection_iCCP=\"iCCP\"\nsection_iTXt=\"iTXt\"\nsection_oFFs=\"oFFs\"\nsection_pCAL=\"pCAL\"\nsection_pHYs=\"pHYs\"\nsection_sBIT=\"sBIT\"\nsection_sCAL=\"sCAL\"\nsection_sPLT=\"sPLT\"\nsection_sRGB=\"sRGB\"\nsection_sTER=\"sTER\"\nsection_tEXt=\"tEXt\"\nsection_tIME=\"tIME\"\nsection_tRNS=\"tRNS\"\nsection_zTXt=\"zTXt\"\n"
  },
  {
    "path": "testcases/_extras/sql.dict",
    "content": "#\n# AFL dictionary for SQL\n# ----------------------\n#\n# Modeled based on SQLite documentation, contains some number of SQLite\n# extensions. Other dialects of SQL may benefit from customized dictionaries.\n#\n# If you append @1 to the file name when loading this dictionary, afl-fuzz\n# will also additionally load a selection of pragma keywords that are very\n# specific to SQLite (and are probably less interesting from the security\n# standpoint, because they are usually not allowed in non-privileged\n# contexts).\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nfunction_abs=\" abs(1)\"\nfunction_avg=\" avg(1)\"\nfunction_changes=\" changes()\"\nfunction_char=\" char(1)\"\nfunction_coalesce=\" coalesce(1,1)\"\nfunction_count=\" count(1)\"\nfunction_date=\" date(1,1,1)\"\nfunction_datetime=\" datetime(1,1,1)\"\nfunction_decimal=\" decimal(1,1)\"\nfunction_glob=\" glob(1,1)\"\nfunction_group_concat=\" group_concat(1,1)\"\nfunction_hex=\" hex(1)\"\nfunction_ifnull=\" ifnull(1,1)\"\nfunction_instr=\" instr(1,1)\"\nfunction_julianday=\" julianday(1,1,1)\"\nfunction_last_insert_rowid=\" last_insert_rowid()\"\nfunction_length=\" length(1)\"\nfunction_like=\" like(1,1)\"\nfunction_likelihood=\" likelihood(1,1)\"\nfunction_likely=\" likely(1)\"\nfunction_load_extension=\" load_extension(1,1)\"\nfunction_lower=\" lower(1)\"\nfunction_ltrim=\" ltrim(1,1)\"\nfunction_max=\" max(1,1)\"\nfunction_min=\" min(1,1)\"\nfunction_nullif=\" nullif(1,1)\"\nfunction_printf=\" printf(1,1)\"\nfunction_quote=\" quote(1)\"\nfunction_random=\" random()\"\nfunction_randomblob=\" randomblob(1)\"\nfunction_replace=\" replace(1,1,1)\"\nfunction_round=\" round(1,1)\"\nfunction_rtrim=\" rtrim(1,1)\"\nfunction_soundex=\" soundex(1)\"\nfunction_sqlite_compileoption_get=\" sqlite_compileoption_get(1)\"\nfunction_sqlite_compileoption_used=\" sqlite_compileoption_used(1)\"\nfunction_sqlite_source_id=\" sqlite_source_id()\"\nfunction_sqlite_version=\" sqlite_version()\"\nfunction_strftime=\" strftime(1,1,1,1)\"\nfunction_substr=\" substr(1,1,1)\"\nfunction_sum=\" sum(1)\"\nfunction_time=\" time(1,1,1)\"\nfunction_total=\" total(1)\"\nfunction_total_changes=\" total_changes()\"\nfunction_trim=\" trim(1,1)\"\nfunction_typeof=\" typeof(1)\"\nfunction_unicode=\" unicode(1)\"\nfunction_unlikely=\" unlikely(1)\"\nfunction_upper=\" upper(1)\"\nfunction_varchar=\" varchar(1)\"\nfunction_zeroblob=\" zeroblob(1)\"\n\nkeyword_ABORT=\"ABORT\"\nkeyword_ACTION=\"ACTION\"\nkeyword_ADD=\"ADD\"\nkeyword_AFTER=\"AFTER\"\nkeyword_ALL=\"ALL\"\nkeyword_ALTER=\"ALTER\"\nkeyword_ANALYZE=\"ANALYZE\"\nkeyword_AND=\"AND\"\nkeyword_AS=\"AS\"\nkeyword_ASC=\"ASC\"\nkeyword_ATTACH=\"ATTACH\"\nkeyword_AUTOINCREMENT=\"AUTOINCREMENT\"\nkeyword_BEFORE=\"BEFORE\"\nkeyword_BEGIN=\"BEGIN\"\nkeyword_BETWEEN=\"BETWEEN\"\nkeyword_BY=\"BY\"\nkeyword_CASCADE=\"CASCADE\"\nkeyword_CASE=\"CASE\"\nkeyword_CAST=\"CAST\"\nkeyword_CHECK=\"CHECK\"\nkeyword_COLLATE=\"COLLATE\"\nkeyword_COLUMN=\"COLUMN\"\nkeyword_COMMIT=\"COMMIT\"\nkeyword_CONFLICT=\"CONFLICT\"\nkeyword_CONSTRAINT=\"CONSTRAINT\"\nkeyword_CREATE=\"CREATE\"\nkeyword_CROSS=\"CROSS\"\nkeyword_CURRENT_DATE=\"CURRENT_DATE\"\nkeyword_CURRENT_TIME=\"CURRENT_TIME\"\nkeyword_CURRENT_TIMESTAMP=\"CURRENT_TIMESTAMP\"\nkeyword_DATABASE=\"DATABASE\"\nkeyword_DEFAULT=\"DEFAULT\"\nkeyword_DEFERRABLE=\"DEFERRABLE\"\nkeyword_DEFERRED=\"DEFERRED\"\nkeyword_DELETE=\"DELETE\"\nkeyword_DESC=\"DESC\"\nkeyword_DETACH=\"DETACH\"\nkeyword_DISTINCT=\"DISTINCT\"\nkeyword_DROP=\"DROP\"\nkeyword_EACH=\"EACH\"\nkeyword_ELSE=\"ELSE\"\nkeyword_END=\"END\"\nkeyword_ESCAPE=\"ESCAPE\"\nkeyword_EXCEPT=\"EXCEPT\"\nkeyword_EXCLUSIVE=\"EXCLUSIVE\"\nkeyword_EXISTS=\"EXISTS\"\nkeyword_EXPLAIN=\"EXPLAIN\"\nkeyword_FAIL=\"FAIL\"\nkeyword_FOR=\"FOR\"\nkeyword_FOREIGN=\"FOREIGN\"\nkeyword_FROM=\"FROM\"\nkeyword_FULL=\"FULL\"\nkeyword_GLOB=\"GLOB\"\nkeyword_GROUP=\"GROUP\"\nkeyword_HAVING=\"HAVING\"\nkeyword_IF=\"IF\"\nkeyword_IGNORE=\"IGNORE\"\nkeyword_IMMEDIATE=\"IMMEDIATE\"\nkeyword_IN=\"IN\"\nkeyword_INDEX=\"INDEX\"\nkeyword_INDEXED=\"INDEXED\"\nkeyword_INITIALLY=\"INITIALLY\"\nkeyword_INNER=\"INNER\"\nkeyword_INSERT=\"INSERT\"\nkeyword_INSTEAD=\"INSTEAD\"\nkeyword_INTERSECT=\"INTERSECT\"\nkeyword_INTO=\"INTO\"\nkeyword_IS=\"IS\"\nkeyword_ISNULL=\"ISNULL\"\nkeyword_JOIN=\"JOIN\"\nkeyword_KEY=\"KEY\"\nkeyword_LEFT=\"LEFT\"\nkeyword_LIKE=\"LIKE\"\nkeyword_LIMIT=\"LIMIT\"\nkeyword_MATCH=\"MATCH\"\nkeyword_NATURAL=\"NATURAL\"\nkeyword_NO=\"NO\"\nkeyword_NOT=\"NOT\"\nkeyword_NOTNULL=\"NOTNULL\"\nkeyword_NULL=\"NULL\"\nkeyword_OF=\"OF\"\nkeyword_OFFSET=\"OFFSET\"\nkeyword_ON=\"ON\"\nkeyword_OR=\"OR\"\nkeyword_ORDER=\"ORDER\"\nkeyword_OUTER=\"OUTER\"\nkeyword_PLAN=\"PLAN\"\nkeyword_PRAGMA=\"PRAGMA\"\nkeyword_PRIMARY=\"PRIMARY\"\nkeyword_QUERY=\"QUERY\"\nkeyword_RAISE=\"RAISE\"\nkeyword_RECURSIVE=\"RECURSIVE\"\nkeyword_REFERENCES=\"REFERENCES\"\nkeyword_REGEXP=\"REGEXP\"\nkeyword_REINDEX=\"REINDEX\"\nkeyword_RELEASE=\"RELEASE\"\nkeyword_RENAME=\"RENAME\"\nkeyword_REPLACE=\"REPLACE\"\nkeyword_RESTRICT=\"RESTRICT\"\nkeyword_RIGHT=\"RIGHT\"\nkeyword_ROLLBACK=\"ROLLBACK\"\nkeyword_ROW=\"ROW\"\nkeyword_SAVEPOINT=\"SAVEPOINT\"\nkeyword_SELECT=\"SELECT\"\nkeyword_SET=\"SET\"\nkeyword_TABLE=\"TABLE\"\nkeyword_TEMP=\"TEMP\"\nkeyword_TEMPORARY=\"TEMPORARY\"\nkeyword_THEN=\"THEN\"\nkeyword_TO=\"TO\"\nkeyword_TRANSACTION=\"TRANSACTION\"\nkeyword_TRIGGER=\"TRIGGER\"\nkeyword_UNION=\"UNION\"\nkeyword_UNIQUE=\"UNIQUE\"\nkeyword_UPDATE=\"UPDATE\"\nkeyword_USING=\"USING\"\nkeyword_VACUUM=\"VACUUM\"\nkeyword_VALUES=\"VALUES\"\nkeyword_VIEW=\"VIEW\"\nkeyword_VIRTUAL=\"VIRTUAL\"\nkeyword_WHEN=\"WHEN\"\nkeyword_WHERE=\"WHERE\"\nkeyword_WITH=\"WITH\"\nkeyword_WITHOUT=\"WITHOUT\"\n\noperator_concat=\" || \"\noperator_ebove_eq=\" >=\"\n\nsnippet_1eq1=\" 1=1\"\nsnippet_at=\" @1\"\nsnippet_backticks=\" `a`\"\nsnippet_blob=\" blob\"\nsnippet_brackets=\" [a]\"\nsnippet_colon=\" :1\"\nsnippet_comment=\" /* */\"\nsnippet_date=\"2001-01-01\"\nsnippet_dollar=\" $1\"\nsnippet_dotref=\" a.b\"\nsnippet_fmtY=\"%Y\"\nsnippet_int=\" int\"\nsnippet_neg1=\" -1\"\nsnippet_pair=\" a,b\"\nsnippet_parentheses=\" (1)\"\nsnippet_plus2days=\"+2 days\"\nsnippet_qmark=\" ?1\"\nsnippet_semicolon=\" ;\"\nsnippet_star=\" *\"\nsnippet_string_pair=\" \\\"a\\\",\\\"b\\\"\"\n\nstring_dbl_q=\" \\\"a\\\"\"\nstring_escaped_q=\" 'a''b'\"\nstring_single_q=\" 'a'\"\n\npragma_application_id@1=\" application_id\"\npragma_auto_vacuum@1=\" auto_vacuum\"\npragma_automatic_index@1=\" automatic_index\"\npragma_busy_timeout@1=\" busy_timeout\"\npragma_cache_size@1=\" cache_size\"\npragma_cache_spill@1=\" cache_spill\"\npragma_case_sensitive_like@1=\" case_sensitive_like\"\npragma_checkpoint_fullfsync@1=\" checkpoint_fullfsync\"\npragma_collation_list@1=\" collation_list\"\npragma_compile_options@1=\" compile_options\"\npragma_count_changes@1=\" count_changes\"\npragma_data_store_directory@1=\" data_store_directory\"\npragma_database_list@1=\" database_list\"\npragma_default_cache_size@1=\" default_cache_size\"\npragma_defer_foreign_keys@1=\" defer_foreign_keys\"\npragma_empty_result_callbacks@1=\" empty_result_callbacks\"\npragma_encoding@1=\" encoding\"\npragma_foreign_key_check@1=\" foreign_key_check\"\npragma_foreign_key_list@1=\" foreign_key_list\"\npragma_foreign_keys@1=\" foreign_keys\"\npragma_freelist_count@1=\" freelist_count\"\npragma_full_column_names@1=\" full_column_names\"\npragma_fullfsync@1=\" fullfsync\"\npragma_ignore_check_constraints@1=\" ignore_check_constraints\"\npragma_incremental_vacuum@1=\" incremental_vacuum\"\npragma_index_info@1=\" index_info\"\npragma_index_list@1=\" index_list\"\npragma_integrity_check@1=\" integrity_check\"\npragma_journal_mode@1=\" journal_mode\"\npragma_journal_size_limit@1=\" journal_size_limit\"\npragma_legacy_file_format@1=\" legacy_file_format\"\npragma_locking_mode@1=\" locking_mode\"\npragma_max_page_count@1=\" max_page_count\"\npragma_mmap_size@1=\" mmap_size\"\npragma_page_count@1=\" page_count\"\npragma_page_size@1=\" page_size\"\npragma_parser_trace@1=\" parser_trace\"\npragma_query_only@1=\" query_only\"\npragma_quick_check@1=\" quick_check\"\npragma_read_uncommitted@1=\" read_uncommitted\"\npragma_recursive_triggers@1=\" recursive_triggers\"\npragma_reverse_unordered_selects@1=\" reverse_unordered_selects\"\npragma_schema_version@1=\" schema_version\"\npragma_secure_delete@1=\" secure_delete\"\npragma_short_column_names@1=\" short_column_names\"\npragma_shrink_memory@1=\" shrink_memory\"\npragma_soft_heap_limit@1=\" soft_heap_limit\"\npragma_stats@1=\" stats\"\npragma_synchronous@1=\" synchronous\"\npragma_table_info@1=\" table_info\"\npragma_temp_store@1=\" temp_store\"\npragma_temp_store_directory@1=\" temp_store_directory\"\npragma_threads@1=\" threads\"\npragma_user_version@1=\" user_version\"\npragma_vdbe_addoptrace@1=\" vdbe_addoptrace\"\npragma_vdbe_debug@1=\" vdbe_debug\"\npragma_vdbe_listing@1=\" vdbe_listing\"\npragma_vdbe_trace@1=\" vdbe_trace\"\npragma_wal_autocheckpoint@1=\" wal_autocheckpoint\"\npragma_wal_checkpoint@1=\" wal_checkpoint\"\npragma_writable_schema@1=\" writable_schema\"\n"
  },
  {
    "path": "testcases/_extras/tiff.dict",
    "content": "#\n# AFL dictionary for TIFF images\n# ------------------------------\n#\n# Just the basic, standard-originating sections; does not include vendor\n# extensions.\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nheader_ii=\"II*\\x00\"\nheader_mm=\"MM\\x00*\"\n\nsection_100=\"\\x00\\x01\"\nsection_101=\"\\x01\\x01\"\nsection_102=\"\\x02\\x01\"\nsection_103=\"\\x03\\x01\"\nsection_106=\"\\x06\\x01\"\nsection_107=\"\\x07\\x01\"\nsection_10D=\"\\x0d\\x01\"\nsection_10E=\"\\x0e\\x01\"\nsection_10F=\"\\x0f\\x01\"\nsection_110=\"\\x10\\x01\"\nsection_111=\"\\x11\\x01\"\nsection_112=\"\\x12\\x01\"\nsection_115=\"\\x15\\x01\"\nsection_116=\"\\x16\\x01\"\nsection_117=\"\\x17\\x01\"\nsection_11A=\"\\x1a\\x01\"\nsection_11B=\"\\x1b\\x01\"\nsection_11C=\"\\x1c\\x01\"\nsection_11D=\"\\x1d\\x01\"\nsection_11E=\"\\x1e\\x01\"\nsection_11F=\"\\x1f\\x01\"\nsection_122=\"\\\"\\x01\"\nsection_123=\"#\\x01\"\nsection_124=\"$\\x01\"\nsection_125=\"%\\x01\"\nsection_128=\"(\\x01\"\nsection_129=\")\\x01\"\nsection_12D=\"-\\x01\"\nsection_131=\"1\\x01\"\nsection_132=\"2\\x01\"\nsection_13B=\";\\x01\"\nsection_13C=\"<\\x01\"\nsection_13D=\"=\\x01\"\nsection_13E=\">\\x01\"\nsection_13F=\"?\\x01\"\nsection_140=\"@\\x01\"\nsection_FE=\"\\xfe\\x00\"\nsection_FF=\"\\xff\\x00\"\n"
  },
  {
    "path": "testcases/_extras/webp.dict",
    "content": "#\n# AFL dictionary for WebP images\n# ------------------------------\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nheader_RIFF=\"RIFF\"\nheader_WEBP=\"WEBP\"\n\nsection_ALPH=\"ALPH\"\nsection_ANIM=\"ANIM\"\nsection_ANMF=\"ANMF\"\nsection_EXIF=\"EXIF\"\nsection_FRGM=\"FRGM\"\nsection_ICCP=\"ICCP\"\nsection_VP8=\"VP8 \"\nsection_VP8L=\"VP8L\"\nsection_VP8X=\"VP8X\"\nsection_XMP=\"XMP \"\n"
  },
  {
    "path": "testcases/_extras/xml.dict",
    "content": "#\n# AFL dictionary for XML\n# ----------------------\n#\n# Several basic syntax elements and attributes, modeled on libxml2.\n#\n# Created by Michal Zalewski <lcamtuf@google.com>\n#\n\nattr_encoding=\" encoding=\\\"1\\\"\"\nattr_generic=\" a=\\\"1\\\"\"\nattr_href=\" href=\\\"1\\\"\"\nattr_standalone=\" standalone=\\\"no\\\"\"\nattr_version=\" version=\\\"1\\\"\"\nattr_xml_base=\" xml:base=\\\"1\\\"\"\nattr_xml_id=\" xml:id=\\\"1\\\"\"\nattr_xml_lang=\" xml:lang=\\\"1\\\"\"\nattr_xml_space=\" xml:space=\\\"1\\\"\"\nattr_xmlns=\" xmlns=\\\"1\\\"\"\n\nentity_builtin=\"&lt;\"\nentity_decimal=\"&#1;\"\nentity_external=\"&a;\"\nentity_hex=\"&#x1;\"\n\nstring_any=\"ANY\"\nstring_brackets=\"[]\"\nstring_cdata=\"CDATA\"\nstring_col_fallback=\":fallback\"\nstring_col_generic=\":a\"\nstring_col_include=\":include\"\nstring_dashes=\"--\"\nstring_empty=\"EMPTY\"\nstring_empty_dblquotes=\"\\\"\\\"\"\nstring_empty_quotes=\"''\"\nstring_entities=\"ENTITIES\"\nstring_entity=\"ENTITY\"\nstring_fixed=\"#FIXED\"\nstring_id=\"ID\"\nstring_idref=\"IDREF\"\nstring_idrefs=\"IDREFS\"\nstring_implied=\"#IMPLIED\"\nstring_nmtoken=\"NMTOKEN\"\nstring_nmtokens=\"NMTOKENS\"\nstring_notation=\"NOTATION\"\nstring_parentheses=\"()\"\nstring_pcdata=\"#PCDATA\"\nstring_percent=\"%a\"\nstring_public=\"PUBLIC\"\nstring_required=\"#REQUIRED\"\nstring_schema=\":schema\"\nstring_system=\"SYSTEM\"\nstring_ucs4=\"UCS-4\"\nstring_utf16=\"UTF-16\"\nstring_utf8=\"UTF-8\"\nstring_xmlns=\"xmlns:\"\n\ntag_attlist=\"<!ATTLIST\"\ntag_cdata=\"<![CDATA[\"\ntag_close=\"</a>\"\ntag_doctype=\"<!DOCTYPE\"\ntag_element=\"<!ELEMENT\"\ntag_entity=\"<!ENTITY\"\ntag_ignore=\"<![IGNORE[\"\ntag_include=\"<![INCLUDE[\"\ntag_notation=\"<!NOTATION\"\ntag_open=\"<a>\"\ntag_open_close=\"<a />\"\ntag_open_exclamation=\"<!\"\ntag_open_q=\"<?\"\ntag_sq2_close=\"]]>\"\ntag_xml_q=\"<?xml?>\"\n"
  },
  {
    "path": "testcases/archives/common/ar/small_archive.a",
    "content": "!<arch>\nlimerick/       1415337776  500   500   100640  191       `\nThere was a young man from Japan\nWhose limericks never would scan.\nWhen asked why that was,\nHe replied \"It's because\nI always try to cram as many words into the last line as I possibly can.\"\n\n"
  },
  {
    "path": "testcases/others/js/small_script.js",
    "content": "if (1==1) eval('1');"
  },
  {
    "path": "testcases/others/rtf/small_document.rtf",
    "content": "{\\rtf1\\pard Test\\par}"
  },
  {
    "path": "testcases/others/sql/simple_queries.sql",
    "content": "create table t1(one smallint);\ninsert into t1 values(1);\nselect * from t1;\n"
  },
  {
    "path": "testcases/others/text/hello_world.txt",
    "content": "hello\n"
  },
  {
    "path": "testcases/others/xml/small_document.xml",
    "content": "<a b=\"c\">d</a>\n"
  },
  {
    "path": "types.h",
    "content": "/*\n   american fuzzy lop - type definitions and minor macros\n   ------------------------------------------------------\n\n   Written and maintained by Michal Zalewski <lcamtuf@google.com>\n\n   Copyright 2013, 2014, 2015 Google Inc. All rights reserved.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at:\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\n */\n\n#ifndef _HAVE_TYPES_H\n#define _HAVE_TYPES_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\ntypedef uint8_t  u8;\ntypedef uint16_t u16;\ntypedef uint32_t u32;\n\n/*\n\n   Ugh. There is an unintended compiler / glibc #include glitch caused by\n   combining the u64 type an %llu in format strings, necessitating a workaround.\n\n   In essence, the compiler is always looking for 'unsigned long long' for %llu.\n   On 32-bit systems, the u64 type (aliased to uint64_t) is expanded to\n   'unsigned long long' in <bits/types.h>, so everything checks out.\n\n   But on 64-bit systems, it is #ifdef'ed in the same file as 'unsigned long'.\n   Now, it only happens in circumstances where the type happens to have the\n   expected bit width, *but* the compiler does not know that... and complains\n   about 'unsigned long' being unsafe to pass to %llu.\n\n */\n\n#ifdef __x86_64__\ntypedef unsigned long long u64;\n#else\ntypedef uint64_t u64;\n#endif /* ^sizeof(...) */\n\ntypedef int8_t   s8;\ntypedef int16_t  s16;\ntypedef int32_t  s32;\ntypedef int64_t  s64;\n\n#ifndef MIN\n#  define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))\n#  define MAX(_a,_b) ((_a) > (_b) ? (_a) : (_b))\n#endif /* !MIN */\n\n#define SWAP16(_x) ({ \\\n    u16 _ret = (_x); \\\n    (u16)((_ret << 8) | (_ret >> 8)); \\\n  })\n\n#define SWAP32(_x) ({ \\\n    u32 _ret = (_x); \\\n    (u32)((_ret << 24) | (_ret >> 24) | \\\n          ((_ret << 8) & 0x00FF0000) | \\\n          ((_ret >> 8) & 0x0000FF00)); \\\n  })\n\n#define R(x) (random() % (x))\n\n#define STRINGIFY_INTERNAL(x) #x\n#define STRINGIFY(x) STRINGIFY_INTERNAL(x)\n\n#define MEM_BARRIER() \\\n  asm volatile(\"\" ::: \"memory\")\n\n#endif /* ! _HAVE_TYPES_H */\n"
  }
]