about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>2021-07-15 19:32:44 +0100
committerGitHub <noreply@github.com>2021-07-15 20:32:44 +0200
commit9e8afcc6156fbcc7b0ed41cde1a5873989b65063 (patch)
treee854fd9b8b8e2e19bcba35713f6c2a375274c02e
parent6f03749c734e535cf9488027c692a7ee2591b60f (diff)
downloadafl++-9e8afcc6156fbcc7b0ed41cde1a5873989b65063.tar.gz
Support for setting a fixed seed for the hash function (#1026)
Co-authored-by: Your Name <you@example.com>
-rw-r--r--frida_mode/README.md3
-rw-r--r--frida_mode/frida.map1
-rw-r--r--frida_mode/include/instrument.h3
-rw-r--r--frida_mode/src/instrument/instrument.c38
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js.c11
-rw-r--r--frida_mode/src/js/js_api.c8
-rw-r--r--frida_mode/ts/lib/afl.ts12
-rw-r--r--include/envs.h1
9 files changed, 67 insertions, 17 deletions
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 6cbb4c4c..3009e171 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -162,6 +162,9 @@ instrumentation (the default where available). Required to use
 * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default the child will
 report instrumented blocks back to the parent so that it can also instrument
 them and they be inherited by the next child on fork.
+* `AFL_FRIDA_INST_SEED` - Sets the initial seed for the hash function used to
+generate block (and hence edge) IDs. Setting this to a constant value may be
+useful for debugging purposes, e.g. investigating unstable edges.
 * `AFL_FRIDA_INST_TRACE` - Log to stdout the address of executed blocks,
 implies `AFL_FRIDA_INST_NO_OPTIMIZE`.
 * `AFL_FRIDA_INST_TRACE_UNIQUE` - As per `AFL_FRIDA_INST_TRACE`, but each edge
diff --git a/frida_mode/frida.map b/frida_mode/frida.map
index 8fc0b174..7223d50e 100644
--- a/frida_mode/frida.map
+++ b/frida_mode/frida.map
@@ -14,6 +14,7 @@
     js_api_set_instrument_jit;
     js_api_set_instrument_libraries;
     js_api_set_instrument_no_optimize;
+    js_api_set_instrument_seed;
     js_api_set_instrument_trace;
     js_api_set_instrument_trace_unique;
     js_api_set_persistent_address;
diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h
index 695b46af..29f14da9 100644
--- a/frida_mode/include/instrument.h
+++ b/frida_mode/include/instrument.h
@@ -12,6 +12,9 @@ extern gboolean         instrument_unique;
 extern __thread guint64 instrument_previous_pc;
 extern guint64          instrument_hash_zero;
 
+extern gboolean instrument_use_fixed_seed;
+extern guint64  instrument_fixed_seed;
+
 extern uint8_t *__afl_area_ptr;
 extern uint32_t __afl_map_size;
 
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index e1dabf92..67aafa5a 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -27,6 +27,9 @@ gboolean instrument_unique = false;
 guint64  instrument_hash_zero = 0;
 guint64  instrument_hash_seed = 0;
 
+gboolean instrument_use_fixed_seed = FALSE;
+guint64  instrument_fixed_seed = 0;
+
 static GumStalkerTransformer *transformer = NULL;
 
 __thread guint64 instrument_previous_pc = 0;
@@ -221,6 +224,8 @@ void instrument_config(void) {
   instrument_optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL);
   instrument_tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL);
   instrument_unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL);
+  instrument_use_fixed_seed = (getenv("AFL_FRIDA_INST_SEED") != NULL);
+  instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED");
 
   instrument_debug_config();
   asan_config();
@@ -235,6 +240,8 @@ void instrument_init(void) {
   OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' ');
   OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' ');
   OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' ');
