about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2021-11-08 18:17:09 +0000
committerYour Name <you@example.com>2021-11-08 18:17:09 +0000
commit3521268269c49db76157094aa2d8471d6f0f1c1d (patch)
tree9513f414e00efaf0dccf1160e3036ce75a573bb8
parent93b8f17242f6f354da189fee68e69c55288e2488 (diff)
downloadafl++-3521268269c49db76157094aa2d8471d6f0f1c1d.tar.gz
Suppress coverage for deterministic branches
-rw-r--r--frida_mode/GNUmakefile2
-rw-r--r--frida_mode/src/instrument/instrument_x64.c74
2 files changed, 75 insertions, 1 deletions
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile
index b5fee7a6..c0abe14c 100644
--- a/frida_mode/GNUmakefile
+++ b/frida_mode/GNUmakefile
@@ -103,7 +103,7 @@ ifndef OS
  $(error "Operating system unsupported")
 endif
 
-GUM_DEVKIT_VERSION=15.0.16
+GUM_DEVKIT_VERSION=15.1.10
 GUM_DEVKIT_FILENAME=frida-gumjs-devkit-$(GUM_DEVKIT_VERSION)-$(OS)-$(ARCH).tar.xz
 GUM_DEVKIT_URL="https://github.com/frida/frida/releases/download/$(GUM_DEVKIT_VERSION)/$(GUM_DEVKIT_FILENAME)"
 
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 =