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.c5
-rw-r--r--frida_mode/src/cmplog/cmplog_x64.c5
-rw-r--r--frida_mode/src/cmplog/cmplog_x86.c5
-rw-r--r--frida_mode/src/instrument/instrument.c5
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c14
-rw-r--r--frida_mode/src/instrument/instrument_arm64.c30
-rw-r--r--frida_mode/src/instrument/instrument_x64.c10
-rw-r--r--frida_mode/src/instrument/instrument_x86.c12
-rw-r--r--frida_mode/src/js/api.js14
-rw-r--r--frida_mode/src/js/js_api.c14
-rw-r--r--frida_mode/src/ranges.c39
11 files changed, 126 insertions, 27 deletions
diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c
index 5792cbfa..095dc242 100644
--- a/frida_mode/src/cmplog/cmplog_arm64.c
+++ b/frida_mode/src/cmplog/cmplog_arm64.c
@@ -204,10 +204,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
 
   gsize address = context->pc;
 
-  register uintptr_t k = (uintptr_t)address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  register uintptr_t k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
     __afl_cmp_map->headers[k].hits = 0;
diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c
index 17912648..ce6b8681 100644
--- a/frida_mode/src/cmplog/cmplog_x64.c
+++ b/frida_mode/src/cmplog/cmplog_x64.c
@@ -188,10 +188,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
 
   gsize address = ctx_read_reg(context, X86_REG_RIP);
 
-  register uintptr_t k = (uintptr_t)address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 7;
+  register uintptr_t k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
     __afl_cmp_map->headers[k].hits = 0;
diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c
index a3a02457..fa06d611 100644
--- a/frida_mode/src/cmplog/cmplog_x86.c
+++ b/frida_mode/src/cmplog/cmplog_x86.c
@@ -193,10 +193,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
 
   gsize address = ctx_read_reg(context, X86_REG_EIP);
 
-  register uintptr_t k = (uintptr_t)address;
-
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  register uintptr_t k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
   if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
     __afl_cmp_map->headers[k].hits = 0;
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index e1e4ac22..a6aac666 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -27,6 +27,7 @@ gboolean instrument_optimize = false;
 gboolean instrument_unique = false;
 guint64  instrument_hash_zero = 0;
 guint64  instrument_hash_seed = 0;
+gboolean instrument_suppress = false;
 
 gboolean instrument_use_fixed_seed = FALSE;
 guint64  instrument_fixed_seed = 0;
