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