about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2022-01-21 13:06:15 +0100
committerGitHub <noreply@github.com>2022-01-21 13:06:15 +0100
commit2bb86863e6d15dbd5bb0c381afa51f476302784e (patch)
tree020fb8d0b012d5ebfd7ded0b32c00b79851a0532
parentb4c2fc94166b22a77c521884a07fdfee2098147a (diff)
parent26a3d1b53b0a3ae690735c550c2985f079f3c672 (diff)
downloadafl++-2bb86863e6d15dbd5bb0c381afa51f476302784e.tar.gz
Merge branch 'dev' into docs_quality_assurance_3
-rw-r--r--Android.bp18
-rw-r--r--GNUmakefile9
-rw-r--r--include/forkserver.h8
-rw-r--r--nyx_mode/LIBNYX_VERSION2
-rw-r--r--nyx_mode/PACKER_VERSION2
-rw-r--r--nyx_mode/QEMU_NXY_VERSION1
-rw-r--r--nyx_mode/QEMU_NYX_VERSION1
-rw-r--r--nyx_mode/README.md14
-rwxr-xr-xnyx_mode/build_nyx_support.sh2
-rw-r--r--nyx_mode/custom_harness/example.c206
-rwxr-xr-xnyx_mode/update_ref.sh2
-rw-r--r--src/afl-cc.c8
-rw-r--r--src/afl-forkserver.c21
-rw-r--r--src/afl-fuzz.c9
-rw-r--r--unicorn_mode/UNICORNAFL_VERSION2
m---------unicorn_mode/unicornafl0
-rw-r--r--utils/aflpp_driver/aflpp_driver.c92
17 files changed, 266 insertions, 131 deletions
diff --git a/Android.bp b/Android.bp
index bf37757d..ac1d5cb6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,3 +1,11 @@
+//
+// NOTE: This file is outdated. None of the AFL++ team uses Android hence
+//       we need users to keep this updated.
+//       In the current state it will likely fail, please send fixes!
+//       Also, this should build frida_mode.
+//
+
+
 cc_defaults {
   name: "afl-defaults",
 
@@ -175,7 +183,7 @@ cc_binary_host {
 }
 
 cc_library_static {
-  name: "afl-llvm-rt",
+  name: "afl-compiler-rt",
   compile_multilib: "64",
   vendor_available: true,
   host_supported: true,
@@ -225,6 +233,7 @@ cc_library_headers {
   ],
 }
 
+/*
 cc_prebuilt_library_static {
   name: "libfrida-gum",
   compile_multilib: "64",
@@ -272,7 +281,7 @@ cc_binary {
   ],
 
   static_libs: [
-    "afl-llvm-rt",
+    "afl-compiler-rt",
     "libfrida-gum",
   ],
 
@@ -290,6 +299,7 @@ cc_binary {
     "utils/afl_frida/android",
   ],
 }
+*/
 
 cc_binary {
   name: "afl-fuzz-32",
@@ -346,7 +356,7 @@ cc_binary_host {
 }
 
 cc_library_static {
-  name: "afl-llvm-rt-32",
+  name: "afl-compiler-rt-32",
   compile_multilib: "32",
   vendor_available: true,
   host_supported: true,
@@ -385,6 +395,7 @@ cc_library_static {
   ],
 }
 
+/*
 cc_prebuilt_library_static {
   name: "libfrida-gum-32",
   compile_multilib: "32",
@@ -400,6 +411,7 @@ cc_prebuilt_library_static {
     "utils/afl_frida/android/arm",
   ],
 }
+*/
 
 subdirs = [
   "custom_mutators",
diff --git a/GNUmakefile b/GNUmakefile
index 527cdcfc..9efb22c2 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -578,10 +578,12 @@ clean:
 	$(MAKE) -C qemu_mode/libcompcov clean
 	$(MAKE) -C qemu_mode/libqasan clean
 	-$(MAKE) -C frida_mode clean
+	rm -rf nyx_mode/packer/linux_initramfs/init.cpio.gz nyx_mode/libnyx/libnyx/target/release/* nyx_mode/QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64
 ifeq "$(IN_REPO)" "1"
 	-test -e coresight_mode/coresight-trace/Makefile && $(MAKE) -C coresight_mode/coresight-trace clean || true
 	-test -e qemu_mode/qemuafl/Makefile && $(MAKE) -C qemu_mode/qemuafl clean || true
-	test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
+	-test -e unicorn_mode/unicornafl/Makefile && $(MAKE) -C unicorn_mode/unicornafl clean || true
+	-test -e nyx_mode/QEMU-Nyx/Makefile && $(MAKE) -C nyx_mode/QEMU-Nyx clean || true
 else
 	rm -rf coresight_mode/coresight_trace
 	rm -rf qemu_mode/qemuafl
@@ -593,11 +595,14 @@ deepclean:	clean
 	rm -rf coresight_mode/coresight-trace
 	rm -rf unicorn_mode/unicornafl
 	rm -rf qemu_mode/qemuafl
+	rm -rf nyx_mode/libnyx nyx_mode/packer nyx_mode/QEMU-Nyx
 ifeq "$(IN_REPO)" "1"
-# NEVER EVER ACTIVATE THAT!!!!! git reset --hard >/dev/null 2>&1 || true
 	git checkout coresight_mode/coresight-trace
 	git checkout unicorn_mode/unicornafl
 	git checkout qemu_mode/qemuafl
+	git checkout nyx_mode/libnyx
+	git checkout nyx_mode/packer
+	git checkout nyx_mode/QEMU-Nyx
 endif
 
 .PHONY: distrib
diff --git a/include/forkserver.h b/include/forkserver.h
index 48db2e26..4a05b17e 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -54,7 +54,13 @@ typedef enum NyxReturnValue {
 typedef struct {
 
   void *(*nyx_new)(const char *sharedir, const char *workdir,
-                   uint32_t worker_id, uint32_t cpu_id, bool create_snapshot);
+                   uint32_t cpu_id, uint32_t input_buffer_size, 
+                   bool input_buffer_write_protection);
+  void *(*nyx_new_parent)(const char *sharedir, const char *workdir,
+                   uint32_t cpu_id, uint32_t input_buffer_size,
+                   bool input_buffer_write_protection);
+  void *(*nyx_new_child)(const char *sharedir, const char *workdir,
+                   uint32_t cpu_id, uint32_t worker_id);
   void (*nyx_shutdown)(void *qemu_process);
   void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable);
   void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec,
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 1ac5611b..109c3c6f 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-ecbcb2d
+a5ae4c1
diff --git a/nyx_mode/PACKER_VERSION b/nyx_mode/PACKER_VERSION
index 2596e40f..0c9db1e3 100644
--- a/nyx_mode/PACKER_VERSION
+++ b/nyx_mode/PACKER_VERSION
@@ -1 +1 @@
-f91742c
+8842549
diff --git a/nyx_mode/QEMU_NXY_VERSION b/nyx_mode/QEMU_NXY_VERSION
deleted file mode 100644
index d2f0328b..00000000
--- a/nyx_mode/QEMU_NXY_VERSION
+++ /dev/null
@@ -1 +0,0 @@
-acc90e462b
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
new file mode 100644
index 00000000..96133165
--- /dev/null
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -0,0 +1 @@
+902306beb0
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index f5350164..b75f1793 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -46,12 +46,9 @@ requires an Intel processor (6th generation onwards) and a special 5.10 kernel
 Nyx uses full system emulation hence your fuzzing targets have to be especially
 packaged.
 
-**For source code based instrumentation with `afl-clang-fast` for the time
-being these must be instrumented to `AFL_LLVM_INSTRUMENT=AFL` to work!**
-
 With your target ready at hand execute the following command
 (note that for binary-only fuzzing with the special 5.10 kernel switch the
-option `instrumentation` below with `process_trace`):
+option `instrumentation` below with `processor_trace`):
 
 ```shell
 python3 nyx_mode/packer/packer/nyx_packer.py \
@@ -130,10 +127,9 @@ git clone https://gitlab.gnome.org/GNOME/libxml2
 cd libxml2
 ```
 
-Remember that currently only classic AFL instrumentation is supported!
+Next, compile libxml2:
 
-```
-export AFL_LLVM_INSTRUMENT=AFL
+``` 
 ./autogen.sh
 ./configure --enable-shared=no
 make CC=afl-clang-fast CXX=afl-clang-fast++ LD=afl-clang-fast
@@ -294,8 +290,8 @@ mkdir /tmp/nyx_custom_agent/
 To compile this example, run the following command (remove the `-DNO_PT_NYX`
 option if you are using KVM-Nyx):
 
-```
-gcc example.c -DNO_PT_NYX -static -I ./packer/ -o /tmp/nyx_custom_agent/target
+``` 
+gcc example.c -DNO_PT_NYX -static -I ../packer/ -o /tmp/nyx_custom_agent/target
 ```
 
 Copy both bootstrap scripts into the sharedir:
diff --git a/nyx_mode/build_nyx_support.sh b/nyx_mode/build_nyx_support.sh
index 8626342d..b6c1d54e 100755
--- a/nyx_mode/build_nyx_support.sh
+++ b/nyx_mode/build_nyx_support.sh
@@ -53,7 +53,7 @@ fi
 echo "[*] Checking QEMU-Nyx ..."
 if [ ! -f "QEMU-Nyx/x86_64-softmmu/qemu-system-x86_64" ]; then
     cd QEMU-Nyx/
-    ./compile_qemu_nyx.sh || exit 1
+    ./compile_qemu_nyx.sh static || exit 1
     cd ..
 fi
 
diff --git a/nyx_mode/custom_harness/example.c b/nyx_mode/custom_harness/example.c
index 0b12e60b..00b516a2 100644
--- a/nyx_mode/custom_harness/example.c
+++ b/nyx_mode/custom_harness/example.c
@@ -4,88 +4,134 @@
 #include <inttypes.h>
 #include "nyx.h"
 
-/* this is our "bitmap" that is later shared with the fuzzer (you can also pass the pointer of the bitmap used by compile-time instrumentations in your target) */ 
-uint8_t* trace_buffer[64*1024] = {0};
-
-int main(int argc, char** argv){
-	/* if you want to debug code running in Nyx, hprintf() is the way to go. 
-	*  Long story short -- it's just a guest-to-hypervisor printf. Hence the name "hprintf" 
-	*/
-	hprintf("Agent test\n");
-
-	/* Request information on available (host) capabilites (optional) */
-	host_config_t host_config;
-    kAFL_hypercall(HYPERCALL_KAFL_GET_HOST_CONFIG, (uintptr_t)&host_config);
-	hprintf("[capablities] host_config.bitmap_size: 0x%"PRIx64"\n", host_config.bitmap_size);
-    hprintf("[capablities] host_config.ijon_bitmap_size: 0x%"PRIx64"\n", host_config.ijon_bitmap_size);
-    hprintf("[capablities] host_config.payload_buffer_size: 0x%"PRIx64"x\n", host_config.payload_buffer_size);
-	
-	/* Submit agent configuration */
-	memset(trace_buffer, 0, 64*1024); // makes sure that the bitmap buffer is already mapped into the guest's memory (alternatively you can use mlock) */
-	agent_config_t agent_config = {0};
-	agent_config.agent_timeout_detection = 0; 								/* timeout detection is implemented by the agent (currently not used) */
-	agent_config.agent_tracing = 1;											/* set this flag to propagade that instrumentation-based fuzzing is availabe */
-	agent_config.agent_ijon_tracing = 0; 									/* set this flag to propagade that IJON extension is implmented agent-wise */
-	agent_config.trace_buffer_vaddr = (uintptr_t)trace_buffer;				/* trace "bitmap" pointer - required for instrumentation-only fuzzing */
-	agent_config.ijon_trace_buffer_vaddr = (uintptr_t)NULL;					/* "IJON" buffer pointer */
-    agent_config.agent_non_reload_mode = 1;									/* non-reload mode is supported (usually because the agent implements a fork-server; currently not used) */
-    kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
-
-	/* Tell hypervisor the virtual address of the payload (input) buffer (call mlock to ensure that this buffer stays in the guest's memory)*/
-	kAFL_payload* payload_buffer = mmap((void*)0x4000000ULL, PAYLOAD_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
-	mlock(payload_buffer, (size_t)PAYLOAD_SIZE);
-	memset(payload_buffer, 0, PAYLOAD_SIZE);
-	kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
-	hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
-
-	/* the main fuzzing loop */
-	while(1){
-
-		/* Creates a root snapshot on first execution. Also we requested the next input with this hypercall */
-		kAFL_hypercall(HYPERCALL_KAFL_USER_FAST_ACQUIRE, 0); // root snapshot <--
+#define TRACE_BUFFER_SIZE (1024 * 64)
+
+int main(int argc, char **argv) {
+
+  /* if you want to debug code running in Nyx, hprintf() is the way to go.
+   *  Long story short -- it's just a guest-to-hypervisor printf. Hence the name
+   * "hprintf"
+   */
+  hprintf("Agent test\n");
+
+  /* Request information on available (host) capabilites (optional) */
+  host_config_t host_config;
+  kAFL_hypercall(HYPERCALL_KAFL_GET_HOST_CONFIG, (uintptr_t)&host_config);
+  hprintf("[capablities] host_config.bitmap_size: 0x%" PRIx64 "\n",
+          host_config.bitmap_size);
+  hprintf("[capablities] host_config.ijon_bitmap_size: 0x%" PRIx64 "\n",
+          host_config.ijon_bitmap_size);
+  hprintf("[capablities] host_config.payload_buffer_size: 0x%" PRIx64 "x\n",
+          host_config.payload_buffer_size);
+
+  /* this is our "bitmap" that is later shared with the fuzzer (you can also
+   * pass the pointer of the bitmap used by compile-time instrumentations in
+   * your target) */
+  uint8_t *trace_buffer = mmap(NULL, TRACE_BUFFER_SIZE, PROT_READ | PROT_WRITE,
+                               MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  memset(trace_buffer, 0,
+         TRACE_BUFFER_SIZE);  // makes sure that the bitmap buffer is already
+                              // mapped into the guest's memory (alternatively
+                              // you can use mlock) */
+
+  /* Submit agent configuration */
+  agent_config_t agent_config = {0};
+  agent_config.agent_magic = NYX_AGENT_MAGIC;
+  agent_config.agent_version = NYX_AGENT_VERSION;
+  agent_config.agent_timeout_detection =
+      0; /* timeout detection is implemented by the agent (currently not used)
+          */
+  agent_config.agent_tracing =
+      1; /* set this flag to propagade that instrumentation-based fuzzing is
+            availabe */
+  agent_config.agent_ijon_tracing = 0; /* set this flag to propagade that IJON
+                                          extension is implmented agent-wise */
+  agent_config.trace_buffer_vaddr =
+      (uintptr_t)trace_buffer; /* trace "bitmap" pointer - required for
+                                  instrumentation-only fuzzing */
+  agent_config.ijon_trace_buffer_vaddr =
+      (uintptr_t)NULL;                             /* "IJON" buffer pointer */
+  agent_config.agent_non_reload_mode =
+      1; /* non-reload mode is supported (usually because the agent implements a
+            fork-server; currently not used) */
+  agent_config.coverage_bitmap_size = TRACE_BUFFER_SIZE;
+  kAFL_hypercall(HYPERCALL_KAFL_SET_AGENT_CONFIG, (uintptr_t)&agent_config);
+
+  /* Tell hypervisor the virtual address of the payload (input) buffer (call
+   * mlock to ensure that this buffer stays in the guest's memory)*/
+  kAFL_payload *payload_buffer =
+      mmap(NULL, host_config.payload_buffer_size, PROT_READ | PROT_WRITE,
+           MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+  mlock(payload_buffer, (size_t)host_config.payload_buffer_size);
+  memset(payload_buffer, 0, host_config.payload_buffer_size);
+  kAFL_hypercall(HYPERCALL_KAFL_GET_PAYLOAD, (uintptr_t)payload_buffer);
+  hprintf("[init] payload buffer is mapped at %p\n", payload_buffer);
+
+  /* the main fuzzing loop */
+  while (1) {
+
+    /* Creates a root snapshot on first execution. Also we requested the next
+     * input with this hypercall */
+    kAFL_hypercall(HYPERCALL_KAFL_USER_FAST_ACQUIRE, 0);  // root snapshot <--
 
 #ifdef DEBUG
-		hprintf("Size: %ld Data: %x %x %x %x\n", payload_buffer->size,
-								payload_buffer->data[4],
-								payload_buffer->data[5],
-								payload_buffer->data[6],
-								payload_buffer->data[7]
-								);
+    hprintf("Size: %ld Data: %x %x %x %x\n", payload_buffer->size,
+            payload_buffer->data[4], payload_buffer->data[5],
+            payload_buffer->data[6], payload_buffer->data[7]);
 #endif
 
-		uint32_t len = payload_buffer->size;
-
-		/* set a byte to make AFL++ happy (otherwise the fuzzer might refuse to start fuzzing at all) */
-		((uint8_t*)trace_buffer)[0] = 0x1;
-
-		if (len >= 4){
-			/* set a byte in the bitmap to guide your fuzzer */
-			((uint8_t*)trace_buffer)[0] = 0x1;
-			if (payload_buffer->data[0] == '!'){
-				((uint8_t*)trace_buffer)[1] = 0x1;
-				if (payload_buffer->data[1] == 'N'){
-					((uint8_t*)trace_buffer)[2] = 0x1;
-					if (payload_buffer->data[2] == 'Y'){
-						((uint8_t*)trace_buffer)[3] = 0x1;
-						if (payload_buffer->data[3] == 'X'){
-							((uint8_t*)trace_buffer)[4] = 0x1;
-							/* Notifiy the hypervisor and the fuzzer that a "crash" has occured. Also a string is passed by this hypercall (this is currently not supported by AFL++-Nyx) */
-							kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED, (uintptr_t)"Something went wrong\n");
-						}
-					}
-				}
-			}
-		}
-		/* this hypercall is used to notify the hypervisor and the fuzzer that a single fuzzing "execution" has finished.
-		 * If the reload-mode is enabled, we will jump back to our root snapshot. 
-		 * Otherwise, the hypervisor passes control back to the guest once the bitmap buffer has been "processed" by the fuzzer.
-		 */
-		kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
-
-		/* This shouldn't happen if you have enabled the reload mode */ 
-		hprintf("This should never happen :)\n");
-	}
-
-
-	return 0;
+    uint32_t len = payload_buffer->size;
+
+    /* set a byte to make AFL++ happy (otherwise the fuzzer might refuse to
+     * start fuzzing at all) */
+    ((uint8_t *)trace_buffer)[0] = 0x1;
+
+    if (len >= 4) {
+
+      /* set a byte in the bitmap to guide your fuzzer */
+      ((uint8_t *)trace_buffer)[0] = 0x1;
+      if (payload_buffer->data[0] == '!') {
+
+        ((uint8_t *)trace_buffer)[1] = 0x1;
+        if (payload_buffer->data[1] == 'N') {
+
+          ((uint8_t *)trace_buffer)[2] = 0x1;
+          if (payload_buffer->data[2] == 'Y') {
+
+            ((uint8_t *)trace_buffer)[3] = 0x1;
+            if (payload_buffer->data[3] == 'X') {
+
+              ((uint8_t *)trace_buffer)[4] = 0x1;
+              /* Notifiy the hypervisor and the fuzzer that a "crash" has
+               * occured. Also a string is passed by this hypercall (this is
+               * currently not supported by AFL++-Nyx) */
+              kAFL_hypercall(HYPERCALL_KAFL_PANIC_EXTENDED,
+                             (uintptr_t) "Something went wrong\n");
+
+            }
+
+          }
+
+        }
+
+      }
+
+    }
+
+    /* this hypercall is used to notify the hypervisor and the fuzzer that a
+     * single fuzzing "execution" has finished. If the reload-mode is enabled,
+     * we will jump back to our root snapshot. Otherwise, the hypervisor passes
+     * control back to the guest once the bitmap buffer has been "processed" by
+     * the fuzzer.
+     */
+    kAFL_hypercall(HYPERCALL_KAFL_RELEASE, 0);
+
+    /* This shouldn't happen if you have enabled the reload mode */
+    hprintf("This should never happen :)\n");
+
+  }
+
+  return 0;
+
 }
+
diff --git a/nyx_mode/update_ref.sh b/nyx_mode/update_ref.sh
index 3e94a42b..898a803f 100755
--- a/nyx_mode/update_ref.sh
+++ b/nyx_mode/update_ref.sh
@@ -71,7 +71,7 @@ echo "$NEW_VERSION" > "$UC_VERSION_FILE"
 echo "Done. New XXX version is $NEW_VERSION."
 
 
-UC_VERSION_FILE='./QEMU_NXY_VERSION'
+UC_VERSION_FILE='./QEMU_NYX_VERSION'
 NEW_VERSION=""
 
 cd ./QEMU-Nyx || exit 1
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 974b1d2a..9197c74b 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -767,15 +767,13 @@ static void edit_params(u32 argc, char **argv, char **envp) {
       u8 *afllib = find_object("libAFLDriver.a", argv[0]);
 
       if (!be_quiet)
-        WARNF(
-            "Found erroneous '-fsanitize=fuzzer', trying to replace with "
-            "libAFLDriver.a");
+        OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
 
       if (!afllib) {
 
         WARNF(
-            "Cannot find 'libAFLDriver.a' to replace a wrong "
-            "'-fsanitize=fuzzer' in the flags - this will fail!");
+            "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+            "the flags - this will fail!");
 
       } else {
 
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index eebbb7c8..ffcb30c3 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -405,24 +405,27 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
 
     }
 
-    if (fsrv->nyx_parent) {
-
+    if (fsrv->nyx_standalone){
       fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
-          fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id,
-          !fsrv->nyx_standalone);
-
-    } else {
+          fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
+    }
+    else{
+      if (fsrv->nyx_parent) {
+        fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_parent(
+            fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true);
 
-      fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(
-          fsrv->target_path, x, fsrv->nyx_id, fsrv->nyx_bind_cpu_id, true);
+      } else {
+        fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child(
+            fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id);
 
+      }
     }
 
     if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); }
 
     u32 tmp_map_size =
         fsrv->nyx_handlers->nyx_get_bitmap_buffer_size(fsrv->nyx_runner);
-    fsrv->real_map_size = fsrv->map_size;
+    fsrv->real_map_size = tmp_map_size;
     fsrv->map_size = (((tmp_map_size + 63) >> 6) << 6);
     if (!be_quiet) { ACTF("Target map size: %u", fsrv->real_map_size); }
 
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 1edf82f4..50874f47 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -404,6 +404,12 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
   plugin->nyx_new = dlsym(handle, "nyx_new");
   if (plugin->nyx_new == NULL) { goto fail; }
 
+  plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent");
+  if (plugin->nyx_new_parent == NULL) { goto fail; }
+
+  plugin->nyx_new_child = dlsym(handle, "nyx_new_child");
+  if (plugin->nyx_new_child == NULL) { goto fail; }
+
   plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown");
   if (plugin->nyx_shutdown == NULL) { goto fail; }
 
@@ -1340,7 +1346,8 @@ int main(int argc, char **argv_orig, char **envp) {
               "0)");
 
         }
-
+        
+        afl->fsrv.nyx_parent = true;
         afl->fsrv.nyx_id = 0;
 
       }
diff --git a/unicorn_mode/UNICORNAFL_VERSION b/unicorn_mode/UNICORNAFL_VERSION
index 5dcaf66b..8b9c9fc0 100644
--- a/unicorn_mode/UNICORNAFL_VERSION
+++ b/unicorn_mode/UNICORNAFL_VERSION
@@ -1 +1 @@
-566bc3dd5942a5f8779026ca80eb313d5517e778
+7b0c61f25042ebed910b88da2ca42778b858b852
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
-Subproject 566bc3dd5942a5f8779026ca80eb313d5517e77
+Subproject 7b0c61f25042ebed910b88da2ca42778b858b85
diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c
index ff42f3b9..c648674a 100644
--- a/utils/aflpp_driver/aflpp_driver.c
+++ b/utils/aflpp_driver/aflpp_driver.c
@@ -45,6 +45,9 @@ $AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
+#ifndef __HAIKU__
+  #include <sys/syscall.h>
+#endif
 
 #include "config.h"
 #include "types.h"
@@ -62,6 +65,27 @@ extern unsigned char *__afl_fuzz_ptr;
 int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
 __attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
 
+// Default nop ASan hooks for manual posisoning when not linking the ASan
+// runtime
+// https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning
+__attribute__((weak)) void __asan_poison_memory_region(
+    void const volatile *addr, size_t size) {
+
+  (void)addr;
+  (void)size;
+
+}
+
+__attribute__((weak)) void __asan_unpoison_memory_region(
+    void const volatile *addr, size_t size) {
+
+  (void)addr;
+  (void)size;
+
+}
+
+__attribute__((weak)) void *__asan_region_is_poisoned(void *beg, size_t size);
+
 // Notify AFL about persistent mode.
 static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
 int                  __afl_persistent_loop(unsigned int);
@@ -175,6 +199,9 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
 
   unsigned char *buf = (unsigned char *)malloc(MAX_FILE);
 
+  __asan_poison_memory_region(buf, MAX_FILE);
+  ssize_t prev_length = 0;
+
   for (int i = 1; i < argc; i++) {
 
     int fd = 0;
@@ -183,10 +210,26 @@ static int ExecuteFilesOnyByOne(int argc, char **argv) {
 
     if (fd == -1) { continue; }
 
-    ssize_t length = read(fd, buf, MAX_FILE);
+#ifndef __HAIKU__
+    ssize_t length = syscall(SYS_read, fd, buf, MAX_FILE);
+#else
+    ssize_t length = _kern_read(fd, buf, MAX_FILE);
+#endif  // HAIKU
 
     if (length > 0) {
 
+      if (length < prev_length) {
+
+        __asan_poison_memory_region(buf + length, prev_length - length);
+
+      } else {
+
+        __asan_unpoison_memory_region(buf + prev_length, length - prev_length);
+
+      }
+
+      prev_length = length;
+
       printf("Reading %zu bytes from %s\n", length, argv[i]);
       LLVMFuzzerTestOneInput(buf, length);
       printf("Execution successful.\n");
@@ -284,29 +327,48 @@ int main(int argc, char **argv) {
   // on the first execution of LLVMFuzzerTestOneInput is ignored.
   LLVMFuzzerTestOneInput(dummy_input, 1);
 
-  int num_runs = 0;
-  while (__afl_persistent_loop(N)) {
+  __asan_poison_memory_region(__afl_fuzz_ptr, MAX_FILE);
+  size_t prev_length = 0;
 
-#ifdef _DEBUG
-    fprintf(stderr, "CLIENT crc: %016llx len: %u\n",
-            hash64(__afl_fuzz_ptr, *__afl_fuzz_len, 0xa5b35705),
-            *__afl_fuzz_len);
-    fprintf(stderr, "RECV:");
-    for (int i = 0; i < *__afl_fuzz_len; i++)
-      fprintf(stderr, "%02x", __afl_fuzz_ptr[i]);
-    fprintf(stderr, "\n");
-#endif
+  // for speed only insert asan functions if the target is linked with asan
+  if (__asan_region_is_poisoned) {
+
+    while (__afl_persistent_loop(N)) {
+
+      size_t length = *__afl_fuzz_len;
+
+      if (likely(length)) {
+
+        if (length < prev_length) {
+
+          __asan_poison_memory_region(__afl_fuzz_ptr + length,
+                                      prev_length - length);
+
+        } else if (length > prev_length) {
 
-    if (*__afl_fuzz_len) {
+          __asan_unpoison_memory_region(__afl_fuzz_ptr + prev_length,
+                                        length - prev_length);
+
+        }
+
+        prev_length = length;
+        LLVMFuzzerTestOneInput(__afl_fuzz_ptr, length);
+
+      }
+
+    }
+
+  } else {
+
+    while (__afl_persistent_loop(N)) {
 
-      num_runs++;
       LLVMFuzzerTestOneInput(__afl_fuzz_ptr, *__afl_fuzz_len);
 
     }
 
   }
 
-  printf("%s: successfully executed %d input(s)\n", argv[0], num_runs);
+  return 0;
 
 }