+  OKF("Instrumentation - fixed seed [%c] [0x%016" G_GINT64_MODIFIER "x]",
+      instrument_use_fixed_seed ? 'X' : ' ', instrument_fixed_seed);
 
   if (instrument_tracing && instrument_optimize) {
 
@@ -270,7 +277,8 @@ void instrument_init(void) {
     g_assert(edges_notified != MAP_FAILED);
 
     /*
-     * Configure the shared memory region to be removed once the process dies.
+     * Configure the shared memory region to be removed once the process
+     * dies.
      */
     if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
 
@@ -283,14 +291,26 @@ void instrument_init(void) {
 
   }
 
-  /*
-   * By using a different seed value for the hash, we can make different
-   * instances have edge collisions in different places when carrying out
-   * parallel fuzzing. The seed itself, doesn't have to be random, it just
-   * needs to be different for each instance.
-   */
-  instrument_hash_seed =
-      g_get_monotonic_time() ^ (((guint64)getpid()) << 32) ^ syscall(SYS_gettid);
+  if (instrument_use_fixed_seed) {
+
+    /*
+     * This configuration option may be useful for diagnostics or
+     * debugging.
+     */
+    instrument_hash_seed = instrument_fixed_seed;
+
+  } else {
+
+    /*
+     * By using a different seed value for the hash, we can make different
+     * instances have edge collisions in different places when carrying out
+     * parallel fuzzing. The seed itself, doesn't have to be random, it
+     * just needs to be different for each instance.
+     */
+    instrument_hash_seed = g_get_monotonic_time() ^
+                           (((guint64)getpid()) << 32) ^ syscall(SYS_gettid);
+
+  }
 
   OKF("Instrumentation - seed [0x%016" G_GINT64_MODIFIER "x]",
       instrument_hash_seed);
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 1d843024..b8f2d39a 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -117,6 +117,12 @@ class Afl {
     static setInstrumentNoOptimize() {
         Afl.jsApiSetInstrumentNoOptimize();
     }
+    /*
+     * See `AFL_FRIDA_INST_SEED`
+     */
+    static setInstrumentSeed(seed) {
+        Afl.jsApiSetInstrumentSeed(seed);
+    }
     /**
      * See `AFL_FRIDA_INST_TRACE_UNIQUE`.
      */
@@ -231,6 +237,7 @@ Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_de
 Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
 Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
 Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
+Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
 Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
 Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []);
 Afl.jsApiSetPersistentAddress = Afl.jsApiGetFunction("js_api_set_persistent_address", "void", ["pointer"]);
diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c
index 86ae6d29..e3cd4933 100644
--- a/frida_mode/src/js/js.c
+++ b/frida_mode/src/js/js.c
@@ -89,10 +89,7 @@ static void load_cb(GObject *source_object, GAsyncResult *result,
   UNUSED_PARAMETER(source_object);
   UNUSED_PARAMETER(user_data);
   gum_script_load_finish(script, result);
-  if (error != NULL)
-  {
-    FATAL("Failed to load script - %s", error->message);
-  }
+  if (error != NULL) { FATAL("Failed to load script - %s", error->message); }
 
 }
 
@@ -102,10 +99,7 @@ static void create_cb(GObject *source_object, GAsyncResult *result,
   UNUSED_PARAMETER(source_object);
   UNUSED_PARAMETER(user_data);
   script = gum_script_backend_create_finish(backend, result, &error);
-  if (error != NULL)
-  {
-    FATAL("Failed to create script: %s", error->message);
-  }
+  if (error != NULL) { FATAL("Failed to create script: %s", error->message); }
 
   gum_script_set_message_handler(script, js_msg, NULL, NULL);
 
@@ -145,3 +139,4 @@ gboolean js_stalker_callback(const cs_insn *insn, gboolean begin,
   return js_user_callback(insn, begin, excluded, output);
 
 }
+
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index fd8128c5..930a6dc0 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -127,6 +127,14 @@ __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
 
 }
 
+__attribute__((visibility("default"))) void js_api_set_instrument_seed(
+    guint64 seed) {
+
+  instrument_use_fixed_seed = TRUE;
+  instrument_fixed_seed = seed;
+
+}
+
 __attribute__((visibility("default"))) void js_api_set_instrument_trace(void) {
 
   instrument_tracing = TRUE;
diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts
index 67e21beb..6326c099 100644
--- a/frida_mode/ts/lib/afl.ts
+++ b/frida_mode/ts/lib/afl.ts
@@ -140,6 +140,13 @@ class Afl {
     Afl.jsApiSetInstrumentNoOptimize();
   }
 
+  /*
+   * See `AFL_FRIDA_INST_SEED`
+   */
+  public static setInstrumentSeed(seed: NativePointer): void {
+    Afl.jsApiSetInstrumentSeed(seed);
+  }
+
   /**
    * See `AFL_FRIDA_INST_TRACE_UNIQUE`.
    */
@@ -295,6 +302,11 @@ class Afl {
     "void",
     []);
 
+  private static readonly jsApiSetInstrumentSeed = Afl.jsApiGetFunction(
+    "js_api_set_instrument_seed",
+    "void",
+    ["uint64"]);
+
   private static readonly jsApiSetInstrumentTrace = Afl.jsApiGetFunction(
     "js_api_set_instrument_trace",
     "void",
diff --git a/include/envs.h b/include/envs.h
index 4bab54ce..26cc250f 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -60,6 +60,7 @@ static char *afl_environment_variables[] = {
     "AFL_FRIDA_INST_NO_OPTIMIZE",
     "AFL_FRIDA_INST_NO_PREFETCH",
     "AFL_FRIDA_INST_RANGES",
+    "AFL_FRIDA_INST_SEED",
     "AFL_FRIDA_INST_TRACE",
     "AFL_FRIDA_INST_TRACE_UNIQUE",
     "AFL_FRIDA_JS_SCRIPT",