@@ -290,6 +291,7 @@ void instrument_config(void) {
       (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE"));
   instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL);
   instrument_regs_filename = getenv("AFL_FRIDA_INST_REGS_FILE");
+  instrument_suppress = (getenv("AFL_FRIDA_INST_NO_SUPPRESS") == NULL);
 
   instrument_debug_config();
   instrument_coverage_config();
@@ -321,6 +323,9 @@ void instrument_init(void) {
   FOKF(cBLU "Instrumentation" cRST " - " cGRN "instructions:" cYEL " [%c]",
        instrument_coverage_insn ? 'X' : ' ');
 
+  FOKF(cBLU "Instrumentation" cRST " - " cGRN "suppression:" cYEL " [%c]",
+       instrument_suppress ? 'X' : ' ');
+
   if (instrument_tracing && instrument_optimize) {
 
     WARNF("AFL_FRIDA_INST_TRACE implies AFL_FRIDA_INST_NO_OPTIMIZE");
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index cb2a322b..51f78a35 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -273,7 +273,19 @@ void instrument_flush(GumStalkerOutput *output) {
 
 gpointer instrument_cur(GumStalkerOutput *output) {
 
-  return gum_arm_writer_cur(output->writer.arm);
+  gpointer curr = NULL;
+
+  if (output->encoding == GUM_INSTRUCTION_SPECIAL) {
+
+    curr = gum_thumb_writer_cur(output->writer.thumb);
+
+  } else {
+
+    curr = gum_arm_writer_cur(output->writer.arm);
+
+  }
+
+  return curr;
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index c7584a87..4372861d 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -196,6 +196,14 @@ static void instrument_coverage_switch(GumStalkerObserver *self,
   insn = instrument_disassemble(from_insn);
   deterministic = instrument_is_deterministic(insn);
   cs_free(insn, 1);
+
+  /*
+   * If the branch is deterministic, then we should start execution at the
+   * begining of the block. From here, we will branch and skip the coverage
+   * code and jump right to the target code of the instrumented block.
+   * Otherwise, if the branch is non-deterministic, then we need to branch
+   * part way into the block to where the coverage instrumentation starts.
+   */
   if (deterministic) { return; }
 
   /*
@@ -305,7 +313,7 @@ void instrument_coverage_optimize(const cs_insn    *instr,
 
   // gum_arm64_writer_put_brk_imm(cw, 0x0);
 
-  instrument_coverage_suppress_init();
+  if (instrument_suppress) { instrument_coverage_suppress_init(); }
 
   code_addr = cw->pc;
 
@@ -325,9 +333,13 @@ void instrument_coverage_optimize(const cs_insn    *instr,
   block_start =
       GSIZE_TO_POINTER(GUM_ADDRESS(cw->code) - GUM_RESTORATION_PROLOG_SIZE);
 
-  if (!g_hash_table_add(coverage_blocks, block_start)) {
+  if (instrument_suppress) {
+
+    if (!g_hash_table_add(coverage_blocks, block_start)) {
+
+      FATAL("Failed - g_hash_table_add");
 
-    FATAL("Failed - g_hash_table_add");
+    }
 
   }
 
@@ -363,7 +375,17 @@ void instrument_coverage_optimize(const cs_insn    *instr,
 
   code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
 
-  gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+  if (instrument_suppress) {
+
+    gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+
+  } else {
+
+    size_t offset = offsetof(afl_log_code, code.stp_x0_x1);
+    gum_arm64_writer_put_bytes(cw, &code.bytes[offset],
+                               sizeof(afl_log_code) - offset);
+
+  }
 
 }
 
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index f7b7d6c5..8338f8e7 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -380,11 +380,15 @@ void instrument_coverage_optimize(const cs_insn    *instr,
 
   }
 
-  instrument_coverage_suppress_init();
+  if (instrument_suppress) {
 
-  if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+    instrument_coverage_suppress_init();
 
-    FATAL("Failed - g_hash_table_add");
+    if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+
+      FATAL("Failed - g_hash_table_add");
+
+    }
 
   }
 
diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c
index f15893cb..4667ea29 100644
--- a/frida_mode/src/instrument/instrument_x86.c
+++ b/frida_mode/src/instrument/instrument_x86.c
@@ -203,13 +203,17 @@ void instrument_coverage_optimize(const cs_insn    *instr,
 
   code.code = template;
 
-  instrument_coverage_suppress_init();
+  if (instrument_suppress) {
 
-  // gum_x86_writer_put_breakpoint(cw);
+    instrument_coverage_suppress_init();
 
-  if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+    // gum_x86_writer_put_breakpoint(cw);
 
-    FATAL("Failed - g_hash_table_add");
+    if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+
+      FATAL("Failed - g_hash_table_add");
+
+    }
 
   }
 
diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js
index fce7a5d7..a65d32df 100644
--- a/frida_mode/src/js/api.js
+++ b/frida_mode/src/js/api.js
@@ -151,6 +151,12 @@ class Afl {
         Afl.jsApiSetInstrumentLibraries();
     }
     /**
+     * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD`
+     */
+    static setInstrumentNoDynamicLoad() {
+      Afl.jsApiSetInstrumentNoDynamicLoad();
+    }
+    /**
      * See `AFL_FRIDA_INST_NO_OPTIMIZE`
      */
     static setInstrumentNoOptimize() {
@@ -170,6 +176,12 @@ class Afl {
     static setInstrumentSeed(seed) {
         Afl.jsApiSetInstrumentSeed(seed);
     }
+    /*
+     * See `AFL_FRIDA_INST_NO_SUPPRESS`
+     */
+    static setInstrumentSuppressDisable() {
+        Afl.jsApiSetInstrumentSuppressDisable();
+    }
     /**
      * See `AFL_FRIDA_INST_TRACE_UNIQUE`.
      */
@@ -336,9 +348,11 @@ Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_de
 Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []);
 Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []);
 Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []);
+Afl.jsApiSetInstrumentNoDynamicLoad = Afl.jsApiGetFunction("js_api_set_instrument_no_dynamic_load", "void", []);
 Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []);
 Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]);
 Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]);
