diff options
-rw-r--r-- | frida_mode/GNUmakefile | 59 | ||||
-rw-r--r-- | frida_mode/hook/frida_hook.c | 2 | ||||
-rw-r--r-- | frida_mode/src/ctx/ctx_arm32.c | 2 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_arm32.c | 76 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_arm64.c | 35 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x64.c | 39 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_x86.c | 39 | ||||
-rw-r--r-- | frida_mode/src/js/js.c | 8 | ||||
-rw-r--r-- | frida_mode/src/prefetch.c | 1 | ||||
-rw-r--r-- | frida_mode/src/stats/stats_arm32.c | 1 |
10 files changed, 204 insertions, 58 deletions
diff --git a/frida_mode/GNUmakefile b/frida_mode/GNUmakefile index 39c96d5b..9f2bcd42 100644 --- a/frida_mode/GNUmakefile +++ b/frida_mode/GNUmakefile @@ -57,7 +57,10 @@ ifdef DEBUG CFLAGS+=-Werror \ -Wall \ -Wextra \ - -Wpointer-arith + -Wpointer-arith \ + -Wno-unknown-pragmas \ + -Wno-pointer-to-int-cast \ + -Wno-int-to-pointer-cast else CFLAGS+=-Wno-pointer-arith endif @@ -142,7 +145,7 @@ ifndef OS $(error "Operating system unsupported") endif -GUM_DEVKIT_VERSION=15.2.1 +GUM_DEVKIT_VERSION=16.0.1 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)" @@ -206,7 +209,7 @@ $(FRIDA_MAKEFILE): | $(BUILD_DIR) .PHONY: $(GUM_DEVIT_LIBRARY) $(GUM_DEVIT_LIBRARY): $(FRIDA_MAKEFILE) - cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH) + cd $(FRIDA_DIR) && make gum-$(OS)$(GUM_ARCH) FRIDA_V8=disabled $(GUM_DEVIT_HEADER): $(FRIDA_MAKEFILE) | $(FRIDA_BUILD_DIR) echo "#include <stdio.h>" > $@ @@ -245,40 +248,40 @@ TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ else ifeq "$(ARCH)" "arm64" -CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ +CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ ifeq "$(OS)" "android" CFLAGS += -static-libstdc++ endif else -CFLAGS+=-I $(FRIDA_DIR)build/frida_thin-$(OS)-$(ARCH)/include/frida-1.0 \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/capstone/ \ - -I $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ +CFLAGS+=-I $(FRIDA_DIR)build/$(OS)-$(ARCH)/include/frida-1.0 \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/glib-2.0/include/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/capstone/ \ + -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/json-glib-1.0/ \ endif TRACE_LDFLAGS+=$(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/lib/libfrida-gum-1.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libtcc.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libunwind.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libffi.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libelf.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/liblzma.a \ - $(FRIDA_DIR)build/frida_thin-sdk-$(OS)-$(ARCH)/lib/libz.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsoup-2.4.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libsqlite3.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libtcc.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libjson-glib-1.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libquickjs.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libcapstone.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libunwind.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libffi.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libdwarf.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libelf.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgio-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libgobject-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libglib-2.0.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/liblzma.a \ + $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/lib/libz.a \ CFLAGS+=-I $(FRIDA_DIR)build/frida-$(OS)-$(ARCH)/include/frida-1.0 \ -I $(FRIDA_DIR)build/sdk-$(OS)-$(ARCH)/include/glib-2.0/ \ diff --git a/frida_mode/hook/frida_hook.c b/frida_mode/hook/frida_hook.c index 79e2348d..da1a59b2 100644 --- a/frida_mode/hook/frida_hook.c +++ b/frida_mode/hook/frida_hook.c @@ -54,10 +54,12 @@ __attribute__((visibility("default"))) void afl_persistent_hook( __attribute__((visibility("default"))) void afl_persistent_hook( GumCpuContext *regs, uint8_t *input_buf, uint32_t input_buf_len) { + // do a length check matching the target! memcpy((void *)regs->r[0], input_buf, input_buf_len); regs->r[1] = input_buf_len; + } #else diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c index 28fc706b..0e5b25a4 100644 --- a/frida_mode/src/ctx/ctx_arm32.c +++ b/frida_mode/src/ctx/ctx_arm32.c @@ -7,6 +7,8 @@ gsize ctx_read_reg(GumArmCpuContext *ctx, arm_reg reg) { + UNUSED_PARAMETER(ctx); + UNUSED_PARAMETER(reg); FFATAL("ctx_read_reg unimplemented for this architecture"); } diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index f2e825ee..cb2a322b 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -1,6 +1,7 @@ #include "frida-gumjs.h" #include "instrument.h" +#include "stalker.h" #include "util.h" #if defined(__arm__) @@ -8,8 +9,9 @@ #define PAGE_MASK (~(GUM_ADDRESS(0xfff))) #define PAGE_ALIGNED(x) ((GUM_ADDRESS(x) & PAGE_MASK) == GUM_ADDRESS(x)) -gboolean instrument_cache_enabled = FALSE; -gsize instrument_cache_size = 0; +gboolean instrument_cache_enabled = FALSE; +gsize instrument_cache_size = 0; +static GHashTable *coverage_blocks = NULL; extern __thread guint64 instrument_previous_pc; @@ -22,7 +24,24 @@ typedef struct { // shared_mem[cur_location ^ prev_location]++; // prev_location = cur_location >> 1; - /* We can remove this branch when we add support for branch suppression */ + // str r0, [sp, #-128] ; 0xffffff80 + // str r1, [sp, #-132] ; 0xffffff7c + // ldr r0, [pc, #-20] ; 0xf691b29c + // ldrh r1, [r0] + // movw r0, #33222 ; 0x81c6 + // eor r0, r0, r1 + // ldr r1, [pc, #-40] ; 0xf691b298 + // add r1, r1, r0 + // ldrb r0, [r1] + // add r0, r0, #1 + // add r0, r0, r0, lsr #8 + // strb r0, [r1] + // movw r0, #49379 ; 0xc0e3 + // ldr r1, [pc, #-64] ; 0xf691b29c + // strh r0, [r1] + // ldr r1, [sp, #-132] ; 0xffffff7c + // ldr r0, [sp, #-128] ; 0xffffff80 + uint32_t b_code; /* b imm */ uint8_t *shared_mem; uint64_t *prev_location; @@ -115,6 +134,46 @@ gboolean instrument_is_coverage_optimize_supported(void) { } +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer from_address, + gpointer start_address, void *from_insn, + gpointer *target) { + + UNUSED_PARAMETER(self); + UNUSED_PARAMETER(from_address); + UNUSED_PARAMETER(start_address); + UNUSED_PARAMETER(from_insn); + + if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) { + + return; + + } + + *target = + (guint8 *)*target + G_STRUCT_OFFSET(afl_log_code_asm_t, str_r0_sp_rz); + +} + +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); + + } + +} + static void patch_t3_insn(uint32_t *insn, uint16_t val) { uint32_t orig = GUINT32_FROM_LE(*insn); @@ -135,14 +194,17 @@ void instrument_coverage_optimize(const cs_insn *instr, guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); gsize map_size_pow2; gsize area_offset_ror; - GumAddress code_addr = 0; - - // gum_arm64_writer_put_brk_imm(cw, 0x0); - code_addr = cw->pc; + instrument_coverage_suppress_init(); block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code)); + if (!g_hash_table_add(coverage_blocks, block_start)) { + + FATAL("Failed - g_hash_table_add"); + + } + code.code = template; g_assert(PAGE_ALIGNED(__afl_area_ptr)); diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 87811b38..c7584a87 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -156,26 +156,47 @@ static gboolean instrument_is_deterministic(const cs_insn *from_insn) { } +cs_insn *instrument_disassemble(gconstpointer address) { + + csh capstone; + cs_insn *insn = NULL; + + cs_open(CS_ARCH_ARM64, GUM_DEFAULT_CS_ENDIAN, &capstone); + cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON); + + cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn); + + cs_close(&capstone); + + return insn; + +} + static void instrument_coverage_switch(GumStalkerObserver *self, gpointer from_address, - gpointer start_address, - const cs_insn *from_insn, - gpointer *target) { + gpointer start_address, void *from_insn, + gpointer *target) { UNUSED_PARAMETER(self); UNUSED_PARAMETER(from_address); UNUSED_PARAMETER(start_address); - gsize fixup_offset; + cs_insn *insn = NULL; + gboolean deterministic = FALSE; + gsize fixup_offset; if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target)) && - !g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target + 4))) { + !g_hash_table_contains(coverage_blocks, + GSIZE_TO_POINTER((guint8 *)*target + 4))) { return; } - if (instrument_is_deterministic(from_insn)) { return; } + insn = instrument_disassemble(from_insn); + deterministic = instrument_is_deterministic(insn); + cs_free(insn, 1); + if (deterministic) { return; } /* * Since each block is prefixed with a restoration prologue, we need to be @@ -208,7 +229,7 @@ static void instrument_coverage_switch(GumStalkerObserver *self, */ fixup_offset = GUM_RESTORATION_PROLOG_SIZE + G_STRUCT_OFFSET(afl_log_code_asm_t, restoration_prolog); - *target += fixup_offset; + *target = (guint8 *)*target + fixup_offset; } diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 13ced4a3..f7b7d6c5 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -171,11 +171,11 @@ void instrument_coverage_optimize_init(void) { } -static void instrument_coverage_switch(GumStalkerObserver *self, - gpointer from_address, - gpointer start_address, - const cs_insn *from_insn, - gpointer *target) { +static void instrument_coverage_switch_insn(GumStalkerObserver *self, + gpointer from_address, + gpointer start_address, + const cs_insn *from_insn, + gpointer *target) { UNUSED_PARAMETER(self); UNUSED_PARAMETER(from_address); @@ -224,6 +224,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self, } +cs_insn *instrument_disassemble(gconstpointer address) { + + csh capstone; + cs_insn *insn = NULL; + + cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone); + cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON); + + cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn); + + cs_close(&capstone); + + return insn; + +} + +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer from_address, + gpointer start_address, void *from_insn, + gpointer *target) { + + if (from_insn == NULL) { return; } + cs_insn *insn = instrument_disassemble(from_insn); + instrument_coverage_switch_insn(self, from_address, start_address, insn, + target); + cs_free(insn, 1); + +} + static void instrument_coverage_suppress_init(void) { static gboolean initialized = false; diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index eabd5be4..f15893cb 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -83,11 +83,11 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -static void instrument_coverage_switch(GumStalkerObserver *self, - gpointer from_address, - gpointer start_address, - const cs_insn *from_insn, - gpointer *target) { +static void instrument_coverage_switch_insn(GumStalkerObserver *self, + gpointer from_address, + gpointer start_address, + const cs_insn *from_insn, + gpointer *target) { UNUSED_PARAMETER(self); UNUSED_PARAMETER(from_address); @@ -130,6 +130,35 @@ static void instrument_coverage_switch(GumStalkerObserver *self, } +cs_insn *instrument_disassemble(gconstpointer address) { + + csh capstone; + cs_insn *insn = NULL; + + cs_open(CS_ARCH_X86, GUM_CPU_MODE, &capstone); + cs_option(capstone, CS_OPT_DETAIL, CS_OPT_ON); + + cs_disasm(capstone, address, 16, GPOINTER_TO_SIZE(address), 1, &insn); + + cs_close(&capstone); + + return insn; + +} + +static void instrument_coverage_switch(GumStalkerObserver *self, + gpointer from_address, + gpointer start_address, void *from_insn, + gpointer *target) { + + if (from_insn == NULL) { return; } + cs_insn *insn = instrument_disassemble(from_insn); + instrument_coverage_switch_insn(self, from_address, start_address, insn, + target); + cs_free(insn, 1); + +} + static void instrument_coverage_suppress_init(void) { static gboolean initialized = false; diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c index 6bc31864..25187694 100644 --- a/frida_mode/src/js/js.c +++ b/frida_mode/src/js/js.c @@ -18,10 +18,8 @@ static GumScriptScheduler *scheduler; static GMainContext *context; static GMainLoop *main_loop; -static void js_msg(GumScript *script, const gchar *message, GBytes *data, - gpointer user_data) { +static void js_msg(const gchar *message, GBytes *data, gpointer user_data) { - UNUSED_PARAMETER(script); UNUSED_PARAMETER(data); UNUSED_PARAMETER(user_data); FOKF("%s", message); @@ -124,8 +122,8 @@ void js_start(void) { main_loop = g_main_loop_new(context, true); g_main_context_push_thread_default(context); - gum_script_backend_create(backend, "example", source, cancellable, create_cb, - &error); + gum_script_backend_create(backend, "example", source, NULL, cancellable, + create_cb, &error); while (g_main_context_pending(context)) g_main_context_iteration(context, FALSE); diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 905e0ae9..f093cd53 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -29,7 +29,6 @@ gboolean prefetch_enable = TRUE; gboolean prefetch_backpatch = TRUE; static prefetch_data_t *prefetch_data = NULL; -static int prefetch_shm_id = -1; static GHashTable *cant_prefetch = NULL; diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c index bd652aa3..6c72a476 100644 --- a/frida_mode/src/stats/stats_arm32.c +++ b/frida_mode/src/stats/stats_arm32.c @@ -13,6 +13,7 @@ void starts_arch_init(void) { void stats_write_arch(stats_data_t *data) { + UNUSED_PARAMETER(data); FFATAL("Stats not supported on this architecture"); } |