about summary refs log tree commit diff
path: root/frida_mode/src
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/cmplog/cmplog_arm64.c6
-rw-r--r--frida_mode/src/cmplog/cmplog_x64.c6
-rw-r--r--frida_mode/src/cmplog/cmplog_x86.c6
-rw-r--r--frida_mode/src/instrument/instrument_x64.c74
-rw-r--r--frida_mode/src/js/api.js7
-rw-r--r--frida_mode/src/js/js_api.c6
-rw-r--r--frida_mode/src/stalker.c9
7 files changed, 100 insertions, 14 deletions
diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c
index ccc8e89e..c6590bb4 100644
--- a/frida_mode/src/cmplog/cmplog_arm64.c
+++ b/frida_mode/src/cmplog/cmplog_arm64.c
@@ -5,6 +5,7 @@
 
 #include "ctx.h"
 #include "frida_cmplog.h"
+#include "instrument.h"
 #include "util.h"
 
 #if defined(__aarch64__)
@@ -111,10 +112,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
   void *ptr1 = GSIZE_TO_POINTER(x0);
   void *ptr2 = GSIZE_TO_POINTER(x1);
 
-  uintptr_t k = address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  guint64 k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
 
diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c
index 5319f727..7fbcf408 100644
--- a/frida_mode/src/cmplog/cmplog_x64.c
+++ b/frida_mode/src/cmplog/cmplog_x64.c
@@ -5,6 +5,7 @@
 
 #include "ctx.h"
 #include "frida_cmplog.h"
+#include "instrument.h"
 #include "util.h"
 
 #if defined(__x86_64__)
@@ -106,10 +107,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
   void *ptr1 = GSIZE_TO_POINTER(rdi);
   void *ptr2 = GSIZE_TO_POINTER(rsi);
 
-  uintptr_t k = address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  guint64 k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
 
diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c
index 27d06720..bdd1af4e 100644
--- a/frida_mode/src/cmplog/cmplog_x86.c
+++ b/frida_mode/src/cmplog/cmplog_x86.c
@@ -5,6 +5,7 @@
 
 #include "ctx.h"
 #include "frida_cmplog.h"
+#include "instrument.h"
 #include "util.h"
 
 #if defined(__i386__)
@@ -111,10 +112,7 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
   void *ptr1 = GSIZE_TO_POINTER(arg1);
   void *ptr2 = GSIZE_TO_POINTER(arg2);
 
-  uintptr_t k = address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  guint64 k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
 
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 19ec81b2..27704f9b 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -19,6 +19,7 @@
 
 #include "instrument.h"
 #include "ranges.h"
+#include "stalker.h"
 
 #if defined(__x86_64__)
 
@@ -30,6 +31,8 @@
     #endif
   #endif
 