+Afl.jsApiSetInstrumentSuppressDisable = Afl.jsApiGetFunction("js_api_set_instrument_suppress_disable", "void", []);
 Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []);
 Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []);
 Afl.jsApiSetInstrumentUnstableCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_unstable_coverage_file", "void", ["pointer"]);
diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c
index 01bba4ff..288aec95 100644
--- a/frida_mode/src/js/js_api.c
+++ b/frida_mode/src/js/js_api.c
@@ -156,6 +156,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_instructions(
 
 }
 
+__attribute__((visibility("default"))) void
+js_api_set_instrument_no_dynamic_load(void) {
+
+  ranges_inst_dynamic_load = FALSE;
+
+}
+
 __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize(
     void) {
 
@@ -289,6 +296,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_cache_size(
 
 }
 
+__attribute__((visibility("default"))) void
+js_api_set_instrument_suppress_disable(void) {
+
+  instrument_suppress = false;
+
+}
+
 __attribute__((visibility("default"))) void js_api_set_js_main_hook(
     const js_main_hook_t hook) {
 
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 72cb9730..e9fc3b4e 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -18,6 +18,7 @@ typedef struct {
 gboolean ranges_debug_maps = FALSE;
 gboolean ranges_inst_libs = FALSE;
 gboolean ranges_inst_jit = FALSE;
+gboolean ranges_inst_dynamic_load = TRUE;
 
 static GArray *module_ranges = NULL;
 static GArray *libs_ranges = NULL;
@@ -25,6 +26,7 @@ static GArray *jit_ranges = NULL;
 static GArray *include_ranges = NULL;
 static GArray *exclude_ranges = NULL;
 static GArray *ranges = NULL;
+static GArray *whole_memory_ranges = NULL;
 
 static void convert_address_token(gchar *token, GumMemoryRange *range) {
 
@@ -387,6 +389,21 @@ static GArray *collect_jit_ranges(void) {
 
 }
 
+static GArray *collect_whole_mem_ranges(void) {
+
+  GArray        *result;
+  GumMemoryRange range;
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
+
+  range.base_address = 0;
+  range.size = G_MAXULONG;
+
+  g_array_append_val(result, range);
+
+  return result;
+
+}
+
 static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra,
                                 GumMemoryRange *rb) {
 
@@ -574,11 +591,17 @@ void ranges_config(void) {
   if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; }
   if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; }
   if (getenv("AFL_FRIDA_INST_JIT") != NULL) { ranges_inst_jit = TRUE; }
+  if (getenv("AFL_FRIDA_INST_NO_DYNAMIC_LOAD") != NULL) {
+
+    ranges_inst_dynamic_load = FALSE;
+
+  }
 
   if (ranges_debug_maps) { ranges_print_debug_maps(); }
 
   include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
   exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
+  whole_memory_ranges = collect_whole_mem_ranges();
 
 }
 
@@ -628,10 +651,20 @@ void ranges_init(void) {
   print_ranges("step4", step4);
 
   /*
-   * After step4, we have the total ranges to be instrumented, we now subtract
-   * that from the original ranges of the modules to configure stalker.
+   * After step 4 we have the total ranges to be instrumented, we now subtract
+   * that either from the original ranges of the modules or from the whole
+   * memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker.
    */
-  step5 = subtract_ranges(module_ranges, step4);
+  if (ranges_inst_dynamic_load) {
+
+    step5 = subtract_ranges(module_ranges, step4);
+
+  } else {
+
+    step5 = subtract_ranges(whole_memory_ranges, step4);
+
+  }
+
   print_ranges("step5", step5);
 
   ranges = merge_ranges(step5);