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 --- include/envs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/envs.h') 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", -- 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/envs.h') 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/envs.h') 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/envs.h') 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 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/envs.h') 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