From a033364d55332530b15f2a0f2863b3448bb2bab9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 21 Oct 2019 23:07:05 +0200 Subject: implement neverZero counter for __afl_trace() --- gcc_plugin/afl-gcc-rt.o.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'gcc_plugin/afl-gcc-rt.o.c') diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index dd79a0ec..6cf9f167 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -50,8 +50,10 @@ static u8 is_persistent; void __afl_trace(u32 x) { u32 l = __afl_prev_loc; - u32 n = l ^ x; - *(__afl_area_ptr + n) += 1; + const u32 n = l ^ x; + u8 *const bitmap_ptr = __afl_area_ptr + n; + *bitmap_ptr += 1 + (*bitmap_ptr == (u8)~0); /* neverZero */ + __afl_prev_loc = (x >> 1); return; -- cgit 1.4.1 From 9a5882a2909c663b58f1e36b4298eeb09ecc3bf4 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Mon, 21 Oct 2019 23:35:09 +0200 Subject: sync afl-gcc-rt.o.c from its more current llvm cousin --- gcc_plugin/afl-gcc-rt.o.c | 90 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 8 deletions(-) (limited to 'gcc_plugin/afl-gcc-rt.o.c') diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index 6cf9f167..1dfca9e3 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -21,12 +21,16 @@ */ +#ifdef __ANDROID__ +#include "android-ashmem.h" +#endif #include "../config.h" #include "../types.h" #include #include #include +#include #include #include @@ -34,17 +38,21 @@ #include #include +#include +#include + /* Globals needed by the injected instrumentation. The __afl_area_initial region is used for instrumentation output before __afl_map_shm() has a chance to run. It will end up as .comm, so it shouldn't be too wasteful. */ u8 __afl_area_initial[MAP_SIZE]; u8 *__afl_area_ptr = __afl_area_initial; -u32 __afl_prev_loc; - -/* Running in persistent mode? */ -static u8 is_persistent; +#ifdef __ANDROID__ +u32 __afl_prev_loc; +#else +__thread u32 __afl_prev_loc; +#endif /* Trace a basic block with some ID */ void __afl_trace(u32 x) { @@ -59,6 +67,10 @@ void __afl_trace(u32 x) { } +/* Running in persistent mode? */ + +static u8 is_persistent; + /* SHM setup. */ static void __afl_map_shm(void) { @@ -71,9 +83,38 @@ static void __afl_map_shm(void) { if (id_str) { +#ifdef USEMMAP + const char* shm_file_path = id_str; + int shm_fd = -1; + unsigned char* shm_base = NULL; + + /* create the shared memory segment as if it was a file */ + shm_fd = shm_open(shm_file_path, O_RDWR, 0600); + if (shm_fd == -1) { + + printf("shm_open() failed\n"); + exit(1); + + } + + /* map the shared memory segment to the address space of the process */ + shm_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); + if (shm_base == MAP_FAILED) { + + close(shm_fd); + shm_fd = -1; + + printf("mmap() failed\n"); + exit(2); + + } + + __afl_area_ptr = shm_base; +#else u32 shm_id = atoi(id_str); __afl_area_ptr = shmat(shm_id, NULL, 0); +#endif /* Whooooops. */ @@ -97,6 +138,8 @@ static void __afl_start_forkserver(void) { u8 child_stopped = 0; + void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); + /* Phone home and tell the parent that we're OK. If parent isn't there, assume we're not running in forkserver mode and just execute program. */ @@ -133,6 +176,8 @@ static void __afl_start_forkserver(void) { if (!child_pid) { + signal(SIGCHLD, old_sigchld_handler); + close(FORKSRV_FD); close(FORKSRV_FD + 1); return; @@ -178,18 +223,47 @@ int __afl_persistent_loop(unsigned int max_cnt) { if (first_pass) { + /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. + On subsequent calls, the parent will take care of that, but on the first + iteration, it's our job to erase any trace of whatever happened + before the loop. */ + + if (is_persistent) { + + memset(__afl_area_ptr, 0, MAP_SIZE); + __afl_area_ptr[0] = 1; + __afl_prev_loc = 0; + + } + cycle_cnt = max_cnt; first_pass = 0; return 1; } - if (is_persistent && --cycle_cnt) { + if (is_persistent) { - raise(SIGSTOP); - return 1; + if (--cycle_cnt) { + + raise(SIGSTOP); - } else + __afl_area_ptr[0] = 1; + __afl_prev_loc = 0; + + return 1; + + } else { + + /* When exiting __AFL_LOOP(), make sure that the subsequent code that + follows the loop is not traced. We do that by pivoting back to the + dummy output region. */ + + __afl_area_ptr = __afl_area_initial; + + } + + } return 0; -- cgit 1.4.1 From 1398d8d5a64b11a62e8ed25732e2114a5dc47564 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Wed, 23 Oct 2019 03:23:14 +0200 Subject: gcc sucks --- README.md | 4 +++- gcc_plugin/afl-gcc-rt.o.c | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'gcc_plugin/afl-gcc-rt.o.c') diff --git a/README.md b/README.md index d58b49e2..de012e62 100644 --- a/README.md +++ b/README.md @@ -55,12 +55,14 @@ | Feature/Instrumentation | AFL-GCC | LLVM_MODE | GCC_PLUGIN | QEMU_MODE | Unicorn | | ----------------------- |:-------:|:---------:|:----------:|:---------:|:-------:| | laf-intel / CompCov | | x | | x | x | - | NeverZero | X | x(1) | X | x | x | + | NeverZero | X | x(1) | (2) | x | x | | Persistent mode | | x | X | x | | | Whitelist | | x | X | | | | InsTrim | | x | | | | + neverZero: (1) only in LLVM >= 9.0 due to a bug in llvm in previous versions + (2) gcc create non-performant code, hence it is disabled in gcc_plugin So all in all this is the best-of AFL that is currently out there :-) diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index 1dfca9e3..47049167 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -58,10 +58,11 @@ __thread u32 __afl_prev_loc; void __afl_trace(u32 x) { u32 l = __afl_prev_loc; - const u32 n = l ^ x; - u8 *const bitmap_ptr = __afl_area_ptr + n; - *bitmap_ptr += 1 + (*bitmap_ptr == (u8)~0); /* neverZero */ - + __afl_area_ptr[l ^ x]++; + /* // neverZero is disable as gcc creates non-performant code. shame on you gcc + if (__afl_area_ptr[l ^ x] == 0) + __afl_area_ptr[l ^ x]++; + */ __afl_prev_loc = (x >> 1); return; -- cgit 1.4.1 From 7d9eed0ed5a57f16b15fe2576da4aec79e0909c9 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Wed, 23 Oct 2019 11:33:20 +0200 Subject: no functional change, avoid conditional jump --- gcc_plugin/afl-gcc-rt.o.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'gcc_plugin/afl-gcc-rt.o.c') diff --git a/gcc_plugin/afl-gcc-rt.o.c b/gcc_plugin/afl-gcc-rt.o.c index 47049167..5b70a247 100644 --- a/gcc_plugin/afl-gcc-rt.o.c +++ b/gcc_plugin/afl-gcc-rt.o.c @@ -58,11 +58,14 @@ __thread u32 __afl_prev_loc; void __afl_trace(u32 x) { u32 l = __afl_prev_loc; - __afl_area_ptr[l ^ x]++; - /* // neverZero is disable as gcc creates non-performant code. shame on you gcc - if (__afl_area_ptr[l ^ x] == 0) - __afl_area_ptr[l ^ x]++; - */ + +#if 0 /* enable for neverZero feature. By default disabled since too inefficient :-( */ + /* @Marc: avoid conditional jumps here */ + __afl_area_ptr[l ^ x] += 1 + (__afl_area_ptr[l ^ x] == (u8)~0); +#else + ++__afl_area_ptr[l ^ x]; +#endif + __afl_prev_loc = (x >> 1); return; -- cgit 1.4.1