From ca4a8c0f920f83c86aeb599b94b50fce2af68389 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 19 Jul 2022 12:24:03 +0200 Subject: post_process 0/NULL return support --- docs/Changelog.md | 3 +++ docs/custom_mutators.md | 4 ++++ src/afl-fuzz-bitmap.c | 15 +++++++++++++-- src/afl-fuzz-cmplog.c | 13 +++++++++++-- src/afl-fuzz-mutators.c | 18 +++++++++++++----- src/afl-fuzz-python.c | 11 ++++++++++- src/afl-fuzz-run.c | 33 ++++++++++++++++++++++++++++----- 7 files changed, 82 insertions(+), 15 deletions(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index ff3907f0..c7414ff2 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,9 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . ### Version ++4.02a (dev) + - afl-fuzz: + - change post_process hook to allow returning NULL and 0 length to + tell afl-fuzz to skip this mutated input - gcc_plugin: - Adacore submitted CMPLOG support to the gcc_plugin! :-) - llvm_mode: diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 7b4e0516..d84e4e02 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -159,6 +159,10 @@ def deinit(): # optional for Python This can return any python object that implements the buffer protocol and supports PyBUF_SIMPLE. These include bytes, bytearray, etc. + You can decide in the post_process mutator to not send the mutated data + to the target, e.g. if it is too short, too corrupted, etc. If so, + return a NULL buffer and zero length (or a 0 length string in Python). + - `queue_new_entry` (optional): This methods is called after adding a new test case to the queue. If the diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 089f7bb5..b3a10bb7 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -647,8 +647,19 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (afl->fsrv.exec_tmout < afl->hang_tmout) { - u8 new_fault; - len = write_to_testcase(afl, &mem, len, 0); + u8 new_fault; + u32 tmp_len = write_to_testcase(afl, &mem, len, 0); + + if (likely(tmp_len)) { + + len = tmp_len; + + } else { + + len = write_to_testcase(afl, &mem, len, 1); + + } + new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout); classify_counts(&afl->fsrv); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 258d9ea7..d0c829e2 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -47,9 +47,18 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) { u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { - u8 fault; + u8 fault; + u32 tmp_len = write_to_testcase(afl, (void **)&out_buf, len, 0); - write_to_testcase(afl, (void **)&out_buf, len, 0); + if (likely(tmp_len)) { + + len = tmp_len; + + } else { + + len = write_to_testcase(afl, (void **)&out_buf, len, 1); + + } fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout); diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index dd97a7d3..b9daebfa 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -430,13 +430,21 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf, retlen = write_to_testcase(afl, (void **)&retbuf, retlen, 0); - fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); - ++afl->trim_execs; + if (unlikely(!retlen)) { + + ++afl->trim_execs; + + } else { - if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); + ++afl->trim_execs; - classify_counts(&afl->fsrv); - cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; } + + classify_counts(&afl->fsrv); + cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); + + } } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index a3d864c3..a43d80bb 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -535,7 +535,16 @@ size_t post_process_py(void *py_mutator, u8 *buf, size_t buf_size, Py_DECREF(py_value); - *out_buf = (u8 *)py->post_process_buf.buf; + if (unlikely(py->post_process_buf.len == 0)) { + + *out_buf = NULL; + + } else { + + *out_buf = (u8 *)py->post_process_buf.buf; + + } + return py->post_process_buf.len; } else { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 0f3be1a7..b97a8e6a 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -109,17 +109,36 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { if (unlikely(!new_buf && new_size <= 0)) { - FATAL("Custom_post_process failed (ret: %lu)", - (long unsigned)new_size); + new_size = 0; + new_buf = new_mem; + // FATAL("Custom_post_process failed (ret: %lu)", (long + // unsigned)new_size); - } + } else { - new_mem = new_buf; + new_mem = new_buf; + + } } }); + if (unlikely(!new_size)) { + + // perform dummy runs (fix = 1), but skip all others + if (fix) { + + new_size = len; + + } else { + + return 0; + + } + + } + if (unlikely(new_size < afl->min_length && !fix)) { new_size = afl->min_length; @@ -969,7 +988,11 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - len = write_to_testcase(afl, (void **)&out_buf, len, 0); + if (unlikely(len = write_to_testcase(afl, (void **)&out_buf, len, 0) == 0)) { + + return 0; + + } fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout); -- cgit 1.4.1 From c67f98865eec641ce7480b0882331c9799575dbb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 19 Jul 2022 14:53:43 +0200 Subject: fix --- src/afl-fuzz-run.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index b97a8e6a..d1ffb46c 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -107,7 +107,7 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { new_size = el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); - if (unlikely(!new_buf && new_size <= 0)) { + if (unlikely(!new_buf || new_size <= 0)) { new_size = 0; new_buf = new_mem; @@ -226,14 +226,18 @@ static void write_with_gap(afl_state_t *afl, u8 *mem, u32 len, u32 skip_at, new_size = el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); - if (unlikely(!new_buf || new_size <= 0)) { + if (unlikely(!new_buf && new_size <= 0)) { - FATAL("Custom_post_process failed (ret: %lu)", - (long unsigned)new_size); + new_size = 0; + new_buf = new_mem; + // FATAL("Custom_post_process failed (ret: %lu)", (long + // unsigned)new_size); - } + } else { - new_mem = new_buf; + new_mem = new_buf; + + } } -- cgit 1.4.1 From 4d20b2d28b732f20e4c9885a3d4ac4440d66bf12 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 19 Jul 2022 17:04:53 +0200 Subject: fix --- src/afl-fuzz-run.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index d1ffb46c..631548d4 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -76,24 +76,6 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { u32 __attribute__((hot)) write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { -#ifdef _AFL_DOCUMENT_MUTATIONS - s32 doc_fd; - char fn[PATH_MAX]; - snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir, - afl->document_counter++, - describe_op(afl, 0, NAME_MAX - strlen("000000000:"))); - - if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION)) >= - 0) { - - if (write(doc_fd, *mem, len) != len) - PFATAL("write to mutation file failed: %s", fn); - close(doc_fd); - - } - -#endif - if (unlikely(afl->custom_mutators_count)) { ssize_t new_size = len; @@ -172,6 +154,25 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { } +#ifdef _AFL_DOCUMENT_MUTATIONS + s32 doc_fd; + char fn[PATH_MAX]; + snprintf(fn, PATH_MAX, "%s/mutations/%09u:%s", afl->out_dir, + afl->document_counter++, + describe_op(afl, 0, NAME_MAX - strlen("000000000:"))); + + if ((doc_fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, DEFAULT_PERMISSION)) >= + 0) { + + if (write(doc_fd, *mem, len) != len) + PFATAL("write to mutation file failed: %s", fn); + close(doc_fd); + + } + +#endif + + fprintf(stderr, "len = %u\n", len); return len; } @@ -992,7 +993,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { u8 fault; - if (unlikely(len = write_to_testcase(afl, (void **)&out_buf, len, 0) == 0)) { + if (unlikely(len = write_to_testcase(afl, (void **)&out_buf, len, 0)) == 0) { return 0; -- cgit 1.4.1 From d09023245204808a0eedfee221216d999fe85d5c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 19 Jul 2022 17:06:23 +0200 Subject: remove debug --- src/afl-fuzz-run.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 631548d4..c0e72ae6 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -172,7 +172,6 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { #endif - fprintf(stderr, "len = %u\n", len); return len; } -- cgit 1.4.1 From 0373628adf2e27079b84048c474db1c8cbea49ed Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 19 Jul 2022 17:28:57 +0200 Subject: fix custom mutator examples --- custom_mutators/examples/example.c | 2 +- custom_mutators/examples/post_library_gif.so.c | 13 ++++--- custom_mutators/examples/post_library_png.so.c | 48 +++++++++----------------- docs/custom_mutators.md | 5 +++ 4 files changed, 31 insertions(+), 37 deletions(-) diff --git a/custom_mutators/examples/example.c b/custom_mutators/examples/example.c index 5c174e10..3f299508 100644 --- a/custom_mutators/examples/example.c +++ b/custom_mutators/examples/example.c @@ -352,7 +352,7 @@ uint8_t afl_custom_queue_get(my_mutator_t *data, const uint8_t *filename) { * @return if the file contents was modified return 1 (True), 0 (False) * otherwise */ -uint8_t afl_custom_queue_new_entry(my_mutator_t * data, +uint8_t afl_custom_queue_new_entry(my_mutator_t *data, const uint8_t *filename_new_queue, const uint8_t *filename_orig_queue) { diff --git a/custom_mutators/examples/post_library_gif.so.c b/custom_mutators/examples/post_library_gif.so.c index aec05720..9cd224f4 100644 --- a/custom_mutators/examples/post_library_gif.so.c +++ b/custom_mutators/examples/post_library_gif.so.c @@ -72,6 +72,7 @@ #include #include #include +#include "alloc-inl.h" /* Header that must be present at the beginning of every test case: */ @@ -127,9 +128,11 @@ size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf, } /* Allocate memory for new buffer, reusing previous allocation if - possible. */ + possible. Note we have to use afl-fuzz's own realloc! + Note that you should only do this if you need to grow the buffer, + otherwise work with in_buf, and assign it to *out_buf instead. */ - *out_buf = realloc(data->buf, len); + *out_buf = afl_realloc(out_buf, len); /* If we're out of memory, the most graceful thing to do is to return the original buffer and give up on modifying it. Let AFL handle OOM on its @@ -142,9 +145,9 @@ size_t afl_custom_post_process(post_state_t *data, unsigned char *in_buf, } - /* Copy the original data to the new location. */ - - memcpy(*out_buf, in_buf, len); + if (len > strlen(HEADER)) + memcpy(*out_buf + strlen(HEADER), in_buf + strlen(HEADER), + len - strlen(HEADER)); /* Insert the new header. */ diff --git a/custom_mutators/examples/post_library_png.so.c b/custom_mutators/examples/post_library_png.so.c index 941f7e55..cd65b1bc 100644 --- a/custom_mutators/examples/post_library_png.so.c +++ b/custom_mutators/examples/post_library_png.so.c @@ -29,8 +29,8 @@ #include #include #include - #include +#include "alloc-inl.h" /* A macro to round an integer up to 4 kB. */ @@ -70,9 +70,6 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf, unsigned int len, const unsigned char **out_buf) { - unsigned char *new_buf = (unsigned char *)in_buf; - unsigned int pos = 8; - /* Don't do anything if there's not enough room for the PNG header (8 bytes). */ @@ -83,6 +80,22 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf, } + /* This is not a good way to do it, if you do not need to grow the buffer + then just work with in_buf instead for speed reasons. + But we want to show how to grow a buffer, so this is how it's done: */ + + unsigned int pos = 8; + unsigned char *new_buf = afl_realloc(out_buf, UP4K(len)); + + if (!new_buf) { + + *out_buf = in_buf; + return len; + + } + + memcpy(new_buf, in_buf, len); + /* Minimum size of a zero-length PNG chunk is 12 bytes; if we don't have that, we can bail out. */ @@ -111,33 +124,6 @@ size_t afl_custom_post_process(post_state_t *data, const unsigned char *in_buf, if (real_cksum != file_cksum) { - /* First modification? Make a copy of the input buffer. Round size - up to 4 kB to minimize the number of reallocs needed. */ - - if (new_buf == in_buf) { - - if (len <= data->size) { - - new_buf = data->buf; - - } else { - - new_buf = realloc(data->buf, UP4K(len)); - if (!new_buf) { - - *out_buf = in_buf; - return len; - - } - - data->buf = new_buf; - data->size = UP4K(len); - memcpy(new_buf, in_buf, len); - - } - - } - *(uint32_t *)(new_buf + pos + 8 + chunk_len) = real_cksum; } diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index d84e4e02..6f3353ec 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -38,6 +38,11 @@ performed with the custom mutator. ## 2) APIs +**IMPORTANT NOTE**: If you use our C/C++ API and you want to increase the size +of an **out_buf buffer, you have to use `afl_realloc()` for this, so include +`include/alloc-inl.h` - otherwise afl-fuzz will crash when trying to free +your buffers. + C/C++: ```c -- cgit 1.4.1 From 42c677aa7bebf5cacf1d2cc603a59044a19616c2 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Tue, 19 Jul 2022 23:03:20 +0200 Subject: fix compilation for llvm 10.0 --- instrumentation/SanitizerCoveragePCGUARD.so.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index d5f56aa8..6aa69546 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -262,7 +262,8 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { } // namespace -#if 1 +#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ + extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK llvmGetPassPluginInfo() { -- cgit 1.4.1 From 6c26434a631dce949a39268f9f31e0936cf3dd83 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 21 Jul 2022 13:41:37 +0200 Subject: fix pizza mode --- src/afl-fuzz-state.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index cc4138ae..ddfd4b31 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -518,16 +518,6 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_no_crash_readme = atoi((u8 *)get_afl_env(afl_environment_variables[i])); - if (afl->afl_env.afl_pizza_mode == 0) { - - afl->afl_env.afl_pizza_mode = 1; - - } else { - - afl->pizza_is_served = 1; - - } - } else if (!strncmp(env, "AFL_SYNC_TIME", afl_environment_variable_len)) { @@ -607,6 +597,16 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } + if (afl->afl_env.afl_pizza_mode == 0) { + + afl->afl_env.afl_pizza_mode = 1; + + } else { + + afl->pizza_is_served = 1; + + } + if (issue_detected) { sleep(2); } } -- cgit 1.4.1 From 9657b700b1df90797b17e1d4677d56ee97fe00bc Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 21 Jul 2022 18:48:21 +0100 Subject: Fix some OSX incompatibilities on AARCH64 (#1479) Co-authored-by: Your Name --- frida_mode/GNUmakefile | 2 +- frida_mode/src/instrument/instrument.c | 3 +++ frida_mode/src/instrument/instrument_arm64.c | 3 ++- frida_mode/src/instrument/instrument_x64.c | 9 +++------ frida_mode/src/instrument/instrument_x86.c | 3 ++- frida_mode/src/intercept.c | 4 ++-- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index b9b47b62..bc7df6c0 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -116,7 +116,7 @@ ifndef OS $(error "Operating system unsupported") endif -GUM_DEVKIT_VERSION=15.1.27 +GUM_DEVKIT_VERSION=15.2.1 GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)" diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 9ee7db2d..a9568390 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -20,6 +20,8 @@ #include "stats.h" #include "util.h" +#define FRIDA_DEFAULT_MAP_SIZE (64UL << 10) + gboolean instrument_tracing = false; gboolean instrument_optimize = false; gboolean instrument_unique = false; @@ -289,6 +291,7 @@ void instrument_config(void) { } void instrument_init(void) { + if (__afl_map_size == MAP_SIZE) __afl_map_size = FRIDA_DEFAULT_MAP_SIZE; if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index afc20f42..3c37ea5f 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -272,9 +272,10 @@ void instrument_coverage_optimize(const cs_insn *instr, GumAddressSpec spec = {.near_address = cw->code, .max_distance = 1ULL << 30}; + guint page_size = gum_query_page_size(); instrument_previous_pc_addr = gum_memory_allocate_near( - &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE); *instrument_previous_pc_addr = instrument_hash_zero; FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("code_addr: %p", cw->code); diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index bfafe067..687b2e40 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -333,19 +333,17 @@ static void instrument_coverage_write(GumAddress address, } -void instrument_coverage_optimize(const cs_insn *instr, +void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output) { - GumX86Writer *cw = output->writer.x86; - /* guint64 area_offset = - * instrument_get_offset_hash(GUM_ADDRESS(instr->address)); */ if (instrument_previous_pc_addr == NULL) { GumAddressSpec spec = {.near_address = cw->code, .max_distance = 1ULL << 30}; + guint page_size = gum_query_page_size(); instrument_previous_pc_addr = gum_memory_allocate_near( - &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE); *instrument_previous_pc_addr = instrument_hash_zero; FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("code_addr: %p", cw->code); @@ -361,7 +359,6 @@ void instrument_coverage_optimize(const cs_insn *instr, } instrument_coverage_write(GUM_ADDRESS(instr->address), output); - } void instrument_coverage_optimize_insn(const cs_insn *instr, diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 048daf32..8798cfcf 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -162,9 +162,10 @@ void instrument_coverage_optimize(const cs_insn *instr, GumAddressSpec spec = {.near_address = cw->code, .max_distance = 1ULL << 30}; + guint page_size = gum_query_page_size(); instrument_previous_pc_addr = gum_memory_allocate_near( - &spec, sizeof(guint64), 0x1000, GUM_PAGE_READ | GUM_PAGE_WRITE); + &spec, sizeof(guint64), page_size, GUM_PAGE_READ | GUM_PAGE_WRITE); *instrument_previous_pc_addr = instrument_hash_zero; FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); FVERBOSE("code_addr: %p", cw->code); diff --git a/frida_mode/src/intercept.c b/frida_mode/src/intercept.c index 26d20c50..e9751848 100644 --- a/frida_mode/src/intercept.c +++ b/frida_mode/src/intercept.c @@ -7,8 +7,8 @@ void intercept_hook(void *address, gpointer replacement, gpointer user_data) { GumInterceptor *interceptor = gum_interceptor_obtain(); gum_interceptor_begin_transaction(interceptor); - GumReplaceReturn ret = - gum_interceptor_replace(interceptor, address, replacement, user_data); + GumReplaceReturn ret = gum_interceptor_replace(interceptor, address, + replacement, user_data, NULL); if (ret != GUM_REPLACE_OK) { FFATAL("gum_interceptor_attach: %d", ret); } gum_interceptor_end_transaction(interceptor); -- cgit 1.4.1 From 0540d30274e3126204ebb8c90088d4925cfa9a94 Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 24 Jul 2022 10:23:33 +0000 Subject: fix message overflow --- src/afl-fuzz.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 287f09df..c5de8e35 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -168,7 +168,7 @@ static void usage(u8 *argv0, int more_help) { " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" " if using QEMU/FRIDA or if you the fuzzing target is " - "compiled" + "compiled\n" " for CmpLog then just use -c 0.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" " 1=small files, 2=larger files (default), 3=all " -- cgit 1.4.1 From d8d6ea93cfdd8b67dd83483eca321bf238e3b0e2 Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 24 Jul 2022 10:30:21 +0000 Subject: fix sentence & code format --- src/afl-fuzz.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index c5de8e35..76a79900 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -167,7 +167,7 @@ static void usage(u8 *argv0, int more_help) { " See docs/README.MOpt.md\n" " -c program - enable CmpLog by specifying a binary compiled for " "it.\n" - " if using QEMU/FRIDA or if you the fuzzing target is " + " if using QEMU/FRIDA or the fuzzing target is " "compiled\n" " for CmpLog then just use -c 0.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\n" @@ -383,9 +383,9 @@ static int stricmp(char const *a, char const *b) { static void fasan_check_afl_preload(char *afl_preload) { char first_preload[PATH_MAX + 1] = {0}; - char *separator = strchr(afl_preload, ':'); + char * separator = strchr(afl_preload, ':'); size_t first_preload_len = PATH_MAX; - char *basename; + char * basename; char clang_runtime_prefix[] = "libclang_rt.asan"; if (separator != NULL && (separator - afl_preload) < PATH_MAX) { @@ -429,7 +429,7 @@ static void fasan_check_afl_preload(char *afl_preload) { nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { - void *handle; + void * handle; nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); ACTF("Trying to load libnyx.so plugin..."); @@ -498,8 +498,8 @@ int main(int argc, char **argv_orig, char **envp) { u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; - char *afl_preload; - char *frida_afl_preload = NULL; + char * afl_preload; + char * frida_afl_preload = NULL; char **use_argv; struct timeval tv; -- cgit 1.4.1 From f22d28333bb61b8d931fddcffab404bd62685bb3 Mon Sep 17 00:00:00 2001 From: yuawn Date: Sun, 24 Jul 2022 10:41:50 +0000 Subject: code format with clang-format-14 --- src/afl-fuzz.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 76a79900..2e151abb 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -383,9 +383,9 @@ static int stricmp(char const *a, char const *b) { static void fasan_check_afl_preload(char *afl_preload) { char first_preload[PATH_MAX + 1] = {0}; - char * separator = strchr(afl_preload, ':'); + char *separator = strchr(afl_preload, ':'); size_t first_preload_len = PATH_MAX; - char * basename; + char *basename; char clang_runtime_prefix[] = "libclang_rt.asan"; if (separator != NULL && (separator - afl_preload) < PATH_MAX) { @@ -429,7 +429,7 @@ static void fasan_check_afl_preload(char *afl_preload) { nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { - void * handle; + void *handle; nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); ACTF("Trying to load libnyx.so plugin..."); @@ -498,8 +498,8 @@ int main(int argc, char **argv_orig, char **envp) { u8 *extras_dir[4]; u8 mem_limit_given = 0, exit_1 = 0, debug = 0, extras_dir_cnt = 0 /*, have_p = 0*/; - char * afl_preload; - char * frida_afl_preload = NULL; + char *afl_preload; + char *frida_afl_preload = NULL; char **use_argv; struct timeval tv; -- cgit 1.4.1 From 7b7914e1d6e5557640bb555a40692bfbda32462e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 25 Jul 2022 09:09:29 +0200 Subject: code format --- frida_mode/src/instrument/instrument.c | 1 + frida_mode/src/instrument/instrument_x64.c | 4 +++- instrumentation/SanitizerCoveragePCGUARD.so.cc | 1 - 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index a9568390..35e85ec8 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -291,6 +291,7 @@ void instrument_config(void) { } void instrument_init(void) { + if (__afl_map_size == MAP_SIZE) __afl_map_size = FRIDA_DEFAULT_MAP_SIZE; if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 687b2e40..b44c8439 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -333,8 +333,9 @@ static void instrument_coverage_write(GumAddress address, } -void instrument_coverage_optimize(const cs_insn * instr, +void instrument_coverage_optimize(const cs_insn *instr, GumStalkerOutput *output) { + GumX86Writer *cw = output->writer.x86; if (instrument_previous_pc_addr == NULL) { @@ -359,6 +360,7 @@ void instrument_coverage_optimize(const cs_insn * instr, } instrument_coverage_write(GUM_ADDRESS(instr->address), output); + } void instrument_coverage_optimize_insn(const cs_insn *instr, diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 6aa69546..f8ced8fc 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -264,7 +264,6 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { #if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */ - extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK llvmGetPassPluginInfo() { -- cgit 1.4.1 From 67fabcb0be1f48f671a061fd26dd321fdc3425a0 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 25 Jul 2022 11:15:14 +0200 Subject: update compile options --- GNUmakefile | 5 ++++- docs/INSTALL.md | 10 +++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index b6865f0c..04d1411d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -367,13 +367,16 @@ help: @echo Known build environment options: @echo "==========================================" @echo STATIC - compile AFL++ static - @echo ASAN_BUILD - compiles with memory sanitizer for debug purposes + @echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes + @echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes @echo DEBUG - no optimization, -ggdb3, all warnings and -Werror @echo PROFILING - compile afl-fuzz with profiling information @echo INTROSPECTION - compile afl-fuzz with mutation introspection @echo NO_PYTHON - disable python support @echo NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing @echo NO_NYX - disable building nyx mode dependencies + @echo "NO_CORESIGHT - disable building coresight (arm64 only)" + @echo NO_UNICORN_ARM64 - disable building unicorn on arm64 @echo AFL_NO_X86 - if compiling on non-intel/amd platforms @echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)" @echo "==========================================" diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 312b41e9..c60e3ada 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -79,17 +79,21 @@ make STATIC=1 These build options exist: * STATIC - compile AFL++ static -* ASAN_BUILD - compiles with memory sanitizer for debug purposes +* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes +* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for + debug purposes * DEBUG - no optimization, -ggdb3, all warnings and -Werror -* PROFILING - compile with profiling information (gprof) +* PROFILING - compile afl-fuzz with profiling information * INTROSPECTION - compile afl-fuzz with mutation introspection * NO_PYTHON - disable python support * NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing * NO_NYX - disable building nyx mode dependencies +* NO_CORESIGHT - disable building coresight (arm64 only) +* NO_UNICORN_ARM64 - disable building unicorn on arm64 * AFL_NO_X86 - if compiling on non-intel/amd platforms * LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config - (e.g., Debian) + (e.g. Debian) e.g.: `make ASAN_BUILD=1` -- cgit 1.4.1 From c6af98bc355dbd828e2e6b332ab743a6c2f4ce4c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 25 Jul 2022 11:49:49 +0200 Subject: fix --- GNUmakefile | 2 +- docs/INSTALL.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 04d1411d..a64d511f 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -378,7 +378,7 @@ help: @echo "NO_CORESIGHT - disable building coresight (arm64 only)" @echo NO_UNICORN_ARM64 - disable building unicorn on arm64 @echo AFL_NO_X86 - if compiling on non-intel/amd platforms - @echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g. Debian)" + @echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)" @echo "==========================================" @echo e.g.: make ASAN_BUILD=1 diff --git a/docs/INSTALL.md b/docs/INSTALL.md index c60e3ada..4f2b7174 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -93,9 +93,9 @@ These build options exist: * NO_UNICORN_ARM64 - disable building unicorn on arm64 * AFL_NO_X86 - if compiling on non-intel/amd platforms * LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config - (e.g. Debian) + (e.g., Debian) -e.g.: `make ASAN_BUILD=1` +e.g.: `make LLVM_CONFIG=llvm-config-14` ## MacOS X on x86 and arm64 (M1) -- cgit 1.4.1 From f2b7104cd6c808c2caceb1314a19f4dbcfd087d7 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 29 Jul 2022 17:23:30 +0100 Subject: Fix endianness of coverage data on big endian systems --- frida_mode/README.md | 3 ++- frida_mode/src/instrument/instrument_coverage.c | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frida_mode/README.md b/frida_mode/README.md index 4025dba5..1ed368d4 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -151,6 +151,7 @@ instances run CMPLOG mode and instrumentation of the binary is less frequent * `AFL_FRIDA_INST_DEBUG_FILE` - File to write raw assembly of original blocks and their instrumented counterparts during block compilation. +``` Creating block for 0x7ffff7953313: 0x7ffff7953313 mov qword ptr [rax], 0 0x7ffff795331a add rsp, 8 @@ -166,7 +167,7 @@ Generated block 0x7ffff75e98e2 *** - ``` +``` * `AFL_FRIDA_INST_CACHE_SIZE` - Set the size of the instrumentation cache used as a look-up table to cache real to instrumented address block translations. Default is 256Mb. diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c index 68842feb..07d4d622 100644 --- a/frida_mode/src/instrument/instrument_coverage.c +++ b/frida_mode/src/instrument/instrument_coverage.c @@ -317,6 +317,12 @@ static void coverage_write_events(void *key, void *value, void *user_data) { }; +#if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) + evt.offset = __builtin_bswap32(evt.offset); + evt.length = __builtin_bswap16(evt.length); + evt.module = __builtin_bswap16(evt.module); +#endif + coverage_write(fd, &evt, sizeof(coverage_event_t)); } -- cgit 1.4.1 From 4fdd64d6d6ca98145873057115d059704a79aeeb Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 29 Jul 2022 18:24:22 +0100 Subject: Added framework for logging register contents at the end of each basic block --- frida_mode/README.md | 2 ++ frida_mode/Scripting.md | 8 +++++ frida_mode/frida.map | 1 + frida_mode/include/instrument.h | 3 ++ frida_mode/src/instrument/instrument.c | 45 ++++++++++++++++++++++++++-- frida_mode/src/instrument/instrument_arm32.c | 19 ++++++++++++ frida_mode/src/instrument/instrument_arm64.c | 36 ++++++++++++++++++++++ frida_mode/src/instrument/instrument_debug.c | 4 +-- frida_mode/src/instrument/instrument_x64.c | 17 +++++++++++ frida_mode/src/instrument/instrument_x86.c | 11 +++++++ frida_mode/src/js/api.js | 9 ++++++ frida_mode/src/js/js_api.c | 5 ++++ frida_mode/ts/lib/afl.ts | 14 +++++++++ include/envs.h | 1 + 14 files changed, 169 insertions(+), 6 deletions(-) diff --git a/frida_mode/README.md b/frida_mode/README.md index 1ed368d4..29f7968b 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -178,6 +178,8 @@ Default is 256Mb. a file. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use +* `AFL_FRIDA_INST_REGS_FILE` - File to write raw register contents at the start + of each block. `AFL_FRIDA_INST_TRACE`. * `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to instrumented address block translations. diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md index 8634860b..2b18e200 100644 --- a/frida_mode/Scripting.md +++ b/frida_mode/Scripting.md @@ -850,6 +850,14 @@ class Afl { static setInstrumentNoOptimize() { Afl.jsApiSetInstrumentNoOptimize(); } + /** + * See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as + * an argument. + */ + public static setInstrumentRegsFile(file: string): void { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetInstrumentRegsFile(buf); + } /* * See `AFL_FRIDA_INST_SEED` */ diff --git a/frida_mode/frida.map b/frida_mode/frida.map index 6726dbbd..8e956460 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -19,6 +19,7 @@ js_api_set_instrument_libraries; js_api_set_instrument_instructions; js_api_set_instrument_no_optimize; + js_api_set_instrument_regs_file; js_api_set_instrument_seed; js_api_set_instrument_trace; js_api_set_instrument_trace_unique; diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index cd480202..b85aa571 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -13,6 +13,7 @@ extern gboolean instrument_unique; extern guint64 instrument_hash_zero; extern char *instrument_coverage_unstable_filename; extern gboolean instrument_coverage_insn; +extern char * instrument_regs_filename; extern gboolean instrument_use_fixed_seed; extern guint64 instrument_fixed_seed; @@ -66,6 +67,8 @@ void instrument_cache_config(void); void instrument_cache_init(void); void instrument_cache_insert(gpointer real_address, gpointer code_address); void instrument_cache(const cs_insn *instr, GumStalkerOutput *output); +void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data); +void instrument_regs_format(int fd, char *format, ...); #endif diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 35e85ec8..93c498e8 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -32,6 +33,7 @@ gboolean instrument_use_fixed_seed = FALSE; guint64 instrument_fixed_seed = 0; char *instrument_coverage_unstable_filename = NULL; gboolean instrument_coverage_insn = FALSE; +char * instrument_regs_filename = NULL; static GumStalkerTransformer *transformer = NULL; @@ -39,6 +41,8 @@ static GumAddress previous_rip = 0; static GumAddress previous_end = 0; static u8 *edges_notified = NULL; +static int regs_fd = -1; + __thread guint64 instrument_previous_pc; __thread guint64 *instrument_previous_pc_addr = NULL; @@ -232,6 +236,10 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } + if (unlikely(instrument_regs_filename != NULL)) { + gum_stalker_iterator_put_callout(iterator, instrument_write_regs, + (void *)(size_t)regs_fd, NULL); + } } } @@ -242,8 +250,6 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } - instrument_debug_instruction(instr->address, instr->size, output); - if (likely(!excluded)) { asan_instrument(instr, iterator); @@ -268,7 +274,6 @@ static void instrument_basic_block(GumStalkerIterator *iterator, instrument_flush(output); instrument_debug_end(output); instrument_coverage_end(instr->address + instr->size); - } void instrument_config(void) { @@ -281,6 +286,7 @@ void instrument_config(void) { instrument_coverage_unstable_filename = (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE")); instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL); + instrument_regs_filename = getenv("AFL_FRIDA_INST_REGS_FILE"); instrument_debug_config(); instrument_coverage_config(); @@ -394,6 +400,23 @@ void instrument_init(void) { instrument_hash_seed); instrument_hash_zero = instrument_get_offset_hash(0); + FOKF(cBLU "Instrumentation" cRST " - " cGRN "regs:" cYEL " [%s]", + instrument_regs_filename == NULL ? " " : instrument_regs_filename); + + if (instrument_regs_filename != NULL) { + char *path = + g_canonicalize_filename(instrument_regs_filename, g_get_current_dir()); + + FOKF(cBLU "Instrumentation" cRST " - " cGRN "path:" cYEL " [%s]", path); + + regs_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + + if (regs_fd < 0) { FFATAL("Failed to open regs file '%s'", path); } + + g_free(path); + } + asan_init(); cmplog_init(); instrument_coverage_init(); @@ -420,3 +443,19 @@ void instrument_on_fork() { } +void instrument_regs_format(int fd, char *format, ...) { + va_list ap; + char buffer[4096] = {0}; + int ret; + int len; + + va_start(ap, format); + ret = vsnprintf(buffer, sizeof(buffer) - 1, format, ap); + va_end(ap); + + if (ret < 0) { return; } + + len = strnlen(buffer, sizeof(buffer)); + + IGNORED_RETURN(write(fd, buffer, len)); +} diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 572b706c..73923326 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -80,5 +80,24 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { } +void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { + int fd = (int)user_data; + instrument_regs_format(fd, + "r0 : 0x%08x, r1 : 0x%08x, r2 : 0x%08x, r3 : 0x%08x\n", + cpu_context->r[0], cpu_context->r[2], + cpu_context->r[1], cpu_context->r[3]); + instrument_regs_format(fd, + "r4 : 0x%08x, r5 : 0x%08x, r6 : 0x%08x, r7 : 0x%08x\n", + cpu_context->r[4], cpu_context->r[5], + cpu_context->r[6], cpu_context->r[7]); + instrument_regs_format( + fd, "r8 : 0x%08x, r9 : 0x%08x, r10: 0x%08x, r11: 0x%08x\n", + cpu_context->r8, cpu_context->r9, cpu_context->r10, cpu_context->r11); + instrument_regs_format( + fd, "r12: 0x%08x, sp : 0x%08x, lr : 0x%08x, pc : 0x%08x\n", + cpu_context->r12, cpu_context->sp, cpu_context->lr, cpu_context->pc); + instrument_regs_format(fd, "cpsr: 0x%08x\n\n", cpu_context->cpsr); +} + #endif diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 3c37ea5f..9157f8f5 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -406,5 +406,41 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { } +void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { + int fd = (int)(size_t)user_data; + instrument_regs_format( + fd, "x0 : 0x%016x, x1 : 0x%016x, x2 : 0x%016x, x3 : 0x%016x\n", + cpu_context->x[0], cpu_context->x[1], cpu_context->x[2], + cpu_context->x[3]); + instrument_regs_format( + fd, "x4 : 0x%016x, x5 : 0x%016x, x6 : 0x%016x, x7 : 0x%016x\n", + cpu_context->x[4], cpu_context->x[5], cpu_context->x[6], + cpu_context->x[7]); + instrument_regs_format( + fd, "x8 : 0x%016x, x9 : 0x%016x, x10: 0x%016x, x11: 0x%016x\n", + cpu_context->x[8], cpu_context->x[9], cpu_context->x[10], + cpu_context->x[11]); + instrument_regs_format( + fd, "x12: 0x%016x, x13: 0x%016x, x14: 0x%016x, x15: 0x%016x\n", + cpu_context->x[12], cpu_context->x[13], cpu_context->x[14], + cpu_context->x[15]); + instrument_regs_format( + fd, "x16: 0x%016x, x17: 0x%016x, x18: 0x%016x, x19: 0x%016x\n", + cpu_context->x[16], cpu_context->x[17], cpu_context->x[18], + cpu_context->x[19]); + instrument_regs_format( + fd, "x20: 0x%016x, x21: 0x%016x, x22: 0x%016x, x23: 0x%016x\n", + cpu_context->x[20], cpu_context->x[21], cpu_context->x[22], + cpu_context->x[23]); + instrument_regs_format( + fd, "x24: 0x%016x, x25: 0x%016x, x26: 0x%016x, x27: 0x%016x\n", + cpu_context->x[24], cpu_context->x[25], cpu_context->x[26], + cpu_context->x[27]); + instrument_regs_format( + fd, "x28: 0x%016x, fp : 0x%016x, lr : 0x%016x, sp : 0x%016x\n", + cpu_context->x[28], cpu_context->fp, cpu_context->lr, cpu_context->sp); + instrument_regs_format(fd, "pc : 0x%016x\n\n", cpu_context->pc); +} + #endif diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index d26f9cec..17245d65 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -63,14 +63,12 @@ static void instrument_disasm(guint8 *start, guint8 *end, count = cs_disasm(capstone, curr, size, GPOINTER_TO_SIZE(curr), 0, &insn); if (insn == NULL) { - instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER "x\n", - (uint64_t)curr, *(size_t *)curr); + (uint64_t)(size_t)curr, *(size_t *)curr); len += sizeof(size_t); continue; - } for (i = 0; i != count; i++) { diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index b44c8439..9d754082 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -468,5 +468,22 @@ gpointer instrument_cur(GumStalkerOutput *output) { } +void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { + int fd = (int)(size_t)user_data; + instrument_regs_format( + fd, "rax: 0x%016x, rbx: 0x%016x, rcx: 0x%016x, rdx: 0x%016x\n", + cpu_context->rax, cpu_context->rbx, cpu_context->rcx, cpu_context->rdx); + instrument_regs_format( + fd, "rdi: 0x%016x, rsi: 0x%016x, rbp: 0x%016x, rsp: 0x%016x\n", + cpu_context->rdi, cpu_context->rsi, cpu_context->rbp, cpu_context->rsp); + instrument_regs_format( + fd, "r8 : 0x%016x, r9 : 0x%016x, r10: 0x%016x, r11: 0x%016x\n", + cpu_context->r8, cpu_context->r9, cpu_context->r10, cpu_context->r11); + instrument_regs_format( + fd, "r12: 0x%016x, r13: 0x%016x, r14: 0x%016x, r15: 0x%016x\n", + cpu_context->r12, cpu_context->r13, cpu_context->r14, cpu_context->r15); + instrument_regs_format(fd, "rip: 0x%016x\n\n", cpu_context->rip); +} + #endif diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 8798cfcf..eb0c7184 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -270,5 +270,16 @@ void instrument_cache(const cs_insn *instr, GumStalkerOutput *output) { } +void instrument_write_regs(GumCpuContext *cpu_context, gpointer user_data) { + int fd = (int)(size_t)user_data; + instrument_regs_format( + fd, "eax: 0x%08x, ebx: 0x%08x, ecx: 0x%08x, edx: 0x%08x\n", + cpu_context->eax, cpu_context->ebx, cpu_context->ecx, cpu_context->edx); + instrument_regs_format( + fd, "esi: 0x%08x, edi: 0x%08x, ebp: 0x%08x, esp: 0x%08x\n", + cpu_context->esi, cpu_context->edi, cpu_context->ebp, cpu_context->esp); + instrument_regs_format(fd, "eip: 0x%08x\n\n", cpu_context->eip); +} + #endif diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index c1c9d36f..721ef82c 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -150,6 +150,14 @@ class Afl { static setInstrumentNoOptimize() { Afl.jsApiSetInstrumentNoOptimize(); } + /** + * See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as + * an argument. + */ + static setInstrumentRegsFile(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetInstrumentRegsFile(buf); + } /* * See `AFL_FRIDA_INST_SEED` */ @@ -322,6 +330,7 @@ Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); +Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 7cc8ffc7..d0c0aa60 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -156,6 +156,11 @@ __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize( } +__attribute__((visibility("default"))) void js_api_set_instrument_regs_file( + char *path) { + instrument_regs_filename = g_strdup(path); +} + __attribute__((visibility("default"))) void js_api_set_instrument_seed( guint64 seed) { diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index a858f074..455d4305 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -178,6 +178,15 @@ class Afl { Afl.jsApiSetInstrumentNoOptimize(); } + /** + * See `AFL_FRIDA_INST_REGS_FILE`. This function takes a single `string` as + * an argument. + */ + public static setInstrumentRegsFile(file: string): void { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetInstrumentRegsFile(buf); + } + /* * See `AFL_FRIDA_INST_SEED` */ @@ -419,6 +428,11 @@ class Afl { "void", []); + private static readonly jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction( + "js_api_set_instrument_regs_file", + "void", + ["pointer"]); + private static readonly jsApiSetInstrumentSeed = Afl.jsApiGetFunction( "js_api_set_instrument_seed", "void", diff --git a/include/envs.h b/include/envs.h index 9b8917f9..853edbd9 100644 --- a/include/envs.h +++ b/include/envs.h @@ -67,6 +67,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", "AFL_FRIDA_INST_RANGES", + "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE", "AFL_FRIDA_INST_TRACE_UNIQUE", -- cgit 1.4.1 From 6056d4b140f0665c6a701cada9166379be3435ac Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 3 Aug 2022 10:06:52 +0200 Subject: fix pcguard vector select instrumentation --- docs/Changelog.md | 3 +++ instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/Changelog.md b/docs/Changelog.md index c7414ff2..05bbe827 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,6 +12,9 @@ sending a mail to . - afl-fuzz: - change post_process hook to allow returning NULL and 0 length to tell afl-fuzz to skip this mutated input + - afl-cc: + - important fix for the default pcguard mode when LLVM IR vector + selects are produced, thanks to @juppytt for reporting! - gcc_plugin: - Adacore submitted CMPLOG support to the gcc_plugin! :-) - llvm_mode: diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index f8ced8fc..e22c9ead 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -902,7 +902,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage( if (tt) { cnt_sel++; - cnt_sel_inc += tt->getElementCount().getKnownMinValue(); + cnt_sel_inc += (tt->getElementCount().getKnownMinValue() * 2); } -- cgit 1.4.1