about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorvanhauser-thc <vh@thc.org>2024-06-10 18:22:06 +0200
committervanhauser-thc <vh@thc.org>2024-06-10 18:22:06 +0200
commit6ed0a2b4aa0c22f95ba723cfda5b1fb79a224bc8 (patch)
tree9e91158d6301667ca76dc162ddb2a99ab08fb246 /src
parent8e50c0c103cade9723f115fc92e3065f64c79713 (diff)
downloadafl++-6ed0a2b4aa0c22f95ba723cfda5b1fb79a224bc8.tar.gz
fast resume setup detection
Diffstat (limited to 'src')
-rw-r--r--src/afl-fuzz-stats.c8
-rw-r--r--src/afl-fuzz.c100
-rw-r--r--src/afl-performance.c2
3 files changed, 88 insertions, 22 deletions
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 3a71e158..a20c46d0 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -76,7 +76,13 @@ char *get_fuzzing_state(afl_state_t *afl) {
 
 void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
 
-  u8 fn[PATH_MAX];
+  u8 fn[PATH_MAX], fn2[PATH_MAX];
+
+  snprintf(fn2, PATH_MAX, "%s/target_hash", afl->out_dir);
+  FILE *f2 = create_ffile(fn2);
+  fprintf(f2, "%p\n", (void *)get_binary_hash(afl->fsrv.target_path));
+  fclose(f2);
+
   snprintf(fn, PATH_MAX, "%s/fuzzer_setup", afl->out_dir);
   FILE *f = create_ffile(fn);
   u32   i;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index a7ddef6e..bb05c9c6 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2101,45 +2101,105 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  write_setup_file(afl, argc, argv);
-
   setup_cmdline_file(afl, argv + optind);
+  check_binary(afl, argv[optind]);
 
-  read_testcases(afl, NULL);
-  // read_foreign_testcases(afl, 1); for the moment dont do this
-  OKF("Loaded a total of %u seeds.", afl->queued_items);
+  u64 prev_target_hash = 0;
+  s32 fast_resume = 0, fr_fd = -1;
+
+  if (afl->in_place_resume) {
 
-  pivot_inputs(afl);
+    u8 fn[PATH_MAX], buf[32];
+    snprintf(fn, PATH_MAX, "%s/target_hash", afl->out_dir);
+    fr_fd = open(fn, O_RDONLY);
+    if (fr_fd >= 0) {
 
-  if (!afl->timeout_given) { find_timeout(afl); }  // only for resumes!
+      if (read(fr_fd, buf, 32) >= 16) {
 
-  if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) {
+        sscanf(buf, "%p", (void**)&prev_target_hash);
 
-    char tmpfile[PATH_MAX];
+      }
 
-    if (afl->file_extension) {
+      close(fr_fd);
 
-      snprintf(tmpfile, PATH_MAX, "%s/.cur_input.%s", afl->tmp_dir,
-               afl->file_extension);
+    }
+
+  }
+
+
+  write_setup_file(afl, argc, argv);
+
+  if (afl->in_place_resume) {
+
+    u64 target_hash = get_binary_hash(afl->fsrv.target_path);
+
+    if (!target_hash || prev_target_hash != target_hash) {
+
+      ACTF("Target binary is different, cannot perform FAST RESUME!");
 
     } else {
 
-      snprintf(tmpfile, PATH_MAX, "%s/.cur_input", afl->tmp_dir);
+      u8 fn[PATH_MAX];
+      snprintf(fn, PATH_MAX, "%s/fastresume.bin", afl->out_dir);
+      if ((fr_fd = open(fn, O_RDONLY)) >= 0) {
+
+        OKF("Performing FAST RESUME");
+        // fast_resume = 1;
+
+      } else {
+
+        ACTF("fastresume.bin not found, cannot perform FAST RESUME!");
+
+      }
 
     }
 
-    /* there is still a race condition here, but well ... */
-    if (access(tmpfile, F_OK) != -1) {
+  }
 
-      FATAL(
-          "AFL_TMPDIR already has an existing temporary input file: %s - if "
-          "this is not from another instance, then just remove the file.",
-          tmpfile);
+  if (fast_resume) {
+
+    // XXX
+
+  } else {
+
+    read_testcases(afl, NULL);
+
+    pivot_inputs(afl);
+
+    if (!afl->timeout_given) { find_timeout(afl); }  // only for resumes!
+
+    if (afl->afl_env.afl_tmpdir && !afl->in_place_resume) {
+
+      char tmpfile[PATH_MAX];
+
+      if (afl->file_extension) {
+
+        snprintf(tmpfile, PATH_MAX, "%s/.cur_input.%s", afl->tmp_dir,
+                 afl->file_extension);
+
+      } else {
+
+        snprintf(tmpfile, PATH_MAX, "%s/.cur_input", afl->tmp_dir);
+
+      }
+
+      /* there is still a race condition here, but well ... */
+      if (access(tmpfile, F_OK) != -1) {
+
+        FATAL(
+            "AFL_TMPDIR already has an existing temporary input file: %s - if "
+            "this is not from another instance, then just remove the file.",
+            tmpfile);
+
+      }
 
     }
 
   }
 
+  // read_foreign_testcases(afl, 1); for the moment dont do this
+  OKF("Loaded a total of %u seeds.", afl->queued_items);
+
   /* If we don't have a file name chosen yet, use a safe default. */
 
   if (!afl->fsrv.out_file) {
@@ -2196,8 +2256,6 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
-  check_binary(afl, argv[optind]);
-
   #ifdef AFL_PERSISTENT_RECORD
   if (unlikely(afl->fsrv.persistent_record)) {
 
diff --git a/src/afl-performance.c b/src/afl-performance.c
index e8ece6b5..b824fd35 100644
--- a/src/afl-performance.c
+++ b/src/afl-performance.c
@@ -99,11 +99,13 @@ inline u64 hash64(u8 *key, u32 len, u64 seed) {
 
 u64 get_binary_hash(u8 *fn) {
 
+  if (!fn) { return 0; }
   int fd = open(fn, O_RDONLY);
   if (fd < 0) { PFATAL("Unable to open '%s'", fn); }
   struct stat st;
   if (fstat(fd, &st) < 0) { PFATAL("Unable to fstat '%s'", fn); }
   u32 f_len = st.st_size;
+  if (!f_len) { return 0; }
   u8 *f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
   if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); }
   close(fd);