about summary refs log tree commit diff
path: root/unicorn_mode
diff options
context:
space:
mode:
Diffstat (limited to 'unicorn_mode')
-rw-r--r--unicorn_mode/README.md189
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
-rwxr-xr-xunicorn_mode/build_unicorn_support.sh5
-rw-r--r--unicorn_mode/samples/c/Makefile39
-rw-r--r--unicorn_mode/samples/c/harness.c7
-rw-r--r--unicorn_mode/samples/compcov_x64/compcov_test_harness.py2
-rw-r--r--unicorn_mode/samples/persistent/Makefile38
-rw-r--r--unicorn_mode/samples/persistent/harness.c1
-rw-r--r--unicorn_mode/samples/python_simple/COMPILE.md (renamed from unicorn_mode/samples/simple/COMPILE.md)0
-rw-r--r--unicorn_mode/samples/python_simple/sample_inputs/sample1.bin (renamed from unicorn_mode/samples/simple/sample_inputs/sample1.bin)0
-rw-r--r--unicorn_mode/samples/python_simple/sample_inputs/sample2.bin (renamed from unicorn_mode/samples/simple/sample_inputs/sample2.bin)bin1 -> 1 bytes
-rw-r--r--unicorn_mode/samples/python_simple/sample_inputs/sample3.bin (renamed from unicorn_mode/samples/simple/sample_inputs/sample3.bin)0
-rw-r--r--unicorn_mode/samples/python_simple/sample_inputs/sample4.bin (renamed from unicorn_mode/samples/simple/sample_inputs/sample4.bin)0
-rw-r--r--unicorn_mode/samples/python_simple/sample_inputs/sample5.bin (renamed from unicorn_mode/samples/simple/sample_inputs/sample5.bin)0
-rw-r--r--unicorn_mode/samples/python_simple/simple_target.bin (renamed from unicorn_mode/samples/simple/simple_target.bin)bin256 -> 256 bytes
-rw-r--r--unicorn_mode/samples/python_simple/simple_target.c (renamed from unicorn_mode/samples/simple/simple_target.c)0
-rw-r--r--unicorn_mode/samples/python_simple/simple_test_harness.py (renamed from unicorn_mode/samples/simple/simple_test_harness.py)6
-rw-r--r--unicorn_mode/samples/python_simple/simple_test_harness_alt.py (renamed from unicorn_mode/samples/simple/simple_test_harness_alt.py)2
-rw-r--r--unicorn_mode/samples/speedtest/README.md48
-rw-r--r--unicorn_mode/samples/speedtest/c/Makefile36
-rw-r--r--unicorn_mode/samples/speedtest/c/harness.c9
-rw-r--r--unicorn_mode/samples/speedtest/rust/Cargo.toml2
m---------unicorn_mode/unicornafl0
23 files changed, 194 insertions, 192 deletions
diff --git a/unicorn_mode/README.md b/unicorn_mode/README.md
index 0f28cf96..ce87a2e9 100644
--- a/unicorn_mode/README.md
+++ b/unicorn_mode/README.md
@@ -1,74 +1,81 @@
 # Unicorn-based binary-only instrumentation for afl-fuzz
 
-The idea and much of the original implementation comes from Nathan Voss <njvoss299@gmail.com>.
+The idea and much of the original implementation comes from Nathan Voss
+<njvoss299@gmail.com>.
 
 The port to AFL++ is by Dominik Maier <mail@dmnk.co>.
 
-The CompareCoverage and NeverZero counters features are by Andrea Fioraldi <andreafioraldi@gmail.com>.
+The CompareCoverage and NeverZero counters features are by Andrea Fioraldi
+<andreafioraldi@gmail.com>.
 
 ## 1) Introduction
 
