about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile9
l---------PATCHES1
-rw-r--r--README.md6
-rw-r--r--TODO.md2
-rw-r--r--docs/Changelog.md1
-rw-r--r--docs/binaryonly_fuzzing.md45
-rw-r--r--gcc_plugin/Makefile3
-rw-r--r--include/config.h3
-rw-r--r--llvm_mode/Makefile5
-rw-r--r--qemu_mode/README.persistent.md40
-rw-r--r--src/afl-fuzz-one.c4
-rwxr-xr-xtest/test.sh23
-rw-r--r--unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py6
-rw-r--r--unicorn_mode/patches/afl-unicorn-common.h48
-rw-r--r--unicorn_mode/patches/afl-unicorn-cpu-inl.h293
-rw-r--r--unicorn_mode/patches/afl-unicorn-cpu-translate-inl.h57
-rw-r--r--unicorn_mode/patches/afl-unicorn-tcg-op-inl.h59
-rw-r--r--unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h176
-rw-r--r--unicorn_mode/patches/compcov.diff251
-rw-r--r--unicorn_mode/patches/patches.diff107
-rw-r--r--unicorn_mode/samples/c/harness.c21
-rw-r--r--unicorn_mode/samples/persistent/harness.c12
22 files changed, 124 insertions, 1048 deletions
diff --git a/Makefile b/Makefile
index 5af8444a..ea991cd3 100644
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,9 @@
 
 # For Heiko:
 #TEST_MMAP=1
+# the hash character is treated differently in different make versions
+# so use a variable for '#'
+HASH=\#
 
 PREFIX     ?= /usr/local
 BIN_PATH    = $(PREFIX)/bin
@@ -24,7 +27,7 @@ MISC_PATH   = $(PREFIX)/share/afl
 MAN_PATH    = $(PREFIX)/man/man8
 
 PROGNAME    = afl
-VERSION     = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
+VERSION     = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
 
 # PROGS intentionally omit afl-as, which gets installed elsewhere.
 
@@ -127,7 +130,7 @@ endif
 
 COMM_HDR    = include/alloc-inl.h include/config.h include/debug.h include/types.h
 
-ifeq "$(shell echo '\#include <Python.h>@int main() {return 0; }' | tr @ '\n' | $(CC) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
+ifeq "$(shell echo '$(HASH)include <Python.h>@int main() {return 0; }' | tr @ '\n' | $(CC) -x c - -o .test $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1"
 	PYTHON_OK=1
 	PYFLAGS=-DUSE_PYTHON $(PYTHON_INCLUDE) $(LDFLAGS) $(PYTHON_LIB) -DPYTHON_VERSION="\"$(PYTHON_VERSION)\""
 else
@@ -145,7 +148,7 @@ ifdef STATIC
   LDFLAGS += -lm -lrt -lpthread -lz -lutil
 endif
 
-ifeq "$(shell echo '\#include <sys/ipc.h>@\#include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
+ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
 	SHMAT_OK=1
 else
 	SHMAT_OK=0
diff --git a/PATCHES b/PATCHES
deleted file mode 120000
index b34f8c1d..00000000
--- a/PATCHES
+++ /dev/null
@@ -1 +0,0 @@
-docs/PATCHES
\ No newline at end of file
diff --git a/README.md b/README.md
index 4d77f1ae..8c759779 100644
--- a/README.md
+++ b/README.md
@@ -62,11 +62,11 @@
 
   | Feature/Instrumentation | afl-gcc | llvm_mode | gcc_plugin | qemu_mode        | unicorn_mode |
   | ----------------------- |:-------:|:---------:|:----------:|:----------------:|:------------:|
-  | NeverZero               |    x    |     x(1)  |      (2)   |          x       |       x      |
+  | NeverZero               |    x    |     x(1)  |      (2)   |         x        |       x      |
   | Persistent mode         |         |     x     |     x      | x86[_64]/arm[64] |       x      |
   | laf-intel / CompCov     |         |     x     |            | x86[_64]/arm[64] | x86[_64]/arm |
   | CmpLog                  |         |     x     |            | x86[_64]/arm[64] |              |
-  | Whitelist               |         |     x     |     x      |                  |              |
+  | Whitelist               |         |     x     |     x      |        (x)(3)    |              |
   | InsTrim                 |         |     x     |            |                  |              |
 
   neverZero:
@@ -75,6 +75,8 @@
 
   (2) gcc creates non-performant code, hence it is disabled in gcc_plugin
 
+  (3) partially via AFL_CODE_START/AFL_CODE_END
+
   So all in all this is the best-of afl that is currently out there :-)
 
   For new versions and additional information, check out:
diff --git a/TODO.md b/TODO.md
index 39e219ff..02850276 100644
--- a/TODO.md
+++ b/TODO.md
@@ -18,7 +18,7 @@ qemu_mode:
  - instrim for QEMU mode via static analysis (with r2pipe? or angr?)
    Idea: The static analyzer outputs a map in which each edge that must be
    skipped is marked with 1. QEMU loads it at startup in the parent process.
- - rename qemu specific envs to AFL_QEMU (espec. AFL_ENTRYPOINT)
+ - rename qemu specific envs to AFL_QEMU (AFL_ENTRYPOINT, AFL_CODE_START/END, AFL_COMPCOV_LEVEL?)
  - add AFL_QEMU_EXITPOINT (maybe multiple?)
  - add/implement AFL_QEMU_INST_LIBLIST and AFL_QEMU_NOINST_PROGRAM
 
diff --git a/docs/Changelog.md b/docs/Changelog.md
index f6e751e0..e0bb500a 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -21,6 +21,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
      - all Python 2+3 versions supported now
      - changed execs_per_sec in fuzzer_stats from "current" execs per second
        (which is pointless) to total execs per second
+     - bugfix for dictionary insert stage count (fix via Google repo PR)
   - afl-clang-fast:
      - show in the help output for which llvm version it was compiled for
      - now does not need to be recompiled between trace-pc and pass
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index ff98ed00..e49c9b3e 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -8,10 +8,11 @@
 
   The following is a description of how these binaries can be fuzzed with afl++
 
-  !!!!!
-  TL;DR: try DYNINST with afl-dyninst. If it produces too many crashes then
-         use afl -Q qemu_mode, or better: use both in parallel.
-  !!!!!
+## TL;DR:
+
+  qemu_mode in persistent mode is the fastest - if the stability is
+  high enough. Otherwise try retrowrite, afl-dyninst and if these
+  fail too then standard qemu_mode with AFL_ENTRYPOINT to where you need it.
 
 
 ## QEMU
@@ -19,11 +20,19 @@
   Qemu is the "native" solution to the program.
   It is available in the ./qemu_mode/ directory and once compiled it can
   be accessed by the afl-fuzz -Q command line option.
-  The speed decrease is at about 50%.
   It is the easiest to use alternative and even works for cross-platform binaries.
 