+static GHashTable *coverage_blocks = NULL;
+
 gboolean instrument_is_coverage_optimize_supported(void) {
 
   return true;
@@ -207,6 +210,50 @@ static void instrument_coverage_optimize_map_shm(guint64  shm_env_val,
 
 }
 
+static void instrument_coverage_switch(GumStalkerObserver *self,
+                                       gpointer            start_address,
+                                       const cs_insn *     from_insn,
+                                       gpointer *          target) {
+
+  cs_x86 *   x86;
+  cs_x86_op *op;
+  if (from_insn == NULL) { return; }
+
+  x86 = &from_insn->detail->x86;
+  op = x86->operands;
+
+  if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) {
+
+    return;
+
+  }
+
+  switch (from_insn->id) {
+
+    case X86_INS_CALL:
+    case X86_INS_JMP:
+      if (x86->op_count != 1) {
+
+        FATAL("Unexpected operand count: %d", x86->op_count);
+
+      }
+
+      if (op[0].type != X86_OP_IMM) { return; }
+
+      break;
+    case X86_INS_RET:
+      break;
+    default:
+      return;
+
+  }
+
+  // OKF("SKIP: %p %s %s", start_address, from_insn->mnemonic,
+  // from_insn->op_str);
+  *target = *target + sizeof(afl_log_code);
+
+}
+
 void instrument_coverage_optimize_init(void) {
 
   gpointer low_address = NULL;
@@ -255,6 +302,25 @@ void instrument_coverage_optimize_init(void) {
 
 }
 
+static void instrument_coverage_suppress_init(void) {
+
+  static gboolean initialized = false;
+  if (initialized) { return; }
+  initialized = true;
+
+  GumStalkerObserver *         observer = stalker_get_observer();
+  GumStalkerObserverInterface *iface = GUM_STALKER_OBSERVER_GET_IFACE(observer);
+  iface->switch_callback = instrument_coverage_switch;
+
+  coverage_blocks = g_hash_table_new(g_direct_hash, g_direct_equal);
+  if (coverage_blocks == NULL) {
+
+    FATAL("Failed to g_hash_table_new, errno: %d", errno);
+
+  }
+
+}
+
 void instrument_coverage_optimize(const cs_insn *   instr,
                                   GumStalkerOutput *output) {
 
@@ -263,8 +329,16 @@ void instrument_coverage_optimize(const cs_insn *   instr,
   guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address));
   GumAddress code_addr = 0;
 
+  instrument_coverage_suppress_init();
+
   // gum_x86_writer_put_breakpoint(cw);
   code_addr = cw->pc;
+  if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+
+    FATAL("Failed - g_hash_table_add");
+
+  }
+
   code.code = template;
 
   gssize curr_loc_shr_1_offset =
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index 6f9f05d8..5db62389 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -63,6 +63,12 @@ class Afl {
         Afl.jsApiWrite(STDOUT_FILENO, buf, log.length);
     }
     /**
+     * See `AFL_FRIDA_INST_NO_BACKPATCH`.
+     */
+    static setBackpatchDisable() {
+        Afl.jsApiSetBackpatchDisable();
+    }
+    /**
      * See `AFL_FRIDA_DEBUG_MAPS`.
      */
     static setDebugMaps() {
@@ -267,6 +273,7 @@ Afl.jsApiAddIncludeRange = Afl.jsApiGetFunction("js_api_add_include_range", "voi
 Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing");
 Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []);
 Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]);
+Afl.jsApiSetBackpatchDisable = Afl.jsApiGetFunction("js_api_set_backpatch_disable", "void", []);
 Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []);
 Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]);
 Afl.jsApiSetInstrumentCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_coverage_file", "void", ["pointer"]);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index f3d81a32..abc0ac30 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -237,3 +237,9 @@ __attribute__((visibility("default"))) void js_api_set_traceable(void) {
 
 }
 
+__attribute__((visibility("default"))) void js_api_set_backpatch_disable(void) {
+
+  backpatch_enable = FALSE;
+
+}
+
diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c
index 814aaeb3..6ba41bc6 100644
--- a/frida_mode/src/stalker.c
+++ b/frida_mode/src/stalker.c
@@ -6,7 +6,8 @@
 #include "stats.h"
 #include "util.h"
 
-guint stalker_ic_entries = 0;
+guint    stalker_ic_entries = 0;
+gboolean backpatch_enable = TRUE;
 
 static GumStalker *stalker = NULL;
 
@@ -58,6 +59,8 @@ void stalker_config(void) {
 
   if (!gum_stalker_is_supported()) { FATAL("Failed to initialize embedded"); }
 
+  backpatch_enable = (getenv("AFL_FRIDA_INST_NO_BACKPATCH") == NULL);
+
   stalker_ic_entries = util_read_num("AFL_FRIDA_STALKER_IC_ENTRIES");
 
   observer = g_object_new(GUM_TYPE_AFL_STALKER_OBSERVER, NULL);
@@ -87,6 +90,8 @@ static gboolean stalker_exclude_self(const GumRangeDetails *details,
 
 void stalker_init(void) {
 
+  OKF("Instrumentation - backpatch [%c]", backpatch_enable ? 'X' : ' ');
+
   OKF("Stalker - ic_entries [%u]", stalker_ic_entries);
 
 #if !(defined(__x86_64__) || defined(__i386__))
@@ -134,7 +139,7 @@ void stalker_start(void) {
 
 void stalker_trust(void) {
 
-  gum_stalker_set_trust_threshold(stalker, 0);
+  if (backpatch_enable) { gum_stalker_set_trust_threshold(stalker, 0); }
 
 }