about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--custom_mutators/aflpp_tritondse/aflpp_tritondse.py54
-rw-r--r--docs/custom_mutators.md28
-rw-r--r--include/envs.h4
-rw-r--r--src/afl-fuzz.c91
4 files changed, 145 insertions, 32 deletions
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);