diff options
-rw-r--r-- | Dockerfile | 2 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-common.h | 6 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-inl.h | 22 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 96 | ||||
-rw-r--r-- | src/afl-fuzz-cmplog.c | 12 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 32 |
7 files changed, 149 insertions, 22 deletions
diff --git a/Dockerfile b/Dockerfile index 7bb60610..396954ab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ubuntu:eoan MAINTAINER David Carlier <devnexen@gmail.com> LABEL "about"="AFLplusplus docker image" -RUN apt-get update && apt-get install -y \ +RUN apt-get update && apt-get -y install \ --no-install-suggests --no-install-recommends \ automake \ bison \ diff --git a/TODO b/TODO index e935eafa..d153f1b4 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,7 @@ Makefile: afl-fuzz: - sync_fuzzers(): only masters sync from all, slaves only sync from master + - ascii_only mode gcc_plugin: - laf-intel diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index 4d651385..18c36f73 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -35,6 +35,9 @@ #define __AFL_QEMU_COMMON #include "../../config.h" +#include "../../include/cmplog.h" + +#define PERSISTENT_DEFAULT_MAX_CNT 1000 #ifndef CPU_NB_REGS #define AFL_REGS_NUM 1000 @@ -74,6 +77,9 @@ extern int persisent_retaddr_offset; extern __thread abi_ulong afl_prev_loc; +extern struct cmp_map* __afl_cmp_map; +extern __thread u32 __afl_cmp_counter; + void afl_debug_dump_saved_regs(); void afl_persistent_loop(); diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h index ac847371..0ae6364b 100644 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-inl.h @@ -32,11 +32,8 @@ */ #include <sys/shm.h> -#include "../../config.h" #include "afl-qemu-common.h" -#define PERSISTENT_DEFAULT_MAX_CNT 1000 - /*************************** * VARIOUS AUXILIARY STUFF * ***************************/ @@ -81,6 +78,9 @@ u8 afl_compcov_level; __thread abi_ulong afl_prev_loc; +struct cmp_map* __afl_cmp_map; +__thread u32 __afl_cmp_counter; + /* Set in the child process in forkserver mode: */ static int forkserver_installed = 0; @@ -181,6 +181,22 @@ static void afl_setup(void) { if (inst_r) afl_area_ptr[0] = 1; } + + if (getenv("___AFL_EINS_ZWEI_POLIZEI___")) { // CmpLog forkserver + + id_str = getenv(CMPLOG_SHM_ENV_VAR); + + if (id_str) { + + u32 shm_id = atoi(id_str); + + __afl_cmp_map = shmat(shm_id, NULL, 0); + + if (__afl_cmp_map == (void*)-1) _exit(1); + + } + + } if (getenv("AFL_INST_LIBS")) { diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index 6d42bf3d..9f032feb 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -102,31 +102,103 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1, } +static void afl_cmplog_16(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + // if (!__afl_cmp_map->headers[k].cnt) + // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; + + __afl_cmp_map->headers[k].shape = 1; + //__afl_cmp_map->headers[k].type = CMP_TYPE_INS; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +static void afl_cmplog_32(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 3; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +static void afl_cmplog_64(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 7; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + + static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2, TCGMemOp ot, int is_imm) { void *func; - if (!afl_compcov_level || cur_loc > afl_end_code || cur_loc < afl_start_code) + if (cur_loc > afl_end_code || cur_loc < afl_start_code) return; - if (!is_imm && afl_compcov_level < 2) return; + if (__afl_cmp_map) { + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= CMP_MAP_W - 1; - switch (ot) { + switch (ot) { - case MO_64: func = &afl_compcov_log_64; break; - case MO_32: func = &afl_compcov_log_32; break; - case MO_16: func = &afl_compcov_log_16; break; - default: return; + case MO_64: func = &afl_cmplog_64; break; + case MO_32: func = &afl_cmplog_32; break; + case MO_16: func = &afl_cmplog_16; break; + default: return; - } + } + + tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + + } else if (afl_compcov_level) { + + if (!is_imm && afl_compcov_level < 2) return; + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= MAP_SIZE - 7; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; + if (cur_loc >= afl_inst_rms) return; + + switch (ot) { - if (cur_loc >= afl_inst_rms) return; + case MO_64: func = &afl_compcov_log_64; break; + case MO_32: func = &afl_compcov_log_32; break; + case MO_16: func = &afl_compcov_log_16; break; + default: return; - tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + } + + tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + + } } diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 92bac4ab..69efcffa 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -150,8 +150,10 @@ void init_cmplog_forkserver(char** argv) { "msan_track_origins=0", 0); - argv[0] = cmplog_binary; - execv(cmplog_binary, argv); + setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1); + + if (!qemu_mode) argv[0] = cmplog_binary; + execv(argv[0], argv); /* Use a distinctive bitmap signature to tell the parent about execv() falling through. */ @@ -440,9 +442,11 @@ u8 run_cmplog_target(char** argv, u32 timeout) { setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" "symbolize=0:" "msan_track_origins=0", 0); + + setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1); - argv[0] = cmplog_binary; - execv(cmplog_binary, argv); + if (!qemu_mode) argv[0] = cmplog_binary; + execv(argv[0], argv); /* Use a distinctive bitmap value to tell the parent about execv() falling through. */ diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index c21c973f..6fb1964f 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -108,6 +108,8 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { struct range* ranges = add_range(NULL, 0, len); u8* backup = ck_alloc_nozero(len); + u8 needs_write = 0; + u64 orig_hit_cnt, new_hit_cnt; orig_hit_cnt = queued_paths + unique_crashes; @@ -132,7 +134,7 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end); memcpy(buf + rng->start, backup, s); - } + } else needs_write = 1; ck_free(rng); --stage_cur; @@ -150,6 +152,32 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) { ck_free(rng); } + + // save the input with the high entropy + + if (needs_write) { + + s32 fd; + + if (no_unlink) { + + fd = open(queue_cur->fname, O_WRONLY | O_CREAT | O_TRUNC, 0600); + + } else { + + unlink(queue_cur->fname); /* ignore errors */ + fd = open(queue_cur->fname, O_WRONLY | O_CREAT | O_EXCL, 0600); + + } + + if (fd < 0) PFATAL("Unable to create '%s'", queue_cur->fname); + + ck_write(fd, buf, len, queue_cur->fname); + queue_cur->len = len; // no-op, just to be 100% safe + + close(fd); + + } return 0; @@ -362,7 +390,7 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, } - memcpy(buf, orig_buf, len); + memcpy(orig_buf, buf, len); new_hit_cnt = queued_paths + unique_crashes; stage_finds[STAGE_ITS] += new_hit_cnt - orig_hit_cnt; |