diff options
-rw-r--r-- | Android.bp | 18 | ||||
-rw-r--r-- | GNUmakefile | 9 | ||||
-rw-r--r-- | include/forkserver.h | 8 | ||||
-rw-r--r-- | nyx_mode/LIBNYX_VERSION | 2 | ||||
-rw-r--r-- | nyx_mode/PACKER_VERSION | 2 | ||||
-rw-r--r-- | nyx_mode/QEMU_NXY_VERSION | 1 | ||||
-rw-r--r-- | nyx_mode/QEMU_NYX_VERSION | 1 | ||||
-rw-r--r-- | nyx_mode/README.md | 14 | ||||
-rwxr-xr-x | nyx_mode/build_nyx_support.sh | 2 | ||||
-rw-r--r-- | nyx_mode/custom_harness/example.c | 206 | ||||
-rwxr-xr-x | nyx_mode/update_ref.sh | 2 | ||||
-rw-r--r-- | src/afl-cc.c | 8 | ||||
-rw-r--r-- | src/afl-forkserver.c | 21 | ||||
-rw-r--r-- | src/afl-fuzz.c | 9 | ||||
-rw-r--r-- | unicorn_mode/UNICORNAFL_VERSION | 2 | ||||
m--------- | unicorn_mode/unicornafl | 0 | ||||
-rw-r--r-- | utils/aflpp_driver/aflpp_driver.c | 92 |
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; } |