diff options
-rw-r--r-- | frida_mode/GNUmakefile | 2 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x64.c | 74 |
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 = |