+  The speed decrease is at about 50%.
+  However various options exist to increase the speed:
+   - using AFL_ENTRYPOINT to move the forkserver to a later basic block in
+     the binary (+5-10% speed)
+   - using persistent mode [qemu_mode/README.persistent.md](../qemu_mode/README.persistent.md)
+     this will result in 150-300% overall speed - so 3-8x the original
+     qemu_mode speed!
+   - using AFL_CODE_START/AFL_CODE_END to only instrument specific parts
+
   Note that there is also honggfuzz: [https://github.com/google/honggfuzz](https://github.com/google/honggfuzz)
-  which now has a qemu_mode, but its performance is just 1.5%!
+  which now has a qemu_mode, but its performance is just 1.5% ...
 
   As it is included in afl++ this needs no URL.
 
@@ -74,6 +83,27 @@
   [https://github.com/vanhauser-thc/afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst)
 
 
+## RETROWRITE
+
+  If you have an x86/x86_64 binary that still has it's symbols, is compiled
+  with position independant code (PIC/PIE) and does not use most of the C++
+  features then the retrowrite solution might be for you.
+  It decompiles to ASM files which can then be instrumented with afl-gcc.
+
+  It is at about 80-85% performance.
+
+  [https://github.com/HexHive/retrowrite](https://github.com/HexHive/retrowrite)
+
+
+## MCSEMA
+
+  Theoretically you can also decompile to llvm IR with mcsema, and then
+  use llvm_mode to instrument the binary.
+  Good luck with that.
+
+  [https://github.com/lifting-bits/mcsema](https://github.com/lifting-bits/mcsema)
+
+
 ## INTEL-PT
 
   If you have a newer Intel CPU, you can make use of Intels processor trace.
@@ -117,6 +147,9 @@
 
   There is a WIP fuzzer available at [https://github.com/andreafioraldi/frida-fuzzer](https://github.com/andreafioraldi/frida-fuzzer)
 
+  There is also an early implementation in an AFL++ test branch:
+  [https://github.com/vanhauser-thc/AFLplusplus/tree/frida](https://github.com/vanhauser-thc/AFLplusplus/tree/frida)
+
 
 ## PIN & DYNAMORIO
 
diff --git a/gcc_plugin/Makefile b/gcc_plugin/Makefile
index 9ad5c382..9d312a94 100644
--- a/gcc_plugin/Makefile
+++ b/gcc_plugin/Makefile
@@ -35,8 +35,9 @@ CC          ?= gcc
 CXX         ?= g++
 
 PLUGIN_FLAGS = -fPIC -fno-rtti -I"$(shell $(CC) -print-file-name=plugin)/include"
+HASH=\#
 
-ifeq "$(shell echo '\#include <sys/ipc.h>@\#include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
+ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
 	SHMAT_OK=1
 else
 	SHMAT_OK=0
diff --git a/include/config.h b/include/config.h
index 8b8924f5..d47908f6 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,8 @@
 
 /* Version string: */
 
-#define VERSION "++2.60d"  // c = release, d = volatile github dev
+ // c = release, d = volatile github dev, e = experimental branch
+#define VERSION "++2.60d"
 
 /******************************************************
  *                                                    *
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
index 6e0a27af..6fa04e2c 100644
--- a/llvm_mode/Makefile
+++ b/llvm_mode/Makefile
@@ -18,12 +18,13 @@
 
 # For Heiko:
 #TEST_MMAP=1
+HASH=\#
 
 PREFIX      ?= /usr/local
 HELPER_PATH  = $(PREFIX)/lib/afl
 BIN_PATH     = $(PREFIX)/bin
 
-VERSION     = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
+VERSION     = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f2)
 
 ifeq "$(shell uname)" "OpenBSD"
   LLVM_CONFIG ?= $(BIN_PATH)/llvm-config
@@ -116,7 +117,7 @@ endif
 CLANGVER = $(shell $(CC) --version | sed -E -ne '/^.*version\ ([0-9]\.[0-9]\.[0-9]).*/s//\1/p')
 
 
-ifeq "$(shell echo '\#include <sys/ipc.h>@\#include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
+ifeq "$(shell echo '$(HASH)include <sys/ipc.h>@$(HASH)include <sys/shm.h>@int main() { int _id = shmget(IPC_PRIVATE, 65536, IPC_CREAT | IPC_EXCL | 0600); shmctl(_id, IPC_RMID, 0); return 0;}' | tr @ '\n' | $(CC) -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
         SHMAT_OK=1
 else
         SHMAT_OK=0
diff --git a/qemu_mode/README.persistent.md b/qemu_mode/README.persistent.md
index 6948c316..c96a451b 100644
--- a/qemu_mode/README.persistent.md
+++ b/qemu_mode/README.persistent.md
@@ -2,7 +2,7 @@
 
 ## 1) Introduction
 
-Persistent mode let you fuzz your target persistently between to
+Persistent mode let you fuzz your target persistently between two
 addresses - without forking for every fuzzing attempt.
 This increases the speed by a factor between x2 and x5, hence it is
 very, very valuable.
@@ -16,10 +16,12 @@ and aarch64 targets.
 
 The start of the persistent loop has to be set with AFL_QEMU_PERSISTENT_ADDR.
 
-This address can be the address of whatever instruction but the way in which
-you setup persistent mode change if it is the starting instruction of a
-function (suggested). This (as well as the RET address, see below) has to be
-defined in hexadecimal with the 0x prefix or as a decimal value.
+This address can be the address of whatever instruction.
+Setting this address to the start of a function makes the usage simple.
+If the address is however within a function, either RET or OFFSET (see below
+in 2.2 and 2.3) have to be set.
+This address (as well as the RET address, see below) has to be defined in
+hexadecimal with the 0x prefix or as a decimal value.
 
 If the target is compiled with position independant code (PIE/PIC), you must
 add 0x4000000000 to that address, because qemu loads to this base address.
@@ -36,8 +38,8 @@ The emulator will emit a jump to START when translating the instruction at RET.
 It is optional, and only needed if the the return should not be
 at the end of the function to which the START address points into, but earlier.
 
-It is not set, QEMU will assume that START points to a function and will patch
-the return address (on stack or in the link register) to return to START
+If it is not set, QEMU will assume that START points to a function and will
+patch the return address (on stack or in the link register) to return to START
 (like WinAFL).
 
 It is defined by setting AFL_QEMU_PERSISTENT_RET, and too 0x4000000000 has to
@@ -45,25 +47,29 @@ be set if the target is position independant.
 
 ### 2.3) the OFFSET
 
-This option is for x86 only, arm doesn't save the return address on stack.
+This option is valid only for x86/x86_64 only, arm/aarch64 do not save the
+return address on stack.
 
 If the START address is *not* the beginning of a function, and *no* RET has
 been set (so the end of the loop will be at the end of the function but START
-will not be at the beginning), we need an offset from the ESP pointer to locate
-the return address to patch.
+will not be at the beginning of it), we need an offset from the ESP pointer
+to locate the return address to patch.
 
 The value by which the ESP pointer has to be corrected has to set in the
 variable AFL_QEMU_PERSISTENT_RETADDR_OFFSET
 
 Now to get this value right here some help:
 1. use gdb on the target 
-2. set a breakpoint to the function in which START is contained
-3. set a breakpoint to your START address
-4. "run" the target with a valid commandline
-5. at the first breakpoint print the ESP value with `p $esp` and take note of it
-6. "continue" the target until the second breakpoint
-7. again print the ESP value
-8. calculate the difference between the two values - and this is the offset
+2. set a breakpoint to "main" (this is required for PIE/PIC binaries so the
+   addresses are set up)
+3. "run" the target with a valid commandline
+4. set a breakpoint to the function in which START is contained
+5. set a breakpoint to your START address
+6. "continue" to the function start breakpoint
+6. print the ESP value with `print $esp` and take note of it
+7. "continue" the target until the second breakpoint
+8. again print the ESP value
+9. calculate the difference between the two values - and this is the offset
 
 ### 2.4) resetting the register state
 
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 199b3ea8..c1f3f9ac 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1474,7 +1474,7 @@ skip_interest:
   stage_name = "user extras (insert)";
   stage_short = "ext_UI";
   stage_cur = 0;
-  stage_max = extras_cnt * len;
+  stage_max = extras_cnt * (len + 1);
 
   orig_hit_cnt = new_hit_cnt;
 
@@ -3492,7 +3492,7 @@ skip_interest:
   stage_name = "user extras (insert)";
   stage_short = "ext_UI";
   stage_cur = 0;
-  stage_max = extras_cnt * len;
+  stage_max = extras_cnt * (len + 1);
 
   orig_hit_cnt = new_hit_cnt;
 
diff --git a/test/test.sh b/test/test.sh
index d9374f96..c78297f6 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -15,6 +15,12 @@ rm -f test.1 test.2
 test -z "$OK" && { echo Error: diff is not working ; exit 1 ; }
 test -z "$LLVM_CONFIG" && LLVM_CONFIG=llvm-config
 
+# check for '-a' option of grep
+if grep -a test test.sh >/dev/null 2>&1; then
+  GREPAOPTION=' -a'
+else
+  GREPAOPTION=
+fi
 
 ECHO="printf %b\\n"
 $ECHO \\101 2>&1 | grep -qE '^A' || {
@@ -45,6 +51,17 @@ unset AFL_LLVM_INSTRIM
 unset AFL_LLVM_LAF_SPLIT_SWITCHES
 unset AFL_LLVM_LAF_TRANSFORM_COMPARES
 unset AFL_LLVM_LAF_SPLIT_COMPARES
+unset AFL_QEMU_PERSISTENT_ADDR
+unset AFL_QEMU_PERSISTENT_RETADDR_OFFSET
+unset AFL_QEMU_PERSISTENT_GPR
+unset AFL_QEMU_PERSISTENT_RET
+unset AFL_QEMU_PERSISTENT_HOOK
+unset AFL_QEMU_PERSISTENT_CNT
+unset AFL_POST_LIBRARY
+unset AFL_CUSTOM_MUTATOR_LIBRARY
+unset AFL_PYTHON_MODULE
+unset AFL_PRELOAD
+unset LD_PRELOAD
 
 # on OpenBSD we need to work with llvm from /usr/local/bin
 test -e /usr/local/bin/opt && {
@@ -111,7 +128,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
     CODE=1
   }
   test -e test-compcov.harden && {
-    grep -Eq 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
+    grep -Eq$GREPAOPTION 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
       $ECHO "$GREEN[+] ${AFL_GCC} hardened mode succeeded and is working"
     } || {
       $ECHO "$RED[!] ${AFL_GCC} hardened mode is not hardened"
@@ -226,7 +243,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
     CODE=1
   }
   test -e test-compcov.harden && {
-    grep -Eq 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
+    grep -Eq$GREPAOPTION 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden > /dev/null 2>&1 && {
       $ECHO "$GREEN[+] llvm_mode hardened mode succeeded and is working"
     } || {
       $ECHO "$RED[!] llvm_mode hardened mode is not hardened"
@@ -391,7 +408,7 @@ test -e ../afl-gcc-fast -a -e ../afl-gcc-rt.o && {
   }
 
   test -e test-compcov.harden.gccpi && {
-    grep -Eq 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden.gccpi > /dev/null 2>&1 && {
+    grep -Eq$GREPAOPTION 'stack_chk_fail|fstack-protector-all|fortified' test-compcov.harden.gccpi > /dev/null 2>&1 && {
       $ECHO "$GREEN[+] gcc_plugin hardened mode succeeded and is working"
     } || {
       $ECHO "$RED[!] gcc_plugin hardened mode is not hardened"
diff --git a/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py b/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
index bf2367cf..dc56b2aa 100644
--- a/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
+++ b/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
@@ -32,6 +32,7 @@ import os
 import sys
 import time
 import zlib
+import traceback
 
 # GDB Python SDK
 import gdb
@@ -164,7 +165,7 @@ def dump_process_memory(output_dir):
                     print("Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format(entry.start, entry.objfile))
                 else:
                     print("Dumping segment @0x{0:016x} (size:0x{1:x}): {2} [{3}]".format(entry.start, len(seg_content), entry.objfile, repr(seg_info['permissions'])))
-                    compressed_seg_content = zlib.compress(seg_content)
+                    compressed_seg_content = zlib.compress(str(seg_content))
                     md5_sum = hashlib.md5(compressed_seg_content).hexdigest() + ".bin"
                     seg_info["content_file"] = md5_sum
                     
@@ -173,7 +174,8 @@ def dump_process_memory(output_dir):
                     out_file.write(compressed_seg_content)
                     out_file.close()
 
-            except:
+            except Exception as e:
+                traceback.print_exc()
                 print("Exception reading segment ({}): {}".format(entry.objfile, sys.exc_info()[0]))
         else:
             print("Skipping segment {0}@0x{1:016x}".format(entry.objfile, entry.start))
diff --git a/unicorn_mode/patches/afl-unicorn-common.h b/unicorn_mode/patches/afl-unicorn-common.h
deleted file mode 100644
index 7cdab7f6..00000000
--- a/unicorn_mode/patches/afl-unicorn-common.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-   american fuzzy lop++ - unicorn instrumentation
-   ----------------------------------------------
-
-   Originally written by Andrew Griffiths <agriffiths@google.com> and
-                         Michal Zalewski
-
-   Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
-
-   CompareCoverage and NeverZero counters by Andrea Fioraldi
-                                  <andreafioraldi@gmail.com>
-
-   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at:
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   This code is a shim patched into the separately-distributed source
-   code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
-   to implement AFL-style instrumentation and to take care of the remaining
-   parts of the AFL fork server logic.
-
-   The resulting libunicorn binary is essentially a standalone instrumentation
-   tool; for an example of how to leverage it for other purposes, you can
-   have a look at afl-showmap.c.
-
- */
-
-#include "../../config.h"
-
-/* NeverZero */
-
-#if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO)
-#define INC_AFL_AREA(loc)           \
-  asm volatile(                     \
-      "incb (%0, %1, 1)\n"          \
-      "adcb $0, (%0, %1, 1)\n"      \
-      : /* no out */                \
-      : "r"(afl_area_ptr), "r"(loc) \
-      : "memory", "eax")
-#else
-#define INC_AFL_AREA(loc) afl_area_ptr[loc]++
-#endif
-
diff --git a/unicorn_mode/patches/afl-unicorn-cpu-inl.h b/unicorn_mode/patches/afl-unicorn-cpu-inl.h
deleted file mode 100644
index 04d820af..00000000
--- a/unicorn_mode/patches/afl-unicorn-cpu-inl.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-   american fuzzy lop++ - unicorn instrumentation
-   ----------------------------------------------
-
-   Originally written by Andrew Griffiths <agriffiths@google.com> and
-                         Michal Zalewski
-
-   Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
-
-   CompareCoverage and NeverZero counters by Andrea Fioraldi
-                                  <andreafioraldi@gmail.com>
-
-   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at:
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   This code is a shim patched into the separately-distributed source
-   code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
-   to implement AFL-style instrumentation and to take care of the remaining
-   parts of the AFL fork server logic.
-
-   The resulting libunicorn binary is essentially a standalone instrumentation
-   tool; for an example of how to leverage it for other purposes, you can
-   have a look at afl-showmap.c.
-
- */
-
-#include <sys/shm.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "afl-unicorn-common.h"
-
-/***************************
- * VARIOUS AUXILIARY STUFF *
- ***************************/
-
-/* A snippet patched into tb_find_slow to inform the parent process that
-   we have hit a new block that hasn't been translated yet, and to tell
-   it to translate within its own context, too (this avoids translation
-   overhead in the next forked-off copy). */
-
-#define AFL_UNICORN_CPU_SNIPPET1         \
-  do {                                   \
-                                         \
-    afl_request_tsl(pc, cs_base, flags); \
-                                         \
-  } while (0)
-
-/* This snippet kicks in when the instruction pointer is positioned at
-   _start and does the usual forkserver stuff, not very different from
-   regular instrumentation injected via afl-as.h. */
-
-#define AFL_UNICORN_CPU_SNIPPET2          \
-  do {                                    \
-                                          \
-    if (unlikely(afl_first_instr == 0)) { \
-                                          \
-      afl_setup(env->uc);                 \
-      afl_forkserver(env);                \
-      afl_first_instr = 1;                \
-                                          \
-    }                                     \
-    afl_maybe_log(env->uc, tb->pc);       \
-                                          \
-  } while (0)
-
-/* We use one additional file descriptor to relay "needs translation"
-   messages between the child and the fork server. */
-
-#define TSL_FD (FORKSRV_FD - 1)
-
-/* Set in the child process in forkserver mode: */
-
-static unsigned char afl_fork_child;
-static unsigned int  afl_forksrv_pid;
-
-/* Function declarations. */
-
-static void        afl_setup(struct uc_struct* uc);
-static void        afl_forkserver(CPUArchState*);
-static inline void afl_maybe_log(struct uc_struct* uc, unsigned long);
-
-static void afl_wait_tsl(CPUArchState*, int);
-static void afl_request_tsl(target_ulong, target_ulong, uint64_t);
-
-static TranslationBlock* tb_find_slow(CPUArchState*, target_ulong, target_ulong,
-                                      uint64_t);
-
-/* Data structure passed around by the translate handlers: */
-
-struct afl_tsl {
-
-  target_ulong pc;
-  target_ulong cs_base;
-  uint64_t     flags;
-
-};
-
-/*************************
- * ACTUAL IMPLEMENTATION *
- *************************/
-
-/* Set up SHM region and initialize other stuff. */
-
-static void afl_setup(struct uc_struct* uc) {
-
-  char *id_str = getenv(SHM_ENV_VAR), *inst_r = getenv("AFL_INST_RATIO");
-
-  int shm_id;
-
-  if (inst_r) {
-
-    unsigned int r;
-
-    r = atoi(inst_r);
-
-    if (r > 100) r = 100;
-    if (!r) r = 1;
-
-    uc->afl_inst_rms = MAP_SIZE * r / 100;
-
-  } else {
-
-    uc->afl_inst_rms = MAP_SIZE;
-
-  }
-
-  if (id_str) {
-
-    shm_id = atoi(id_str);
-    uc->afl_area_ptr = shmat(shm_id, NULL, 0);
-
-    if (uc->afl_area_ptr == (void*)-1) exit(1);
-
-    /* With AFL_INST_RATIO set to a low value, we want to touch the bitmap
-       so that the parent doesn't give up on us. */
-
-    if (inst_r) uc->afl_area_ptr[0] = 1;
-
-  }
-
-  /* Maintain for compatibility */
-  if (getenv("AFL_QEMU_COMPCOV")) { uc->afl_compcov_level = 1; }
-  if (getenv("AFL_COMPCOV_LEVEL")) {
-
-    uc->afl_compcov_level = atoi(getenv("AFL_COMPCOV_LEVEL"));
-
-  }
-
-}
-
-/* Fork server logic, invoked once we hit first emulated instruction. */
-
-static void afl_forkserver(CPUArchState* env) {
-
-  static unsigned char tmp[4];
-
-  if (!env->uc->afl_area_ptr) return;
-
-  /* Tell the parent that we're alive. If the parent doesn't want
-     to talk, assume that we're not running in forkserver mode. */
-
-  if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
-
-  afl_forksrv_pid = getpid();
-
-  /* All right, let's await orders... */
-
-  while (1) {
-
-    pid_t child_pid;
-    int   status, t_fd[2];
-
-    /* Whoops, parent dead? */
-
-    if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);
-
-    /* Establish a channel with child to grab translation commands. We'll
-       read from t_fd[0], child will write to TSL_FD. */
-
-    if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);
-    close(t_fd[1]);
-
-    child_pid = fork();
-    if (child_pid < 0) exit(4);
-
-    if (!child_pid) {
-
-      /* Child process. Close descriptors and run free. */
-
-      afl_fork_child = 1;
-      close(FORKSRV_FD);
-      close(FORKSRV_FD + 1);
-      close(t_fd[0]);
-      return;
-
-    }
-
-    /* Parent. */
-
-    close(TSL_FD);
-
-    if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5);
-
-    /* Collect translation requests until child dies and closes the pipe. */
-
-    afl_wait_tsl(env, t_fd[0]);
-
-    /* Get and relay exit status to parent. */
-
-    if (waitpid(child_pid, &status, 0) < 0) exit(6);
-    if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7);
-
-  }
-
-}
-
-/* The equivalent of the tuple logging routine from afl-as.h. */
-
-static inline void afl_maybe_log(struct uc_struct* uc, unsigned long cur_loc) {
-
-  static __thread unsigned long prev_loc;
-
-  u8* afl_area_ptr = uc->afl_area_ptr;
-
-  if (!afl_area_ptr) return;
-
-  /* Looks like QEMU always maps to fixed locations, so ASAN is not a
-     concern. Phew. But instruction addresses may be aligned. Let's mangle
-     the value to get something quasi-uniform. */
-
-  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
-  cur_loc &= MAP_SIZE - 1;
-
-  /* Implement probabilistic instrumentation by looking at scrambled block
-     address. This keeps the instrumented locations stable across runs. */
-
-  if (cur_loc >= uc->afl_inst_rms) return;
-
-  register uintptr_t afl_idx = cur_loc ^ prev_loc;
-
-  INC_AFL_AREA(afl_idx);
-
-  prev_loc = cur_loc >> 1;
-
-}
-
-/* This code is invoked whenever QEMU decides that it doesn't have a
-   translation of a particular block and needs to compute it. When this happens,
-   we tell the parent to mirror the operation, so that the next fork() has a
-   cached copy. */
-
-static void afl_request_tsl(target_ulong pc, target_ulong cb, uint64_t flags) {
-
-  struct afl_tsl t;
-
-  if (!afl_fork_child) return;
-
-  t.pc = pc;
-  t.cs_base = cb;
-  t.flags = flags;
-
-  if (write(TSL_FD, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
-    return;
-
-}
-
-/* This is the other side of the same channel. Since timeouts are handled by
-   afl-fuzz simply killing the child, we can just wait until the pipe breaks. */
-
-static void afl_wait_tsl(CPUArchState* env, int fd) {
-
-  struct afl_tsl t;
-
-  while (1) {
-
-    /* Broken pipe means it's time to return to the fork server routine. */
-
-    if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl)) break;
-
-    tb_find_slow(env, t.pc, t.cs_base, t.flags);
-
-  }
-
-  close(fd);
-
-}
-
diff --git a/unicorn_mode/patches/afl-unicorn-cpu-translate-inl.h b/unicorn_mode/patches/afl-unicorn-cpu-translate-inl.h
deleted file mode 100644
index 0a1c034d..00000000
--- a/unicorn_mode/patches/afl-unicorn-cpu-translate-inl.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-   american fuzzy lop++ - unicorn instrumentation
-   ----------------------------------------------
-
-   Originally written by Andrew Griffiths <agriffiths@google.com> and
-                         Michal Zalewski
-
-   Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
-
-   CompareCoverage and NeverZero counters by Andrea Fioraldi
-                                  <andreafioraldi@gmail.com>
-
-   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at:
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   This code is a shim patched into the separately-distributed source
-   code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
-   to implement AFL-style instrumentation and to take care of the remaining
-   parts of the AFL fork server logic.
-
-   The resulting libunicorn binary is essentially a standalone instrumentation
-   tool; for an example of how to leverage it for other purposes, you can
-   have a look at afl-showmap.c.
-
- */
-
-#include "../../config.h"
-
-static void afl_gen_compcov(TCGContext *s, uint64_t cur_loc, TCGv_i64 arg1,
-                            TCGv_i64 arg2, TCGMemOp ot, int is_imm) {
-
-  if (!s->uc->afl_compcov_level || !s->uc->afl_area_ptr) return;
-
-  if (!is_imm && s->uc->afl_compcov_level < 2) return;
-
-  cur_loc = (cur_loc >> 4) ^ (cur_loc << 8);
-  cur_loc &= MAP_SIZE - 7;
-
-  if (cur_loc >= s->uc->afl_inst_rms) return;
-
-  switch (ot) {
-
-    case MO_64: gen_afl_compcov_log_64(s, cur_loc, arg1, arg2); break;
-    case MO_32: gen_afl_compcov_log_32(s, cur_loc, arg1, arg2); break;
-    case MO_16: gen_afl_compcov_log_16(s, cur_loc, arg1, arg2); break;
-    default: return;
-
-  }
-
-}
-
diff --git a/unicorn_mode/patches/afl-unicorn-tcg-op-inl.h b/unicorn_mode/patches/afl-unicorn-tcg-op-inl.h
deleted file mode 100644
index 7069b756..00000000
--- a/unicorn_mode/patches/afl-unicorn-tcg-op-inl.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-   american fuzzy lop++ - unicorn instrumentation
-   ----------------------------------------------
-
-   Originally written by Andrew Griffiths <agriffiths@google.com> and
-                         Michal Zalewski
-
-   Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
-
-   CompareCoverage and NeverZero counters by Andrea Fioraldi
-                                  <andreafioraldi@gmail.com>
-
-   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at:
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   This code is a shim patched into the separately-distributed source
-   code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
-   to implement AFL-style instrumentation and to take care of the remaining
-   parts of the AFL fork server logic.
-
-   The resulting libunicorn binary is essentially a standalone instrumentation
-   tool; for an example of how to leverage it for other purposes, you can
-   have a look at afl-showmap.c.
-
- */
-
-static inline void gen_afl_compcov_log_16(TCGContext *tcg_ctx, uint64_t cur_loc,
-                                          TCGv_i64 arg1, TCGv_i64 arg2) {
-
-  TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
-  TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
-  gen_helper_afl_compcov_log_16(tcg_ctx, tuc, tcur_loc, arg1, arg2);
-
-}
-
-static inline void gen_afl_compcov_log_32(TCGContext *tcg_ctx, uint64_t cur_loc,
-                                          TCGv_i64 arg1, TCGv_i64 arg2) {
-
-  TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
-  TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
-  gen_helper_afl_compcov_log_32(tcg_ctx, tuc, tcur_loc, arg1, arg2);
-
-}
-
-static inline void gen_afl_compcov_log_64(TCGContext *tcg_ctx, uint64_t cur_loc,
-                                          TCGv_i64 arg1, TCGv_i64 arg2) {
-
-  TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, tcg_ctx->uc);
-  TCGv_i64 tcur_loc = tcg_const_i64(tcg_ctx, cur_loc);
-  gen_helper_afl_compcov_log_64(tcg_ctx, tuc, tcur_loc, arg1, arg2);
-
-}
-
diff --git a/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h b/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h
deleted file mode 100644
index d3dbbb3a..00000000
--- a/unicorn_mode/patches/afl-unicorn-tcg-runtime-inl.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-   american fuzzy lop++ - unicorn instrumentation
-   ----------------------------------------------
-
-   Originally written by Andrew Griffiths <agriffiths@google.com> and
-                         Michal Zalewski
-
-   Adapted for afl-unicorn by Dominik Maier <mail@dmnk.co>
-
-   CompareCoverage and NeverZero counters by Andrea Fioraldi
-                                  <andreafioraldi@gmail.com>
-
-   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
-   Copyright 2019-2020 AFLplusplus Project. All rights reserved.
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at:
-
-     http://www.apache.org/licenses/LICENSE-2.0
-
-   This code is a shim patched into the separately-distributed source
-   code of Unicorn 1.0.1. It leverages the built-in QEMU tracing functionality
-   to implement AFL-style instrumentation and to take care of the remaining
-   parts of the AFL fork server logic.
-
-   The resulting libunicorn binary is essentially a standalone instrumentation
-   tool; for an example of how to leverage it for other purposes, you can
-   have a look at afl-showmap.c.
-
- */
-
-#include "uc_priv.h"
-#include "afl-unicorn-common.h"
-
-void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff) == (arg2 & 0xff)) { INC_AFL_AREA(cur_loc); }
-
-}
-
-void HELPER(afl_compcov_log_32)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff) == (arg2 & 0xff)) {
-
-    INC_AFL_AREA(cur_loc);
-    if ((arg1 & 0xffff) == (arg2 & 0xffff)) {
-
-      INC_AFL_AREA(cur_loc + 1);
-      if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { INC_AFL_AREA(cur_loc + 2); }
-
-    }
-
-  }
-
-}
-
-void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff) == (arg2 & 0xff)) {
-
-    INC_AFL_AREA(cur_loc);
-    if ((arg1 & 0xffff) == (arg2 & 0xffff)) {
-
-      INC_AFL_AREA(cur_loc + 1);
-      if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) {
-
-        INC_AFL_AREA(cur_loc + 2);
-        if ((arg1 & 0xffffffff) == (arg2 & 0xffffffff)) {
-
-          INC_AFL_AREA(cur_loc + 3);
-          if ((arg1 & 0xffffffffff) == (arg2 & 0xffffffffff)) {
-
-            INC_AFL_AREA(cur_loc + 4);
-            if ((arg1 & 0xffffffffffff) == (arg2 & 0xffffffffffff)) {
-
-              INC_AFL_AREA(cur_loc + 5);
-              if ((arg1 & 0xffffffffffffff) == (arg2 & 0xffffffffffffff)) {
-
-                INC_AFL_AREA(cur_loc + 6);
-
-              }
-
-            }
-
-          }
-
-        }
-
-      }
-
-    }
-
-  }
-
-}
-
-/* // Little endian CompCov
-void HELPER(afl_compcov_log_16)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
-
-}
-
-void HELPER(afl_compcov_log_32)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
-
-    INC_AFL_AREA(cur_loc + 2);
-    if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
-
-      INC_AFL_AREA(cur_loc + 1);
-      if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
-
-    }
-
-  }
-
-}
-
-void HELPER(afl_compcov_log_64)(void* uc_ptr, uint64_t cur_loc, uint64_t arg1,
-                                uint64_t arg2) {
-
-  u8* afl_area_ptr = ((struct uc_struct*)uc_ptr)->afl_area_ptr;
-
-  if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) {
-
-    INC_AFL_AREA(cur_loc + 6);
-    if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) {
-
-      INC_AFL_AREA(cur_loc + 5);
-      if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) {
-
-        INC_AFL_AREA(cur_loc + 4);
-        if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) {
-
-          INC_AFL_AREA(cur_loc + 3);
-          if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) {
-
-            INC_AFL_AREA(cur_loc + 2);
-            if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) {
-
-              INC_AFL_AREA(cur_loc + 1);
-              if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(cur_loc); }
-
-            }
-
-          }
-
-        }
-
-      }
-
-    }
-
-  }
-
-}
-
-*/
-
diff --git a/unicorn_mode/patches/compcov.diff b/unicorn_mode/patches/compcov.diff
deleted file mode 100644
index 4e71f465..00000000
--- a/unicorn_mode/patches/compcov.diff
+++ /dev/null
@@ -1,251 +0,0 @@
-diff --git a/include/uc_priv.h b/include/uc_priv.h
-index 22f494e..1aa7b3a 100644
---- a/include/uc_priv.h
-+++ b/include/uc_priv.h
-@@ -245,6 +245,12 @@ struct uc_struct {
-     uint32_t target_page_align;
-     uint64_t next_pc;   // save next PC for some special cases
-     bool hook_insert;	// insert new hook at begin of the hook list (append by default)
-+    
-+#ifdef UNICORN_AFL
-+    unsigned char *afl_area_ptr;
-+    int afl_compcov_level;
-+    unsigned int afl_inst_rms;
-+#endif
- };
- 
- // Metadata stub for the variable-size cpu context used with uc_context_*()
-diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c
-index 4995eda..06c7e63 100644
---- a/qemu/target-arm/translate.c
-+++ b/qemu/target-arm/translate.c
-@@ -63,6 +63,12 @@ static TCGv_i64 cpu_exclusive_test;
- static TCGv_i32 cpu_exclusive_info;
- #endif
- 
-+#if defined(UNICORN_AFL)
-+#include "../../afl-unicorn-cpu-translate-inl.h"
-+#else
-+#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0)
-+#endif
-+
- 
- static const char *regnames[] =
-     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
-@@ -8214,6 +8220,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)  // qq
-             } else {
-                 if (set_cc) {
-                     gen_sub_CC(s, tmp, tmp, tmp2);
-+                    afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
-                 } else {
-                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
-                 }
-@@ -8223,6 +8230,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)  // qq
-         case 0x03:
-             if (set_cc) {
-                 gen_sub_CC(s, tmp, tmp2, tmp);
-+                afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
-             } else {
-                 tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp);
-             }
-@@ -8277,6 +8285,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)  // qq
-         case 0x0a:
-             if (set_cc) {
-                 gen_sub_CC(s, tmp, tmp, tmp2);
-+                afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25));
-             }
-             tcg_temp_free_i32(tcg_ctx, tmp);
-             break;
-@@ -9148,7 +9157,7 @@ thumb2_logic_op(int op)
- 
- static int
- gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
--                   TCGv_i32 t0, TCGv_i32 t1)
-+                   TCGv_i32 t0, TCGv_i32 t1, int has_imm)
- {
-     TCGContext *tcg_ctx = s->uc->tcg_ctx;
-     int logic_cc;
-@@ -9195,15 +9204,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
-         }
-         break;
-     case 13: /* sub */
--        if (conds)
-+        if (conds) {
-             gen_sub_CC(s, t0, t0, t1);
--        else
-+            afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm);
-+        } else
-             tcg_gen_sub_i32(tcg_ctx, t0, t0, t1);
-         break;
-     case 14: /* rsb */
--        if (conds)
-+        if (conds) {
-             gen_sub_CC(s, t0, t1, t0);
--        else
-+            afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm);
-+        } else
-             tcg_gen_sub_i32(tcg_ctx, t0, t1, t0);
-         break;
-     default: /* 5, 6, 7, 9, 12, 15. */
-@@ -9572,7 +9583,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
-             conds = (insn & (1 << 20)) != 0;
-             logic_cc = (conds && thumb2_logic_op(op));
-             gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc);
--            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
-+            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10)))
-                 goto illegal_op;
-             tcg_temp_free_i32(tcg_ctx, tmp2);
-             if (rd != 15) {
-@@ -10215,7 +10226,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
-                 }
-                 op = (insn >> 21) & 0xf;
-                 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
--                                       shifter_out, tmp, tmp2))
-+                                       shifter_out, tmp, tmp2, insn & (1 << 10)))
-                     goto illegal_op;
-                 tcg_temp_free_i32(tcg_ctx, tmp2);
-                 rd = (insn >> 8) & 0xf;
-@@ -10471,8 +10482,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
-             if (insn & (1 << 9)) {
-                 if (s->condexec_mask)
-                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
--                else
-+                else {
-                     gen_sub_CC(s, tmp, tmp, tmp2);
-+                    afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 10));
-+                }
-             } else {
-                 if (s->condexec_mask)
-                     tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2);
-@@ -10509,6 +10522,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
-             switch (op) {
-             case 1: /* cmp */
-                 gen_sub_CC(s, tmp, tmp, tmp2);
-+                afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1);
-                 tcg_temp_free_i32(tcg_ctx, tmp);
-                 tcg_temp_free_i32(tcg_ctx, tmp2);
-                 break;
-@@ -10523,8 +10537,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
-             case 3: /* sub */
-                 if (s->condexec_mask)
-                     tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2);
--                else
-+                else {
-                     gen_sub_CC(s, tmp, tmp, tmp2);
-+                    afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1);
-+                }
-                 tcg_temp_free_i32(tcg_ctx, tmp2);
-                 store_reg(s, rd, tmp);
-                 break;
-@@ -10562,6 +10578,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
-                 tmp = load_reg(s, rd);
-                 tmp2 = load_reg(s, rm);
-                 gen_sub_CC(s, tmp, tmp, tmp2);
-+                afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0);
-                 tcg_temp_free_i32(tcg_ctx, tmp2);
-                 tcg_temp_free_i32(tcg_ctx, tmp);
-                 break;
-@@ -10680,6 +10697,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq
-             break;
-         case 0xa: /* cmp */
-             gen_sub_CC(s, tmp, tmp, tmp2);
-+            afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0);
-             rd = 16;
-             break;
-         case 0xb: /* cmn */
-diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c
-index 36fae09..196d346 100644
---- a/qemu/target-i386/translate.c
-+++ b/qemu/target-i386/translate.c
-@@ -33,6 +33,12 @@
- 
- #include "uc_priv.h"
- 
-+#if defined(UNICORN_AFL)
-+#include "../../afl-unicorn-cpu-translate-inl.h"
-+#else
-+#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0)
-+#endif
-+
- #define PREFIX_REPZ   0x01
- #define PREFIX_REPNZ  0x02
- #define PREFIX_LOCK   0x04
-@@ -1555,6 +1561,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d)
-     case OP_SUBL:
-         tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]);
-         tcg_gen_sub_tl(tcg_ctx, *cpu_T[0], *cpu_T[0], *cpu_T[1]);
-+        afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX);
-         gen_op_st_rm_T0_A0(s, ot, d);
-         gen_op_update2_cc(tcg_ctx);
-         set_cc_op(s, CC_OP_SUBB + ot);
-@@ -1582,6 +1589,7 @@ static void gen_op(DisasContext *s, int op, TCGMemOp ot, int d)
-         tcg_gen_mov_tl(tcg_ctx, cpu_cc_src, *cpu_T[1]);
-         tcg_gen_mov_tl(tcg_ctx, cpu_cc_srcT, *cpu_T[0]);
-         tcg_gen_sub_tl(tcg_ctx, cpu_cc_dst, *cpu_T[0], *cpu_T[1]);
-+        afl_gen_compcov(tcg_ctx, s->pc, *cpu_T[0], *cpu_T[1], ot, d == OR_EAX);
-         set_cc_op(s, CC_OP_SUBB + ot);
-         break;
-     }
-diff --git a/qemu/tcg-runtime.c b/qemu/tcg-runtime.c
-index 21b022a..14d7891 100644
---- a/qemu/tcg-runtime.c
-+++ b/qemu/tcg-runtime.c
-@@ -31,9 +31,14 @@
- 
- #define DEF_HELPER_FLAGS_2(name, flags, ret, t1, t2) \
-   dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2));
-+#define DEF_HELPER_FLAGS_4(name, flags, ret, t1, t2, t3, t4) \
-+  dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), dh_ctype(t3), dh_ctype(t4));
- 
- #include "tcg-runtime.h"
- 
-+#ifdef UNICORN_AFL
-+#include "../afl-unicorn-tcg-runtime-inl.h"
-+#endif
- 
- /* 32-bit helpers */
- 
-diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h
-index 38b7dd9..c5a9af9 100644
---- a/qemu/tcg/tcg-op.h
-+++ b/qemu/tcg/tcg-op.h
-@@ -27,6 +27,10 @@
- 
- int gen_new_label(TCGContext *);
- 
-+#ifdef UNICORN_AFL
-+#include "../../afl-unicorn-tcg-op-inl.h"
-+#endif
-+
- static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, int32_t type, void *uc, uint64_t pc)
- {
-     TCGv_i32 tsize = tcg_const_i32(tcg_ctx, size);
-diff --git a/qemu/tcg/tcg-runtime.h b/qemu/tcg/tcg-runtime.h
-index 23a0c37..90b993c 100644
---- a/qemu/tcg/tcg-runtime.h
-+++ b/qemu/tcg/tcg-runtime.h
-@@ -14,3 +14,9 @@ DEF_HELPER_FLAGS_2(sar_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
- 
- DEF_HELPER_FLAGS_2(mulsh_i64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
- DEF_HELPER_FLAGS_2(muluh_i64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-+
-+#ifdef UNICORN_AFL
-+DEF_HELPER_FLAGS_4(afl_compcov_log_16, 0, void, ptr, i64, i64, i64)
-+DEF_HELPER_FLAGS_4(afl_compcov_log_32, 0, void, ptr, i64, i64, i64)
-+DEF_HELPER_FLAGS_4(afl_compcov_log_64, 0, void, ptr, i64, i64, i64)
-+#endif
-diff --git a/qemu/unicorn_common.h b/qemu/unicorn_common.h
-index 8dcbb3e..11e18b4 100644
---- a/qemu/unicorn_common.h
-+++ b/qemu/unicorn_common.h
-@@ -84,6 +84,10 @@ static inline void uc_common_init(struct uc_struct* uc)
- 
-     if (!uc->release)
-         uc->release = release_common;
-+
-+#ifdef UNICORN_AFL
-+    uc->afl_area_ptr = 0;
-+#endif
- }
- 
- #endif
diff --git a/unicorn_mode/patches/patches.diff b/unicorn_mode/patches/patches.diff
deleted file mode 100644
index 71a1e2f3..00000000
--- a/unicorn_mode/patches/patches.diff
+++ /dev/null
@@ -1,107 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 7d73782..fb3ccfd 100644
---- a/Makefile
-+++ b/Makefile
-@@ -88,6 +88,10 @@ AR = llvm-ar
- LDFLAGS := -fsanitize=address ${LDFLAGS}
- endif
- 
-+ifeq ($(UNICORN_AFL),yes)
-+UNICORN_CFLAGS += -DUNICORN_AFL
-+endif
-+
- ifeq ($(CROSS),)
- CC ?= cc
- AR ?= ar
-diff --git a/config.mk b/config.mk
-index c3621fb..c7b4f7e 100644
---- a/config.mk
-+++ b/config.mk
-@@ -8,7 +8,7 @@
- # Compile with debug info when you want to debug code.
- # Change this to 'no' for release edition.
- 
--UNICORN_DEBUG ?= yes
-+UNICORN_DEBUG ?= no
- 
- ################################################################################
- # Specify which archs you want to compile in. By default, we build all archs.
-@@ -28,3 +28,9 @@ UNICORN_STATIC ?= yes
- # a shared library.
- 
- UNICORN_SHARED ?= yes
-+
-+
-+################################################################################
-+# Changing 'UNICORN_AFLL = yes' to 'UNICORN_AFL = no' disables AFL instrumentation
-+
-+UNICORN_AFL ?= yes
-diff --git a/qemu/cpu-exec.c b/qemu/cpu-exec.c
-index 7755adf..8114b70 100644
---- a/qemu/cpu-exec.c
-+++ b/qemu/cpu-exec.c
-@@ -24,6 +24,11 @@
- 
- #include "uc_priv.h"
- 
-+#if defined(UNICORN_AFL)
-+#include "../afl-unicorn-cpu-inl.h"
-+static int afl_first_instr = 0;
-+#endif 
-+
- static tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr);
- static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
-         target_ulong cs_base, uint64_t flags);
-@@ -231,6 +236,10 @@ int cpu_exec(struct uc_struct *uc, CPUArchState *env)   // qq
-                             next_tb & TB_EXIT_MASK, tb);
-                 }
- 
-+#if defined(UNICORN_AFL)
-+                AFL_UNICORN_CPU_SNIPPET2;
-+#endif
-+
-                 /* cpu_interrupt might be called while translating the
-                    TB, but before it is linked into a potentially
-                    infinite loop and becomes env->current_tb. Avoid
-@@ -369,6 +378,11 @@ static TranslationBlock *tb_find_slow(CPUArchState *env, target_ulong pc,
- not_found:
-     /* if no translated code available, then translate it now */
-     tb = tb_gen_code(cpu, pc, cs_base, (int)flags, 0);   // qq
-+    
-+#if defined(UNICORN_AFL)
-+    /* There seems to be no chaining in unicorn ever? :( */
-+    AFL_UNICORN_CPU_SNIPPET1;
-+#endif
- 
- found:
-     /* Move the last found TB to the head of the list */
-diff --git a/qemu/translate-all.c b/qemu/translate-all.c
-index 1a96c34..7ef4878 100644
---- a/qemu/translate-all.c
-+++ b/qemu/translate-all.c
-@@ -403,11 +403,25 @@ static PageDesc *page_find_alloc(struct uc_struct *uc, tb_page_addr_t index, int
- 
- #if defined(CONFIG_USER_ONLY)
-     /* We can't use g_malloc because it may recurse into a locked mutex. */
-+#if defined(UNICORN_AFL)
-+    /* This was added by unicorn-afl to bail out semi-gracefully if out of memory. */
-+# define ALLOC(P, SIZE)                                 \
-+    do {                                                \
-+        void* _tmp = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,    \
-+                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);   \
-+        if (_tmp == (void*)-1) { \
-+            qemu_log(">>> Out of memory for stack, bailing out. <<<\n"); \
-+            exit(1); \
-+        } \
-+        (P) = _tmp; \
-+    } while (0)
-+#else /* !UNICORN_AFL */
- # define ALLOC(P, SIZE)                                 \
-     do {                                                \
-         P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,    \
-                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);   \
-     } while (0)
-+#endif /* UNICORN_AFL */
- #else
- # define ALLOC(P, SIZE) \
-     do { P = g_malloc0(SIZE); } while (0)
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 31416ae2..2eddeb8e 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -71,7 +71,7 @@ static void hook_strlen(uc_engine *uc, uint64_t address, uint32_t size, void *us
     //Hook
     //116b:       e8 c0 fe ff ff          call   1030 <strlen@plt>
     // We place the return at RAX
-    //printf("Strlen hook at addr 0x%lx (size: 0x%x), result: %ld\n", address, size, current_input_len);
+    //printf("Strlen hook at addr 0x%llx (size: 0x%x), result: %ld\n", address, size, current_input_len);
     uc_reg_write(uc, UC_X86_REG_RAX, &current_input_len);
     // We skip the actual call by updating RIP
     uint64_t next_addr = address + size; 
@@ -125,12 +125,6 @@ static bool place_input_callback(
         return false;
     }
 
-    // For persistent mode, we have to set up stack and memory each time.
-    uc_reg_write(uc, UC_X86_REG_RIP, &CODE_ADDRESS); // Set the instruction pointer back
-    // Set up the function parameters accordingly RSI, RDI (see calling convention/disassembly)
-    uc_reg_write(uc, UC_X86_REG_RSI, &INPUT_LOCATION); // argv
-    uc_reg_write(uc, UC_X86_REG_RDI, &EMULATED_ARGC);  // argc == 2
-   
     // We need a valid c string, make sure it never goes out of bounds.
     input[input_len-1] = '\0';
     // Write the testcase to unicorn.
@@ -144,7 +138,7 @@ static bool place_input_callback(
 
 static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t mode) {
     size = pad(size);
-    //printf("SIZE %lx, align: %lx\n", size, ALIGNMENT);
+    //printf("SIZE %llx, align: %llx\n", size, ALIGNMENT);
     uc_err err = uc_mem_map(uc, addr, size, mode);
     if (err != UC_ERR_OK) {
         printf("Error mapping %ld bytes at 0x%lx: %s (mode: %d)\n", size, addr, uc_strerror(err), mode);
@@ -209,7 +203,7 @@ int main(int argc, char **argv, char **envp) {
     // Setup the Stack
     mem_map_checked(uc, STACK_ADDRESS - STACK_SIZE, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
     uint64_t stack_val = STACK_ADDRESS;
-    printf("%ld", stack_val);
+    printf("%lu", stack_val);
     uc_reg_write(uc, UC_X86_REG_RSP, &stack_val);
 
     // reserve some space for our input data
@@ -235,6 +229,13 @@ int main(int argc, char **argv, char **envp) {
     uc_hook strlen_hook;
     uc_hook_add(uc, &strlen_hook, UC_HOOK_CODE, hook_strlen, NULL, strlen_hook_pos, strlen_hook_pos);
 
+    // For persistent-iters=1, we don't need to reset this as it's restarted/reforked for each run.
+    uc_reg_write(uc, UC_X86_REG_RIP, &CODE_ADDRESS); // Set the instruction pointer back
+    // Set up the function parameters accordingly RSI, RDI (see calling convention/disassembly)
+    uc_reg_write(uc, UC_X86_REG_RSI, &INPUT_LOCATION); // argv
+    uc_reg_write(uc, UC_X86_REG_RDI, &EMULATED_ARGC);  // argc == 2
+   
+
     printf("Starting to fuzz :)\n");
     fflush(stdout);
 
@@ -247,7 +248,7 @@ int main(int argc, char **argv, char **envp) {
         1,  // Count of end addresses
         NULL, // Optional calback to run after each exec
         false, // true, if the optional callback should be run also for non-crashes
-        100, // For persistent mode: How many rounds to run
+        1, // For persistent mode: How many rounds to run
         NULL // additional data pointer
     );
     switch(afl_ret) {
diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c
index d8ebffbc..02d96e90 100644
--- a/unicorn_mode/samples/persistent/harness.c
+++ b/unicorn_mode/samples/persistent/harness.c
@@ -77,7 +77,7 @@ static void hook_strlen(uc_engine *uc, uint64_t address, uint32_t size, void *us
     // We place the return at RAX
     uc_reg_write(uc, UC_X86_REG_RAX, &current_input_len);
     // We skip the actual call by updating RIP
-    //printf("Strlen hook at addr 0x%lx (size: 0x%x), result: %ld\n", address, size, current_input_len);
+    //printf("Strlen hook at addr 0x%llx (size: 0x%x), result: %ld\n", address, size, current_input_len);
     uint64_t next_addr = address + size; 
     uc_reg_write(uc, UC_X86_REG_RIP, &next_addr);
 }
@@ -101,7 +101,7 @@ static off_t afl_mmap_file(char *filename, char **buf_ptr) {
     off_t in_len = st.st_size;
     if (in_len == -1) {
 	/* This can only ever happen on 32 bit if the file is exactly 4gb. */
-	fprintf(stderr, "Filesize of %s too large", filename);
+	fprintf(stderr, "Filesize of %s too large\n", filename);
 	goto exit;
     }
 
@@ -148,7 +148,7 @@ static bool place_input_callback(
 
 static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t mode) {
     size = pad(size);
-    //printf("SIZE %lx, align: %lx\n", size, ALIGNMENT);
+    //printf("SIZE %llx, align: %llx\n", size, ALIGNMENT);
     uc_err err = uc_mem_map(uc, addr, size, mode);
     if (err != UC_ERR_OK) {
         printf("Error mapping %ld bytes at 0x%lx: %s (mode: %d)\n", size, addr, uc_strerror(err), mode);
@@ -213,7 +213,7 @@ int main(int argc, char **argv, char **envp) {
     // Setup the Stack
     mem_map_checked(uc, STACK_ADDRESS - STACK_SIZE, STACK_SIZE, UC_PROT_READ | UC_PROT_WRITE);
     uint64_t stack_val = STACK_ADDRESS;
-    printf("%ld", stack_val);
+    printf("%lu", stack_val);
     uc_reg_write(uc, UC_X86_REG_RSP, &stack_val);
 
     // reserve some space for our input data
@@ -256,11 +256,11 @@ int main(int argc, char **argv, char **envp) {
     );
     switch(afl_ret) {
         case UC_AFL_RET_ERROR:
-            printf("Error starting to fuzz");
+            printf("Error starting to fuzz\n");
             return -3;
             break;
         case UC_AFL_RET_NO_AFL:
-            printf("No AFL attached - We are done with a single run.");
+            printf("No AFL attached - We are done with a single run.\n");
             break;
         default:
             break;