about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-forkserver.c10
-rw-r--r--src/afl-fuzz-run.c12
-rw-r--r--src/afl-fuzz-state.c7
-rw-r--r--src/afl-fuzz.c25
4 files changed, 53 insertions, 1 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index a998c10f..cec91f76 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -292,6 +292,9 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) {
   fsrv_to->use_fauxsrv = 0;
   fsrv_to->last_run_timed_out = 0;
 
+  fsrv_to->late_send = from->late_send;
+  fsrv_to->custom_data_ptr = from->custom_data_ptr;
+
   fsrv_to->init_child_func = from->init_child_func;
   // Note: do not copy ->add_extra_func or ->persistent_record*
 
@@ -1952,6 +1955,13 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
 
   }
 
+  if (unlikely(fsrv->late_send)) {
+
+    fsrv->late_send(fsrv->custom_data_ptr, fsrv->custom_input,
+                    fsrv->custom_input_len);
+
+  }
+
   exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout,
                            stop_soon_p);
 
diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c
index c234fc42..2f244a1d 100644
--- a/src/afl-fuzz-run.c
+++ b/src/afl-fuzz-run.c
@@ -194,7 +194,17 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) {
 
       if (el->afl_custom_fuzz_send) {
 
-        el->afl_custom_fuzz_send(el->data, *mem, new_size);
+        if (!afl->afl_env.afl_custom_mutator_late_send) {
+
+          el->afl_custom_fuzz_send(el->data, *mem, new_size);
+
+        } else {
+
+          afl->fsrv.custom_input = *mem;
+          afl->fsrv.custom_input_len = new_size;
+
+        }
+
         sent = 1;
 
       }
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index dd684a19..eead3e50 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -300,6 +300,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
             afl->afl_env.afl_custom_mutator_only =
                 get_afl_env(afl_environment_variables[i]) ? 1 : 0;
 
+          } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LATE_SEND",
+
+                              afl_environment_variable_len)) {
+
+            afl->afl_env.afl_custom_mutator_late_send =
+                get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+
           } else if (!strncmp(env, "AFL_CMPLOG_ONLY_NEW",
 
                               afl_environment_variable_len)) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index b53a9a2d..8a84d447 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2142,6 +2142,31 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  if (afl->custom_mutators_count && afl->afl_env.afl_custom_mutator_late_send) {
+
+    u32 count_send = 0;
+    LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+      if (el->afl_custom_fuzz_send) {
+
+        if (count_send) {
+
+          FATAL(
+              "You can only have one custom send() function if you are using "
+              "AFL_CUSTOM_MUTATOR_LATE_SEND!");
+
+        }
+
+        afl->fsrv.late_send = el->afl_custom_fuzz_send;
+        afl->fsrv.custom_data_ptr = el->data;
+        count_send = 1;
+
+      }
+
+    });
+
+  }
+
   if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
 
     if (afl->custom_only) {