From e46e0bce44f0799731f5e7724ba3dfacafd4c41a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 2 Apr 2023 12:03:45 +0200 Subject: allow pizza mode to be disabled --- include/afl-fuzz.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 58d02af5..5fd393dd 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -398,8 +398,8 @@ typedef struct afl_env_vars { afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, - afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability; + afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts, + afl_no_startup_calibration, afl_no_warn_instability; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, @@ -408,6 +408,8 @@ typedef struct afl_env_vars { *afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal, *afl_target_env, *afl_persistent_record, *afl_exit_on_time; + s32 afl_pizza_mode; + } afl_env_vars_t; struct afl_pass_stat { -- cgit 1.4.1 From 36127fb1970746f53fec44f9394061f57a4e94c3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 12:59:20 +0200 Subject: add -z switch --- docs/Changelog.md | 1 + include/afl-fuzz.h | 3 ++- src/afl-fuzz-queue.c | 7 ++++++- src/afl-fuzz.c | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index fbf50137..8127e594 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,6 +12,7 @@ - fixed a crash in pizza (1st april easter egg) mode. Sorry for everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 + - add -z switch to prefer new coverage findings in seed selection - afl-cc: - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5fd393dd..7ff3315b 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -501,7 +501,8 @@ typedef struct afl_state { custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ - pizza_is_served; /* pizza mode */ + pizza_is_served, /* pizza mode */ + prefer_new; /* prefer new queue entries */ u32 stats_update_freq; /* Stats update frequency (execs) */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 40184645..1cdc8b54 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -74,9 +74,14 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); } weight *= (log(q->bitmap_size) / avg_bitmap_size); weight *= (1 + (q->tc_ref / avg_top_size)); - if (unlikely(weight < 1.0)) { weight = 1.0; } + if (unlikely(weight < 0.1)) { weight = 0.1; } if (unlikely(q->favored)) { weight *= 5; } if (unlikely(!q->was_fuzzed)) { weight *= 2; } + if (unlikely(afl->prefer_new)) { + + weight *= (2.0 * (q->id / (afl->queued_items - 1))); + + } return weight; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3380fd90..0f01360e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -132,6 +132,7 @@ static void usage(u8 *argv0, int more_help) { " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" " quad -- see docs/FAQ.md for more information\n" + " -z - prefer new coverage findings when fuzzing\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, default %u ms). " @@ -569,6 +570,10 @@ int main(int argc, char **argv_orig, char **envp) { afl->max_length = atoi(optarg); break; + case 'z': + afl->prefer_new = 1; + break; + case 'Z': afl->old_seed_selection = 1; break; -- cgit 1.4.1 From 6cc8d607fb24e060591ece4b42d83fc06de68fc6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 13 Apr 2023 11:44:39 +0200 Subject: remove -z option, use -p mmopt instead --- GNUmakefile | 2 +- docs/Changelog.md | 2 +- include/afl-fuzz.h | 3 +-- instrumentation/SanitizerCoverageLTO.so.cc | 2 +- instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +- src/afl-fuzz-queue.c | 14 ++++---------- src/afl-fuzz.c | 7 +------ 7 files changed, 10 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/GNUmakefile b/GNUmakefile index 208e965b..85f164f5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -546,7 +546,7 @@ ifndef AFL_NO_X86 test_build: afl-cc afl-gcc afl-as afl-showmap @echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..." @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) - - ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -o .test-instr0 ./test-instr < /dev/null + -ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -q -m none -o .test-instr0 ./test-instr < /dev/null -echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr @rm -f test-instr @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-cc does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi diff --git a/docs/Changelog.md b/docs/Changelog.md index 736deb30..501300b1 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,7 +12,7 @@ - fixed a crash in pizza (1st april easter egg) mode. Sorry for everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 - - add -z switch to prefer new coverage findings in seed selection + - option `-p mmopt` now also selects new queue items more often - print name of custom mutator in UI - afl-cc: - add CFI sanitizer variant to gcc targets diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 7ff3315b..5fd393dd 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -501,8 +501,7 @@ typedef struct afl_state { custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ - pizza_is_served, /* pizza mode */ - prefer_new; /* prefer new queue entries */ + pizza_is_served; /* pizza mode */ u32 stats_update_freq; /* Stats update frequency (execs) */ diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 5603c455..e41f19b6 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -18,7 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #if LLVM_VERSION_MAJOR < 17 -#include "llvm/ADT/Triple.h" + #include "llvm/ADT/Triple.h" #endif #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 5f23698b..85b1ddd5 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -14,7 +14,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #if LLVM_VERSION_MAJOR < 17 -#include "llvm/ADT/Triple.h" + #include "llvm/ADT/Triple.h" #endif #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 6fc3c743..8ad7cd97 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -149,21 +149,15 @@ void create_alias_table(afl_state_t *afl) { } - if (unlikely(afl->prefer_new) && afl->queued_discovered) { + if (unlikely(afl->schedule == MMOPT) && afl->queued_discovered) { - double avg_weight = sum / active; + u32 cnt = afl->queued_discovered >= 5 ? 5 : afl->queued_discovered; - for (i = n - afl->queued_discovered; i < n; i++) { + for (i = n - cnt; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - if (likely(!q->disabled) && q->weight > avg_weight) { - - double prev_weight = q->weight; - q->weight *= (2.0 * (i / n)); - sum += (q->weight - prev_weight); - - } + if (likely(!q->disabled)) { q->weight *= 2.0; } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a0c322da..5ba54d0b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -132,7 +132,6 @@ static void usage(u8 *argv0, int more_help) { " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" " quad -- see docs/FAQ.md for more information\n" - " -z - prefer new coverage findings when fuzzing\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, default %u ms). " @@ -556,7 +555,7 @@ int main(int argc, char **argv_orig, char **envp) { while ( (opt = getopt( argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YzZ")) > + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > 0) { switch (opt) { @@ -569,10 +568,6 @@ int main(int argc, char **argv_orig, char **envp) { afl->max_length = atoi(optarg); break; - case 'z': - afl->prefer_new = 1; - break; - case 'Z': afl->old_seed_selection = 1; break; -- cgit 1.4.1 From f756734ad2782c3ed56feadb4b7b23fc82a7a968 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 13 Apr 2023 12:07:27 +0200 Subject: fix attempt at post_process implementation --- docs/Changelog.md | 1 + docs/custom_mutators.md | 9 +++++++-- include/afl-fuzz.h | 9 +++++++-- src/afl-fuzz-python.c | 49 +++++++++---------------------------------------- src/afl-fuzz-run.c | 7 ++++++- 5 files changed, 30 insertions(+), 45 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 501300b1..9436fc9f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -13,6 +13,7 @@ everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 - option `-p mmopt` now also selects new queue items more often + - fix bug in post_process custom mutator implementation - print name of custom mutator in UI - afl-cc: - add CFI sanitizer variant to gcc targets diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 82131c92..a1de479e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -118,7 +118,7 @@ def deinit(): # optional for Python ### Custom Mutation -- `init`: +- `init` (optional in Python): This method is called when AFL++ starts up and is used to seed RNG and set up buffers and state. @@ -184,6 +184,11 @@ def deinit(): # optional for Python 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). + NOTE: Do not make any random changes to the data in this function! + + PERFORMANCE for C/C++: If possible make the changes in-place (so modify + the `*data` directly, and return it as `*outbuf = data`. + - `fuzz_send` (optional): This method can be used if you want to send data to the target yourself, @@ -202,7 +207,7 @@ def deinit(): # optional for Python discovered if compiled with INTROSPECTION. The custom mutator can then return a string (const char *) that reports the exact mutations used. -- `deinit`: +- `deinit` (optional in Python): The last method to be called, deinitializing the state. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5fd393dd..8b6502b4 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -885,14 +885,19 @@ struct custom_mutator { * A post-processing function to use right before AFL writes the test case to * disk in order to execute the target. * - * (Optional) If this functionality is not needed, simply don't define this + * NOTE: Do not do any random changes to the data in this function! + * + * PERFORMANCE: If you can modify the data in-place you will have a better + * performance. Modify *data and set `*out_buf = data`. + * + * (Optional) If this functionality is not needed, simply do not define this * function. * * @param[in] data pointer returned in afl_custom_init by this custom mutator * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case * @param[out] out_buf Pointer to the buffer storing the test case after - * processing. External library should allocate memory for out_buf. + * processing. The external library should allocate memory for out_buf. * It can chose to alter buf in-place, if the space is large enough. * @return Size of the output buffer. */ diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 673e5a6c..7dad0770 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -219,11 +219,14 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (py_module != NULL) { - u8 py_notrim = 0, py_idx; - /* init, required */ + u8 py_notrim = 0; py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init"); - if (!py_functions[PY_FUNC_INIT]) - FATAL("init function not found in python module"); + if (!py_functions[PY_FUNC_INIT]) { + + WARNF("init function not found in python module"); + + } + py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); if (!py_functions[PY_FUNC_FUZZ]) py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate"); @@ -231,12 +234,6 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "describe"); py_functions[PY_FUNC_FUZZ_COUNT] = PyObject_GetAttrString(py_module, "fuzz_count"); - if (!py_functions[PY_FUNC_FUZZ]) { - - WARNF("fuzz function not found in python module"); - - } - py_functions[PY_FUNC_POST_PROCESS] = PyObject_GetAttrString(py_module, "post_process"); py_functions[PY_FUNC_INIT_TRIM] = @@ -263,36 +260,6 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (!py_functions[PY_FUNC_DEINIT]) WARNF("deinit function not found in python module"); - for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { - - if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) { - - if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) { - - // Implementing the trim API is optional for now - if (PyErr_Occurred()) { PyErr_Print(); } - py_notrim = 1; - - } else if (py_idx >= PY_OPTIONAL) { - - // Only _init and _deinit are not optional currently - - if (PyErr_Occurred()) { PyErr_Print(); } - - } else { - - fprintf(stderr, - "Cannot find/call function with index %d in external " - "Python module.\n", - py_idx); - return NULL; - - } - - } - - } - if (py_notrim) { py_functions[PY_FUNC_INIT_TRIM] = NULL; @@ -345,6 +312,8 @@ static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, (void)afl; + if (py_mutator->py_functions[PY_FUNC_INIT] == NULL) { return; } + PyObject *py_args, *py_value; /* Provide the init function a seed for the Python RNG */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index f5425011..26e8549d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -133,7 +133,12 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { } - if (new_mem != *mem) { *mem = new_mem; } + if (new_mem != *mem && new_mem != NULL && new_size > 0) { + + *mem = afl_realloc((void **)mem, new_size); + memmove(*mem, new_mem, new_size); + + } if (unlikely(afl->custom_mutators_count)) { -- cgit 1.4.1 From eefd98f3741b5feca32c75b34a8d7b33e34044d0 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 14 Apr 2023 02:25:33 +0200 Subject: add Nyx support in various tools (like afl-cmin) --- afl-cmin | 14 ++++++-- include/common.h | 6 ++++ include/forkserver.h | 3 ++ src/afl-analyze.c | 64 ++++++++++++++++++++++++++++++--- src/afl-common.c | 31 ++++++++++++++++ src/afl-forkserver.c | 65 ++++++++++++++++++++++++++++++++++ src/afl-fuzz.c | 63 --------------------------------- src/afl-showmap.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/afl-tmin.c | 59 ++++++++++++++++++++++++++++++- 9 files changed, 330 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/afl-cmin b/afl-cmin index 15b61f89..12791584 100755 --- a/afl-cmin +++ b/afl-cmin @@ -109,6 +109,7 @@ function usage() { " -O - use binary-only instrumentation (FRIDA mode)\n" \ " -Q - use binary-only instrumentation (QEMU mode)\n" \ " -U - use unicorn-based instrumentation (unicorn mode)\n" \ +" -X - use Nyx mode\n" \ "\n" \ "Minimization settings:\n" \ " -A - allow crashes and timeouts (not recommended)\n" \ @@ -156,7 +157,7 @@ BEGIN { # process options Opterr = 1 # default is to diagnose Optind = 1 # skip ARGV[0] - while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQU?")) != -1) { + while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUX?")) != -1) { if (_go_c == "i") { if (!Optarg) usage() if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} @@ -217,6 +218,12 @@ BEGIN { extra_par = extra_par " -U" unicorn_mode = 1 continue + } else + if (_go_c == "X") { + if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} + extra_par = extra_par " -X" + nyx_mode = 1 + continue } else if (_go_c == "?") { exit 1 @@ -291,7 +298,8 @@ BEGIN { exit 1 } - if (target_bin && !exists_and_is_executable(target_bin)) { + + if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) { "command -v "target_bin" 2>/dev/null" | getline tnew if (!tnew || !exists_and_is_executable(tnew)) { @@ -311,7 +319,7 @@ BEGIN { } } - if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode) { + if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode && !nyx_mode) { if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) { print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr" exit 1 diff --git a/include/common.h b/include/common.h index 0958b035..279a5f47 100644 --- a/include/common.h +++ b/include/common.h @@ -147,5 +147,11 @@ s32 create_file(u8 *fn); void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); +#ifdef __linux__ +/* Nyx helper functions to create and remove tmp workdirs */ +char* create_nyx_tmp_workdir(void); +void remove_nyx_tmp_workdir(char* nyx_out_dir_path); +#endif + #endif diff --git a/include/forkserver.h b/include/forkserver.h index 50898a08..273a9255 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -75,6 +75,9 @@ typedef struct { } nyx_plugin_handler_t; +/* Imports helper functions to enable Nyx mode (Linux only )*/ +nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary); + #endif typedef struct afl_forkserver { diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 548956d8..0bdadfdc 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -121,9 +121,9 @@ static void kill_child() { } -static void classify_counts(u8 *mem) { +static void classify_counts(u8 *mem, u32 mem_size) { - u32 i = map_size; + u32 i = mem_size; if (edges_only) { @@ -222,7 +222,7 @@ static u64 analyze_run_target(u8 *mem, u32 len, u8 first_run) { } - classify_counts(fsrv.trace_bits); + classify_counts(fsrv.trace_bits, fsrv.map_size); total_execs++; if (stop_soon) { @@ -768,6 +768,7 @@ static void usage(u8 *argv0) { " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " "mode)\n" + " -X - use Nyx mode\n" #endif "\n" @@ -814,7 +815,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_init(&fsrv); - while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWh")) > 0) { + while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXh")) > 0) { switch (opt) { @@ -965,6 +966,22 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.mem_limit = mem_limit; break; + + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv.nyx_mode = 1; + fsrv.nyx_parent = true; + fsrv.nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif case 'h': usage(argv[0]); @@ -997,7 +1014,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(argv); +#ifdef __linux__ + if(!fsrv.nyx_mode){ + fsrv.target_path = find_binary(argv[optind]); + } + else{ + fsrv.target_path = ck_strdup(argv[optind]); + } +#else fsrv.target_path = find_binary(argv[optind]); +#endif + fsrv.trace_bits = afl_shm_init(&shm, map_size, 0); detect_file_args(argv + optind, fsrv.out_file, &use_stdin); signal(SIGALRM, kill_child); @@ -1020,6 +1047,23 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv.nyx_mode) { + + fsrv.nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); + fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv.nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } + + fsrv.out_dir_path = create_nyx_tmp_workdir(); + fsrv.nyx_bind_cpu_id = 0; + + use_argv = argv + optind; +#endif + } else { use_argv = argv + optind; @@ -1045,7 +1089,13 @@ int main(int argc, char **argv_orig, char **envp) { &fsrv, NULL, NULL, (fsrv.qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM); read_initial_file(); +#ifdef __linux__ + if(!fsrv.nyx_mode){ + (void)check_binary_signatures(fsrv.target_path); + } +#else (void)check_binary_signatures(fsrv.target_path); +#endif ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...", mem_limit, exec_tmout, edges_only ? ", edges only" : ""); @@ -1069,6 +1119,12 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); +#ifdef __linux__ + if (fsrv.nyx_mode) { + remove_nyx_tmp_workdir(fsrv.out_dir_path); + } +#endif + afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); if (fsrv.target_path) { ck_free(fsrv.target_path); } diff --git a/src/afl-common.c b/src/afl-common.c index 86226c9f..7dbf7129 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1359,3 +1359,34 @@ s32 create_file(u8 *fn) { } +#ifdef __linux__ + +/* Nyx requires a tmp workdir to access specific files (such as mmapped files, + * etc.). This helper function basically creates both a path to a tmp workdir + * and the workdir itself. If the environment variable TMPDIR is set, we use + * that as the base directory, otherwise we use /tmp. */ +char* create_nyx_tmp_workdir(void) { + + char *tmpdir = getenv("TMPDIR"); + + if (!tmpdir) { tmpdir = "/tmp"; } + + char* nyx_out_dir_path = alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); + + if (mkdir(nyx_out_dir_path, 0700)) { + PFATAL("Unable to create nyx workdir"); + } + + return nyx_out_dir_path; +} + +/* Vice versa, we remove the tmp workdir for nyx with this helper function. */ +void remove_nyx_tmp_workdir(char* nyx_out_dir_path) { + /* Fix me: This is not recursive, so it will always fail. Use a libnyx helper function instead + * to remove the workdir safely (and not risking to wipe the whole filesystem accidentally). */ + //if (rmdir(nyx_out_dir_path)) { + // PFATAL("Unable to remove nyx workdir"); + //} + free(nyx_out_dir_path); +} +#endif diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 5aa4c2ff..95328aa2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -49,6 +49,71 @@ #include #include +#ifdef __linux__ +#include + +/* function to load nyx_helper function from libnyx.so */ + +nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { + + void *handle; + nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); + + ACTF("Trying to load libnyx.so plugin..."); + handle = dlopen((char *)libnyx_binary, RTLD_NOW); + if (!handle) { goto fail; } + + 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; } + + plugin->nyx_option_set_reload_mode = + dlsym(handle, "nyx_option_set_reload_mode"); + if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; } + + plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); + if (plugin->nyx_option_set_timeout == NULL) { goto fail; } + + plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); + if (plugin->nyx_option_apply == NULL) { goto fail; } + + plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); + if (plugin->nyx_set_afl_input == NULL) { goto fail; } + + plugin->nyx_exec = dlsym(handle, "nyx_exec"); + if (plugin->nyx_exec == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); + if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer_size = + dlsym(handle, "nyx_get_bitmap_buffer_size"); + if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } + + plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); + if (plugin->nyx_get_aux_string == NULL) { goto fail; } + + OKF("libnyx plugin is ready!"); + return plugin; + +fail: + + FATAL("failed to load libnyx: %s\n", dlerror()); + free(plugin); + return NULL; + +} + +#endif + /** * The correct fds for reading and writing pipes */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a0c322da..8b4fe1e5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -436,69 +436,6 @@ static void fasan_check_afl_preload(char *afl_preload) { } - #ifdef __linux__ - #include - -nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { - - void *handle; - nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); - - ACTF("Trying to load libnyx.so plugin..."); - handle = dlopen((char *)libnyx_binary, RTLD_NOW); - if (!handle) { goto fail; } - - 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; } - - plugin->nyx_option_set_reload_mode = - dlsym(handle, "nyx_option_set_reload_mode"); - if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; } - - plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); - if (plugin->nyx_option_set_timeout == NULL) { goto fail; } - - plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); - if (plugin->nyx_option_apply == NULL) { goto fail; } - - plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); - if (plugin->nyx_set_afl_input == NULL) { goto fail; } - - plugin->nyx_exec = dlsym(handle, "nyx_exec"); - if (plugin->nyx_exec == NULL) { goto fail; } - - plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); - if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; } - - plugin->nyx_get_bitmap_buffer_size = - dlsym(handle, "nyx_get_bitmap_buffer_size"); - if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } - - plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); - if (plugin->nyx_get_aux_string == NULL) { goto fail; } - - OKF("libnyx plugin is ready!"); - return plugin; - -fail: - - FATAL("failed to load libnyx: %s\n", dlerror()); - free(plugin); - return NULL; - -} - - #endif - /* Main entry point */ int main(int argc, char **argv_orig, char **envp) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 29abeb13..3ddebaad 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -434,6 +434,20 @@ static u32 read_file(u8 *in_file) { } +#ifdef __linux__ +/* Execute the target application with an empty input (in Nyx mode). */ +static void showmap_run_target_nyx_mode(afl_forkserver_t *fsrv) { + + afl_fsrv_write_to_testcase(fsrv, NULL, 0); + + if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) == + FSRV_RUN_ERROR) { + + FATAL("Error running target in Nyx mode"); + } +} +#endif + /* Execute target application. */ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { @@ -797,6 +811,7 @@ static void usage(u8 *argv0) { " -W - use qemu-based instrumentation with Wine (Wine mode)\n" " (Not necessary, here for consistency with other afl-* " "tools)\n" + " -X - use Nyx mode\n" #endif "\n" "Other settings:\n" @@ -875,7 +890,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrsh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshX")) > 0) { switch (opt) { @@ -1063,6 +1078,22 @@ int main(int argc, char **argv_orig, char **envp) { break; + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv->nyx_mode = 1; + fsrv->nyx_parent = true; + fsrv->nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif + case 'b': /* Secret undocumented mode. Writes output in raw binary format @@ -1134,7 +1165,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ + fsrv->target_path = find_binary(argv[optind]); + } + else{ + fsrv->target_path = ck_strdup(argv[optind]); + } +#else fsrv->target_path = find_binary(argv[optind]); +#endif + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); if (!quiet_mode) { @@ -1190,6 +1231,26 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv->nyx_mode) { + + use_argv = ck_alloc(sizeof(char *) * (1)); + use_argv[0] = argv[0]; + + fsrv->nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(use_argv[0], "libnyx.so"); + fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv->nyx_handlers == NULL) { + + FATAL("failed to initialize libnyx.so..."); + + } + + fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_bind_cpu_id = 0; +#endif + } else { use_argv = argv + optind; @@ -1226,7 +1287,13 @@ int main(int argc, char **argv_orig, char **envp) { } +#ifdef __linux__ + if(!fsrv->nyx_mode && in_dir){ + (void)check_binary_signatures(fsrv->target_path); + } +#else if (in_dir) { (void)check_binary_signatures(fsrv->target_path); } +#endif shm_fuzz = ck_alloc(sizeof(sharedmem_t)); @@ -1247,7 +1314,13 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz = map + sizeof(u32); configure_afl_kill_signals( - fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM); + fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode + #ifdef __linux__ + || fsrv->nyx_mode + #endif + ) + ? SIGKILL + : SIGTERM); if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) { @@ -1370,6 +1443,12 @@ int main(int argc, char **argv_orig, char **envp) { if (execute_testcases(in_dir) == 0) { +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } +#endif FATAL("could not read input testcases from %s", in_dir); } @@ -1390,7 +1469,15 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - showmap_run_target(fsrv, use_argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ +#endif + showmap_run_target(fsrv, use_argv); +#ifdef __linux__ + } else { + showmap_run_target_nyx_mode(fsrv); + } +#endif tcnt = write_results_to_file(fsrv, out_file); if (!quiet_mode) { @@ -1441,6 +1528,12 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + } +#endif + afl_fsrv_deinit(fsrv); if (stdin_file) { ck_free(stdin_file); } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index c0087f5f..942525d4 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -789,6 +789,7 @@ static void usage(u8 *argv0) { "mode)\n" " (Not necessary, here for consistency with other afl-* " "tools)\n" + " -X - use Nyx mode\n" #endif "\n" @@ -845,7 +846,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXHh")) > 0) { switch (opt) { @@ -1003,6 +1004,22 @@ int main(int argc, char **argv_orig, char **envp) { break; + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv->nyx_mode = 1; + fsrv->nyx_parent = true; + fsrv->nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif + case 'H': /* Hang Mode */ /* Minimizes a testcase to the minimum that still times out */ @@ -1068,7 +1085,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ + fsrv->target_path = find_binary(argv[optind]); + } + else{ + fsrv->target_path = ck_strdup(argv[optind]); + } +#else fsrv->target_path = find_binary(argv[optind]); +#endif + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); detect_file_args(argv + optind, out_file, &fsrv->use_stdin); signal(SIGALRM, kill_child); @@ -1092,6 +1119,23 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv->nyx_mode) { + + fsrv->nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); + fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv->nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } + + fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_bind_cpu_id = 0; + + use_argv = argv + optind; +#endif + } else { use_argv = argv + optind; @@ -1161,7 +1205,14 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz = map + sizeof(u32); read_initial_file(); + +#ifdef __linux__ + if(!fsrv->nyx_mode){ + (void)check_binary_signatures(fsrv->target_path); + } +#else (void)check_binary_signatures(fsrv->target_path); +#endif if (!fsrv->qemu_mode && !unicorn_mode) { @@ -1265,6 +1316,12 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + } +#endif + remove_shm = 0; afl_shm_deinit(&shm); if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); -- cgit 1.4.1 From a96cdc649fbdf2ae6f40d4e966812c46083032a2 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 14 Apr 2023 05:59:12 +0200 Subject: switch to latest libnyx API --- include/forkserver.h | 25 ++++++++++++++++-------- src/afl-forkserver.c | 54 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/include/forkserver.h b/include/forkserver.h index 273a9255..7cbad8c8 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -51,16 +51,23 @@ typedef enum NyxReturnValue { } NyxReturnValue; +typedef enum NyxProcessRole { + StandAlone, + Parent, + Child, +} NyxProcessRole; + typedef struct { - void *(*nyx_new)(const char *sharedir, const char *workdir, 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_config_load)(const char *sharedir); + void (*nyx_config_set_workdir_path)(void *config, const char *workdir); + void (*nyx_config_set_input_buffer_size)(void *config, uint32_t input_buffer_size); + void (*nyx_config_set_input_buffer_write_protection)(void *config, bool input_buffer_write_protection); + void (*nyx_config_set_hprintf_fd)(void *config, int32_t hprintf_fd); + void (*nyx_config_set_process_role)(void *config, enum NyxProcessRole role); + void (*nyx_config_set_reuse_snapshot_path)(void *config, const char *reuse_snapshot_path); + + void *(*nyx_new)(void *config, 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, @@ -73,6 +80,8 @@ typedef struct { uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, uint32_t size); + bool (*nyx_remove_work_dir)(const char *workdir); + } nyx_plugin_handler_t; /* Imports helper functions to enable Nyx mode (Linux only )*/ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 95328aa2..33c46b8c 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -63,14 +63,29 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { handle = dlopen((char *)libnyx_binary, RTLD_NOW); if (!handle) { goto fail; } - plugin->nyx_new = dlsym(handle, "nyx_new"); - if (plugin->nyx_new == NULL) { goto fail; } + plugin->nyx_config_load = dlsym(handle, "nyx_config_load"); + if (plugin->nyx_config_load == NULL) { goto fail; } + + plugin->nyx_config_set_workdir_path = dlsym(handle, "nyx_config_set_workdir_path"); + if (plugin->nyx_config_set_workdir_path == NULL) { goto fail; } + + plugin->nyx_config_set_input_buffer_size = dlsym(handle, "nyx_config_set_input_buffer_size"); + if (plugin->nyx_config_set_input_buffer_size == NULL) { goto fail; } + + plugin->nyx_config_set_input_buffer_write_protection = dlsym(handle, "nyx_config_set_input_buffer_write_protection"); + if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { goto fail; } - plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent"); - if (plugin->nyx_new_parent == NULL) { goto fail; } + plugin->nyx_config_set_hprintf_fd = dlsym(handle, "nyx_config_set_hprintf_fd"); + if (plugin->nyx_config_set_hprintf_fd == NULL) { goto fail; } - plugin->nyx_new_child = dlsym(handle, "nyx_new_child"); - if (plugin->nyx_new_child == NULL) { goto fail; } + plugin->nyx_config_set_process_role = dlsym(handle, "nyx_config_set_process_role"); + if (plugin->nyx_config_set_process_role == NULL) { goto fail; } + + plugin->nyx_config_set_reuse_snapshot_path = dlsym(handle, "nyx_config_set_reuse_snapshot_path"); + if (plugin->nyx_config_set_reuse_snapshot_path == NULL) { goto fail; } + + plugin->nyx_new = dlsym(handle, "nyx_new"); + if (plugin->nyx_new == NULL) { goto fail; } plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); if (plugin->nyx_shutdown == NULL) { goto fail; } @@ -101,6 +116,10 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); if (plugin->nyx_get_aux_string == NULL) { goto fail; } + plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir"); + if (plugin->nyx_remove_work_dir == NULL) { goto fail; } + + OKF("libnyx plugin is ready!"); return plugin; @@ -474,27 +493,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if (fsrv->nyx_standalone) { + void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new( - fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true); + fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, x); + fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); + fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); + if (fsrv->nyx_standalone) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone); } 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_handlers->nyx_config_set_process_role(nyx_config, Parent); } else { - - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child( - fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id); - + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Child); } - } + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); + ck_free(x); if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); } -- cgit 1.4.1 From 47833bcf9e4b642e090f7cc0da25d1ed99688e5e Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Sun, 16 Apr 2023 04:28:19 +0200 Subject: fix remove_nyx_tmp_workdir function --- include/common.h | 2 +- src/afl-common.c | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/common.h b/include/common.h index 279a5f47..e03566de 100644 --- a/include/common.h +++ b/include/common.h @@ -150,7 +150,7 @@ void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, #ifdef __linux__ /* Nyx helper functions to create and remove tmp workdirs */ char* create_nyx_tmp_workdir(void); -void remove_nyx_tmp_workdir(char* nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path); #endif #endif diff --git a/src/afl-common.c b/src/afl-common.c index 7dbf7129..fe0db94d 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1381,12 +1381,22 @@ char* create_nyx_tmp_workdir(void) { } /* Vice versa, we remove the tmp workdir for nyx with this helper function. */ -void remove_nyx_tmp_workdir(char* nyx_out_dir_path) { - /* Fix me: This is not recursive, so it will always fail. Use a libnyx helper function instead - * to remove the workdir safely (and not risking to wipe the whole filesystem accidentally). */ - //if (rmdir(nyx_out_dir_path)) { - // PFATAL("Unable to remove nyx workdir"); - //} - free(nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path) { + char* workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); + + if (access(workdir_path, R_OK) == 0) { + if(fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + WARNF("Unable to remove nyx workdir (%s)", workdir_path); + } + } + + if (access(nyx_out_dir_path, R_OK) == 0) { + if (rmdir(nyx_out_dir_path)) { + WARNF("Unable to remove nyx workdir (%s)", nyx_out_dir_path); + } + } + + ck_free(workdir_path); + ck_free(nyx_out_dir_path); } #endif -- cgit 1.4.1 From 059d470e8dd0a5339daefe0842f4ad5014717838 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Sun, 16 Apr 2023 04:42:09 +0200 Subject: improved Nyx tmp dir handling (additional sanity checks) --- include/forkserver.h | 2 ++ src/afl-analyze.c | 7 +--- src/afl-forkserver.c | 97 +++++++++++++++++++++++++++++++++++----------------- src/afl-fuzz.c | 8 ----- src/afl-showmap.c | 13 +------ src/afl-tmin.c | 7 +--- 6 files changed, 71 insertions(+), 63 deletions(-) (limited to 'include') diff --git a/include/forkserver.h b/include/forkserver.h index 7cbad8c8..ba280d38 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -190,6 +190,8 @@ typedef struct afl_forkserver { u32 nyx_id; /* nyx runner id (0 -> master) */ u32 nyx_bind_cpu_id; /* nyx runner cpu id */ char *nyx_aux_string; + bool nyx_use_tmp_workdir; + char *nyx_tmp_workdir_path; #endif } afl_forkserver_t; diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0bdadfdc..0a4e7fb5 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -1058,7 +1058,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("failed to initialize libnyx.so..."); } - fsrv.out_dir_path = create_nyx_tmp_workdir(); + fsrv.nyx_use_tmp_workdir = true; fsrv.nyx_bind_cpu_id = 0; use_argv = argv + optind; @@ -1119,11 +1119,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); -#ifdef __linux__ - if (fsrv.nyx_mode) { - remove_nyx_tmp_workdir(fsrv.out_dir_path); - } -#endif afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ae2adc3d..0e705c63 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -126,11 +126,39 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { fail: FATAL("failed to load libnyx: %s\n", dlerror()); - free(plugin); + ck_free(plugin); return NULL; } +void afl_nyx_runner_kill(afl_forkserver_t *fsrv){ + if (fsrv->nyx_mode) { + + if (fsrv->nyx_aux_string){ + ck_free(fsrv->nyx_aux_string); + } + + /* check if we actually got a valid nyx runner */ + if (fsrv->nyx_runner) { + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } + + /* if we have use a tmp work dir we need to remove it */ + if (fsrv->nyx_use_tmp_workdir && fsrv->nyx_tmp_workdir_path) { + remove_nyx_tmp_workdir(fsrv, fsrv->nyx_tmp_workdir_path); + } + } +} + +/* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp + * files) before exiting. Used before "afl_fsrv_killall()" is registered as + * an atexit() handler. */ +#define NYX_PRE_FATAL(fsrv, x...) \ + do { \ + afl_nyx_runner_kill(fsrv); \ + FATAL(x); \ + } while (0) + #endif /** @@ -168,6 +196,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->nyx_runner = NULL; fsrv->nyx_id = 0xFFFFFFFF; fsrv->nyx_bind_cpu_id = 0xFFFFFFFF; + fsrv->nyx_use_tmp_workdir = false; + fsrv->nyx_tmp_workdir_path = NULL; #endif // this structure needs default so we initialize it if this was not done @@ -481,21 +511,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } - if (fsrv->out_dir_path == NULL) { FATAL("Nyx workdir path not found..."); } + if (fsrv->nyx_use_tmp_workdir){ + fsrv->nyx_tmp_workdir_path = create_nyx_tmp_workdir(); + fsrv->out_dir_path = fsrv->nyx_tmp_workdir_path; + } else { + if (fsrv->out_dir_path == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); } + } - char *x = alloc_printf("%s/workdir", fsrv->out_dir_path); + char *workdir_path = alloc_printf("%s/workdir", fsrv->out_dir_path); - if (fsrv->nyx_id == 0xFFFFFFFF) { FATAL("Nyx ID is not set..."); } + if (fsrv->nyx_id == 0xFFFFFFFF) {NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); } if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) { - - FATAL("Nyx CPU ID is not set..."); - + NYX_PRE_FATAL(fsrv, "Nyx CPU ID is not set..."); } void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); - fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, x); + fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, workdir_path); fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); @@ -512,22 +545,36 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (getenv("NYX_REUSE_SNAPSHOT") != NULL){ if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) { - FATAL("NYX_REUSE_SNAPSHOT path does not exist"); + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist"); } /* stupid sanity check to avoid passing an empty or invalid snapshot directory */ char* snapshot_file_path = alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); if (access(snapshot_file_path, R_OK) == -1) { - FATAL("NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); } - free(snapshot_file_path); + ck_free(snapshot_file_path); + + /* another sanity check to avoid passing a snapshot directory that is + * located in the current workdir (the workdir will be wiped by libnyx on startup) */ + char* outdir_path_real = realpath(fsrv->out_dir_path, NULL); + char* workdir_snapshot_path = alloc_printf("%s/workdir/snapshot", outdir_path_real); + char* reuse_snapshot_path_real = realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + + if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0){ + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path is located in current workdir (use another output directory)"); + } + + ck_free(reuse_snapshot_path_real); + ck_free(workdir_snapshot_path); + ck_free(outdir_path_real); fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(nyx_config, getenv("NYX_REUSE_SNAPSHOT")); } fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); - ck_free(x); + ck_free(workdir_path); if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); } @@ -555,13 +602,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) { case Abort: - FATAL("Error: Nyx abort occured..."); + NYX_PRE_FATAL(fsrv, "Error: Nyx abort occured..."); break; case IoError: - FATAL("Error: QEMU-Nyx has died..."); + NYX_PRE_FATAL(fsrv, "Error: QEMU-Nyx has died..."); break; case Error: - FATAL("Error: Nyx runtime error has occured..."); + NYX_PRE_FATAL(fsrv, "Error: Nyx runtime error has occured..."); break; default: break; @@ -571,7 +618,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* autodict in Nyx mode */ if (!ignore_autodict) { - x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); + char* x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); int nyx_autodict_fd = open(x, O_RDONLY); ck_free(x); @@ -584,7 +631,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u8 *dict = ck_alloc(f_len); if (dict == NULL) { - FATAL("Could not allocate %u bytes of autodictionary memory", + NYX_PRE_FATAL(fsrv, "Could not allocate %u bytes of autodictionary memory", f_len); } @@ -602,7 +649,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else { - FATAL( + NYX_PRE_FATAL(fsrv, "Reading autodictionary fail at position %u with %u bytes " "left.", offset, len); @@ -1289,19 +1336,7 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { fsrv->child_pid = -1; #ifdef __linux__ - if (fsrv->nyx_mode) { - - if (fsrv->nyx_aux_string){ - free(fsrv->nyx_aux_string); - } - - /* check if we actually got a valid nyx runner */ - if (fsrv->nyx_runner) { - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); - } - - } - + afl_nyx_runner_kill(fsrv); #endif } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8b4fe1e5..0e380f73 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2191,14 +2191,6 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->pending_not_fuzzed || !valid_seeds) { - #ifdef __linux__ - if (afl->fsrv.nyx_mode) { - - afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner); - - } - - #endif FATAL("We need at least one valid input seed that does not crash!"); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 3ddebaad..832730fd 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1247,7 +1247,7 @@ int main(int argc, char **argv_orig, char **envp) { } - fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_use_tmp_workdir = true; fsrv->nyx_bind_cpu_id = 0; #endif @@ -1443,12 +1443,6 @@ int main(int argc, char **argv_orig, char **envp) { if (execute_testcases(in_dir) == 0) { -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); - } -#endif FATAL("could not read input testcases from %s", in_dir); } @@ -1528,11 +1522,6 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - } -#endif afl_fsrv_deinit(fsrv); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 942525d4..98403049 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1130,7 +1130,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("failed to initialize libnyx.so..."); } - fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_use_tmp_workdir = true; fsrv->nyx_bind_cpu_id = 0; use_argv = argv + optind; @@ -1316,11 +1316,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - } -#endif remove_shm = 0; afl_shm_deinit(&shm); -- cgit 1.4.1 From 56f7e3aa088e715b054f10c01b6b5a7e5acf8931 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 16 Apr 2023 12:42:32 +0200 Subject: hidden -Y option for nyx, code format --- afl-cmin | 10 +-- afl-cmin.bash | 30 +++++--- include/common.h | 4 +- include/forkserver.h | 13 +++- src/afl-analyze.c | 29 +++++--- src/afl-common.c | 26 +++++-- src/afl-forkserver.c | 151 +++++++++++++++++++++++++++----------- src/afl-showmap.c | 54 +++++++++----- src/afl-tmin.c | 27 ++++--- utils/aflpp_driver/aflpp_driver.c | 23 +++--- 10 files changed, 243 insertions(+), 124 deletions(-) (limited to 'include') diff --git a/afl-cmin b/afl-cmin index 12791584..c5e64410 100755 --- a/afl-cmin +++ b/afl-cmin @@ -124,9 +124,9 @@ function usage() { "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ "AFL_KEEP_TRACES: leave the temporary /.traces directory\n" \ "AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ -"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination\n" \ -" (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is set,\n" \ -" this will be set to the same value as AFL_KILL_SIGNAL.\n" \ +"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on\n" \ +" termination (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is\n" \ +" set, this will be set to the same value as AFL_KILL_SIGNAL.\n" \ "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \ "AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \ "AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ @@ -157,7 +157,7 @@ BEGIN { # process options Opterr = 1 # default is to diagnose Optind = 1 # skip ARGV[0] - while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUX?")) != -1) { + while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXY?")) != -1) { if (_go_c == "i") { if (!Optarg) usage() if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} @@ -219,7 +219,7 @@ BEGIN { unicorn_mode = 1 continue } else - if (_go_c == "X") { + if (_go_c == "X" || _go_c == "Y") { if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} extra_par = extra_par " -X" nyx_mode = 1 diff --git a/afl-cmin.bash b/afl-cmin.bash index 10c9477a..bcf62eba 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -53,7 +53,7 @@ unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN \ export AFL_QUIET=1 -while getopts "+i:o:f:m:t:eOQUACh" opt; do +while getopts "+i:o:f:m:t:eOQUAChXY" opt; do case "$opt" in @@ -94,6 +94,14 @@ while getopts "+i:o:f:m:t:eOQUACh" opt; do EXTRA_PAR="$EXTRA_PAR -Q" QEMU_MODE=1 ;; + "Y") + EXTRA_PAR="$EXTRA_PAR -X" + NYX_MODE=1 + ;; + "X") + EXTRA_PAR="$EXTRA_PAR -X" + NYX_MODE=1 + ;; "U") EXTRA_PAR="$EXTRA_PAR -U" UNICORN_MODE=1 @@ -128,6 +136,7 @@ Execution control settings: -O - use binary-only instrumentation (FRIDA mode) -Q - use binary-only instrumentation (QEMU mode) -U - use unicorn-based instrumentation (Unicorn mode) + -X - use Nyx mode Minimization settings: @@ -206,16 +215,19 @@ if [ ! "$TIMEOUT" = "none" ]; then fi -if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then +if [ "$NYX_MODE" = "" ]; then + if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then - TNEW="`which "$TARGET_BIN" 2>/dev/null`" + TNEW="`which "$TARGET_BIN" 2>/dev/null`" - if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then - echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2 - exit 1 - fi + if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then + echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2 + exit 1 + fi + + TARGET_BIN="$TNEW" - TARGET_BIN="$TNEW" + fi fi @@ -228,7 +240,7 @@ grep -aq AFL_DUMP_MAP_SIZE "./$TARGET_BIN" && { } } -if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" ]; then +if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" -a "$NYX_MODE" = "" ]; then if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then echo "[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented." 1>&2 diff --git a/include/common.h b/include/common.h index e03566de..8d85d201 100644 --- a/include/common.h +++ b/include/common.h @@ -149,8 +149,8 @@ void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, #ifdef __linux__ /* Nyx helper functions to create and remove tmp workdirs */ -char* create_nyx_tmp_workdir(void); -void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path); +char *create_nyx_tmp_workdir(void); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char *nyx_out_dir_path); #endif #endif diff --git a/include/forkserver.h b/include/forkserver.h index ba280d38..f5069ce2 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -52,20 +52,25 @@ typedef enum NyxReturnValue { } NyxReturnValue; typedef enum NyxProcessRole { + StandAlone, Parent, Child, + } NyxProcessRole; typedef struct { void *(*nyx_config_load)(const char *sharedir); void (*nyx_config_set_workdir_path)(void *config, const char *workdir); - void (*nyx_config_set_input_buffer_size)(void *config, uint32_t input_buffer_size); - void (*nyx_config_set_input_buffer_write_protection)(void *config, bool input_buffer_write_protection); + void (*nyx_config_set_input_buffer_size)(void *config, + uint32_t input_buffer_size); + void (*nyx_config_set_input_buffer_write_protection)( + void *config, bool input_buffer_write_protection); void (*nyx_config_set_hprintf_fd)(void *config, int32_t hprintf_fd); void (*nyx_config_set_process_role)(void *config, enum NyxProcessRole role); - void (*nyx_config_set_reuse_snapshot_path)(void *config, const char *reuse_snapshot_path); + void (*nyx_config_set_reuse_snapshot_path)(void *config, + const char *reuse_snapshot_path); void *(*nyx_new)(void *config, uint32_t worker_id); void (*nyx_shutdown)(void *qemu_process); @@ -191,7 +196,7 @@ typedef struct afl_forkserver { u32 nyx_bind_cpu_id; /* nyx runner cpu id */ char *nyx_aux_string; bool nyx_use_tmp_workdir; - char *nyx_tmp_workdir_path; + char *nyx_tmp_workdir_path; #endif } afl_forkserver_t; diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0a4e7fb5..5b122741 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -815,7 +815,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_init(&fsrv); - while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXh")) > 0) { + while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXYh")) > 0) { switch (opt) { @@ -966,8 +966,9 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.mem_limit = mem_limit; break; - - #ifdef __linux__ + + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -977,11 +978,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'h': usage(argv[0]); @@ -1015,12 +1016,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(argv); #ifdef __linux__ - if(!fsrv.nyx_mode){ + if (!fsrv.nyx_mode) { + fsrv.target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv.target_path = ck_strdup(argv[optind]); + } + #else fsrv.target_path = find_binary(argv[optind]); #endif @@ -1048,6 +1053,7 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv.nyx_mode) { fsrv.nyx_id = 0; @@ -1055,7 +1061,9 @@ int main(int argc, char **argv_orig, char **envp) { u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); if (fsrv.nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } fsrv.nyx_use_tmp_workdir = true; @@ -1090,9 +1098,7 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); #ifdef __linux__ - if(!fsrv.nyx_mode){ - (void)check_binary_signatures(fsrv.target_path); - } + if (!fsrv.nyx_mode) { (void)check_binary_signatures(fsrv.target_path); } #else (void)check_binary_signatures(fsrv.target_path); #endif @@ -1119,7 +1125,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); - afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); if (fsrv.target_path) { ck_free(fsrv.target_path); } diff --git a/src/afl-common.c b/src/afl-common.c index 5692e277..a5c48e80 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1365,36 +1365,46 @@ s32 create_file(u8 *fn) { * etc.). This helper function basically creates both a path to a tmp workdir * and the workdir itself. If the environment variable TMPDIR is set, we use * that as the base directory, otherwise we use /tmp. */ -char* create_nyx_tmp_workdir(void) { +char *create_nyx_tmp_workdir(void) { char *tmpdir = getenv("TMPDIR"); if (!tmpdir) { tmpdir = "/tmp"; } - char* nyx_out_dir_path = alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); + char *nyx_out_dir_path = + alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); - if (mkdir(nyx_out_dir_path, 0700)) { - PFATAL("Unable to create nyx workdir"); - } + if (mkdir(nyx_out_dir_path, 0700)) { PFATAL("Unable to create nyx workdir"); } return nyx_out_dir_path; + } /* Vice versa, we remove the tmp workdir for nyx with this helper function. */ -void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path) { - char* workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char *nyx_out_dir_path) { + + char *workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); if (access(workdir_path, R_OK) == 0) { - if(fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + + if (fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + WARNF("Unable to remove nyx workdir (%s)", workdir_path); + } + } if (rmdir(nyx_out_dir_path)) { + WARNF("Unable to remove nyx workdir (%s)", nyx_out_dir_path); + } ck_free(workdir_path); ck_free(nyx_out_dir_path); + } + #endif + diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index fd4e213d..aa8c8622 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -50,7 +50,7 @@ #include #ifdef __linux__ -#include + #include /* function to load nyx_helper function from libnyx.so */ @@ -66,22 +66,32 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_config_load = dlsym(handle, "nyx_config_load"); if (plugin->nyx_config_load == NULL) { goto fail; } - plugin->nyx_config_set_workdir_path = dlsym(handle, "nyx_config_set_workdir_path"); + plugin->nyx_config_set_workdir_path = + dlsym(handle, "nyx_config_set_workdir_path"); if (plugin->nyx_config_set_workdir_path == NULL) { goto fail; } - plugin->nyx_config_set_input_buffer_size = dlsym(handle, "nyx_config_set_input_buffer_size"); + plugin->nyx_config_set_input_buffer_size = + dlsym(handle, "nyx_config_set_input_buffer_size"); if (plugin->nyx_config_set_input_buffer_size == NULL) { goto fail; } - plugin->nyx_config_set_input_buffer_write_protection = dlsym(handle, "nyx_config_set_input_buffer_write_protection"); - if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { goto fail; } + plugin->nyx_config_set_input_buffer_write_protection = + dlsym(handle, "nyx_config_set_input_buffer_write_protection"); + if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { - plugin->nyx_config_set_hprintf_fd = dlsym(handle, "nyx_config_set_hprintf_fd"); + goto fail; + + } + + plugin->nyx_config_set_hprintf_fd = + dlsym(handle, "nyx_config_set_hprintf_fd"); if (plugin->nyx_config_set_hprintf_fd == NULL) { goto fail; } - plugin->nyx_config_set_process_role = dlsym(handle, "nyx_config_set_process_role"); + plugin->nyx_config_set_process_role = + dlsym(handle, "nyx_config_set_process_role"); if (plugin->nyx_config_set_process_role == NULL) { goto fail; } - plugin->nyx_config_set_reuse_snapshot_path = dlsym(handle, "nyx_config_set_reuse_snapshot_path"); + plugin->nyx_config_set_reuse_snapshot_path = + dlsym(handle, "nyx_config_set_reuse_snapshot_path"); if (plugin->nyx_config_set_reuse_snapshot_path == NULL) { goto fail; } plugin->nyx_new = dlsym(handle, "nyx_new"); @@ -119,7 +129,6 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir"); if (plugin->nyx_remove_work_dir == NULL) { goto fail; } - OKF("libnyx plugin is ready!"); return plugin; @@ -131,33 +140,40 @@ fail: } -void afl_nyx_runner_kill(afl_forkserver_t *fsrv){ +void afl_nyx_runner_kill(afl_forkserver_t *fsrv) { + if (fsrv->nyx_mode) { - if (fsrv->nyx_aux_string){ - ck_free(fsrv->nyx_aux_string); - } + if (fsrv->nyx_aux_string) { ck_free(fsrv->nyx_aux_string); } /* check if we actually got a valid nyx runner */ if (fsrv->nyx_runner) { + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } /* if we have use a tmp work dir we need to remove it */ if (fsrv->nyx_use_tmp_workdir && fsrv->nyx_tmp_workdir_path) { + remove_nyx_tmp_workdir(fsrv, fsrv->nyx_tmp_workdir_path); + } + } + } -/* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp - * files) before exiting. Used before "afl_fsrv_killall()" is registered as - * an atexit() handler. */ -#define NYX_PRE_FATAL(fsrv, x...) \ - do { \ - afl_nyx_runner_kill(fsrv); \ - FATAL(x); \ - } while (0) + /* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp + * files) before exiting. Used before "afl_fsrv_killall()" is registered as + * an atexit() handler. */ + #define NYX_PRE_FATAL(fsrv, x...) \ + do { \ + \ + afl_nyx_runner_kill(fsrv); \ + FATAL(x); \ + \ + } while (0) #endif @@ -511,70 +527,116 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } - if (fsrv->nyx_use_tmp_workdir){ + if (fsrv->nyx_use_tmp_workdir) { + fsrv->nyx_tmp_workdir_path = create_nyx_tmp_workdir(); fsrv->out_dir_path = fsrv->nyx_tmp_workdir_path; + } else { - if (fsrv->out_dir_path == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); } + + if (fsrv->out_dir_path == NULL) { + + NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); + + } + } /* libnyx expects an absolute path */ - char* outdir_path_absolute = realpath(fsrv->out_dir_path, NULL); - if (outdir_path_absolute == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path cannot be resolved ..."); } + char *outdir_path_absolute = realpath(fsrv->out_dir_path, NULL); + if (outdir_path_absolute == NULL) { + + NYX_PRE_FATAL(fsrv, "Nyx workdir path cannot be resolved ..."); + + } char *workdir_path = alloc_printf("%s/workdir", outdir_path_absolute); - if (fsrv->nyx_id == 0xFFFFFFFF) {NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); } + if (fsrv->nyx_id == 0xFFFFFFFF) { + + NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); + + } if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) { + NYX_PRE_FATAL(fsrv, "Nyx CPU ID is not set..."); + } - void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); + void *nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, workdir_path); fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); - fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); + fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, + true); if (fsrv->nyx_standalone) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone); + } else { + if (fsrv->nyx_parent) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Parent); + } else { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Child); + } + } - if (getenv("NYX_REUSE_SNAPSHOT") != NULL){ + if (getenv("NYX_REUSE_SNAPSHOT") != NULL) { if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) { + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist"); + } - /* stupid sanity check to avoid passing an empty or invalid snapshot directory */ - char* snapshot_file_path = alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); + /* stupid sanity check to avoid passing an empty or invalid snapshot + * directory */ + char *snapshot_file_path = + alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); if (access(snapshot_file_path, R_OK) == -1) { - NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + + NYX_PRE_FATAL( + fsrv, + "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + } + ck_free(snapshot_file_path); /* another sanity check to avoid passing a snapshot directory that is - * located in the current workdir (the workdir will be wiped by libnyx on startup) */ - char* workdir_snapshot_path = alloc_printf("%s/workdir/snapshot", outdir_path_absolute); - char* reuse_snapshot_path_real = realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + * located in the current workdir (the workdir will be wiped by libnyx on + * startup) */ + char *workdir_snapshot_path = + alloc_printf("%s/workdir/snapshot", outdir_path_absolute); + char *reuse_snapshot_path_real = + realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + + if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0) { + + NYX_PRE_FATAL(fsrv, + "NYX_REUSE_SNAPSHOT path is located in current workdir " + "(use another output directory)"); - if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0){ - NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path is located in current workdir (use another output directory)"); } ck_free(reuse_snapshot_path_real); ck_free(workdir_snapshot_path); - fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(nyx_config, getenv("NYX_REUSE_SNAPSHOT")); + fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path( + nyx_config, getenv("NYX_REUSE_SNAPSHOT")); + } - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); + fsrv->nyx_runner = + fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); ck_free(workdir_path); ck_free(outdir_path_absolute); @@ -621,7 +683,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* autodict in Nyx mode */ if (!ignore_autodict) { - char* x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); + char *x = + alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); int nyx_autodict_fd = open(x, O_RDONLY); ck_free(x); @@ -634,8 +697,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u8 *dict = ck_alloc(f_len); if (dict == NULL) { - NYX_PRE_FATAL(fsrv, "Could not allocate %u bytes of autodictionary memory", - f_len); + NYX_PRE_FATAL( + fsrv, "Could not allocate %u bytes of autodictionary memory", + f_len); } @@ -652,7 +716,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else { - NYX_PRE_FATAL(fsrv, + NYX_PRE_FATAL( + fsrv, "Reading autodictionary fail at position %u with %u bytes " "left.", offset, len); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 832730fd..df030672 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -444,8 +444,11 @@ static void showmap_run_target_nyx_mode(afl_forkserver_t *fsrv) { FSRV_RUN_ERROR) { FATAL("Error running target in Nyx mode"); + } + } + #endif /* Execute target application. */ @@ -890,7 +893,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshX")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) { switch (opt) { @@ -1078,7 +1081,8 @@ int main(int argc, char **argv_orig, char **envp) { break; - #ifdef __linux__ + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -1088,11 +1092,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'b': @@ -1166,12 +1170,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + fsrv->target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv->target_path = ck_strdup(argv[optind]); + } + #else fsrv->target_path = find_binary(argv[optind]); #endif @@ -1232,11 +1240,12 @@ int main(int argc, char **argv_orig, char **envp) { get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv->nyx_mode) { use_argv = ck_alloc(sizeof(char *) * (1)); use_argv[0] = argv[0]; - + fsrv->nyx_id = 0; u8 *libnyx_binary = find_afl_binary(use_argv[0], "libnyx.so"); @@ -1288,9 +1297,12 @@ int main(int argc, char **argv_orig, char **envp) { } #ifdef __linux__ - if(!fsrv->nyx_mode && in_dir){ + if (!fsrv->nyx_mode && in_dir) { + (void)check_binary_signatures(fsrv->target_path); + } + #else if (in_dir) { (void)check_binary_signatures(fsrv->target_path); } #endif @@ -1313,14 +1325,14 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz_len = (u32 *)map; fsrv->shmem_fuzz = map + sizeof(u32); - configure_afl_kill_signals( - fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode - #ifdef __linux__ - || fsrv->nyx_mode - #endif - ) - ? SIGKILL - : SIGTERM); + configure_afl_kill_signals(fsrv, NULL, NULL, + (fsrv->qemu_mode || unicorn_mode +#ifdef __linux__ + || fsrv->nyx_mode +#endif + ) + ? SIGKILL + : SIGTERM); if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) { @@ -1464,13 +1476,18 @@ int main(int argc, char **argv_orig, char **envp) { shm_fuzz = deinit_shmem(fsrv, shm_fuzz); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + #endif showmap_run_target(fsrv, use_argv); #ifdef __linux__ + } else { + showmap_run_target_nyx_mode(fsrv); + } + #endif tcnt = write_results_to_file(fsrv, out_file); if (!quiet_mode) { @@ -1522,7 +1539,6 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } - afl_fsrv_deinit(fsrv); if (stdin_file) { ck_free(stdin_file); } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 98403049..e7442d1d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -846,7 +846,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) { switch (opt) { @@ -1004,7 +1004,8 @@ int main(int argc, char **argv_orig, char **envp) { break; - #ifdef __linux__ + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -1014,11 +1015,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'H': /* Hang Mode */ @@ -1086,12 +1087,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + fsrv->target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv->target_path = ck_strdup(argv[optind]); + } + #else fsrv->target_path = find_binary(argv[optind]); #endif @@ -1120,6 +1125,7 @@ int main(int argc, char **argv_orig, char **envp) { get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv->nyx_mode) { fsrv->nyx_id = 0; @@ -1127,7 +1133,9 @@ int main(int argc, char **argv_orig, char **envp) { u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); if (fsrv->nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } fsrv->nyx_use_tmp_workdir = true; @@ -1207,9 +1215,7 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); #ifdef __linux__ - if(!fsrv->nyx_mode){ - (void)check_binary_signatures(fsrv->target_path); - } + if (!fsrv->nyx_mode) { (void)check_binary_signatures(fsrv->target_path); } #else (void)check_binary_signatures(fsrv->target_path); #endif @@ -1316,7 +1322,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); - remove_shm = 0; afl_shm_deinit(&shm); if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index 34294809..4e8f466d 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -78,10 +78,10 @@ extern unsigned int __afl_map_size; on the other hand this is what Google needs to make LLVMFuzzerRunDriver() work. Choose your poison Google! */ /*__attribute__((weak))*/ int LLVMFuzzerTestOneInput(const uint8_t *Data, - size_t Size); -__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); -__attribute__((weak)) int LLVMFuzzerRunDriver( - int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size)); + size_t Size); +__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); +__attribute__((weak)) int LLVMFuzzerRunDriver( + int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size)); // Default nop ASan hooks for manual poisoning when not linking the ASan // runtime @@ -268,15 +268,16 @@ static int ExecuteFilesOnyByOne(int argc, char **argv, __attribute__((weak)) int main(int argc, char **argv) { -// Enable if LLVMFuzzerTestOneInput() has the weak attribute -/* - if (!LLVMFuzzerTestOneInput) { + // Enable if LLVMFuzzerTestOneInput() has the weak attribute + /* + if (!LLVMFuzzerTestOneInput) { - fprintf(stderr, "Error: function LLVMFuzzerTestOneInput() not found!\n"); - abort(); + fprintf(stderr, "Error: function LLVMFuzzerTestOneInput() not found!\n"); + abort(); - } -*/ + } + + */ if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) printf( -- cgit 1.4.1 From 7f734c96d187312868178e8ead95dc103c557c1f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 17 Apr 2023 10:25:10 +0200 Subject: v4.06c release --- README.md | 4 ++-- docs/Changelog.md | 5 +++-- include/config.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/README.md b/README.md index 821b8cb7..c012c400 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ logo -Release version: [4.05c](https://github.com/AFLplusplus/AFLplusplus/releases) +Release version: [4.06c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.06a +GitHub version: 4.07a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 3337feb9..587fb64c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,7 +3,7 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. -### Version ++4.06a (dev) +### Version ++4.06c (release) - afl-fuzz: - ensure temporary file descriptor is closed when not used - added `AFL_NO_WARN_INSTABILITY` @@ -29,9 +29,10 @@ - fix issue on MacOS - unicorn_mode: - updated and minor issues fixed + - nyx_mode support for all tools + - better sanitizer default options support for all tools - new custom module: autotoken, a grammar free fuzzer for text inputs - fixed custom mutator C examples - - better sanitizer default options support for all tools - more minor fixes and cross-platform support ### Version ++4.05c (release) diff --git a/include/config.h b/include/config.h index e46f515a..b6249a0f 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.06a" +#define VERSION "++4.06c" /****************************************************** * * -- cgit 1.4.1 From 02b9e583f2a5dd7d83bd4c02af8d2081532689ed Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 17 Apr 2023 14:41:05 +0200 Subject: v4.07a init --- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 587fb64c..30e76f2c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,10 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. +### Version ++4.07a (dev) + - soon :) + + ### Version ++4.06c (release) - afl-fuzz: - ensure temporary file descriptor is closed when not used diff --git a/include/config.h b/include/config.h index b6249a0f..764c29dc 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.06c" +#define VERSION "++4.07a" /****************************************************** * * -- cgit 1.4.1 From 9ab902402cd33156257fc0355c0105e7e03f5ba3 Mon Sep 17 00:00:00 2001 From: Maik Betka <9078425+voidptr127@users.noreply.github.com> Date: Mon, 17 Apr 2023 17:09:48 +0200 Subject: fixed code clones in atnwalk.c, introduced new environment variable AFL_POST_PROCESS_KEEP_ORIGINAL in AFL++ to integrate atnwalk without re-compiling afl-fuzz --- custom_mutators/atnwalk/atnwalk.c | 144 +++++++++++++------------------------- include/afl-fuzz.h | 4 +- include/envs.h | 1 + src/afl-fuzz-run.c | 11 +-- src/afl-fuzz-state.c | 7 ++ src/afl-fuzz.c | 2 + 6 files changed, 66 insertions(+), 103 deletions(-) (limited to 'include') diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c index 0194ff18..901b8a9e 100644 --- a/custom_mutators/atnwalk/atnwalk.c +++ b/custom_mutators/atnwalk/atnwalk.c @@ -1,4 +1,4 @@ -#include "../../include/afl-fuzz.h" +#include "afl-fuzz.h" #include #include @@ -9,7 +9,7 @@ #include #define BUF_SIZE_INIT 4096 -#define SOCKET_NAME "/tmp/atnwalk.socket" +#define SOCKET_NAME "./atnwalk.socket" // how many errors (e.g. timeouts) to tolerate until moving on to the next queue entry #define ATNWALK_ERRORS_MAX 1 @@ -155,6 +155,29 @@ unsigned int afl_custom_fuzz_count(atnwalk_mutator_t *data, const unsigned char return data->stage_havoc_max + data->stage_splice_max; } + +size_t fail_fatal(int fd_socket, uint8_t **out_buf) { + if (fd_socket != -1) { + close(fd_socket); + } + *out_buf = NULL; + return 0; +} + + +size_t fail_gracefully(int fd_socket, atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { + if (fd_socket != -1) { + close(fd_socket); + } + data->atnwalk_error_count++; + if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { + data->afl->stage_max = data->afl->stage_cur; + } + *out_buf = buf; + return buf_size; +} + + /** * Perform custom mutations on a given input * @@ -202,7 +225,7 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u } } - // keep track of found new corpus seeds per stage and run the stage twice as long as initially planned + // keep track of found new corpus seeds per stage if (data->afl->queued_items + data->afl->saved_crashes > data->prev_hits) { if (data->stage_splice_cur <= 1) { data->afl->stage_finds[STAGE_HAVOC] += data->afl->queued_items + data->afl->saved_crashes - data->prev_hits; @@ -216,38 +239,28 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u // check whether this input produces a lot of timeouts, if it does then abandon this queue entry if (data->afl->total_tmouts - data->prev_timeouts >= EXEC_TIMEOUT_MAX) { data->afl->stage_max = data->afl->stage_cur; - *out_buf = buf; - return buf_size; + return fail_gracefully(-1, data, buf, buf_size, out_buf); } // initialize the socket fd_socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd_socket == -1) { - *out_buf = NULL; - return 0; - } + if (fd_socket == -1) { return fail_fatal(fd_socket, out_buf); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); if (connect(fd_socket, (const struct sockaddr *) &addr, sizeof(addr)) == -1) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // ask whether the server is alive ctrl_buf[0] = SERVER_ARE_YOU_ALIVE; if (!write_all(fd_socket, ctrl_buf, 1)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // see whether the server replies as expected if (!read_all(fd_socket, ctrl_buf, 1) || ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // tell the server what we want to do @@ -262,88 +275,48 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u ctrl_buf[0] = wanted; put_uint32(ctrl_buf + 1, (uint32_t) buf_size); if (!write_all(fd_socket, ctrl_buf, 5)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // send the data to mutate and encode if (!write_all(fd_socket, buf, buf_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } if (wanted & SERVER_CROSSOVER_BIT) { // since we requested crossover, we will first tell how much additional data is to be expected put_uint32(ctrl_buf, (uint32_t) add_buf_size); if (!write_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // send the additional data for crossover if (!write_all(fd_socket, add_buf, add_buf_size)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // lastly, a seed is required for crossover so send one put_uint64(ctrl_buf, (uint64_t) rand()); if (!write_all(fd_socket, ctrl_buf, 8)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } } // since we requested mutation, we need to provide a seed for that put_uint64(ctrl_buf, (uint64_t) rand()); if (!write_all(fd_socket, ctrl_buf, 8)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // obtain the required buffer size for the data that will be returned if (!read_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } size_t new_size = (size_t) to_uint32(ctrl_buf); // if the data is too large then we ignore this round if (new_size > max_size) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } if (new_size > buf_size) { @@ -360,13 +333,7 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u // obtain the encoded data if (!read_all(fd_socket, *out_buf, new_size)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } close(fd_socket); @@ -398,54 +365,41 @@ size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf, size_t buf // initialize the socket fd_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (fd_socket == -1) { - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); if (connect(fd_socket, (const struct sockaddr *) &addr, sizeof(addr)) == -1) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // ask whether the server is alive ctrl_buf[0] = SERVER_ARE_YOU_ALIVE; if (!write_all(fd_socket, ctrl_buf, 1)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // see whether the server replies as expected if (!read_all(fd_socket, ctrl_buf, 1) || ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // tell the server what we want and how much data will be sent ctrl_buf[0] = SERVER_DECODE_BIT; put_uint32(ctrl_buf + 1, (uint32_t) buf_size); if (!write_all(fd_socket, ctrl_buf, 5)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // send the data to decode if (!write_all(fd_socket, buf, buf_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // obtain the required buffer size for the data that will be returned if (!read_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } size_t new_size = (size_t) to_uint32(ctrl_buf); @@ -458,9 +412,7 @@ size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf, size_t buf // obtain the decoded data if (!read_all(fd_socket, *out_buf, new_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } close(fd_socket); diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 23c20cc4..5d9b17e7 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -386,8 +386,8 @@ typedef struct afl_env_vars { afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, - afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_no_startup_calibration; + afl_keep_timeouts, afl_pizza_mode, afl_post_process_keep_original, + afl_no_crash_readme, afl_no_startup_calibration; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, diff --git a/include/envs.h b/include/envs.h index 2204a100..1527dfcb 100644 --- a/include/envs.h +++ b/include/envs.h @@ -177,6 +177,7 @@ static char *afl_environment_variables[] = { "AFL_PATH", "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD", + "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV", "AFL_PYTHON_MODULE", diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 26a1ea36..3c3d4817 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -130,15 +130,16 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { new_size = afl->max_length; } - // TODO: think about how to enable the change without breaking other implementations - // if (new_mem != *mem) { *mem = new_mem; } /* everything as planned. use the potentially new data. */ - // TODO: think about how to enable the change without breaking other implementations afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size); - // TODO: think about how to enable the change without breaking other implementations - // len = new_size; + if (likely(!afl->afl_env.afl_post_process_keep_original)) { + + if (new_mem != *mem) { *mem = new_mem; } + len = new_size; + + } } else { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 0576f84f..10bc2768 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -377,6 +377,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_POST_PROCESS_KEEP_ORIGINAL", + + afl_environment_variable_len)) { + + afl->afl_env.afl_post_process_keep_original = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TMPDIR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 1f0fcab1..b83af257 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -284,6 +284,8 @@ static void usage(u8 *argv0, int more_help) { PERSISTENT_MSG + "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to the queue,\n" + " but execute the post-processed one\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TARGET_ENV: pass extra environment variables to target\n" "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" -- cgit 1.4.1 From 4e5f42cab6b8c501eeaf76ec7ca920089f6e0f3a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 20 Apr 2023 10:39:23 +0200 Subject: afl-showmap custom mutator support --- GNUmakefile | 2 +- TODO.md | 4 +-- afl-cmin | 2 ++ afl-cmin.bash | 2 ++ docs/Changelog.md | 3 +- include/afl-fuzz.h | 8 +++-- src/afl-showmap.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 107 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/GNUmakefile b/GNUmakefile index 5bc3f9d5..0f890308 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -453,7 +453,7 @@ afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/ $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) diff --git a/TODO.md b/TODO.md index e7789cf6..dba75070 100644 --- a/TODO.md +++ b/TODO.md @@ -3,14 +3,14 @@ ## Should - splicing selection weighted? - - support afl_custom_{send,post_process}, persistent and deferred fork - server in afl-showmap + - support persistent and deferred fork server in afl-showmap? - better autodetection of shifting runtime timeout values - Update afl->pending_not_fuzzed for MOpt - afl-plot to support multiple plot_data - parallel builds for source-only targets - get rid of check_binary, replace with more forkserver communication - first fuzzer should be a main automatically? not sure. + - reload fuzz binary on signal ## Maybe diff --git a/afl-cmin b/afl-cmin index c5e64410..e2c26d91 100755 --- a/afl-cmin +++ b/afl-cmin @@ -133,6 +133,8 @@ function usage() { "AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ "printed to stdout\n" \ "AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary\n" +"AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send)\n" +"AFL_PYTHON_MODULE: custom mutator library (post_process and send)\n" exit 1 } diff --git a/afl-cmin.bash b/afl-cmin.bash index bcf62eba..5258758e 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -151,6 +151,8 @@ AFL_KEEP_TRACES: leave the temporary \.traces directory AFL_NO_FORKSRV: run target via execve instead of using the forkserver AFL_PATH: last resort location to find the afl-showmap binary AFL_SKIP_BIN_CHECK: skip check for target binary +AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send) +AFL_PYTHON_MODULE: custom mutator library (post_process and send) _EOF_ exit 1 fi diff --git a/docs/Changelog.md b/docs/Changelog.md index 30e76f2c..5ed5ef2b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,7 +4,8 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.07a (dev) - - soon :) + - afl-showmap: + - added custom mutator post_process and send support ### Version ++4.06c (release) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 8b6502b4..ec69ba17 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1103,7 +1103,6 @@ u32 count_bits(afl_state_t *, u8 *); u32 count_bytes(afl_state_t *, u8 *); u32 count_non_255_bytes(afl_state_t *, u8 *); void simplify_trace(afl_state_t *, u8 *); -void classify_counts(afl_forkserver_t *); #ifdef WORD_SIZE_64 void discover_word(u8 *ret, u64 *current, u64 *virgin); #else @@ -1117,6 +1116,9 @@ u8 *describe_op(afl_state_t *, u8, size_t); u8 save_if_interesting(afl_state_t *, void *, u32, u8); u8 has_new_bits(afl_state_t *, u8 *); u8 has_new_bits_unclassified(afl_state_t *, u8 *); +#ifndef AFL_SHOWMAP +void classify_counts(afl_forkserver_t *); +#endif /* Extras */ @@ -1192,11 +1194,13 @@ void fix_up_sync(afl_state_t *); void check_asan_opts(afl_state_t *); void check_binary(afl_state_t *, u8 *); void check_if_tty(afl_state_t *); -void setup_signal_handlers(void); void save_cmdline(afl_state_t *, u32, char **); void read_foreign_testcases(afl_state_t *, int); void write_crash_readme(afl_state_t *afl); u8 check_if_text_buf(u8 *buf, u32 len); +#ifndef AFL_SHOWMAP +void setup_signal_handlers(void); +#endif /* CmpLog */ diff --git a/src/afl-showmap.c b/src/afl-showmap.c index df030672..b5a61de5 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -30,8 +30,10 @@ */ #define AFL_MAIN +#define AFL_SHOWMAP #include "config.h" +#include "afl-fuzz.h" #include "types.h" #include "debug.h" #include "alloc-inl.h" @@ -62,6 +64,8 @@ #include #include +static afl_state_t *afl; + static char *stdin_file; /* stdin file */ static u8 *in_dir = NULL, /* input folder */ @@ -308,12 +312,73 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { } +void pre_afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *mem, u32 len) { + + static u8 buf[MAX_FILE]; + u32 sent = 0; + + if (unlikely(afl->custom_mutators_count)) { + + ssize_t new_size = len; + u8 *new_mem = mem; + u8 *new_buf = NULL; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_post_process) { + + new_size = + el->afl_custom_post_process(el->data, new_mem, new_size, &new_buf); + + if (unlikely(!new_buf || new_size <= 0)) { + + return; + + } else { + + new_mem = new_buf; + len = new_size; + + } + + } + + }); + + if (new_mem != mem && new_mem != NULL) { + + mem = buf; + memcpy(mem, new_mem, new_size); + + } + + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, mem, len); + sent = 1; + + } + + }); + + } + + } + + if (likely(!sent)) { afl_fsrv_write_to_testcase(fsrv, mem, len); } + +} + /* Execute target application. */ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, u32 len) { - afl_fsrv_write_to_testcase(fsrv, mem, len); + pre_afl_fsrv_write_to_testcase(fsrv, mem, len); if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); } @@ -835,6 +900,10 @@ static void usage(u8 *argv0) { "This tool displays raw tuple data captured by AFL instrumentation.\n" "For additional help, consult %s/README.md.\n\n" + "If you use -i mode, then custom mutator post_process send send " + "functionality\n" + "is supported.\n\n" + "Environment variables used:\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n" "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing " @@ -1266,6 +1335,8 @@ int main(int argc, char **argv_orig, char **envp) { } + afl = calloc(1, sizeof(afl_state_t)); + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); @@ -1380,6 +1451,26 @@ int main(int argc, char **argv_orig, char **envp) { } + if (in_dir) { + + afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + afl->afl_env.afl_custom_mutator_library = + getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); + afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE"); + setup_custom_mutators(afl); + + } else { + + if (getenv("AFL_CUSTOM_MUTATOR_LIBRARY") || getenv("AFL_PYTHON_MODULE")) { + + WARNF( + "Custom mutator environment detected, this is only supported in -i " + "mode!\n"); + + } + + } + if (in_dir) { DIR *dir_in, *dir_out = NULL; -- cgit 1.4.1 From 30495e6bfe4119c9be6597ad0def01e7e0cb8a67 Mon Sep 17 00:00:00 2001 From: eleguevel Date: Fri, 21 Apr 2023 12:00:56 +0200 Subject: frida mode: add dynamic loaded code exclusion Add the AFL_FRIDA_INST_NO_DYNAMIC_LOAD environment variable and its associated JS function setInstrumentNoDynamicLoad to prevent the instrumentation of late dynamic loaded code. Resolve #1708 --- docs/env_variables.md | 2 ++ frida_mode/README.md | 4 +++- frida_mode/Scripting.md | 6 ++++++ frida_mode/frida.map | 1 + frida_mode/include/ranges.h | 1 + frida_mode/src/js/api.js | 7 +++++++ frida_mode/src/js/js_api.c | 7 +++++++ frida_mode/src/ranges.c | 39 ++++++++++++++++++++++++++++++++++++--- frida_mode/ts/lib/afl.ts | 12 ++++++++++++ include/envs.h | 1 + 10 files changed, 76 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/docs/env_variables.md b/docs/env_variables.md index a6a0ae44..c5995d13 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -677,6 +677,8 @@ support. * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. +* `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` - Don't instrument the code loaded late at + runtime. Strictly limits instrumentation to what has been included. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. diff --git a/frida_mode/README.md b/frida_mode/README.md index aac13153..49a1fe38 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -178,11 +178,13 @@ Default is 256Mb. * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. +* `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` - Don't instrument the code loaded late at + runtime. Strictly limits instrumentation to what has been included. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use + `AFL_FRIDA_INST_TRACE`. * `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. * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md index 023e4a19..dfd09e7b 100644 --- a/frida_mode/Scripting.md +++ b/frida_mode/Scripting.md @@ -844,6 +844,12 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + static setInstrumentNoDynamicLoad() { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ diff --git a/frida_mode/frida.map b/frida_mode/frida.map index baf067ab..a98c2096 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -19,6 +19,7 @@ js_api_set_instrument_jit; js_api_set_instrument_libraries; js_api_set_instrument_instructions; + js_api_set_instrument_no_dynamic_load; js_api_set_instrument_no_optimize; js_api_set_instrument_regs_file; js_api_set_instrument_seed; diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h index 3bd9eaa6..ca28acd9 100644 --- a/frida_mode/include/ranges.h +++ b/frida_mode/include/ranges.h @@ -6,6 +6,7 @@ extern gboolean ranges_debug_maps; extern gboolean ranges_inst_libs; extern gboolean ranges_inst_jit; +extern gboolean ranges_inst_dynamic_load; void ranges_config(void); void ranges_init(void); diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index f9ea1ffb..a65d32df 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -150,6 +150,12 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + static setInstrumentNoDynamicLoad() { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -342,6 +348,7 @@ Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_de Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); +Afl.jsApiSetInstrumentNoDynamicLoad = Afl.jsApiGetFunction("js_api_set_instrument_no_dynamic_load", "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"]); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 2e996c1c..00278082 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -156,6 +156,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_instructions( } +__attribute__((visibility("default"))) void js_api_set_instrument_no_dynamic_load( + void) { + + ranges_inst_dynamic_load = FALSE; + +} + __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize( void) { diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 72cb9730..e9fc3b4e 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -18,6 +18,7 @@ typedef struct { gboolean ranges_debug_maps = FALSE; gboolean ranges_inst_libs = FALSE; gboolean ranges_inst_jit = FALSE; +gboolean ranges_inst_dynamic_load = TRUE; static GArray *module_ranges = NULL; static GArray *libs_ranges = NULL; @@ -25,6 +26,7 @@ static GArray *jit_ranges = NULL; static GArray *include_ranges = NULL; static GArray *exclude_ranges = NULL; static GArray *ranges = NULL; +static GArray *whole_memory_ranges = NULL; static void convert_address_token(gchar *token, GumMemoryRange *range) { @@ -387,6 +389,21 @@ static GArray *collect_jit_ranges(void) { } +static GArray *collect_whole_mem_ranges(void) { + + GArray *result; + GumMemoryRange range; + result = g_array_new(false, false, sizeof(GumMemoryRange)); + + range.base_address = 0; + range.size = G_MAXULONG; + + g_array_append_val(result, range); + + return result; + +} + static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra, GumMemoryRange *rb) { @@ -574,11 +591,17 @@ void ranges_config(void) { if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; } if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; } if (getenv("AFL_FRIDA_INST_JIT") != NULL) { ranges_inst_jit = TRUE; } + if (getenv("AFL_FRIDA_INST_NO_DYNAMIC_LOAD") != NULL) { + + ranges_inst_dynamic_load = FALSE; + + } if (ranges_debug_maps) { ranges_print_debug_maps(); } include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); + whole_memory_ranges = collect_whole_mem_ranges(); } @@ -628,10 +651,20 @@ void ranges_init(void) { print_ranges("step4", step4); /* - * After step4, we have the total ranges to be instrumented, we now subtract - * that from the original ranges of the modules to configure stalker. + * After step 4 we have the total ranges to be instrumented, we now subtract + * that either from the original ranges of the modules or from the whole + * memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker. */ - step5 = subtract_ranges(module_ranges, step4); + if (ranges_inst_dynamic_load) { + + step5 = subtract_ranges(module_ranges, step4); + + } else { + + step5 = subtract_ranges(whole_memory_ranges, step4); + + } + print_ranges("step5", step5); ranges = merge_ranges(step5); diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 6a2350e7..7d1fac6b 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -178,6 +178,13 @@ class Afl { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + public static setInstrumentNoDynamicLoad(): void { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } + /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -443,6 +450,11 @@ class Afl { "void", []); + private static readonly jsApiSetInstrumentNoDynamicLoad = Afl.jsApiGetFunction( + "js_api_set_instrument_no_dynamic_load", + "void", + []); + private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction( "js_api_set_instrument_no_optimize", "void", diff --git a/include/envs.h b/include/envs.h index 066921b9..41eabf60 100644 --- a/include/envs.h +++ b/include/envs.h @@ -65,6 +65,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE", + "AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", -- cgit 1.4.1 From 7b33148b7553f11dac7a382495a6829fa14f23fe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 08:23:27 +0200 Subject: add AFL_LLVM_LTO_SKIPINIT to envs.h --- include/envs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 23599b26..5e68c80b 100644 --- a/include/envs.h +++ b/include/envs.h @@ -160,8 +160,9 @@ static char *afl_environment_variables[] = { "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", "AFL_TRY_AFFINITY", - "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", + "AFL_LLVM_LTO_SKIPINIT" + "AFL_LLVM_LTO_STARTID", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN", -- cgit 1.4.1 From 21865c622483d2e2285de3dfad4626c28ca27843 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 16:47:37 +0200 Subject: rename env to AFL_IGNORE_PROBLEMS_COVERAGE --- docs/FAQ.md | 3 ++- docs/env_variables.md | 3 ++- include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 4 ++-- src/afl-fuzz.c | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/docs/FAQ.md b/docs/FAQ.md index 4a9080f8..76350c79 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -229,7 +229,8 @@ If you find an interesting or important question missing, submit it via If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then the existing map will be used also for the newly loaded libraries, which allows it to work, however, the efficiency of the fuzzing will be partially - degraded. + degraded. Note that there is additionally `AFL_IGNORE_PROBLEMS_COVERAGE` to + additionally tell AFL++ to ignore any coverage from the late loaded libaries.

diff --git a/docs/env_variables.md b/docs/env_variables.md index 087ccdb7..b1f23159 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -406,7 +406,8 @@ checks or alter some of the more exotic semantics of the tool: - If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session (not at startup), it will terminate. If you do not want this, then you can - set `AFL_IGNORE_PROBLEMS`. + set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage + from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`. - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the fuzzer to import test cases from other instances before doing anything else. diff --git a/include/envs.h b/include/envs.h index 5e68c80b..fe5ee0e3 100644 --- a/include/envs.h +++ b/include/envs.h @@ -106,6 +106,7 @@ static char *afl_environment_variables[] = { "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS", + "AFL_IGNORE_PROBLEMS_COVERAGE", "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 74506e4c..0912e52b 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1565,13 +1565,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { "be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n" "To ignore this set AFL_IGNORE_PROBLEMS=1 but this will lead to " "ambiguous coverage data.\n" - "In addition, you can set AFL_LLVM_IGNORE_PROBLEMS_COVERAGE=1 to " + "In addition, you can set AFL_IGNORE_PROBLEMS_COVERAGE=1 to " "ignore the additional coverage instead (use with caution!).\n"); abort(); } else { - u8 ignore_dso_after_fs = !!getenv("AFL_LLVM_IGNORE_PROBLEMS_COVERAGE"); + u8 ignore_dso_after_fs = !!getenv("AFL_IGNORE_PROBLEMS_COVERAGE"); if (__afl_debug && ignore_dso_after_fs) { fprintf(stderr, "Ignoring coverage from dynamically loaded code\n"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ebdbb3fa..c44144f5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -259,6 +259,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n" + "AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n + " ignore those libs for coverage\n" "AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n" "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" -- cgit 1.4.1 From 3e84d6a2ae7df5f6b9073a91ccc6acef50b45aab Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 27 Apr 2023 11:49:00 +0200 Subject: afl++ -> AFL++ --- Dockerfile | 4 ++-- GNUmakefile | 12 ++++++------ GNUmakefile.gcc_plugin | 6 +++--- GNUmakefile.llvm | 6 +++--- afl-cmin | 2 +- docs/Changelog.md | 2 +- docs/INSTALL.md | 2 +- include/alloc-inl.h | 2 +- instrumentation/SanitizerCoverageLTO.so.cc | 30 +++++++++++++++--------------- instrumentation/afl-llvm-common.cc | 2 +- instrumentation/afl-llvm-dict2file.so.cc | 2 +- qemu_mode/build_qemu_support.sh | 4 ++-- src/afl-cc.c | 2 +- src/afl-forkserver.c | 6 +++--- src/afl-fuzz.c | 10 +++++----- src/afl-ld-lto.c | 4 ++-- test/test-dlopen.c | 2 +- test/test-gcc-plugin.sh | 2 +- test/test-performance.sh | 4 ++-- test/test-pre.sh | 2 +- unicorn_mode/build_unicorn_support.sh | 2 +- 21 files changed, 54 insertions(+), 54 deletions(-) (limited to 'include') diff --git a/Dockerfile b/Dockerfile index 4e53de40..1b5ffd28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ # FROM ubuntu:22.04 AS aflplusplus -LABEL "maintainer"="afl++ team " +LABEL "maintainer"="AFL++ team " LABEL "about"="AFLplusplus container image" ### Comment out to enable these features @@ -94,4 +94,4 @@ RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \ RUN echo "set encoding=utf-8" > /root/.vimrc && \ echo ". /etc/bash_completion" >> ~/.bashrc && \ echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \ - echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc + echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc diff --git a/GNUmakefile b/GNUmakefile index 23cae65d..5900ad61 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -39,7 +39,7 @@ ASAN_OPTIONS=detect_leaks=0 SYS = $(shell uname -s) ARCH = $(shell uname -m) -$(info [*] Compiling afl++ for OS $(SYS) on ARCH $(ARCH)) +$(info [*] Compiling AFL++ for OS $(SYS) on ARCH $(ARCH)) ifdef NO_SPLICING override CFLAGS_OPT += -DNO_SPLICING @@ -359,7 +359,7 @@ performance-test: source-only help: @echo "HELP --- the following make targets exist:" @echo "==========================================" - @echo "all: the main afl++ binaries and llvm/gcc instrumentation" + @echo "all: the main AFL++ binaries and llvm/gcc instrumentation" @echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap" @echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap" @echo "distrib: everything (for both binary-only and source code fuzzing)" @@ -367,7 +367,7 @@ help: @echo "install: installs everything you have compiled with the build option above" @echo "clean: cleans everything compiled (not downloads when on a checkout)" @echo "deepclean: cleans everything including downloads" - @echo "uninstall: uninstall afl++ from the system" + @echo "uninstall: uninstall AFL++ from the system" @echo "code-format: format the code, do this before you commit and send a PR please!" @echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem" @echo "unit: perform unit tests (based on cmocka and GNU linker)" @@ -749,7 +749,7 @@ endif @echo %.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@ + @echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@ @echo .SH NAME >> $@ @echo .B $* >> $@ @echo >> $@ @@ -761,8 +761,8 @@ endif @./$* -hh 2>&1 | tail -n +4 >> $@ @echo >> $@ @echo .SH AUTHOR >> $@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> $@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@ @echo >> $@ @echo .SH LICENSE >> $@ @echo Apache License Version 2.0, January 2004 >> $@ diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index 4c4e10c4..41face4c 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -175,7 +175,7 @@ all_done: test_build .NOTPARALLEL: clean %.8: % - @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ./$@ + @echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@ @echo .SH NAME >> ./$@ @echo .B $* >> ./$@ @echo >> ./$@ @@ -187,8 +187,8 @@ all_done: test_build @./$* -h 2>&1 | tail -n +4 >> ./$@ @echo >> ./$@ @echo .SH AUTHOR >> ./$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ @echo >> ./$@ @echo .SH LICENSE >> ./$@ @echo Apache License Version 2.0, January 2004 >> ./$@ diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm index a053403b..c1b006ba 100644 --- a/GNUmakefile.llvm +++ b/GNUmakefile.llvm @@ -510,7 +510,7 @@ install: all install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/ %.8: % - @echo .TH $* 8 $(BUILD_DATE) "afl++" > ./$@ + @echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@ @echo .SH NAME >> ./$@ @printf "%s" ".B $* \- " >> ./$@ @./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@ @@ -524,8 +524,8 @@ install: all @./$* -h 2>&1 | tail -n +4 >> ./$@ @echo >> ./$@ @echo .SH AUTHOR >> ./$@ - @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@ - @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ + @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@ + @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@ @echo >> ./$@ @echo .SH LICENSE >> ./$@ @echo Apache License Version 2.0, January 2004 >> ./$@ diff --git a/afl-cmin b/afl-cmin index 63cfdd7e..ae723c1b 100755 --- a/afl-cmin +++ b/afl-cmin @@ -149,7 +149,7 @@ BEGIN { redirected = 0 } - print "corpus minimization tool for afl++ (awk version)\n" + print "corpus minimization tool for AFL++ (awk version)\n" # defaults extra_par = "" diff --git a/docs/Changelog.md b/docs/Changelog.md index 20b915fa..cd5ed9fc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -229,7 +229,7 @@ afl-showmap and other tools. - afl-cc: - detect overflow reads on initial input buffer for asan - - new cmplog mode (incompatible with older afl++ versions) + - new cmplog mode (incompatible with older AFL++ versions) - support llvm IR select instrumentation for default PCGUARD and LTO - fix for shared linking on MacOS - better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 591b7ded..c54cb9ad 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -51,7 +51,7 @@ make source-only These build targets exist: -* all: the main afl++ binaries and llvm/gcc instrumentation +* all: the main AFL++ binaries and llvm/gcc instrumentation * binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap diff --git a/include/alloc-inl.h b/include/alloc-inl.h index ae37028e..bbb42e88 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -42,7 +42,7 @@ // Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators #ifndef _WANT_ORIGINAL_AFL_ALLOC - // afl++ stuff without memory corruption checks - for speed + // AFL++ stuff without memory corruption checks - for speed /* User-facing macro to sprintf() to a dynamically allocated buffer. */ diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 42583f9e..6a719737 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1,4 +1,4 @@ -/* SanitizeCoverage.cpp ported to afl++ LTO :-) */ +/* SanitizeCoverage.cpp ported to AFL++ LTO :-) */ #define AFL_LLVM_PASS @@ -234,7 +234,7 @@ class ModuleSanitizerCoverageLTO SanitizerCoverageOptions Options; - // afl++ START + // AFL++ START // const SpecialCaseList * Allowlist; // const SpecialCaseList * Blocklist; uint32_t autodictionary = 1; @@ -260,7 +260,7 @@ class ModuleSanitizerCoverageLTO Value *MapPtrFixed = NULL; std::ofstream dFile; size_t found = 0; - // afl++ END + // AFL++ END }; @@ -404,7 +404,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( Int8Ty = IRB.getInt8Ty(); Int1Ty = IRB.getInt1Ty(); - /* afl++ START */ + /* AFL++ START */ char *ptr; LLVMContext &Ctx = M.getContext(); Ct = &Ctx; @@ -978,7 +978,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( } - // afl++ END + // AFL++ END SanCovTracePCIndir = M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy); @@ -1002,7 +1002,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( for (auto &F : M) instrumentFunction(F, DTCallback, PDTCallback); - // afl++ START + // AFL++ START if (dFile.is_open()) dFile.close(); if (!getenv("AFL_LLVM_LTO_SKIPINIT") && @@ -1156,7 +1156,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( } - // afl++ END + // AFL++ END // We don't reference these arrays directly in any of our runtime functions, // so we need to prevent them from being dead stripped. @@ -1213,10 +1213,10 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB, // (catchswitch blocks). if (BB->getFirstInsertionPt() == BB->end()) return false; - // afl++ START + // AFL++ START if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1) return false; - // afl++ END + // AFL++ END if (Options.NoPrune || &F.getEntryBlock() == BB) return true; @@ -1258,10 +1258,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction( // if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName())) // return; - // afl++ START + // AFL++ START if (!F.size()) return; if (!isInInstrumentList(&F, FMNAME)) return; - // afl++ END + // AFL++ END if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge) SplitAllCriticalEdges( @@ -1559,7 +1559,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage( for (size_t i = 0, N = AllBlocks.size(); i < N; i++) { - // afl++ START + // AFL++ START if (BlockList.size()) { int skip = 0; @@ -1581,7 +1581,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage( } - // afl++ END + // AFL++ END InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc); @@ -1647,7 +1647,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F, if (Options.TracePCGuard) { - // afl++ START + // AFL++ START ++afl_global_id; if (dFile.is_open()) { @@ -1711,7 +1711,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F, // done :) inst++; - // afl++ END + // AFL++ END /* XXXXXXXXXXXXXXXXXXX diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc index 5d82aa25..7f17b02d 100644 --- a/instrumentation/afl-llvm-common.cc +++ b/instrumentation/afl-llvm-common.cc @@ -584,7 +584,7 @@ bool isInInstrumentList(llvm::Function *F, std::string Filename) { } // Calculate the number of average collisions that would occur if all -// location IDs would be assigned randomly (like normal afl/afl++). +// location IDs would be assigned randomly (like normal afl/AFL++). // This uses the "balls in bins" algorithm. unsigned long long int calculateCollisions(uint32_t edges) { diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index 97f1d47f..cf368e35 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -744,7 +744,7 @@ static void registerAFLdict2filePass(const PassManagerBuilder &, } static RegisterPass X("afl-dict2file", - "afl++ dict2file instrumentation pass", + "AFL++ dict2file instrumentation pass", false, false); static RegisterStandardPasses RegisterAFLdict2filePass( diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index a064fe58..f59cba78 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -356,7 +356,7 @@ fi if ! command -v "$CROSS" > /dev/null ; then if [ "$CPU_TARGET" = "$(uname -m)" ] ; then - echo "[+] Building afl++ qemu support libraries with CC=$CC" + echo "[+] Building AFL++ qemu support libraries with CC=$CC" echo "[+] Building libcompcov ..." make -C libcompcov && echo "[+] libcompcov ready" echo "[+] Building unsigaction ..." @@ -371,7 +371,7 @@ if ! command -v "$CROSS" > /dev/null ; then echo "[!] Cross compiler $CROSS could not be found, cannot compile libcompcov libqasan and unsigaction" fi else - echo "[+] Building afl++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\"" + echo "[+] Building AFL++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\"" echo "[+] Building libcompcov ..." make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready" echo "[+] Building unsigaction ..." diff --git a/src/afl-cc.c b/src/afl-cc.c index d1001187..99ce39d4 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -642,7 +642,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { } //#if LLVM_MAJOR >= 13 - // // Use the old pass manager in LLVM 14 which the afl++ passes still + // // Use the old pass manager in LLVM 14 which the AFL++ passes still // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; //#endif diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index aa8c8622..30c8901c 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -489,7 +489,7 @@ static void report_error_and_exit(int error) { break; case FS_ERROR_OLD_CMPLOG: FATAL( - "the -c cmplog target was instrumented with an too old afl++ " + "the -c cmplog target was instrumented with an too old AFL++ " "version, you need to recompile it."); break; case FS_ERROR_OLD_CMPLOG_QEMU: @@ -987,7 +987,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { - // workaround for recent afl++ versions + // workaround for recent AFL++ versions if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND) status = (status & 0xf0ffffff); @@ -1059,7 +1059,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, FATAL( "Target's coverage map size of %u is larger than the one this " - "afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart " + "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart " " afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile " "afl-fuzz", tmp_map_size, fsrv->map_size, tmp_map_size); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 71d2afd8..646dc50b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1280,16 +1280,16 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260; - OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" " - "Eißfeldt, Andrea Fioraldi and Dominik Maier"); - OKF("afl++ is open source, get it at " + OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea " + "Fioraldi and Heiko \"hexcoder\" Eißfeldt"); + OKF("AFL++ is open source, get it at " "https://github.com/AFLplusplus/AFLplusplus"); - OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md"); + OKF("NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md"); #ifdef __linux__ if (afl->fsrv.nyx_mode) { - OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)"); + OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)"); OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz"); } diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 5438bd9f..420dd817 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -2,7 +2,7 @@ american fuzzy lop++ - wrapper for llvm 11+ lld ----------------------------------------------- - Written by Marc Heuse for afl++ + Written by Marc Heuse for AFL++ Maintained by Marc Heuse , Heiko Eißfeldt @@ -210,7 +210,7 @@ static void edit_params(int argc, char **argv) { if (strcmp(argv[i], "--afl") == 0) { - if (!be_quiet) OKF("afl++ test command line flag detected, exiting."); + if (!be_quiet) OKF("AFL++ test command line flag detected, exiting."); exit(0); } diff --git a/test/test-dlopen.c b/test/test-dlopen.c index b81bab13..39442f93 100644 --- a/test/test-dlopen.c +++ b/test/test-dlopen.c @@ -28,7 +28,7 @@ int main(int argc, char **argv) { } - // must use deferred forkserver as otherwise afl++ instrumentation aborts + // must use deferred forkserver as otherwise AFL++ instrumentation aborts // because all dlopen() of instrumented libs must be before the forkserver __AFL_INIT(); diff --git a/test/test-gcc-plugin.sh b/test/test-gcc-plugin.sh index 54e6987f..3690a80a 100755 --- a/test/test-gcc-plugin.sh +++ b/test/test-gcc-plugin.sh @@ -23,7 +23,7 @@ test -e ../afl-gcc-fast -a -e ../afl-compiler-rt.o && { $ECHO "$GREEN[+] gcc_plugin run reported $TUPLES instrumented locations which is fine" } || { $ECHO "$RED[!] gcc_plugin instrumentation produces a weird numbers: $TUPLES" - $ECHO "$YELLOW[-] this is a known issue in gcc, not afl++. It is not flagged as an error because travis builds would all fail otherwise :-(" + $ECHO "$YELLOW[-] this is a known issue in gcc, not AFL++. It is not flagged as an error because travis builds would all fail otherwise :-(" #CODE=1 } test "$TUPLES" -lt 2 && SKIP=1 diff --git a/test/test-performance.sh b/test/test-performance.sh index d61e2f2a..50957141 100755 --- a/test/test-performance.sh +++ b/test/test-performance.sh @@ -7,7 +7,7 @@ FILE=$AFL_PERFORMANCE_FILE test -z "$FILE" && FILE=.afl_performance test -e $FILE || { - echo Warning: This script measure the performance of afl++ and saves the result for future comparisons into $FILE + echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE echo Press ENTER to continue or CONTROL-C to abort read IN } @@ -74,7 +74,7 @@ afl-system-config > /dev/null 2>&1 echo Performance settings applied. echo -$ECHO "${RESET}${GREY}[*] starting afl++ performance test framework ..." +$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..." $ECHO "$BLUE[*] Testing: ${AFL_GCC}" GCC=x diff --git a/test/test-pre.sh b/test/test-pre.sh index b8b286e5..1ca9dfb5 100755 --- a/test/test-pre.sh +++ b/test/test-pre.sh @@ -133,7 +133,7 @@ MEM_LIMIT=none export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin" -$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..." +$ECHO "${RESET}${GREY}[*] starting AFL++ test framework ..." test -z "$SYS" && $ECHO "$YELLOW[-] uname -m did not succeed" diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index 53ec2481..d3d16ad5 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -182,7 +182,7 @@ git pull sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null git checkout "$UNICORNAFL_VERSION" || exit 1 -echo "[*] making sure afl++ header files match" +echo "[*] making sure AFL++ header files match" cp "../../include/config.h" "./include" || exit 1 echo "[*] Configuring Unicorn build..." -- cgit 1.4.1 From a2daef29f9c323c0a6a7a64013aadb79ffd3e534 Mon Sep 17 00:00:00 2001 From: van Hauser Date: Thu, 27 Apr 2023 17:57:22 +0200 Subject: slightly different weighting algo (#1719) * better seed selection * slightly different weighting calculation * remove unnecessary memset --- include/afl-fuzz.h | 4 +-- src/afl-fuzz-queue.c | 92 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 65 insertions(+), 31 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 831a0dbc..8fb7ecb1 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1223,7 +1223,7 @@ double rand_next_percent(afl_state_t *afl); static inline u32 rand_below(afl_state_t *afl, u32 limit) { - if (limit <= 1) return 0; + if (unlikely(limit <= 1)) return 0; /* The boundary not being necessarily a power of 2, we need to ensure the result uniformity. */ @@ -1256,7 +1256,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) { expand havoc mode */ static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) { - if (limit <= 1) return 0; + if (unlikely(limit <= 1)) return 0; switch (rand_below(afl, 3)) { diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 8ad7cd97..b10bf749 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -49,11 +49,13 @@ inline u32 select_next_queue_entry(afl_state_t *afl) { u32 s = rand_below(afl, afl->queued_items); double p = rand_next_percent(afl); + /* fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u" " ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p < afl->alias_probability[s] ? s : afl->alias_table[s]); */ + return (p < afl->alias_probability[s] ? s : afl->alias_table[s]); } @@ -87,25 +89,28 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, void create_alias_table(afl_state_t *afl) { - u32 n = afl->queued_items, i = 0, a, g; + u32 n = afl->queued_items, i = 0, nSmall = 0, nLarge = n - 1; double sum = 0; + double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double)); + u32 *Small = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); + u32 *Large = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); + afl->alias_table = (u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32)); afl->alias_probability = (double *)afl_realloc( (void **)&afl->alias_probability, n * sizeof(double)); - double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double)); - int *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); - int *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); - if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) { + if (!P || !Small || !Large || !afl->alias_table || !afl->alias_probability) { FATAL("could not acquire memory for alias table"); } - memset((void *)afl->alias_table, 0, n * sizeof(u32)); memset((void *)afl->alias_probability, 0, n * sizeof(double)); + memset((void *)afl->alias_table, 0, n * sizeof(u32)); + memset((void *)Small, 0, n * sizeof(u32)); + memset((void *)Large, 0, n * sizeof(u32)); if (likely(afl->schedule < RARE)) { @@ -166,7 +171,15 @@ void create_alias_table(afl_state_t *afl) { for (i = 0; i < n; i++) { // weight is always 0 for disabled entries - P[i] = (afl->queue_buf[i]->weight * n) / sum; + if (unlikely(afl->queue_buf[i]->disabled)) { + + P[i] = 0; + + } else { + + P[i] = (afl->queue_buf[i]->weight * n) / sum; + + } } @@ -176,60 +189,81 @@ void create_alias_table(afl_state_t *afl) { struct queue_entry *q = afl->queue_buf[i]; - if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); } + if (likely(!q->disabled)) { + + q->perf_score = calculate_score(afl, q); + sum += q->perf_score; - sum += q->perf_score; + } } for (i = 0; i < n; i++) { // perf_score is always 0 for disabled entries - P[i] = (afl->queue_buf[i]->perf_score * n) / sum; + if (unlikely(afl->queue_buf[i]->disabled)) { + + P[i] = 0; + + } else { + + P[i] = (afl->queue_buf[i]->perf_score * n) / sum; + + } } } - int nS = 0, nL = 0, s; - for (s = (s32)n - 1; s >= 0; --s) { + // Done collecting weightings in P, now create the arrays. + + for (s32 j = (s32)(n - 1); j >= 0; j--) { - if (P[s] < 1) { + if (P[j] < 1) { - S[nS++] = s; + Small[nSmall++] = (u32)j; } else { - L[nL++] = s; + Large[nLarge--] = (u32)j; } } - while (nS && nL) { + while (nSmall && nLarge != n - 1) { + + u32 small = Small[--nSmall]; + u32 large = Large[++nLarge]; + + afl->alias_probability[small] = P[small]; + afl->alias_table[small] = large; - a = S[--nS]; - g = L[--nL]; - afl->alias_probability[a] = P[a]; - afl->alias_table[a] = g; - P[g] = P[g] + P[a] - 1; - if (P[g] < 1) { + P[large] = P[large] - (1 - P[small]); - S[nS++] = g; + if (P[large] < 1) { + + Small[nSmall++] = large; } else { - L[nL++] = g; + Large[nLarge--] = large; } } - while (nL) - afl->alias_probability[L[--nL]] = 1; + while (nSmall) { + + afl->alias_probability[Small[--nSmall]] = 1; + + } - while (nS) - afl->alias_probability[S[--nS]] = 1; + while (nLarge != n - 1) { + + afl->alias_probability[Large[++nLarge]] = 1; + + } afl->reinit_table = 0; @@ -264,7 +298,7 @@ void create_alias_table(afl_state_t *afl) { */ /* fprintf(stderr, " entry alias probability perf_score weight - filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u + filename\n"); for (i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u %0.9f %0.9f %s\n", i, afl->alias_table[i], afl->alias_probability[i], afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight, afl->queue_buf[i]->fname); -- cgit 1.4.1 From 22db79aefafb48fed48199a86a39babdee795870 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 May 2023 15:07:49 +0200 Subject: fix reallocs --- include/alloc-inl.h | 7 +++---- src/afl-fuzz.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/alloc-inl.h b/include/alloc-inl.h index bbb42e88..1e9a192b 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -704,12 +704,11 @@ static inline void *afl_realloc(void **buf, size_t size_needed) { *buf = NULL; return NULL; - } else { - - new_buf = newer_buf; - } + new_buf = newer_buf; + memset(((u8 *)new_buf) + current_size, 0, next_size - current_size); + new_buf->complete_size = next_size; *buf = (void *)(new_buf->buf); return *buf; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 646dc50b..c02479cf 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1979,6 +1979,7 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->non_instrumented_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) { + u32 old_map_size = map_size; map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE; afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size); afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size); @@ -1990,6 +1991,18 @@ int main(int argc, char **argv_orig, char **envp) { afl->first_trace = ck_realloc(afl->first_trace, map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size); + if (old_map_size < map_size) { + + memset(afl->var_bytes + old_map_size, 0, map_size - old_map_size); + memset(afl->top_rated + old_map_size, 0, map_size - old_map_size); + memset(afl->clean_trace + old_map_size, 0, map_size - old_map_size); + memset(afl->clean_trace_custom + old_map_size, 0, + map_size - old_map_size); + memset(afl->first_trace + old_map_size, 0, map_size - old_map_size); + memset(afl->map_tmp_buf + old_map_size, 0, map_size - old_map_size); + + } + } afl->argv = use_argv; @@ -2017,6 +2030,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Re-initializing maps to %u bytes", new_map_size); + u32 old_map_size = map_size; afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); @@ -2029,6 +2043,18 @@ int main(int argc, char **argv_orig, char **envp) { afl->first_trace = ck_realloc(afl->first_trace, new_map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + if (old_map_size < new_map_size) { + + memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size); + memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size); + memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size); + memset(afl->clean_trace_custom + old_map_size, 0, + new_map_size - old_map_size); + memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size); + memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size); + + } + afl_fsrv_kill(&afl->fsrv); afl_shm_deinit(&afl->shm); afl->fsrv.map_size = new_map_size; @@ -2079,6 +2105,7 @@ int main(int argc, char **argv_orig, char **envp) { OKF("Re-initializing maps to %u bytes due cmplog", new_map_size); + u32 old_map_size = map_size; afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size); afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size); afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size); @@ -2091,6 +2118,18 @@ int main(int argc, char **argv_orig, char **envp) { afl->first_trace = ck_realloc(afl->first_trace, new_map_size); afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size); + if (old_map_size < new_map_size) { + + memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size); + memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size); + memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size); + memset(afl->clean_trace_custom + old_map_size, 0, + new_map_size - old_map_size); + memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size); + memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size); + + } + afl_fsrv_kill(&afl->fsrv); afl_fsrv_kill(&afl->cmplog_fsrv); afl_shm_deinit(&afl->shm); -- cgit 1.4.1 From 70da0c2e405102dc044cb4bed0f4f1e847c90d0b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 May 2023 16:09:18 +0200 Subject: better tritondse support --- custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 54 ++++++++++--- docs/custom_mutators.md | 28 +++++++ include/envs.h | 4 + src/afl-fuzz.c | 91 ++++++++++++++++------ 4 files changed, 145 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py index 49f67d75..9584b368 100644 --- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py +++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py @@ -7,6 +7,7 @@ from tritondse import Config from tritondse import CoverageStrategy from tritondse import ProcessState from tritondse import Program +from tritondse import CleLoader from tritondse import Seed from tritondse import SeedFormat from tritondse import SymbolicExecutor @@ -16,7 +17,7 @@ from tritondse import SymbolicExplorator #logging.basicConfig(level=logging.INFO) is_debug = False -out_path = "out/tritondse/queue" +out_path = "" input_file = None prog = None config = None @@ -29,28 +30,38 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState): #logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \ # ({repr(se.seed.content)})") global count - global hasshes + global hashes + print('DEBUG - prehook') if se.seed.hash not in hashes: hashes.add(se.seed.hash) filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash if not os.path.exists(filename): + if is_debug: + print('Creating queue input ' + filename) with open(filename, 'wb') as file: file.write(se.seed.content) count += 1 + else: + print('has hash: ' + se.seed.hash) if input_file: + if is_debug: + print('Writing to ' + input_file + ' the content: ' + str(se.seed.content)) with open(input_file, 'wb') as file: file.write(se.seed.content) + else: + print('no input!') def init(seed): global prog global config global dse + global out_path global input_file global is_debug # Load the program (LIEF-based program loader). - prog = Program(os.environ['TRITON_DSE_TARGET']) - # Set the configuration. + prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM']) + # Process other configuration environment variables. argv = None try: foo = os.environ['AFL_DEBUG'] @@ -58,15 +69,42 @@ def init(seed): except KeyError: pass try: - argv_list = os.environ['TRITON_DSE_TARGET_ARGV'] - argv = argv_list.split() + foo = os.environ['AFL_CUSTOM_INFO_OUT'] + out_path = foo + '/../tritondse/queue' except KeyError: pass try: - foo = os.environ['TRITON_DSE_TARGET_INPUT'] + foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT'] input_file = foo except KeyError: pass + try: + argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV'] + argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ] + argv_tmp += argv_list.split() + argv = [] + # now check for @@ + for item in argv_tmp: + if "@@" in item: + input_file = out_path + '/../.input' + argv.append(input_file) + else: + argv.append(item) + except KeyError: + pass + # Create the output directory + os.makedirs(out_path, exist_ok=True) + # Debug + if is_debug: + print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM']) + if argv: + print('DEBUG argv: ') + print(argv) + if input_file: + print('DEBUG input_file: ' + input_file) + print('DEBUG out_path: ' + out_path) + print('') + # Now set up TritonDSE config = Config(coverage_strategy = CoverageStrategy.PATH, debug = is_debug, pipe_stdout = is_debug, @@ -79,8 +117,6 @@ def init(seed): dse = SymbolicExplorator(config, prog) # Add callbacks. dse.callback_manager.register_pre_execution_callback(pre_exec_hook) - # Create the output directory - os.makedirs(out_path, exist_ok=True) #def fuzz(buf, add_buf, max_size): diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index a1de479e..3f7e9e6e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`. In case your setup is different, set the necessary variables like this: `PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`. +### Helpers + +For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the +`afl_custom_init()` which contains all information that you need. +Note that if you access it, you need to recompile your custom mutator if +you update AFL++ because the structure might have changed! + +For mutators written in Python, Rust, GO, etc. there are a few environment +variables set to help you to get started: + +`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed. +If your custom mutator is used with modes like Qemu (`-Q`), this will still +contain the target program, not afl-qemu-trace. + +`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz +then this value is found in this environment variable. + +`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the +target program and still has the `@@` identifier in there. + +Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV` +is either empty or does not contain `@@` then the target gets the input via +`stdin`. + +`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance, +so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to +`out/foobar`. + ### Custom Mutator Preparation For C/C++ mutators, the source code must be compiled as a shared object: diff --git a/include/envs.h b/include/envs.h index fe5ee0e3..edfd06e4 100644 --- a/include/envs.h +++ b/include/envs.h @@ -37,6 +37,10 @@ static char *afl_environment_variables[] = { "AFL_CRASH_EXITCODE", "AFL_CUSTOM_MUTATOR_LIBRARY", "AFL_CUSTOM_MUTATOR_ONLY", + "AFL_CUSTOM_INFO_PROGRAM", + "AFL_CUSTOM_INFO_PROGRAM_ARGV", + "AFL_CUSTOM_INFO_PROGRAM_INPUT", + "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index f982258f..4339ddd2 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1530,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->limit_time_sig > 0 && afl->custom_mutators_count) { - - if (afl->custom_only) { - - FATAL("Custom mutators are incompatible with MOpt (-L)"); - - } - - u32 custom_fuzz = 0; - LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { - - if (el->afl_custom_fuzz) { custom_fuzz = 1; } - - }); - - if (custom_fuzz) { - - WARNF("afl_custom_fuzz is incompatible with MOpt (-L)"); - - } - - } - if (afl->afl_env.afl_max_det_extras) { s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras); @@ -1827,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) { printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536)); #endif + if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) { + + setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1); + + } + + if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) { + + setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1); + + } + + { + + u8 envbuf[8096] = "", tmpbuf[8096] = ""; + for (s32 i = optind + 1; i < argc; ++i) { + + strcpy(tmpbuf, envbuf); + if (strchr(argv[i], ' ') && !strchr(argv[i], '"') && + !strchr(argv[i], '\'')) { + + if (!strchr(argv[i], '\'')) { + + snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]); + + } else { + + snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]); + + } + + } else { + + snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]); + + } + + } + + setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1); + + } + + setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR + setup_custom_mutators(afl); + if (afl->limit_time_sig > 0 && afl->custom_mutators_count) { + + if (afl->custom_only) { + + FATAL("Custom mutators are incompatible with MOpt (-L)"); + + } + + u32 custom_fuzz = 0; + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz) { custom_fuzz = 1; } + + }); + + if (custom_fuzz) { + + WARNF("afl_custom_fuzz is incompatible with MOpt (-L)"); + + } + + } + write_setup_file(afl, argc, argv); setup_cmdline_file(afl, argv + optind); -- cgit 1.4.1 From abd6eace9d767e4db6019e8eb69080d2352015c9 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 18 May 2023 10:32:15 +0200 Subject: improved symqemu custom mutator --- custom_mutators/symqemu/README.md | 2 +- custom_mutators/symqemu/symqemu.c | 239 +++++++++++++++----------------------- include/afl-fuzz.h | 1 + src/afl-fuzz-one.c | 1 + 4 files changed, 98 insertions(+), 145 deletions(-) (limited to 'include') diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md index 55ce05c5..b7702c06 100644 --- a/custom_mutators/symqemu/README.md +++ b/custom_mutators/symqemu/README.md @@ -8,4 +8,4 @@ on how to build symqemu-x86_x64 and put it in your `PATH`. just type `make` to build this custom mutator. -```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 AFL_DISABLE_TRIM=1 afl-fuzz ...``` +```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_DISABLE_TRIM=1 afl-fuzz ...``` diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c index 9030397b..163ae240 100644 --- a/custom_mutators/symqemu/symqemu.c +++ b/custom_mutators/symqemu/symqemu.c @@ -13,6 +13,9 @@ afl_state_t *afl_struct; static u32 debug = 0; +static u32 found_items = 0; + +#define SYMQEMU_LOCATION "symqemu" #define DBG(x...) \ if (debug) { fprintf(stderr, x); } @@ -22,7 +25,6 @@ typedef struct my_mutator { afl_state_t *afl; u8 *mutator_buf; u8 *out_dir; - u8 *queue_dir; u8 *target; u8 *symqemu; u8 *input_file; @@ -67,8 +69,13 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { if (!data->symqemu) FATAL("symqemu binary %s not found", exec_name); DBG("Found %s\n", data->symqemu); - if (getenv("AFL_CUSTOM_MUTATOR_ONLY")) - FATAL("the symqemu module cannot be used with AFL_CUSTOM_MUTATOR_ONLY."); + if (getenv("AFL_CUSTOM_MUTATOR_ONLY")) { + + WARNF( + "the symqemu module is not very effective with " + "AFL_CUSTOM_MUTATOR_ONLY."); + + } if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) { @@ -84,14 +91,11 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { u32 len = strlen(path_tmp) + 32; u8 *symqemu_path = malloc(len); data->out_dir = malloc(len); - data->queue_dir = malloc(len); - snprintf(symqemu_path, len, "%s/../symqemu", path_tmp); - snprintf(data->out_dir, len, "%s/../symqemu/out", path_tmp); - snprintf(data->queue_dir, len, "%s/../symqemu/queue", path_tmp); + snprintf(symqemu_path, len, "%s/%s", path_tmp, SYMQEMU_LOCATION); + snprintf(data->out_dir, len, "%s/out", symqemu_path, path_tmp); - mkdir(symqemu_path, 0755); - mkdir(data->out_dir, 0755); - mkdir(data->queue_dir, 0755); + (void)mkdir(symqemu_path, 0755); + (void)mkdir(data->out_dir, 0755); setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1); @@ -153,8 +157,8 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { data->argv[0] = data->symqemu; data->argv[1] = data->target; - DBG("out_dir=%s, queue_dir=%s, target=%s, input_file=%s, argc=%u\n", - data->out_dir, data->queue_dir, data->target, + DBG("out_dir=%s, target=%s, input_file=%s, argc=%u\n", data->out_dir, + data->target, data->input_file ? (char *)data->input_file : (char *)"", data->argc); @@ -174,29 +178,39 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) { } - OKF("Custom mutator symqemu loaded - note that the initial startup of " - "afl-fuzz will be delayed the more starting seeds are present. This is " - "fine, do not worry!"); - return data; } -/* When a new queue entry is added we run this input with the symqemu - instrumented binary */ -uint8_t afl_custom_queue_new_entry(my_mutator_t *data, - const uint8_t *filename_new_queue, - const uint8_t *filename_orig_queue) { +/* No need to receive a splicing item */ +void afl_custom_splice_optout(void *data) { + + (void)(data); + +} + +u32 afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, size_t buf_size) { + + if (likely(!afl_struct->queue_cur->favored || + afl_struct->queue_cur->was_fuzzed)) { + + return 0; + + } int pipefd[2]; struct stat st; - if (data->afl->afl_env.afl_no_ui) - ACTF("Sending to symqemu: %s", filename_new_queue); - u8 *fn = alloc_printf("%s", filename_new_queue); - if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) { - ck_free(fn); - PFATAL("Couldn't find enqueued file: %s", fn); + if (afl_struct->afl_env.afl_no_ui) { + + ACTF("Sending to symqemu: %s", afl_struct->queue_cur->fname); + + } + + if (!(stat(afl_struct->queue_cur->fname, &st) == 0 && S_ISREG(st.st_mode) && + st.st_size)) { + + PFATAL("Couldn't find enqueued file: %s", afl_struct->queue_cur->fname); } @@ -204,7 +218,6 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data, if (pipe(pipefd) == -1) { - ck_free(fn); PFATAL( "Couldn't create a pipe for interacting with symqemu child process"); @@ -212,19 +225,12 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data, } - int fd = open(fn, O_RDONLY); - if (fd < 0) return 0; - ssize_t r = read(fd, data->mutator_buf, MAX_FILE); - DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r); - ck_free(fn); - close(fd); - if (data->input_file) { - fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); - ssize_t s = write(fd, data->mutator_buf, r); + int fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); + ssize_t s = write(fd, buf, buf_size); close(fd); - DBG("wrote %zd/%zd to %s\n", s, r, data->input_file); + DBG("wrote %zd/%zd to %s\n", s, buf_size, data->input_file); } @@ -232,35 +238,20 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data, if (pid == -1) return 0; - if (pid) { + if (likely(pid)) { if (!data->input_file || afl_struct->fsrv.use_stdin) { close(pipefd[0]); - if (fd >= 0) { - - if (r <= 0) { - - close(pipefd[1]); - return 0; - - } + if (fcntl(pipefd[1], F_GETPIPE_SZ)) { - if (r > fcntl(pipefd[1], F_GETPIPE_SZ)) - fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE); - ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue); - - } else { - - ck_free(fn); - close(pipefd[1]); - PFATAL( - "Something happened to the enqueued file before sending its " - "contents to symqemu binary"); + fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE); } + ck_write(pipefd[1], buf, buf_size, data->input_file); + close(pipefd[1]); } @@ -268,46 +259,6 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data, pid = waitpid(pid, NULL, 0); DBG("symqemu finished executing!\n"); - // At this point we need to transfer files to output dir, since their names - // collide and symqemu will just overwrite them - - struct dirent **nl; - int32_t items = scandir(data->out_dir, &nl, NULL, NULL); - u8 *origin_name = basename(filename_new_queue); - u8 source_name[4096], destination_name[4096]; - int32_t i; - - if (items > 0) { - - for (i = 0; i < (u32)items; ++i) { - - // symqemu output files start with a digit - if (!isdigit(nl[i]->d_name[0])) continue; - - struct stat st; - snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir, - nl[i]->d_name); - DBG("file=%s\n", source_name); - - if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) { - - snprintf(destination_name, sizeof(destination_name), "%s/id:%06u,%s", - data->queue_dir, data->counter++, nl[i]->d_name); - DBG("src=%s dst=%s\n", source_name, destination_name); - rename(source_name, destination_name); - - } - - free(nl[i]); - - } - - free(nl); - - } - - DBG("Done!\n"); - } else /* (pid == 0) */ { // child if (afl_struct->fsrv.use_stdin) { @@ -338,33 +289,31 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data, } - return 0; - -} - -/* -uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, - size_t buf_size) { + /* back in mother process */ - uint32_t count = 0, i; struct dirent **nl; - int32_t items = scandir(data->out_dir, &nl, NULL, NULL); + s32 i, items = scandir(data->out_dir, &nl, NULL, NULL); + found_items = 0; + char source_name[4096]; if (items > 0) { for (i = 0; i < (u32)items; ++i) { + // symqemu output files start with a digit + if (!isdigit(nl[i]->d_name[0])) continue; + struct stat st; - u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name); - DBG("test=%s\n", fn); - if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) { + snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir, + nl[i]->d_name); + DBG("file=%s\n", source_name); + + if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) { - DBG("found=%s\n", fn); - count++; + ++found_items; } - ck_free(fn); free(nl[i]); } @@ -373,65 +322,67 @@ uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, } - DBG("dir=%s, count=%u\n", data->out_dir, count); - return count; + DBG("Done, found %u items!\n", found_items); -} + return found_items; -*/ +} -// here we actually just read the files generated from symqemu -/* -size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size, - u8 **out_buf, uint8_t *add_buf, size_t add_buf_size, +size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, + u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size) { struct dirent **nl; - int32_t i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL); - ssize_t size = 0; + s32 done = 0, i, items = scandir(data->out_dir, &nl, NULL, NULL); + char source_name[4096]; - if (items <= 0) return 0; + if (items > 0) { - for (i = 0; i < (u32)items; ++i) { + for (i = 0; i < (u32)items; ++i) { - struct stat st; - u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name); + // symqemu output files start with a digit + if (!isdigit(nl[i]->d_name[0])) continue; - if (done == 0) { + struct stat st; + snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir, + nl[i]->d_name); + DBG("file=%s\n", source_name); - if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) { + if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) { - int fd = open(fn, O_RDONLY); + int fd = open(source_name, O_RDONLY); + if (fd < 0) { goto got_an_issue; } - if (fd >= 0) { + ssize_t r = read(fd, data->mutator_buf, MAX_FILE); + close(fd); - size = read(fd, data->mutator_buf, max_size); - *out_buf = data->mutator_buf; + DBG("fn=%s, fd=%d, size=%ld\n", source_name, fd, r); - close(fd); - done = 1; + if (r < 1) { goto got_an_issue; } - } + done = 1; + --found_items; + unlink(source_name); + + *out_buf = data->mutator_buf; + return (u32)r; } - unlink(fn); + free(nl[i]); } - ck_free(fn); - free(nl[i]); + free(nl); } - free(nl); - DBG("FUZZ size=%lu\n", size); - return (uint32_t)size; +got_an_issue: + *out_buf = NULL; + return 0; } -*/ - /** * Deinitialize everything * diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 8fb7ecb1..beb2de2a 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -184,6 +184,7 @@ struct queue_entry { handicap, /* Number of queue cycles behind */ depth, /* Path depth */ exec_cksum, /* Checksum of the execution trace */ + custom, /* Marker for custom mutators */ stats_mutated; /* stats: # of mutations performed */ u8 *trace_mini; /* Trace bytes, if kept */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index c6e9a295..5c71fc59 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1912,6 +1912,7 @@ custom_mutator_stage: afl->stage_name = "custom mutator"; afl->stage_short = "custom"; + afl->stage_cur = 0; afl->stage_val_type = STAGE_VAL_NONE; bool has_custom_fuzz = false; u32 shift = unlikely(afl->custom_only) ? 7 : 8; -- cgit 1.4.1 From 029e039cbcbf9e30f35eb255162679b8d609d25d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 21 May 2023 17:49:14 +0200 Subject: code format --- .custom-format.py | 2 +- frida_mode/src/lib/lib_apple.c | 4 +-- include/config.h | 2 +- instrumentation/SanitizerCoverageLTO.so.cc | 4 +-- instrumentation/SanitizerCoveragePCGUARD.so.cc | 4 +-- instrumentation/afl-compiler-rt.o.c | 14 +++++----- instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +- instrumentation/cmplog-routines-pass.cc | 4 +-- instrumentation/compare-transform-pass.so.cc | 2 +- instrumentation/split-compares-pass.so.cc | 2 +- qemu_mode/libcompcov/libcompcov.so.c | 6 ++++- src/afl-cc.c | 8 +++--- src/afl-fuzz-redqueen.c | 32 +++++++++++------------ utils/afl_untracer/afl-untracer.c | 2 +- utils/libtokencap/libtokencap.so.c | 6 ++++- utils/socket_fuzzing/socketfuzz.c | 3 ++- 16 files changed, 53 insertions(+), 44 deletions(-) (limited to 'include') diff --git a/.custom-format.py b/.custom-format.py index 1295ce55..1d5c8839 100755 --- a/.custom-format.py +++ b/.custom-format.py @@ -24,7 +24,7 @@ import importlib.metadata # string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use -CURRENT_LLVM = os.getenv('LLVM_VERSION', 14) +CURRENT_LLVM = os.getenv('LLVM_VERSION', 15) CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "") diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c index 634e0e30..d29d0303 100644 --- a/frida_mode/src/lib/lib_apple.c +++ b/frida_mode/src/lib/lib_apple.c @@ -17,8 +17,8 @@ static gboolean lib_get_main_module(const GumModuleDetails *details, GumDarwinModule **ret = (GumDarwinModule **)user_data; GumDarwinModule *module = gum_darwin_module_new_from_memory( - details->path, mach_task_self(), details->range->base_address, - GUM_DARWIN_MODULE_FLAGS_NONE, NULL); + details->path, mach_task_self(), details->range->base_address, + GUM_DARWIN_MODULE_FLAGS_NONE, NULL); FVERBOSE("Found main module: %s", module->name); diff --git a/include/config.h b/include/config.h index 764c29dc..194786f7 100644 --- a/include/config.h +++ b/include/config.h @@ -81,7 +81,7 @@ will be kept and written to the crash/ directory as RECORD:... files. Note that every crash will be written, not only unique ones! */ -//#define AFL_PERSISTENT_RECORD +// #define AFL_PERSISTENT_RECORD /* console output colors: There are three ways to configure its behavior * 1. default: colored outputs fixed on: defined USE_COLOR && defined diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index b3b0d2cd..d7b03634 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -1478,8 +1478,8 @@ GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection( ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); auto Array = new GlobalVariable( - *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, - Constant::getNullValue(ArrayTy), "__sancov_gen_"); + *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, + Constant::getNullValue(ArrayTy), "__sancov_gen_"); #if LLVM_VERSION_MAJOR >= 13 if (TargetTriple.supportsCOMDAT() && diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 41c38283..8fed2042 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -714,8 +714,8 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection( ArrayType *ArrayTy = ArrayType::get(Ty, NumElements); auto Array = new GlobalVariable( - *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, - Constant::getNullValue(ArrayTy), "__sancov_gen_"); + *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage, + Constant::getNullValue(ArrayTy), "__sancov_gen_"); #if LLVM_VERSION_MAJOR >= 13 if (TargetTriple.supportsCOMDAT() && diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 5372fae0..3f8b519b 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -544,12 +544,12 @@ static void __afl_map_shm(void) { if (__afl_map_size && __afl_map_size > MAP_SIZE) { - u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE"); - if (!map_env || atoi((char *)map_env) < MAP_SIZE) { + u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE"); + if (!map_env || atoi((char *)map_env) < MAP_SIZE) { - fprintf(stderr, "FS_ERROR_MAP_SIZE\n"); - send_forkserver_error(FS_ERROR_MAP_SIZE); - _exit(1); + fprintf(stderr, "FS_ERROR_MAP_SIZE\n"); + send_forkserver_error(FS_ERROR_MAP_SIZE); + _exit(1); } @@ -561,13 +561,13 @@ static void __afl_map_shm(void) { if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) { - if (__afl_map_addr) + if (__afl_map_addr) send_forkserver_error(FS_ERROR_MAP_ADDR); else send_forkserver_error(FS_ERROR_SHMAT); perror("shmat for map"); - _exit(1); + _exit(1); } diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc index db5bd55e..61f97d77 100644 --- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc @@ -45,7 +45,7 @@ #include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/Debug.h" -//#include "llvm/Transforms/IPO/PassManagerBuilder.h" +// #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/IR/PassManager.h" diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 39db5aa4..c3fbed8d 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -542,7 +542,7 @@ bool CmpLogRoutines::hookRtns(Module &M) { Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy); Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy); Value *v3Pbitcast = IRB.CreateBitCast( - v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits())); + v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits())); Value *v3Pcasted = IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false); args.push_back(v1Pcasted); @@ -608,7 +608,7 @@ bool CmpLogRoutines::hookRtns(Module &M) { Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy); Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy); Value *v3Pbitcast = IRB.CreateBitCast( - v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits())); + v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits())); Value *v3Pcasted = IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false); args.push_back(v1Pcasted); diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc index efc99d20..5dd705cf 100644 --- a/instrumentation/compare-transform-pass.so.cc +++ b/instrumentation/compare-transform-pass.so.cc @@ -623,7 +623,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp, IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt())); Value *icmp = cur_lenchk_IRB.CreateICmpEQ( - sizedValue, ConstantInt::get(sizedValue->getType(), i)); + sizedValue, ConstantInt::get(sizedValue->getType(), i)); cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb); cur_lenchk_bb->getTerminator()->eraseFromParent(); diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc index 8a07610c..aec6758e 100644 --- a/instrumentation/split-compares-pass.so.cc +++ b/instrumentation/split-compares-pass.so.cc @@ -60,7 +60,7 @@ using namespace llvm; // uncomment this toggle function verification at each step. horribly slow, but // helps to pinpoint a potential problem in the splitting code. -//#define VERIFY_TOO_MUCH 1 +// #define VERIFY_TOO_MUCH 1 namespace { diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c index b6ee0019..b57e9701 100644 --- a/qemu_mode/libcompcov/libcompcov.so.c +++ b/qemu_mode/libcompcov/libcompcov.so.c @@ -68,7 +68,11 @@ static int debug_fd = -1; #define MAX_MAPPINGS 1024 -static struct mapping { void *st, *en; } __compcov_ro[MAX_MAPPINGS]; +static struct mapping { + + void *st, *en; + +} __compcov_ro[MAX_MAPPINGS]; static u32 __compcov_ro_cnt; diff --git a/src/afl-cc.c b/src/afl-cc.c index 972ac8cd..e3cc04dd 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -933,10 +933,10 @@ static void edit_params(u32 argc, char **argv, char **envp) { } - //#if LLVM_MAJOR >= 13 - // // Use the old pass manager in LLVM 14 which the AFL++ passes still - // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; - //#endif + // #if LLVM_MAJOR >= 13 + // // Use the old pass manager in LLVM 14 which the AFL++ passes still + // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager"; + // #endif if (lto_mode && !have_c) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 6e4a655b..d9dc50df 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -28,8 +28,8 @@ #include "afl-fuzz.h" #include "cmplog.h" -//#define _DEBUG -//#define CMPLOG_INTROSPECTION +// #define _DEBUG +// #define CMPLOG_INTROSPECTION // CMP attribute enum enum { @@ -571,7 +571,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -//#ifdef CMPLOG_SOLVE_TRANSFORM +// #ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -771,7 +771,7 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { #endif -//#endif +// #endif static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, @@ -803,8 +803,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // o_pattern, pattern, repl, changed_val, idx, taint_len, // hshape, attr); - //#ifdef CMPLOG_SOLVE_TRANSFORM - // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 + // #ifdef CMPLOG_SOLVE_TRANSFORM + // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (afl->cmplog_enable_transform && (lvl & LVL3)) { u8 *endptr; @@ -1120,7 +1120,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - //#endif + // #endif // we only allow this for ascii2integer (above) so leave if this is the case if (unlikely(pattern == o_pattern)) { return 0; } @@ -1275,7 +1275,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) - //#ifdef CMPLOG_SOLVE_ARITHMETIC + // #ifdef CMPLOG_SOLVE_ARITHMETIC if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) { return 0; @@ -1440,8 +1440,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - //#endif /* - // CMPLOG_SOLVE_ARITHMETIC + // #endif /* + // CMPLOG_SOLVE_ARITHMETIC return 0; @@ -1948,9 +1948,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, #ifndef CMPLOG_COMBINE (void)(cbuf); #endif - //#ifndef CMPLOG_SOLVE_TRANSFORM - // (void)(changed_val); - //#endif + // #ifndef CMPLOG_SOLVE_TRANSFORM + // (void)(changed_val); + // #endif if (afl->fsrv.total_execs - last_update > screen_update) { @@ -2418,7 +2418,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - //#endif + // #endif return 0; @@ -2818,9 +2818,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } else if ((lvl & LVL1) - //#ifdef CMPLOG_SOLVE_TRANSFORM + // #ifdef CMPLOG_SOLVE_TRANSFORM || ((lvl & LVL3) && afl->cmplog_enable_transform) - //#endif + // #endif ) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { diff --git a/utils/afl_untracer/afl-untracer.c b/utils/afl_untracer/afl-untracer.c index a18e314e..e1038212 100644 --- a/utils/afl_untracer/afl-untracer.c +++ b/utils/afl_untracer/afl-untracer.c @@ -288,7 +288,7 @@ library_list_t *find_library(char *name) { #pragma GCC optimize("O0") void breakpoint(void) { - if (debug) fprintf(stderr, "Breakpoint function \"breakpoint\" reached.\n"); + if (debug) fprintf(stderr, "Breakpoint function \"breakpoint\" reached.\n"); } diff --git a/utils/libtokencap/libtokencap.so.c b/utils/libtokencap/libtokencap.so.c index 299056ab..b21f3068 100644 --- a/utils/libtokencap/libtokencap.so.c +++ b/utils/libtokencap/libtokencap.so.c @@ -81,7 +81,11 @@ void *(*__libc_memmem)(const void *haystack, size_t haystack_len, #define MAX_MAPPINGS 1024 -static struct mapping { void *st, *en; } __tokencap_ro[MAX_MAPPINGS]; +static struct mapping { + + void *st, *en; + +} __tokencap_ro[MAX_MAPPINGS]; static u32 __tokencap_ro_cnt; static u8 __tokencap_ro_loaded; diff --git a/utils/socket_fuzzing/socketfuzz.c b/utils/socket_fuzzing/socketfuzz.c index 3ec8383b..7497519e 100644 --- a/utils/socket_fuzzing/socketfuzz.c +++ b/utils/socket_fuzzing/socketfuzz.c @@ -23,7 +23,8 @@ #include #include #include -//#include "logging.h" // switche from preeny_info() to fprintf(stderr, "Info: " +// #include "logging.h" // switched from preeny_info() to fprintf(stderr, "Info: +// " // // originals -- cgit 1.4.1 From 501226c992e5c47672907c5dde7f968f4e8fb001 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 23 May 2023 14:41:59 +0200 Subject: correct rtn cmplog map size --- include/cmplog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/cmplog.h b/include/cmplog.h index 6e16e6b0..e4821444 100644 --- a/include/cmplog.h +++ b/include/cmplog.h @@ -34,7 +34,7 @@ #define CMP_MAP_W 65536 #define CMP_MAP_H 32 -#define CMP_MAP_RTN_H (CMP_MAP_H / 4) +#define CMP_MAP_RTN_H (CMP_MAP_H / 2) #define SHAPE_BYTES(x) (x + 1) -- cgit 1.4.1