-The code in ./unicorn_mode allows you to build the
-(Unicorn Engine)[https://github.com/unicorn-engine/unicorn] with AFL++ support.
-This means, you can run anything that can be emulated in unicorn and obtain instrumentation
-output for black-box, closed-source binary code snippets. This mechanism
-can be then used by afl-fuzz to stress-test targets that couldn't be built
-with afl-cc or used in QEMU mode.
+The code in [unicorn_mode/](./) allows you to build the
+[Unicorn Engine](https://github.com/unicorn-engine/unicorn) with AFL++ support.
+This means, you can run anything that can be emulated in unicorn and obtain
+instrumentation output for black-box, closed-source binary code snippets. This
+mechanism can be then used by afl-fuzz to stress-test targets that couldn't be
+built with afl-cc or used in QEMU mode.
 
-There is a significant performance penalty compared to native AFL,
-but at least we're able to use AFL++ on these binaries, right?
+There is a significant performance penalty compared to native AFL, but at least
+we're able to use AFL++ on these binaries, right?
 
 ## 2) How to use
 
-First, you will need a working harness for your target in unicorn, using Python, C, or Rust.
-For some pointers for more advanced emulation, take a look at [BaseSAFE](https://github.com/fgsect/BaseSAFE) and [Qiling](https://github.com/qilingframework/qiling).
+First, you will need a working harness for your target in unicorn, using Python,
+C, or Rust.
 
-### Building AFL++'s Unicorn Mode
+For some pointers for more advanced emulation, take a look at
+[BaseSAFE](https://github.com/fgsect/BaseSAFE) and
+[Qiling](https://github.com/qilingframework/qiling).
 
-First, make AFL++ as usual.
-Once that completes successfully you need to build and add in the Unicorn Mode
-features:
+### Building AFL++'s Unicorn mode
+
+First, make AFL++ as usual. Once that completes successfully, you need to build
+and add in the Unicorn mode features:
 
 ```
 cd unicorn_mode
 ./build_unicorn_support.sh
 ```
 
-NOTE: This script checks out a Unicorn Engine fork as submodule that has been tested
-and is stable-ish, based on the unicorn engine `next` branch.
-
-Building Unicorn will take a little bit (~5-10 minutes). Once it completes
-it automatically compiles a sample application and verifies that it works.
-
-### Fuzzing with Unicorn Mode
-
-To use unicorn-mode effectively you need to prepare the following:
-
-	* Relevant binary code to be fuzzed
-	* Knowledge of the memory map and good starting state
-	* Folder containing sample inputs to start fuzzing with
-		+ Same ideas as any other AFL++ inputs
-		+ Quality/speed of results will depend greatly on the quality of starting
-		  samples
-		+ See AFL's guidance on how to create a sample corpus
-	* Unicornafl-based test harness in Rust, C, or Python, which:
-		+ Adds memory map regions
-		+ Loads binary code into memory
-		+ Calls uc.afl_fuzz() / uc.afl_start_forkserver
-		+ Loads and verifies data to fuzz from a command-line specified file
-			+ AFL++ will provide mutated inputs by changing the file passed to
-			  the test harness
-			+ Presumably the data to be fuzzed is at a fixed buffer address
-			+ If input constraints (size, invalid bytes, etc.) are known they
-			  should be checked in the place_input handler. If a constraint
-			  fails, just return false from the handler. AFL++ will treat the input as 'uninteresting' and move on.
-		+ Sets up registers and memory state for beginning of test
-		+ Emulates the interesting code from beginning to end
-		+ If a crash is detected, the test harness must 'crash' by
-		  throwing a signal (SIGSEGV, SIGKILL, SIGABORT, etc.), or indicate a crash in the crash validation callback.
-
-Once you have all those things ready to go you just need to run afl-fuzz in
-'unicorn-mode' by passing in the '-U' flag:
+NOTE: This script checks out a Unicorn Engine fork as submodule that has been
+tested and is stable-ish, based on the unicorn engine `next` branch.
+
+Building Unicorn will take a little bit (~5-10 minutes). Once it completes, it
+automatically compiles a sample application and verifies that it works.
+
+### Fuzzing with Unicorn mode
+
+To use unicorn-mode effectively, you need to prepare the following:
+
+* Relevant binary code to be fuzzed
+* Knowledge of the memory map and good starting state
+* Folder containing sample inputs to start fuzzing with
+    * Same ideas as any other AFL++ inputs
+    * Quality/speed of results will depend greatly on the quality of starting
+      samples
+    * See AFL's guidance on how to create a sample corpus
+* Unicornafl-based test harness in Rust, C, or Python, which:
+    * Adds memory map regions
+    * Loads binary code into memory
+    * Calls uc.afl_fuzz() / uc.afl_start_forkserver
+    * Loads and verifies data to fuzz from a command-line specified file
+        * AFL++ will provide mutated inputs by changing the file passed to the
+          test harness
+        * Presumably the data to be fuzzed is at a fixed buffer address
+        * If input constraints (size, invalid bytes, etc.) are known, they
+          should be checked in the place_input handler. If a constraint fails,
+          just return false from the handler. AFL++ will treat the input as
+          'uninteresting' and move on.
+    * Sets up registers and memory state to start testing
+    * Emulates the interesting code from beginning to end
+    * If a crash is detected, the test harness must 'crash' by throwing a signal
+      (SIGSEGV, SIGKILL, SIGABORT, etc.), or indicate a crash in the crash
+      validation callback.
+
+Once you have all those things ready to go, you just need to run afl-fuzz in
+`unicorn-mode` by passing in the `-U` flag:
 
 ```
 afl-fuzz -U -m none -i /path/to/inputs -o /path/to/results -- ./test_harness @@
@@ -78,39 +85,45 @@ The normal afl-fuzz command line format applies to everything here. Refer to
 AFL's main documentation for more info about how to use afl-fuzz effectively.
 
 For a much clearer vision of what all of this looks like, refer to the sample
-provided in the 'unicorn_mode/samples' directory. There is also a blog post that
+provided in the [samples/](./samples/) directory. There is also a blog post that
 uses slightly older concepts, but describes the general ideas, at:
 
 [https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf](https://medium.com/@njvoss299/afl-unicorn-fuzzing-arbitrary-binary-code-563ca28936bf)
 
-The ['helper_scripts'](./helper_scripts) directory also contains several helper scripts that allow you
-to dump context from a running process, load it, and hook heap allocations. For details
-on how to use this check out the follow-up blog post to the one linked above.
+The [helper_scripts/](./helper_scripts/) directory also contains several helper
+scripts that allow you to dump context from a running process, load it, and hook
+heap allocations. For details on how to use this, check out the follow-up blog
+post to the one linked above:
+
+[https://hackernoon.com/afl-unicorn-part-2-fuzzing-the-unfuzzable-bea8de3540a5](https://hackernoon.com/afl-unicorn-part-2-fuzzing-the-unfuzzable-bea8de3540a5)
 
-A example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
+An example use of AFL-Unicorn mode is discussed in the paper Unicorefuzz:
 [https://www.usenix.org/conference/woot19/presentation/maier](https://www.usenix.org/conference/woot19/presentation/maier)
 
 ## 3) Options
 
-As for the QEMU-based instrumentation, unicornafl comes with a sub-instruction based instrumentation similar in purpose to laf-intel.
+As for the QEMU-based instrumentation, unicornafl comes with a sub-instruction
+based instrumentation similar in purpose to laf-intel.
 
-The options that enable Unicorn CompareCoverage are the same used for QEMU.
-This will split up each multi-byte compare to give feedback for each correct byte.
-`AFL_COMPCOV_LEVEL=1` is to instrument comparisons with only immediate values.
+The options that enable Unicorn CompareCoverage are the same used for QEMU. This
+will split up each multi-byte compare to give feedback for each correct byte:
 
-`AFL_COMPCOV_LEVEL=2` instruments all comparison instructions.
+* `AFL_COMPCOV_LEVEL=1` to instrument comparisons with only immediate values.
+* `AFL_COMPCOV_LEVEL=2` to instrument all comparison instructions.
 
-Comparison instructions are currently instrumented only for the x86, x86_64 and ARM targets.
+Comparison instructions are currently instrumented only for the x86, x86_64, and
+ARM targets.
 
 ## 4) Gotchas, feedback, bugs
 
-Running the build script builds Unicornafl and its python bindings and installs
-them on your system.
-This installation will leave any existing Unicorn installations untouched.
-If you want to use unicornafl instead of unicorn in a script,
-replace all `unicorn` imports with `unicornafl` inputs, everything else should "just work".
-If you use 3rd party code depending on unicorn, you can use unicornafl monkeypatching:
-Before importing anything that depends on unicorn, do:
+Running the build script builds unicornafl and its Python bindings and installs
+them on your system. This installation will leave any existing Unicorn
+installations untouched.
+
+If you want to use unicornafl instead of unicorn in a script, replace all
+`unicorn` imports with `unicornafl` inputs, everything else should "just work".
+If you use 3rd party code depending on unicorn, you can use unicornafl
+monkeypatching. Before importing anything that depends on unicorn, do:
 
 ```python
 import unicornafl
@@ -119,20 +132,30 @@ unicornafl.monkeypatch()
 
 This will replace all unicorn imports with unicornafl inputs.
 
-5) Examples
+## 5) Examples
+
+Apart from reading the documentation in `afl.c` and the Python bindings of
+unicornafl, the best documentation are the [samples/](./samples).
 
-Apart from reading the documentation in `afl.c` and the python bindings of unicornafl, the best documentation are the [samples/](./samples).
 The following examples exist at the time of writing:
 
-- c: A simple example how to use the c bindings
-- compcov_x64: A python example that uses compcov to traverse hard-to-reach blocks
-- persistent: A c example using persistent mode for maximum speed, and resetting the target state between each iteration
-- simple: A simple python example
-- speedtest/c: The c harness for an example target, used to compare c, python, and rust bindings and fix speed issues
-- speedtest/python: Fuzzing the same target in python
-- speedtest/rust: Fuzzing the same target using a rust harness
-
-Usually, the place to look at is the `harness` in each folder. The source code in each harness is pretty well documented.
-Most harnesses also have the `afl-fuzz` commandline, or even offer a `make fuzz` Makefile target.
-Targets in these folders, if x86, can usually be made using `make target` in each folder or get shipped pre-built (plus their source).
-Especially take a look at the [speedtest documentation](./samples/speedtest/README.md) to see how the languages compare.
\ No newline at end of file
+- c: A simple example on how to use the C bindings
+- compcov_x64: A Python example that uses compcov to traverse hard-to-reach
+  blocks
+- persistent: A C example using persistent mode for maximum speed, and resetting
+  the target state between each iteration
+- simple: A simple Python example
+- speedtest/c: The C harness for an example target, used to compare C, Python,
+  and Rust bindings and fix speed issues
+- speedtest/python: Fuzzing the same target in Python
+- speedtest/rust: Fuzzing the same target using a Rust harness
+
+Usually, the place to look at is the `harness` in each folder. The source code
+in each harness is pretty well documented. Most harnesses also have the
+`afl-fuzz` commandline, or even offer a `make fuzz` Makefile target. Targets in
+these folders, if x86, can usually be made using `make target` in each folder or
+get shipped pre-built (plus their source).
+
+Especially take a look at the
+[speedtest documentation](./samples/speedtest/README.md) to see how the
+languages compare.
\ No newline at end of file
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 8b9c9fc0..4697a492 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-7b0c61f25042ebed910b88da2ca42778b858b852
+46879845
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index 340ac77c..74f9e174 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -180,8 +180,7 @@ sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
 git checkout "$UNICORNAFL_VERSION" || exit 1
 
 echo "[*] making sure afl++ header files match"
-cp "../../include/config.h" "." || exit 1
-cp "../../include/types.h" "." || exit 1
+cp "../../include/config.h" "./include" || exit 1
 
 echo "[*] Configuring Unicorn build..."
 
@@ -213,7 +212,7 @@ echo "[*] Unicornafl bindings installed successfully."
 # Compile the sample, run it, verify that it works!
 echo "[*] Testing unicornafl python functionality by running a sample test harness"
 
-cd ../samples/simple || echo "Cannot cd"
+cd ../samples/python_simple || echo "Cannot cd"
 
 # Run afl-showmap on the sample application. If anything comes out then it must have worked!
 unset AFL_INST_RATIO
diff --git a/unicorn_mode/samples/c/Makefile b/unicorn_mode/samples/c/Makefile
index cb491e10..fd6dbe77 100644
--- a/unicorn_mode/samples/c/Makefile
+++ b/unicorn_mode/samples/c/Makefile
@@ -4,29 +4,28 @@
 .POSIX:
 UNAME_S =$(shell uname -s)# GNU make
 UNAME_S:sh=uname -s       # BSD make
-_UNIQ=_QINU_
 
-LIBDIR = ../../unicornafl
+UNICORNAFL_LIB = ../../unicornafl/build
+UNICORN_LIB = ../../unicornafl/unicorn/build
 BIN_EXT =
 AR_EXT = a
 
 # Verbose output?
 V ?= 0
 
-CFLAGS += -Wall -Werror -I../../unicornafl/include
+CFLAGS += -Wall -Werror -I../../unicornafl/unicorn/include -I../../unicornafl/include
 
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
 
-_LRT = $(_UNIQ)$(UNAME_S:Linux=)
-__LRT = $(_LRT:$(_UNIQ)=-lrt)
-LRT = $(__LRT:$(_UNIQ)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT = 
+endif
 
 LDFLAGS += $(LRT)
 
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
 .PHONY: all clean
 
 all: harness
@@ -34,14 +33,20 @@ all: harness
 clean:
 	rm -rf *.o harness harness-debug
 
-harness.o: harness.c ../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -O3 -c harness.c
+harness.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -O3 -c harness.c
+
+harness-debug.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -g -c harness.c -o $@
 
-harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -g -c harness.c -o $@
+../../unicornafl/build/libunicornafl.a:
+	cd ../.. && ./build_unicorn_support.sh
 
 harness: harness.o
-	${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+	${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o $@
 
 debug: harness-debug.o
-	${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+	${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o harness-debug
+
+fuzz: harness
+	DYLD_FALLBACK_LIBRARY_PATH="../../unicornafl/unicorn/build" LD_LIBRARY_PATH="../../unicornafl/unicorn/build" ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
diff --git a/unicorn_mode/samples/c/harness.c b/unicorn_mode/samples/c/harness.c
index 4bda6e2d..30972ce7 100644
--- a/unicorn_mode/samples/c/harness.c
+++ b/unicorn_mode/samples/c/harness.c
@@ -8,7 +8,7 @@
 
    Run under AFL as follows:
 
-   $ cd <afl_path>/unicorn_mode/samples/simple/
+   $ cd <afl_path>/unicorn_mode/samples/c
    $ make
    $ ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
 */
@@ -26,6 +26,7 @@
 #include <sys/mman.h>
 
 #include <unicorn/unicorn.h>
+#include <unicornafl/unicornafl.h>
 
 // Path to the file containing the binary to emulate
 #define BINARY_FILE ("persistent_target_x86_64")
@@ -141,7 +142,7 @@ static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t
     //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);
+        printf("Error mapping %ld bytes at 0x%llx: %s (mode: %d)\n", size, (unsigned long long) addr, uc_strerror(err), (int) mode);
         exit(1);
     }
 }
@@ -184,7 +185,7 @@ int main(int argc, char **argv, char **envp) {
 
     // Map memory.
     mem_map_checked(uc, BASE_ADDRESS, len, UC_PROT_ALL);
-    printf("Len: %lx\n", len);
+    printf("Len: %lx\n", (unsigned long) len);
     fflush(stdout);
 
     // write machine code to be emulated to memory
diff --git a/unicorn_mode/samples/compcov_x64/compcov_test_harness.py b/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
index f0749d1b..52f0a286 100644
--- a/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
+++ b/unicorn_mode/samples/compcov_x64/compcov_test_harness.py
@@ -10,7 +10,7 @@
 
    Run under AFL as follows:
 
-   $ cd <afl_path>/unicorn_mode/samples/simple/
+   $ cd <afl_path>/unicorn_mode/samples/python_simple
    $ AFL_COMPCOV_LEVEL=2 ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python compcov_test_harness.py @@
 """
 
diff --git a/unicorn_mode/samples/persistent/Makefile b/unicorn_mode/samples/persistent/Makefile
index 80a47550..35584416 100644
--- a/unicorn_mode/samples/persistent/Makefile
+++ b/unicorn_mode/samples/persistent/Makefile
@@ -4,29 +4,28 @@
 .POSIX:
 UNAME_S =$(shell uname -s)# GNU make
 UNAME_S:sh=uname -s       # BSD make
-_UNIQ=_QINU_
 
-LIBDIR = ../../unicornafl
+UNICORNAFL_LIB = ../../unicornafl/build
+UNICORN_LIB = ../../unicornafl/unicorn/build
 BIN_EXT =
 AR_EXT = a
 
 # Verbose output?
 V ?= 0
 
-CFLAGS += -Wall -Werror -I../../unicornafl/include
+CFLAGS += -Wall -Werror -I../../unicornafl/unicorn/include -I../../unicornafl/include
 
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
 
-_LRT = $(_UNIQ)$(UNAME_S)
-__LRT = $(_LRT:$(_UNIQ)Linux=-lrt)
-LRT = $(__LRT:$(_UNIQ)$(UNAME_S)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT = 
+endif
 
 LDFLAGS += $(LRT)
 
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
 .PHONY: all clean
 
 all: harness
@@ -34,20 +33,23 @@ all: harness
 clean:
 	rm -rf *.o harness harness-debug
 
-harness.o: harness.c ../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -O3 -c harness.c
+harness.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -O3 -c harness.c
 
-harness-debug.o: harness.c ../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -DAFL_DEBUG=1 -g -c harness.c -o $@
+harness-debug.o: harness.c ../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -DAFL_DEBUG=1 -g -c harness.c -o $@
 
 harness: harness.o
-	${MYCC} -L${LIBDIR} harness.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+	${CC} harness.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o $@
 
 debug: harness-debug.o
-	${MYCC} -L${LIBDIR} harness-debug.o ../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+	${CC} harness-debug.o ../../unicornafl/build/libunicornafl.a $(LDFLAGS) -o harness-debug
+
+../../unicornafl/build/libunicornafl.a:
+	cd ../.. && ./build_unicorn_support.sh
 
 fuzz: harness
-	../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
+	DYLD_FALLBACK_LIBRARY_PATH="../../unicornafl/unicorn/build" LD_LIBRARY_PATH="../../unicornafl/unicorn/build" ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
 
 debugmake:
 	@echo UNAME_S=$(UNAME_S), _LRT=$(_LRT), __LRT=$(__LRT), LRT=$(LRT)
diff --git a/unicorn_mode/samples/persistent/harness.c b/unicorn_mode/samples/persistent/harness.c
index eae3f1fc..37b652e0 100644
--- a/unicorn_mode/samples/persistent/harness.c
+++ b/unicorn_mode/samples/persistent/harness.c
@@ -30,6 +30,7 @@
 #include <sys/mman.h>
 
 #include <unicorn/unicorn.h>
+#include <unicornafl/unicornafl.h>
 
 // Path to the file containing the binary to emulate
 #define BINARY_FILE ("persistent_target_x86_64")
diff --git a/unicorn_mode/samples/simple/COMPILE.md b/unicorn_mode/samples/python_simple/COMPILE.md
index f7bf5b50..f7bf5b50 100644
--- a/unicorn_mode/samples/simple/COMPILE.md
+++ b/unicorn_mode/samples/python_simple/COMPILE.md
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample1.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample1.bin
index 85df5078..85df5078 100644
--- a/unicorn_mode/samples/simple/sample_inputs/sample1.bin
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample1.bin
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample2.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample2.bin
index f76dd238..f76dd238 100644
--- a/unicorn_mode/samples/simple/sample_inputs/sample2.bin
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample2.bin
Binary files differdiff --git a/unicorn_mode/samples/simple/sample_inputs/sample3.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample3.bin
index 6b2aaa76..6b2aaa76 100644
--- a/unicorn_mode/samples/simple/sample_inputs/sample3.bin
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample3.bin
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample4.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample4.bin
index 71bd63e6..71bd63e6 100644
--- a/unicorn_mode/samples/simple/sample_inputs/sample4.bin
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample4.bin
diff --git a/unicorn_mode/samples/simple/sample_inputs/sample5.bin b/unicorn_mode/samples/python_simple/sample_inputs/sample5.bin
index aed2973e..aed2973e 100644
--- a/unicorn_mode/samples/simple/sample_inputs/sample5.bin
+++ b/unicorn_mode/samples/python_simple/sample_inputs/sample5.bin
diff --git a/unicorn_mode/samples/simple/simple_target.bin b/unicorn_mode/samples/python_simple/simple_target.bin
index 0095eb6c..0095eb6c 100644
--- a/unicorn_mode/samples/simple/simple_target.bin
+++ b/unicorn_mode/samples/python_simple/simple_target.bin
Binary files differdiff --git a/unicorn_mode/samples/simple/simple_target.c b/unicorn_mode/samples/python_simple/simple_target.c
index 49e1b4d8..49e1b4d8 100644
--- a/unicorn_mode/samples/simple/simple_target.c
+++ b/unicorn_mode/samples/python_simple/simple_target.c
diff --git a/unicorn_mode/samples/simple/simple_test_harness.py b/unicorn_mode/samples/python_simple/simple_test_harness.py
index cd04ad3a..8758192e 100644
--- a/unicorn_mode/samples/simple/simple_test_harness.py
+++ b/unicorn_mode/samples/python_simple/simple_test_harness.py
@@ -10,7 +10,7 @@
 
    Run under AFL as follows:
 
-   $ cd <afl_path>/unicorn_mode/samples/simple/
+   $ cd <afl_path>/unicorn_mode/samples/python_simple
    $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness.py @@ 
 """
 
@@ -19,7 +19,7 @@ import os
 import signal
 
 from unicornafl import *
-from unicornafl.mips_const import *
+from unicorn.mips_const import *
 
 # Path to the file containing the binary to emulate
 BINARY_FILE = os.path.join(
@@ -156,7 +156,7 @@ def main():
         uc.mem_write(DATA_ADDRESS, input)
 
     # Start the fuzzer.
-    uc.afl_fuzz(args.input_file, place_input_callback, [end_address])
+    uc_afl_fuzz(uc=uc, input_file=args.input_file, place_input_callback=place_input_callback, exits=[end_address])
 
 
 if __name__ == "__main__":
diff --git a/unicorn_mode/samples/simple/simple_test_harness_alt.py b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
index 3249b13d..5fb3f82f 100644
--- a/unicorn_mode/samples/simple/simple_test_harness_alt.py
+++ b/unicorn_mode/samples/python_simple/simple_test_harness_alt.py
@@ -13,7 +13,7 @@
 
    Run under AFL as follows:
 
-   $ cd <afl_path>/unicorn_mode/samples/simple/
+   $ cd <afl_path>/unicorn_mode/samples/python_simple
    $ ../../../afl-fuzz -U -m none -i ./sample_inputs -o ./output -- python simple_test_harness_alt.py @@ 
 """
 
diff --git a/unicorn_mode/samples/speedtest/README.md b/unicorn_mode/samples/speedtest/README.md
index bd5ba8d0..f46a5772 100644
--- a/unicorn_mode/samples/speedtest/README.md
+++ b/unicorn_mode/samples/speedtest/README.md
@@ -5,7 +5,11 @@ to show the raw speed of C, Rust, and Python harnesses.
 
 ## Compiling...
 
-Make sure, you built unicornafl first (`../../build_unicorn_support.sh`).
+Make sure you built unicornafl first (`../../build_unicorn_support.sh`).
+Build the target using the provided Makefile.
+This will also run the [./get_offsets.py](./get_offsets.py) script,
+which finds some relevant addresses in the target binary using `objdump`,
+and dumps them to different files.
 Then, follow these individual steps:
 
 ### Rust
@@ -13,7 +17,7 @@ Then, follow these individual steps:
 ```bash
 cd rust
 cargo build --release
-../../../afl-fuzz -i ../sample_inputs -o out -- ./target/release/harness @@
+../../../../afl-fuzz -i ../sample_inputs -o out -U -- ./target/release/harness @@
 ```
 
 ### C
@@ -21,52 +25,16 @@ cargo build --release
 ```bash
 cd c
 make
-../../../afl-fuzz -i ../sample_inputs -o out -- ./harness @@
+../../../../afl-fuzz -i ../sample_inputs -o out -U -- ./harness @@
 ```
 
 ### python
 
 ```bash
 cd python
-../../../afl-fuzz -i ../sample_inputs -o out -U -- python3 ./harness.py @@
+../../../../afl-fuzz -i ../sample_inputs -o out -U -- python3 ./harness.py @@
 ```
 
 ## Results
 
 TODO: add results here.
-
-## Compiling speedtest_target.c
-
-You shouldn't need to compile simple_target.c since a X86_64 binary version is
-pre-built and shipped in this sample folder. This file documents how the binary
-was built in case you want to rebuild it or recompile it for any reason.
-
-The pre-built binary (simple_target_x86_64.bin) was built using -g -O0 in gcc.
-
-Then load the binary and execute the main function directly.
-
-## Addresses for the harness
-
-To find the address (in hex) of main, run:
-
-```bash
-objdump -M intel -D target | grep '<main>:' | cut -d" " -f1
-```
-
-To find all call sites to magicfn, run:
-
-```bash
-objdump -M intel -D target | grep '<magicfn>$' | cut -d":" -f1
-```
-
-For malloc callsites:
-
-```bash
-objdump -M intel -D target | grep '<malloc@plt>$' | cut -d":" -f1
-```
-
-And free callsites:
-
-```bash
-objdump -M intel -D target | grep '<free@plt>$' | cut -d":" -f1
-```
\ No newline at end of file
diff --git a/unicorn_mode/samples/speedtest/c/Makefile b/unicorn_mode/samples/speedtest/c/Makefile
index 46789954..d34f49fa 100644
--- a/unicorn_mode/samples/speedtest/c/Makefile
+++ b/unicorn_mode/samples/speedtest/c/Makefile
@@ -4,29 +4,28 @@
 .POSIX:
 UNAME_S =$(shell uname -s)# GNU make
 UNAME_S:sh=uname -s       # BSD make
-_UNIQ=_QINU_
 
-LIBDIR = ../../../unicornafl
+UNICORNAFL_LIB = ../../../unicornafl/build
+UNICORN_LIB = ../../../unicornafl/unicorn/build
 BIN_EXT =
 AR_EXT = a
 
 # Verbose output?
 V ?= 0
 
-CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -I../../../unicornafl/include
+CFLAGS += -Wall -I../../../unicornafl/unicorn/include -I../../../unicornafl/include
 
-LDFLAGS += -L$(LIBDIR) -lpthread -lm
+LDFLAGS += -L$(UNICORNAFL_LIB) -L$(UNICORN_LIB) -lpthread -lm -lunicornafl -lunicorn -lc++
 
-_LRT = $(_UNIQ)$(UNAME_S:Linux=)
-__LRT = $(_LRT:$(_UNIQ)=-lrt)
-LRT = $(__LRT:$(_UNIQ)=)
+ifeq ($(UNAME), Linux)
+# do something Linux-y
+LRT = -lrt
+else
+LRT = 
+endif
 
 LDFLAGS += $(LRT)
 
-_CC = $(_UNIQ)$(CROSS)
-__CC = $(_CC:$(_UNIQ)=$(CC))
-MYCC = $(__CC:$(_UNIQ)$(CROSS)=$(CROSS)gcc)
-
 .PHONY: all clean
 
 all: ../target harness
@@ -38,17 +37,20 @@ afl-fuzz: ../../../../afl-fuzz
 clean:
 	rm -rf *.o harness harness-debug
 
-harness.o: harness.c ../../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -O3 -c harness.c -o $@
+../../../unicornafl/build/libunicornafl.a:
+	cd ../../.. && ./build_unicorn_support.sh
+
+harness.o: harness.c ../../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -O3 -c harness.c -o $@
 
-harness-debug.o: harness.c ../../../unicornafl/include/unicorn/*.h
-	${MYCC} ${CFLAGS} -fsanitize=address -g -Og -c harness.c -o $@
+harness-debug.o: harness.c ../../../unicornafl/unicorn/include/unicorn/*.h
+	${CC} ${CFLAGS} -fsanitize=address -g -Og -c harness.c -o $@
 
 harness: harness.o
-	${MYCC} -L${LIBDIR} harness.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o $@
+	${CC} harness.o $(LDFLAGS) -o $@
 
 harness-debug: harness-debug.o
-	${MYCC} -fsanitize=address -g -Og -L${LIBDIR} harness-debug.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
+	${CC} -fsanitize=address -g -Og harness-debug.o ../../../unicornafl/libunicornafl.a $(LDFLAGS) -o harness-debug
 
 ../target:
 	$(MAKE) -C ..
diff --git a/unicorn_mode/samples/speedtest/c/harness.c b/unicorn_mode/samples/speedtest/c/harness.c
index e8de3d80..184934b9 100644
--- a/unicorn_mode/samples/speedtest/c/harness.c
+++ b/unicorn_mode/samples/speedtest/c/harness.c
@@ -8,9 +8,9 @@
 
    Run under AFL as follows:
 
-   $ cd <afl_path>/unicorn_mode/samples/simple/
+   $ cd <afl_path>/unicorn_mode/samples/speedtest/c
    $ make
-   $ ../../../afl-fuzz -m none -i sample_inputs -o out -- ./harness @@
+   $ ../../../../afl-fuzz -i ../sample_inputs -o out -U -- ./harness @@
 */
 
 // This is not your everyday Unicorn.
@@ -28,6 +28,7 @@
 #include <sys/mman.h>
 
 #include <unicorn/unicorn.h>
+#include <unicornafl/unicornafl.h>
 
 // Path to the file containing the binary to emulate
 #define BINARY_FILE ("../target")
@@ -124,7 +125,7 @@ static void mem_map_checked(uc_engine *uc, uint64_t addr, size_t size, uint32_t
     //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);
+        printf("Error mapping %ld bytes at 0x%llx: %s (mode: %d)\n", (unsigned long) size, (unsigned long long) addr, uc_strerror(err), (int) mode);
         exit(1);
     }
 }
@@ -306,7 +307,7 @@ int main(int argc, char **argv, char **envp) {
         exit(-1);
     }
     uint64_t start_address;
-    if(fscanf(f, "%lx", &start_address) == EOF) {
+    if(fscanf(f, "%llx", (unsigned long long) &start_address) == EOF) {
         puts("Start address not found in target.offests.main");
         exit(-1);
     }
diff --git a/unicorn_mode/samples/speedtest/rust/Cargo.toml b/unicorn_mode/samples/speedtest/rust/Cargo.toml
index 9b81be0b..766b2f27 100644
--- a/unicorn_mode/samples/speedtest/rust/Cargo.toml
+++ b/unicorn_mode/samples/speedtest/rust/Cargo.toml
@@ -1,5 +1,5 @@
 [package]
-name = "unicornafl_harness"
+name = "harness"
 version = "0.1.0"
 authors = ["Dominik Maier <domenukk@gmail.com>"]
 edition = "2018"
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject 7b0c61f25042ebed910b88da2ca42778b858b85
+Subproject 468798455a9f9790d2da369a18ed49fda3a64e8