diff options
Diffstat (limited to 'frida_mode/src')
37 files changed, 711 insertions, 1842 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c index b2e763ca..f78f690c 100644 --- a/frida_mode/src/asan/asan.c +++ b/frida_mode/src/asan/asan.c @@ -1,18 +1,18 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "asan.h" -static gboolean asan_enabled = FALSE; -gboolean asan_initialized = FALSE; +gboolean asan_initialized = FALSE; -void asan_config(void) { +void asan_init(void) { if (getenv("AFL_USE_FASAN") != NULL) { OKF("Frida ASAN mode enabled"); - asan_enabled = TRUE; + asan_arch_init(); + asan_initialized = TRUE; } else { @@ -22,14 +22,3 @@ void asan_config(void) { } -void asan_init(void) { - - if (asan_enabled) { - - asan_arch_init(); - asan_initialized = TRUE; - - } - -} - diff --git a/frida_mode/src/asan/asan_arm.c b/frida_mode/src/asan/asan_arm.c new file mode 100644 index 00000000..79475ced --- /dev/null +++ b/frida_mode/src/asan/asan_arm.c @@ -0,0 +1,28 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "asan.h" +#include "util.h" + +#if defined(__arm__) +void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (asan_initialized) { + + FATAL("ASAN mode not supported on this architecture"); + + } + +} + +void asan_arch_init(void) { + + FATAL("ASAN mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c index 65524e03..6262ee18 100644 --- a/frida_mode/src/asan/asan_arm64.c +++ b/frida_mode/src/asan/asan_arm64.c @@ -1,80 +1,18 @@ -#include <dlfcn.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "asan.h" -#include "ctx.h" #include "util.h" #if defined(__aarch64__) - -typedef struct { - - size_t size; - cs_arm64_op operand; - -} asan_ctx_t; - -typedef void (*asan_loadN_t)(gsize address, uint8_t size); -typedef void (*asan_storeN_t)(gsize address, uint8_t size); - -asan_loadN_t asan_loadN = NULL; -asan_storeN_t asan_storeN = NULL; - -static void asan_callout(GumCpuContext *ctx, gpointer user_data) { - - asan_ctx_t * asan_ctx = (asan_ctx_t *)user_data; - cs_arm64_op * operand = &asan_ctx->operand; - arm64_op_mem *mem = &operand->mem; - gsize base = 0; - gsize index = 0; - gsize address; - - if (mem->base != ARM64_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); } - - if (mem->index != ARM64_REG_INVALID) { - - index = ctx_read_reg(ctx, mem->index); - - } - - address = base + index + mem->disp; - - if ((operand->access & CS_AC_READ) == CS_AC_READ) { - - asan_loadN(address, asan_ctx->size); - - } - - if ((operand->access & CS_AC_WRITE) == CS_AC_WRITE) { - - asan_storeN(address, asan_ctx->size); - - } - -} - void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + UNUSED_PARAMETER(instr); UNUSED_PARAMETER(iterator); + if (asan_initialized) { - cs_arm64 arm64 = instr->detail->arm64; - cs_arm64_op *operand; - asan_ctx_t * ctx; - - if (!asan_initialized) return; - - for (uint8_t i = 0; i < arm64.op_count; i++) { - - operand = &arm64.operands[i]; - - if (operand->type != ARM64_OP_MEM) { continue; } - - ctx = g_malloc0(sizeof(asan_ctx_t)); - ctx->size = ctx_get_size(instr, &arm64.operands[0]); - memcpy(&ctx->operand, operand, sizeof(cs_arm64_op)); - gum_stalker_iterator_put_callout(iterator, asan_callout, ctx, g_free); + FATAL("ASAN mode not supported on this architecture"); } @@ -82,13 +20,7 @@ void asan_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { void asan_arch_init(void) { - asan_loadN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_loadN"); - asan_storeN = (asan_loadN_t)dlsym(RTLD_DEFAULT, "__asan_storeN"); - if (asan_loadN == NULL || asan_storeN == NULL) { - - FATAL("Frida ASAN failed to find '__asan_loadN' or '__asan_storeN'"); - - } + FATAL("ASAN mode not supported on this architecture"); } diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c index 5c12669f..a2eabe3c 100644 --- a/frida_mode/src/asan/asan_x64.c +++ b/frida_mode/src/asan/asan_x64.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c index 6d2f9e2b..8490b490 100644 --- a/frida_mode/src/asan/asan_x86.c +++ b/frida_mode/src/asan/asan_x86.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c index a2609c8e..7b11c350 100644 --- a/frida_mode/src/cmplog/cmplog.c +++ b/frida_mode/src/cmplog/cmplog.c @@ -1,32 +1,19 @@ -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include <unistd.h> - -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "util.h" #define DEFAULT_MMAP_MIN_ADDR (32UL << 10) -#define MAX_MEMFD_SIZE (64UL << 10) extern struct cmp_map *__afl_cmp_map; -static GArray * cmplog_ranges = NULL; -static GHashTable * hash_yes = NULL; -static GHashTable * hash_no = NULL; -static long page_size = 0; -static long page_offset_mask = 0; -static long page_mask = 0; +static GArray *cmplog_ranges = NULL; static gboolean cmplog_range(const GumRangeDetails *details, gpointer user_data) { - GArray * cmplog_ranges = (GArray *)user_data; + UNUSED_PARAMETER(user_data); GumMemoryRange range = *details->range; g_array_append_val(cmplog_ranges, range); return TRUE; @@ -40,50 +27,20 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) { } -static void cmplog_get_ranges(void) { - - OKF("CMPLOG - Collecting ranges"); - - cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100); - gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, cmplog_ranges); - g_array_sort(cmplog_ranges, cmplog_sort); - -} - -void cmplog_config(void) { - -} - void cmplog_init(void) { if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } - cmplog_get_ranges(); + cmplog_ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), 100); + gum_process_enumerate_ranges(GUM_PAGE_READ, cmplog_range, NULL); + g_array_sort(cmplog_ranges, cmplog_sort); for (guint i = 0; i < cmplog_ranges->len; i++) { GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); - OKF("CMPLOG Range - %3u: 0x%016" G_GINT64_MODIFIER - "X - 0x%016" G_GINT64_MODIFIER "X", - i, range->base_address, range->base_address + range->size); - - } - - page_size = sysconf(_SC_PAGE_SIZE); - page_offset_mask = page_size - 1; - page_mask = ~(page_offset_mask); - - hash_yes = g_hash_table_new(g_direct_hash, g_direct_equal); - if (hash_yes == NULL) { - - FATAL("Failed to g_hash_table_new, errno: %d", errno); - - } - - hash_no = g_hash_table_new(g_direct_hash, g_direct_equal); - if (hash_no == NULL) { - - FATAL("Failed to g_hash_table_new, errno: %d", errno); + OKF("CMPLOG Range - 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER + "X", + range->base_address, range->base_address + range->size); } @@ -96,45 +53,6 @@ static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit, } -gboolean cmplog_test_addr(guint64 addr, size_t size) { - - if (g_hash_table_contains(hash_yes, GSIZE_TO_POINTER(addr))) { return true; } - if (g_hash_table_contains(hash_no, GSIZE_TO_POINTER(addr))) { return false; } - - void * page_addr = GSIZE_TO_POINTER(addr & page_mask); - size_t page_offset = addr & page_offset_mask; - - /* If it spans a page, then bail */ - if (page_size - page_offset < size) { return false; } - - /* - * Our address map can change (e.g. stack growth), use msync as a fallback to - * validate our address. - */ - if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) { - - if (!g_hash_table_add(hash_no, GSIZE_TO_POINTER(addr))) { - - FATAL("Failed - g_hash_table_add"); - - } - - return false; - - } else { - - if (!g_hash_table_add(hash_yes, GSIZE_TO_POINTER(addr))) { - - FATAL("Failed - g_hash_table_add"); - - } - - return true; - - } - -} - gboolean cmplog_is_readable(guint64 addr, size_t size) { if (cmplog_ranges == NULL) FATAL("CMPLOG not initialized"); @@ -149,26 +67,20 @@ gboolean cmplog_is_readable(guint64 addr, size_t size) { */ if (addr < DEFAULT_MMAP_MIN_ADDR) { return false; } - /* Check our addres/length don't wrap around */ - if (SIZE_MAX - addr < size) { return false; } - GumAddress inner_base = addr; GumAddress inner_limit = inner_base + size; for (guint i = 0; i < cmplog_ranges->len; i++) { GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); - - GumAddress outer_base = range->base_address; - GumAddress outer_limit = outer_base + range->size; + GumAddress outer_base = range->base_address; + GumAddress outer_limit = outer_base + range->size; if (cmplog_contains(inner_base, inner_limit, outer_base, outer_limit)) return true; } - if (cmplog_test_addr(addr, size)) { return true; } - return false; } diff --git a/frida_mode/src/cmplog/cmplog_arm.c b/frida_mode/src/cmplog/cmplog_arm.c new file mode 100644 index 00000000..5af28f3f --- /dev/null +++ b/frida_mode/src/cmplog/cmplog_arm.c @@ -0,0 +1,19 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "frida_cmplog.h" +#include "util.h" + +#if defined(__arm__) +void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } + FATAL("CMPLOG mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c index dd97f38d..187d0162 100644 --- a/frida_mode/src/cmplog/cmplog_arm64.c +++ b/frida_mode/src/cmplog/cmplog_arm64.c @@ -1,304 +1,17 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" -#include "cmplog.h" -#include "ctx.h" #include "frida_cmplog.h" #include "util.h" #if defined(__aarch64__) - -typedef struct { - - arm64_op_type type; - uint8_t size; - - union { - - arm64_op_mem mem; - arm64_reg reg; - int64_t imm; - - }; - -} cmplog_ctx_t; - -typedef struct { - - cmplog_ctx_t operand1; - cmplog_ctx_t operand2; - size_t size; - -} cmplog_pair_ctx_t; - -static gboolean cmplog_read_mem(GumCpuContext *ctx, uint8_t size, - arm64_op_mem *mem, gsize *val) { - - gsize base = 0; - gsize index = 0; - gsize address; - - if (mem->base != ARM64_REG_INVALID) { base = ctx_read_reg(ctx, mem->base); } - - if (mem->index != ARM64_REG_INVALID) { - - index = ctx_read_reg(ctx, mem->index); - - } - - address = base + index + mem->disp; - - if (!cmplog_is_readable(address, size)) { return FALSE; } - - switch (size) { - - case 1: - *val = *((guint8 *)GSIZE_TO_POINTER(address)); - return TRUE; - case 2: - *val = *((guint16 *)GSIZE_TO_POINTER(address)); - return TRUE; - case 4: - *val = *((guint32 *)GSIZE_TO_POINTER(address)); - return TRUE; - case 8: - *val = *((guint64 *)GSIZE_TO_POINTER(address)); - return TRUE; - default: - FATAL("Invalid operand size: %d\n", size); - - } - - return FALSE; - -} - -static gboolean cmplog_get_operand_value(GumCpuContext *context, - cmplog_ctx_t *ctx, gsize *val) { - - switch (ctx->type) { - - case ARM64_OP_REG: - *val = ctx_read_reg(context, ctx->reg); - return TRUE; - case ARM64_OP_IMM: - *val = ctx->imm; - return TRUE; - case ARM64_OP_MEM: - return cmplog_read_mem(context, ctx->size, &ctx->mem, val); - default: - FATAL("Invalid operand type: %d\n", ctx->type); - - } - - return FALSE; - -} - -static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) { - - UNUSED_PARAMETER(user_data); - - gsize address = context->pc; - gsize x0 = ctx_read_reg(context, ARM64_REG_X0); - gsize x1 = ctx_read_reg(context, ARM64_REG_X1); - - if (((G_MAXULONG - x0) < 32) || ((G_MAXULONG - x1) < 32)) return; - - if (!cmplog_is_readable(x0, 32) || !cmplog_is_readable(x1, 32)) return; - - 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; - - __afl_cmp_map->headers[k].type = CMP_TYPE_RTN; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = 31; - - hits &= CMP_MAP_RTN_H - 1; - gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1, - 32); - gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2, - 32); - -} - -static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx, - cs_arm64_op * operand) { - - ctx->type = operand->type; - switch (operand->type) { - - case ARM64_OP_REG: - gum_memcpy(&ctx->reg, &operand->reg, sizeof(arm64_reg)); - break; - case ARM64_OP_IMM: - gum_memcpy(&ctx->imm, &operand->imm, sizeof(int64_t)); - break; - case ARM64_OP_MEM: - gum_memcpy(&ctx->mem, &operand->mem, sizeof(arm64_op_mem)); - break; - default: - FATAL("Invalid operand type: %d\n", operand->type); - - } - -} - -static void cmplog_instrument_call(const cs_insn * instr, - GumStalkerIterator *iterator) { - - cs_arm64 arm64 = instr->detail->arm64; - cs_arm64_op *operand; - - switch (instr->id) { - - case ARM64_INS_BL: - case ARM64_INS_BLR: - case ARM64_INS_BLRAA: - case ARM64_INS_BLRAAZ: - case ARM64_INS_BLRAB: - case ARM64_INS_BLRABZ: - break; - default: - return; - - } - - if (arm64.op_count != 1) return; - - operand = &arm64.operands[0]; - - if (operand->type == ARM64_OP_INVALID) return; - - gum_stalker_iterator_put_callout(iterator, cmplog_call_callout, NULL, NULL); - -} - -static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1, - gsize operand2, uint8_t size) { - - gsize address = context->pc; - - register uintptr_t k = (uintptr_t)address; - - k = (k >> 4) ^ (k << 8); - k &= CMP_MAP_W - 1; - - __afl_cmp_map->headers[k].type = CMP_TYPE_INS; - - u32 hits = __afl_cmp_map->headers[k].hits; - __afl_cmp_map->headers[k].hits = hits + 1; - - __afl_cmp_map->headers[k].shape = (size - 1); - - hits &= CMP_MAP_H - 1; - __afl_cmp_map->log[k][hits].v0 = operand1; - __afl_cmp_map->log[k][hits].v1 = operand2; - -} - -static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) { - - cmplog_pair_ctx_t *ctx = (cmplog_pair_ctx_t *)user_data; - gsize operand1; - gsize operand2; - - if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; } - if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; } - - cmplog_handle_cmp_sub(context, operand1, operand2, ctx->size); - -} - -static void cmplog_instrument_cmp_sub_put_callout(GumStalkerIterator *iterator, - cs_arm64_op * operand1, - cs_arm64_op * operand2, - size_t size) { - - cmplog_pair_ctx_t *ctx = g_malloc(sizeof(cmplog_pair_ctx_t)); - if (ctx == NULL) return; - - cmplog_instrument_put_operand(&ctx->operand1, operand1); - cmplog_instrument_put_operand(&ctx->operand2, operand2); - ctx->size = size; - - gum_stalker_iterator_put_callout(iterator, cmplog_cmp_sub_callout, ctx, - g_free); - -} - -static void cmplog_instrument_cmp_sub(const cs_insn * instr, - GumStalkerIterator *iterator) { - - cs_arm64 arm64 = instr->detail->arm64; - cs_arm64_op *operand1; - cs_arm64_op *operand2; - size_t size; - - switch (instr->id) { - - case ARM64_INS_ADCS: - case ARM64_INS_ADDS: - case ARM64_INS_ANDS: - case ARM64_INS_BICS: - case ARM64_INS_CMN: - case ARM64_INS_CMP: - case ARM64_INS_CMPEQ: - case ARM64_INS_CMPGE: - case ARM64_INS_CMPGT: - case ARM64_INS_CMPHI: - case ARM64_INS_CMPHS: - case ARM64_INS_CMPLE: - case ARM64_INS_CMPLO: - case ARM64_INS_CMPLS: - case ARM64_INS_CMPLT: - case ARM64_INS_CMPNE: - case ARM64_INS_EORS: - case ARM64_INS_NANDS: - case ARM64_INS_NEGS: - case ARM64_INS_NGCS: - case ARM64_INS_NORS: - case ARM64_INS_NOTS: - case ARM64_INS_ORNS: - case ARM64_INS_ORRS: - case ARM64_INS_SBCS: - case ARM64_INS_SUBS: - break; - - default: - return; - - } - - if (arm64.op_count != 2) return; - - operand1 = &arm64.operands[0]; - operand2 = &arm64.operands[1]; - - if (operand1->type == ARM64_OP_INVALID) return; - if (operand2->type == ARM64_OP_INVALID) return; - - size = ctx_get_size(instr, &arm64.operands[0]); - - cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2, size); - -} - void cmplog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) { - if (__afl_cmp_map == NULL) return; - - cmplog_instrument_call(instr, iterator); - cmplog_instrument_cmp_sub(instr, iterator); + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(iterator); + if (__afl_cmp_map == NULL) { return; } + FATAL("CMPLOG mode not supported on this architecture"); } diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c index 0d18767a..9f56c32a 100644 --- a/frida_mode/src/cmplog/cmplog_x64.c +++ b/frida_mode/src/cmplog/cmplog_x64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "cmplog.h" @@ -177,7 +177,7 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1, register uintptr_t k = (uintptr_t)address; k = (k >> 4) ^ (k << 8); - k &= CMP_MAP_W - 7; + k &= CMP_MAP_W - 1; __afl_cmp_map->headers[k].type = CMP_TYPE_INS; @@ -198,6 +198,8 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) { gsize operand1; gsize operand2; + if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch"); + if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; } if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; } @@ -231,15 +233,6 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr, case X86_INS_CMP: case X86_INS_SUB: - case X86_INS_SCASB: - case X86_INS_SCASD: - case X86_INS_SCASQ: - case X86_INS_SCASW: - case X86_INS_CMPSB: - case X86_INS_CMPSD: - case X86_INS_CMPSQ: - case X86_INS_CMPSS: - case X86_INS_CMPSW: break; default: return; @@ -254,8 +247,13 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr, if (operand1->type == X86_OP_INVALID) return; if (operand2->type == X86_OP_INVALID) return; - /* Both operands are the same size */ - if (operand1->size == 1) { return; } + if ((operand1->type == X86_OP_MEM) && + (operand1->mem.segment != X86_REG_INVALID)) + return; + + if ((operand2->type == X86_OP_MEM) && + (operand2->mem.segment != X86_REG_INVALID)) + return; cmplog_instrument_cmp_sub_put_callout(iterator, operand1, operand2); diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c index dd666c34..a27df0af 100644 --- a/frida_mode/src/cmplog/cmplog_x86.c +++ b/frida_mode/src/cmplog/cmplog_x86.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c index da5cb13a..c5900533 100644 --- a/frida_mode/src/ctx/ctx_x64.c +++ b/frida_mode/src/ctx/ctx_x64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -49,18 +49,9 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) { X86_REG_8L(X86_REG_BL, ctx->rbx) X86_REG_8L(X86_REG_CL, ctx->rcx) X86_REG_8L(X86_REG_DL, ctx->rdx) - X86_REG_8L(X86_REG_SPL, ctx->rsp) X86_REG_8L(X86_REG_BPL, ctx->rbp) X86_REG_8L(X86_REG_SIL, ctx->rsi) X86_REG_8L(X86_REG_DIL, ctx->rdi) - X86_REG_8L(X86_REG_R8B, ctx->r8) - X86_REG_8L(X86_REG_R9B, ctx->r9) - X86_REG_8L(X86_REG_R10B, ctx->r10) - X86_REG_8L(X86_REG_R11B, ctx->r11) - X86_REG_8L(X86_REG_R12B, ctx->r12) - X86_REG_8L(X86_REG_R13B, ctx->r13) - X86_REG_8L(X86_REG_R14B, ctx->r14) - X86_REG_8L(X86_REG_R15B, ctx->r15) X86_REG_8H(X86_REG_AH, ctx->rax) X86_REG_8H(X86_REG_BH, ctx->rbx) @@ -71,23 +62,14 @@ gsize ctx_read_reg(GumX64CpuContext *ctx, x86_reg reg) { X86_REG_16(X86_REG_BX, ctx->rbx) X86_REG_16(X86_REG_CX, ctx->rcx) X86_REG_16(X86_REG_DX, ctx->rdx) - X86_REG_16(X86_REG_SP, ctx->rsp) - X86_REG_16(X86_REG_BP, ctx->rbp) X86_REG_16(X86_REG_DI, ctx->rdi) X86_REG_16(X86_REG_SI, ctx->rsi) - X86_REG_16(X86_REG_R8W, ctx->r8) - X86_REG_16(X86_REG_R9W, ctx->r9) - X86_REG_16(X86_REG_R10W, ctx->r10) - X86_REG_16(X86_REG_R11W, ctx->r11) - X86_REG_16(X86_REG_R12W, ctx->r12) - X86_REG_16(X86_REG_R13W, ctx->r13) - X86_REG_16(X86_REG_R14W, ctx->r14) - X86_REG_16(X86_REG_R15W, ctx->r15) + X86_REG_16(X86_REG_BP, ctx->rbp) X86_REG_32(X86_REG_EAX, ctx->rax) - X86_REG_32(X86_REG_EBX, ctx->rbx) X86_REG_32(X86_REG_ECX, ctx->rcx) X86_REG_32(X86_REG_EDX, ctx->rdx) + X86_REG_32(X86_REG_EBX, ctx->rbx) X86_REG_32(X86_REG_ESP, ctx->rsp) X86_REG_32(X86_REG_EBP, ctx->rbp) X86_REG_32(X86_REG_ESI, ctx->rsi) diff --git a/frida_mode/src/ctx/ctx_x86.c b/frida_mode/src/ctx/ctx_x86.c index 1a587702..45308272 100644 --- a/frida_mode/src/ctx/ctx_x86.c +++ b/frida_mode/src/ctx/ctx_x86.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -42,7 +42,6 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { X86_REG_8L(X86_REG_BL, ctx->ebx) X86_REG_8L(X86_REG_CL, ctx->ecx) X86_REG_8L(X86_REG_DL, ctx->edx) - X86_REG_8L(X86_REG_SPL, ctx->esp) X86_REG_8L(X86_REG_BPL, ctx->ebp) X86_REG_8L(X86_REG_SIL, ctx->esi) X86_REG_8L(X86_REG_DIL, ctx->edi) @@ -56,15 +55,14 @@ gsize ctx_read_reg(GumIA32CpuContext *ctx, x86_reg reg) { X86_REG_16(X86_REG_BX, ctx->ebx) X86_REG_16(X86_REG_CX, ctx->ecx) X86_REG_16(X86_REG_DX, ctx->edx) - X86_REG_16(X86_REG_SP, ctx->esp) - X86_REG_16(X86_REG_BP, ctx->ebp) X86_REG_16(X86_REG_DI, ctx->edi) X86_REG_16(X86_REG_SI, ctx->esi) + X86_REG_16(X86_REG_BP, ctx->ebp) X86_REG_32(X86_REG_EAX, ctx->eax) - X86_REG_32(X86_REG_EBX, ctx->ebx) X86_REG_32(X86_REG_ECX, ctx->ecx) X86_REG_32(X86_REG_EDX, ctx->edx) + X86_REG_32(X86_REG_EBX, ctx->ebx) X86_REG_32(X86_REG_ESP, ctx->esp) X86_REG_32(X86_REG_EBP, ctx->ebp) X86_REG_32(X86_REG_ESI, ctx->esi) diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c index a0ffd028..e71386a0 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -1,46 +1,35 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "entry.h" #include "instrument.h" -#include "persistent.h" -#include "ranges.h" #include "stalker.h" -#include "stats.h" #include "util.h" extern void __afl_manual_init(); -guint64 entry_point = 0; -gboolean entry_reached = FALSE; +guint64 entry_start = 0; static void entry_launch(void) { - OKF("Entry point reached"); __afl_manual_init(); /* Child here */ - instrument_on_fork(); - stats_on_fork(); - -} - -void entry_config(void) { - - entry_point = util_read_address("AFL_ENTRYPOINT"); + previous_pc = 0; } void entry_init(void) { - OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point); + entry_start = util_read_address("AFL_ENTRYPOINT"); + OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_start); } -void entry_start(void) { +void entry_run(void) { - if (entry_point == 0) { entry_launch(); } + if (entry_start == 0) { entry_launch(); } } @@ -55,16 +44,6 @@ static void entry_callout(GumCpuContext *cpu_context, gpointer user_data) { void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) { UNUSED_PARAMETER(output); - OKF("AFL_ENTRYPOINT reached"); - - if (persistent_start == 0) { - - entry_reached = TRUE; - ranges_exclude(); - stalker_trust(); - - } - gum_stalker_iterator_put_callout(iterator, entry_callout, NULL, NULL); } diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index 67aafa5a..cd1ac0be 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -1,19 +1,14 @@ #include <unistd.h> -#include <sys/shm.h> -#include <sys/mman.h> -#include <sys/syscall.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" -#include "hash.h" #include "asan.h" #include "entry.h" #include "frida_cmplog.h" #include "instrument.h" -#include "js.h" #include "persistent.h" #include "prefetch.h" #include "ranges.h" @@ -21,55 +16,46 @@ #include "stats.h" #include "util.h" -gboolean instrument_tracing = false; -gboolean instrument_optimize = false; -gboolean instrument_unique = false; -guint64 instrument_hash_zero = 0; -guint64 instrument_hash_seed = 0; - -gboolean instrument_use_fixed_seed = FALSE; -guint64 instrument_fixed_seed = 0; - +static gboolean tracing = false; +static gboolean optimize = false; static GumStalkerTransformer *transformer = NULL; -__thread guint64 instrument_previous_pc = 0; - -static GumAddress previous_rip = 0; -static u8 * edges_notified = NULL; - -static void trace_debug(char *format, ...) { - - va_list ap; - char buffer[4096] = {0}; - int ret; - int len; - - va_start(ap, format); - ret = vsnprintf(buffer, sizeof(buffer) - 1, format, ap); - va_end(ap); - - if (ret < 0) { return; } - - len = strnlen(buffer, sizeof(buffer)); - - IGNORED_RETURN(write(STDOUT_FILENO, buffer, len)); - -} +__thread uint64_t previous_pc = 0; -guint64 instrument_get_offset_hash(GumAddress current_rip) { - - guint64 area_offset = hash64((unsigned char *)¤t_rip, - sizeof(GumAddress), instrument_hash_seed); - return area_offset &= MAP_SIZE - 1; +__attribute__((hot)) static void on_basic_block(GumCpuContext *context, + gpointer user_data) { -} + UNUSED_PARAMETER(context); + /* + * This function is performance critical as it is called to instrument every + * basic block. By moving our print buffer to a global, we avoid it affecting + * the critical path with additional stack adjustments if tracing is not + * enabled. If tracing is enabled, then we're printing a load of diagnostic + * information so this overhead is unlikely to be noticeable. + */ + static char buffer[200]; + int len; + GumAddress current_pc = GUM_ADDRESS(user_data); + uint8_t * cursor; + uint64_t value; + if (unlikely(tracing)) { + + /* Avoid any functions which may cause an allocation since the target app + * may already be running inside malloc and it isn't designed to be + * re-entrant on a single thread */ + len = snprintf(buffer, sizeof(buffer), + "current_pc: 0x%016" G_GINT64_MODIFIER + "x, previous_pc: 0x%016" G_GINT64_MODIFIER "x\n", + current_pc, previous_pc); + + IGNORED_RETURN(write(STDOUT_FILENO, buffer, len + 1)); -__attribute__((hot)) static void instrument_increment_map(GumAddress edge) { + } - uint8_t *cursor; - uint64_t value; + current_pc = (current_pc >> 4) ^ (current_pc << 8); + current_pc &= MAP_SIZE - 1; - cursor = &__afl_area_ptr[edge]; + cursor = &__afl_area_ptr[current_pc ^ previous_pc]; value = *cursor; if (value == 0xff) { @@ -83,47 +69,12 @@ __attribute__((hot)) static void instrument_increment_map(GumAddress edge) { } *cursor = value; + previous_pc = current_pc >> 1; } -__attribute__((hot)) static void on_basic_block(GumCpuContext *context, - gpointer user_data) { - - UNUSED_PARAMETER(context); - - GumAddress current_rip = GUM_ADDRESS(user_data); - guint64 current_pc = instrument_get_offset_hash(current_rip); - guint64 edge; - - edge = current_pc ^ instrument_previous_pc; - - instrument_increment_map(edge); - - if (unlikely(instrument_tracing)) { - - if (!instrument_unique || edges_notified[edge] == 0) { - - trace_debug("TRACE: edge: %10" G_GINT64_MODIFIER - "d, current_rip: 0x%016" G_GINT64_MODIFIER - "x, previous_rip: 0x%016" G_GINT64_MODIFIER "x\n", - edge, current_rip, previous_rip); - - } - - if (instrument_unique) { edges_notified[edge] = 1; } - - previous_rip = current_rip; - - } - - instrument_previous_pc = - ((current_pc & (MAP_SIZE - 1) >> 1)) | ((current_pc & 0x1) << 15); - -} - -static void instrument_basic_block(GumStalkerIterator *iterator, - GumStalkerOutput * output, - gpointer user_data) { +static void instr_basic_block(GumStalkerIterator *iterator, + GumStalkerOutput *output, gpointer user_data) { UNUSED_PARAMETER(user_data); @@ -133,9 +84,7 @@ static void instrument_basic_block(GumStalkerIterator *iterator, while (gum_stalker_iterator_next(iterator, &instr)) { - if (unlikely(begin)) { instrument_debug_start(instr->address, output); } - - if (instr->address == entry_point) { entry_prologue(iterator, output); } + if (instr->address == entry_start) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } if (instr->address == persistent_ret) { persistent_epilogue(output); } @@ -172,15 +121,11 @@ static void instrument_basic_block(GumStalkerIterator *iterator, instrument_debug_start(instr->address, output); - if (likely(entry_reached)) { - - prefetch_write(GSIZE_TO_POINTER(instr->address)); - - } + prefetch_write(GSIZE_TO_POINTER(instr->address)); if (likely(!excluded)) { - if (likely(instrument_optimize)) { + if (likely(optimize)) { instrument_coverage_optimize(instr, output); @@ -193,6 +138,8 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } + begin = FALSE; + } instrument_debug_instruction(instr->address, instr->size); @@ -204,117 +151,38 @@ static void instrument_basic_block(GumStalkerIterator *iterator, } - if (js_stalker_callback(instr, begin, excluded, output)) { - - gum_stalker_iterator_keep(iterator); - - } - - begin = FALSE; + gum_stalker_iterator_keep(iterator); } - instrument_flush(output); instrument_debug_end(output); } -void instrument_config(void) { - - instrument_optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL); - instrument_tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL); - instrument_unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL); - instrument_use_fixed_seed = (getenv("AFL_FRIDA_INST_SEED") != NULL); - instrument_fixed_seed = util_read_num("AFL_FRIDA_INST_SEED"); - - instrument_debug_config(); - asan_config(); - cmplog_config(); - -} - void instrument_init(void) { - if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; + optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL); + tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL); - OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' '); - OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' '); - OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' '); - OKF("Instrumentation - fixed seed [%c] [0x%016" G_GINT64_MODIFIER "x]", - instrument_use_fixed_seed ? 'X' : ' ', instrument_fixed_seed); + if (!instrument_is_coverage_optimize_supported()) optimize = false; - if (instrument_tracing && instrument_optimize) { + OKF("Instrumentation - optimize [%c]", optimize ? 'X' : ' '); + OKF("Instrumentation - tracing [%c]", tracing ? 'X' : ' '); - WARNF("AFL_FRIDA_INST_TRACE implies AFL_FRIDA_INST_NO_OPTIMIZE"); - instrument_optimize = FALSE; - - } + if (tracing && optimize) { - if (instrument_unique && instrument_optimize) { - - WARNF("AFL_FRIDA_INST_TRACE_UNIQUE implies AFL_FRIDA_INST_NO_OPTIMIZE"); - instrument_optimize = FALSE; + FATAL("AFL_FRIDA_INST_OPTIMIZE and AFL_FRIDA_INST_TRACE are incompatible"); } - if (instrument_unique) { instrument_tracing = TRUE; } - if (__afl_map_size != 0x10000) { FATAL("Bad map size: 0x%08x", __afl_map_size); } - transformer = gum_stalker_transformer_make_from_callback( - instrument_basic_block, NULL, NULL); - - if (instrument_unique) { - - int shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600); - if (shm_id < 0) { FATAL("shm_id < 0 - errno: %d\n", errno); } - - edges_notified = shmat(shm_id, NULL, 0); - g_assert(edges_notified != MAP_FAILED); - - /* - * Configure the shared memory region to be removed once the process - * dies. - */ - if (shmctl(shm_id, IPC_RMID, NULL) < 0) { - - FATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno); - - } - - /* Clear it, not sure it's necessary, just seems like good practice */ - memset(edges_notified, '\0', MAP_SIZE); - - } - - if (instrument_use_fixed_seed) { - - /* - * This configuration option may be useful for diagnostics or - * debugging. - */ - instrument_hash_seed = instrument_fixed_seed; - - } else { - - /* - * By using a different seed value for the hash, we can make different - * instances have edge collisions in different places when carrying out - * parallel fuzzing. The seed itself, doesn't have to be random, it - * just needs to be different for each instance. - */ - instrument_hash_seed = g_get_monotonic_time() ^ - (((guint64)getpid()) << 32) ^ syscall(SYS_gettid); - - } - - OKF("Instrumentation - seed [0x%016" G_GINT64_MODIFIER "x]", - instrument_hash_seed); - instrument_hash_zero = instrument_get_offset_hash(0); + transformer = + gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL); instrument_debug_init(); asan_init(); @@ -329,9 +197,3 @@ GumStalkerTransformer *instrument_get_transformer(void) { } -void instrument_on_fork() { - - instrument_previous_pc = instrument_hash_zero; - -} - diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 0e15940a..1a3c40bb 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -22,17 +22,5 @@ void instrument_coverage_optimize(const cs_insn * instr, } -void instrument_flush(GumStalkerOutput *output) { - - gum_arm_writer_flush(output->writer.arm); - -} - -gpointer instrument_cur(GumStalkerOutput *output) { - - return gum_arm_writer_cur(output->writer.arm); - -} - #endif diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index cf37e048..fa3afb48 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" @@ -12,15 +12,15 @@ static GumAddress current_log_impl = GUM_ADDRESS(0); static const guint8 afl_log_code[] = { // __afl_area_ptr[current_pc ^ previous_pc]++; - // previous_pc = current_pc ROR 1; + // previous_pc = current_pc >> 1; 0xE1, 0x0B, 0xBF, 0xA9, // stp x1, x2, [sp, -0x10]! 0xE3, 0x13, 0xBF, 0xA9, // stp x3, x4, [sp, -0x10]! // x0 = current_pc - 0x21, 0x02, 0x00, 0x58, // ldr x1, #0x44, =&__afl_area_ptr + 0xe1, 0x01, 0x00, 0x58, // ldr x1, #0x3c, =&__afl_area_ptr 0x21, 0x00, 0x40, 0xf9, // ldr x1, [x1] (=__afl_area_ptr) - 0x22, 0x02, 0x00, 0x58, // ldr x2, #0x44, =&previous_pc + 0xe2, 0x01, 0x00, 0x58, // ldr x2, #0x3c, =&previous_pc 0x42, 0x00, 0x40, 0xf9, // ldr x2, [x2] (=previous_pc) // __afl_area_ptr[current_pc ^ previous_pc]++; @@ -30,11 +30,8 @@ static const guint8 afl_log_code[] = { 0x63, 0x00, 0x1f, 0x9a, // adc x3, x3, xzr 0x23, 0x68, 0x22, 0xf8, // str x3, [x1, x2] - // previous_pc = current_pc ROR 1; - 0xe4, 0x07, 0x40, 0x8b, // add x4, xzr, x0, LSR #1 - 0xe0, 0xff, 0x00, 0x8b, // add x0, xzr, x0, LSL #63 - 0x80, 0xc0, 0x40, 0x8b, // add x0, x4, x0, LSR #48 - + // previous_pc = current_pc >> 1; + 0xe0, 0x07, 0x40, 0x8b, // add x0, xzr, x0, LSR #1 0xe2, 0x00, 0x00, 0x58, // ldr x2, #0x1c, =&previous_pc 0x40, 0x00, 0x00, 0xf9, // str x0, [x2] @@ -57,7 +54,8 @@ void instrument_coverage_optimize(const cs_insn * instr, GumStalkerOutput *output) { guint64 current_pc = instr->address; - guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); + guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); + area_offset &= MAP_SIZE - 1; GumArm64Writer *cw = output->writer.arm64; if (current_log_impl == 0 || @@ -74,7 +72,7 @@ void instrument_coverage_optimize(const cs_insn * instr, gum_arm64_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); uint8_t **afl_area_ptr_ptr = &__afl_area_ptr; - uint64_t *afl_prev_loc_ptr = &instrument_previous_pc; + uint64_t *afl_prev_loc_ptr = &previous_pc; gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_area_ptr_ptr, sizeof(afl_area_ptr_ptr)); gum_arm64_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr, @@ -95,17 +93,5 @@ void instrument_coverage_optimize(const cs_insn * instr, } -void instrument_flush(GumStalkerOutput *output) { - - gum_arm64_writer_flush(output->writer.arm64); - -} - -gpointer instrument_cur(GumStalkerOutput *output) { - - return gum_arm64_writer_cur(output->writer.arm64); - -} - #endif diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index b8cca634..f8c1df77 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -3,18 +3,15 @@ #include <stdio.h> #include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" -#include "instrument.h" #include "util.h" static int debugging_fd = -1; static gpointer instrument_gen_start = NULL; -char *instrument_debug_filename = NULL; - static void instrument_debug(char *format, ...) { va_list ap; @@ -34,44 +31,24 @@ static void instrument_debug(char *format, ...) { } -static void instrument_disasm(guint8 *start, guint8 *end) { +static void instrument_disasm(guint8 *code, guint size) { csh capstone; cs_err err; - uint16_t size; cs_insn *insn; - size_t count = 0; - size_t i; - uint16_t len; + size_t count, i; err = cs_open(GUM_DEFAULT_CS_ARCH, GUM_DEFAULT_CS_MODE | GUM_DEFAULT_CS_ENDIAN, &capstone); g_assert(err == CS_ERR_OK); - size = GPOINTER_TO_SIZE(end) - GPOINTER_TO_SIZE(start); - - for (guint8 *curr = start; curr < end; curr += len, size -= len, len = 0) { - - count = cs_disasm(capstone, curr, size, GPOINTER_TO_SIZE(curr), 0, &insn); - if (insn == NULL) { - - instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t* 0x%016" G_GSIZE_MODIFIER - "x\n", - curr, *(size_t *)curr); - - len += sizeof(size_t); - continue; - - } - - for (i = 0; i != count; i++) { - - instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t%s %s\n", insn[i].address, - insn[i].mnemonic, insn[i].op_str); + count = cs_disasm(capstone, code, size, GPOINTER_TO_SIZE(code), 0, &insn); + g_assert(insn != NULL); - len += insn[i].size; + for (i = 0; i != count; i++) { - } + instrument_debug("\t0x%" G_GINT64_MODIFIER "x\t%s %s\n", insn[i].address, + insn[i].mnemonic, insn[i].op_str); } @@ -81,25 +58,32 @@ static void instrument_disasm(guint8 *start, guint8 *end) { } -void instrument_debug_config(void) { +static gpointer instrument_cur(GumStalkerOutput *output) { - instrument_debug_filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); +#if defined(__i386__) || defined(__x86_64__) + return gum_x86_writer_cur(output->writer.x86); +#elif defined(__aarch64__) + return gum_arm64_writer_cur(output->writer.arm64); +#elif defined(__arm__) + return gum_arm_writer_cur(output->writer.arm); +#else + #error "Unsupported architecture" +#endif } void instrument_debug_init(void) { - OKF("Instrumentation debugging - enabled [%c]", - instrument_debug_filename == NULL ? ' ' : 'X'); + char *filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); + OKF("Instrumentation debugging - enabled [%c]", filename == NULL ? ' ' : 'X'); - if (instrument_debug_filename == NULL) { return; } + if (filename == NULL) { return; } - OKF("Instrumentation debugging - file [%s]", instrument_debug_filename); + OKF("Instrumentation debugging - file [%s]", filename); - if (instrument_debug_filename == NULL) { return; } + if (filename == NULL) { return; } - char *path = - g_canonicalize_filename(instrument_debug_filename, g_get_current_dir()); + char *path = g_canonicalize_filename(filename, g_get_current_dir()); OKF("Instrumentation debugging - path [%s]", path); @@ -127,7 +111,7 @@ void instrument_debug_instruction(uint64_t address, uint16_t size) { if (likely(debugging_fd < 0)) { return; } uint8_t *start = (uint8_t *)GSIZE_TO_POINTER(address); - instrument_disasm(start, start + size); + instrument_disasm(start, size); } @@ -135,10 +119,11 @@ void instrument_debug_end(GumStalkerOutput *output) { if (likely(debugging_fd < 0)) { return; } gpointer instrument_gen_end = instrument_cur(output); + uint16_t size = GPOINTER_TO_SIZE(instrument_gen_end) - + GPOINTER_TO_SIZE(instrument_gen_start); - instrument_debug("\nGenerated block %p-%p\n", instrument_gen_start, - instrument_gen_end); - instrument_disasm(instrument_gen_start, instrument_gen_end); + instrument_debug("\nGenerated block %p\n", instrument_gen_start); + instrument_disasm(instrument_gen_start, size); } diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index fec8afbb..901f3bd0 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" @@ -10,21 +10,23 @@ static GumAddress current_log_impl = GUM_ADDRESS(0); static const guint8 afl_log_code[] = { + // 0xcc, + 0x9c, /* pushfq */ 0x51, /* push rcx */ 0x52, /* push rdx */ - 0x48, 0x8b, 0x0d, 0x26, + 0x48, 0x8b, 0x0d, 0x28, 0x00, 0x00, 0x00, /* mov rcx, sym.&previous_pc */ 0x48, 0x8b, 0x11, /* mov rdx, qword [rcx] */ 0x48, 0x31, 0xfa, /* xor rdx, rdi */ - 0x48, 0x03, 0x15, 0x11, + 0x48, 0x03, 0x15, 0x13, 0x00, 0x00, 0x00, /* add rdx, sym._afl_area_ptr_ptr */ 0x80, 0x02, 0x01, /* add byte ptr [rdx], 1 */ 0x80, 0x12, 0x00, /* adc byte ptr [rdx], 0 */ - 0x66, 0xd1, 0xcf, /* ror di, 1 */ + 0x48, 0xd1, 0xef, /* shr rdi, 1 */ 0x48, 0x89, 0x39, /* mov qword [rcx], rdi */ 0x5a, /* pop rdx */ @@ -32,8 +34,7 @@ static const guint8 afl_log_code[] = { 0x9d, /* popfq */ 0xc3, /* ret */ - - 0x90 + 0x90, 0x90, 0x90 /* nop pad */ /* Read-only data goes here: */ /* uint8_t* __afl_area_ptr */ @@ -47,11 +48,12 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -static guint8 align_pad[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; - -static void instrument_coverate_write_function(GumStalkerOutput *output) { +void instrument_coverage_optimize(const cs_insn * instr, + GumStalkerOutput *output) { - guint64 misalign = 0; + guint64 current_pc = instr->address; + guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); + area_offset &= MAP_SIZE - 1; GumX86Writer *cw = output->writer.x86; if (current_log_impl == 0 || @@ -63,17 +65,10 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { gum_x86_writer_put_jmp_near_label(cw, after_log_impl); - misalign = (cw->pc & 0x7); - if (misalign != 0) { - - gum_x86_writer_put_bytes(cw, align_pad, 8 - misalign); - - } - current_log_impl = cw->pc; gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); - uint64_t *afl_prev_loc_ptr = &instrument_previous_pc; + uint64_t *afl_prev_loc_ptr = &previous_pc; gum_x86_writer_put_bytes(cw, (const guint8 *)&__afl_area_ptr, sizeof(__afl_area_ptr)); gum_x86_writer_put_bytes(cw, (const guint8 *)&afl_prev_loc_ptr, @@ -83,15 +78,6 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } -} - -void instrument_coverage_optimize(const cs_insn * instr, - GumStalkerOutput *output) { - - GumX86Writer *cw = output->writer.x86; - guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); - instrument_coverate_write_function(output); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -GUM_RED_ZONE_SIZE); gum_x86_writer_put_push_reg(cw, GUM_REG_RDI); @@ -103,17 +89,5 @@ void instrument_coverage_optimize(const cs_insn * instr, } -void instrument_flush(GumStalkerOutput *output) { - - gum_x86_writer_flush(output->writer.x86); - -} - -gpointer instrument_cur(GumStalkerOutput *output) { - - return gum_x86_writer_cur(output->writer.x86); - -} - #endif diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 7bf48f96..585bb5b8 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -16,7 +16,7 @@ static void instrument_coverage_function(GumX86Writer *cw) { gum_x86_writer_put_push_reg(cw, GUM_REG_EDX); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, - GUM_ADDRESS(&instrument_previous_pc)); + GUM_ADDRESS(&previous_pc)); gum_x86_writer_put_mov_reg_reg_ptr(cw, GUM_REG_EDX, GUM_REG_ECX); gum_x86_writer_put_xor_reg_reg(cw, GUM_REG_EDX, GUM_REG_EDI); @@ -30,8 +30,7 @@ static void instrument_coverage_function(GumX86Writer *cw) { uint8_t adc_byte_ptr_edx_0[] = {0x80, 0x12, 0x00}; gum_x86_writer_put_bytes(cw, adc_byte_ptr_edx_0, sizeof(adc_byte_ptr_edx_0)); - uint8_t ror_di_1[] = {0x66, 0xd1, 0xcf}; - gum_x86_writer_put_bytes(cw, ror_di_1, sizeof(ror_di_1)); + gum_x86_writer_put_shr_reg_u8(cw, GUM_REG_EDI, 1); gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_ECX, GUM_REG_EDI); gum_x86_writer_put_pop_reg(cw, GUM_REG_EDX); @@ -47,8 +46,15 @@ gboolean instrument_is_coverage_optimize_supported(void) { } -static void instrument_coverate_write_function(GumStalkerOutput *output) { +void instrument_coverage_optimize(const cs_insn * instr, + GumStalkerOutput *output) { + + UNUSED_PARAMETER(instr); + UNUSED_PARAMETER(output); + guint64 current_pc = instr->address; + guint64 area_offset = (current_pc >> 4) ^ (current_pc << 8); + area_offset &= MAP_SIZE - 1; GumX86Writer *cw = output->writer.x86; if (current_log_impl == 0 || @@ -67,15 +73,7 @@ static void instrument_coverate_write_function(GumStalkerOutput *output) { } -} - -void instrument_coverage_optimize(const cs_insn * instr, - GumStalkerOutput *output) { - - GumX86Writer *cw = output->writer.x86; - guint64 area_offset = instrument_get_offset_hash(GUM_ADDRESS(instr->address)); - instrument_coverate_write_function(output); - + // gum_x86_writer_put_breakpoint(cw); gum_x86_writer_put_push_reg(cw, GUM_REG_EDI); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDI, area_offset); gum_x86_writer_put_call_address(cw, current_log_impl); @@ -83,17 +81,5 @@ void instrument_coverage_optimize(const cs_insn * instr, } -void instrument_flush(GumStalkerOutput *output) { - - gum_x86_writer_flush(output->writer.x86); - -} - -gpointer instrument_cur(GumStalkerOutput *output) { - - return gum_x86_writer_cur(output->writer.x86); - -} - #endif diff --git a/frida_mode/src/interceptor.c b/frida_mode/src/interceptor.c new file mode 100644 index 00000000..d2802752 --- /dev/null +++ b/frida_mode/src/interceptor.c @@ -0,0 +1,35 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "interceptor.h" + +void intercept(void *address, gpointer replacement, gpointer user_data) { + + GumInterceptor *interceptor = gum_interceptor_obtain(); + gum_interceptor_begin_transaction(interceptor); + GumReplaceReturn ret = + gum_interceptor_replace(interceptor, address, replacement, user_data); + if (ret != GUM_REPLACE_OK) { FATAL("gum_interceptor_attach: %d", ret); } + gum_interceptor_end_transaction(interceptor); + +} + +void unintercept(void *address) { + + GumInterceptor *interceptor = gum_interceptor_obtain(); + + gum_interceptor_begin_transaction(interceptor); + gum_interceptor_revert(interceptor, address); + gum_interceptor_end_transaction(interceptor); + gum_interceptor_flush(interceptor); + +} + +void unintercept_self(void) { + + GumInvocationContext *ctx = gum_interceptor_get_current_invocation(); + unintercept(ctx->function); + +} + diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c index 59a3fcf9..13a7d1e7 100644 --- a/frida_mode/src/lib/lib.c +++ b/frida_mode/src/lib/lib.c @@ -6,7 +6,7 @@ #include <sys/mman.h> #include <unistd.h> - #include "frida-gumjs.h" + #include "frida-gum.h" #include "debug.h" @@ -151,10 +151,6 @@ static void lib_get_text_section(lib_details_t *details) { } -void lib_config(void) { - -} - void lib_init(void) { lib_details_t lib_details; diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c index 2aa48a13..8f863861 100644 --- a/frida_mode/src/lib/lib_apple.c +++ b/frida_mode/src/lib/lib_apple.c @@ -1,5 +1,5 @@ #ifdef __APPLE__ - #include "frida-gumjs.h" + #include "frida-gum.h" #include "debug.h" @@ -56,10 +56,6 @@ gboolean lib_get_text_section(const GumDarwinSectionDetails *details, } -void lib_config(void) { - -} - void lib_init(void) { GumDarwinModule *module = NULL; diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c index 91687046..1ab9993f 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -1,5 +1,4 @@ #include <errno.h> -#include <fcntl.h> #include <unistd.h> #include <sys/types.h> @@ -11,15 +10,14 @@ #include <sys/personality.h> #endif -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" #include "entry.h" #include "instrument.h" -#include "intercept.h" -#include "js.h" +#include "interceptor.h" #include "lib.h" #include "output.h" #include "persistent.h" @@ -29,8 +27,6 @@ #include "stats.h" #include "util.h" -#define PROC_MAX 65536 - #ifdef __APPLE__ extern mach_port_t mach_task_self(); extern GumAddress gum_darwin_find_entrypoint(mach_port_t task); @@ -45,6 +41,13 @@ typedef int *(*main_fn_t)(int argc, char **argv, char **envp); static main_fn_t main_fn = NULL; +static int on_fork(void) { + + prefetch_read(); + return fork(); + +} + #ifdef __APPLE__ static void on_main_os(int argc, char **argv, char **envp) { @@ -75,7 +78,7 @@ static void on_main_os(int argc, char **argv, char **envp) { #endif -static void embedded_init(void) { +static void embedded_init() { static gboolean initialized = false; if (!initialized) { @@ -87,117 +90,25 @@ static void embedded_init(void) { } -static void afl_print_cmdline(void) { - - char * buffer = g_malloc0(PROC_MAX); - gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid()); - int fd = open(fname, O_RDONLY); - - if (fd < 0) { - - WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); - return; - - } - - ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1); - if (bytes_read < 0) { - - FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno); - - } - - int idx = 0; - - for (ssize_t i = 0; i < bytes_read; i++) { - - if (i == 0 || buffer[i - 1] == '\0') { - - OKF("AFL - COMMANDLINE: argv[%d] = %s", idx++, &buffer[i]); - - } - - } - - close(fd); - g_free(fname); - g_free(buffer); - -} - -static void afl_print_env(void) { - - char * buffer = g_malloc0(PROC_MAX); - gchar *fname = g_strdup_printf("/proc/%d/environ", getppid()); - int fd = open(fname, O_RDONLY); - - if (fd < 0) { - - WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); - return; - - } - - ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1); - if (bytes_read < 0) { - - FATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno); - - } - - int idx = 0; - - for (ssize_t i = 0; i < bytes_read; i++) { - - if (i == 0 || buffer[i - 1] == '\0') { - - OKF("AFL - ENVIRONMENT %3d: %s", idx++, &buffer[i]); - - } - - } - - close(fd); - g_free(fname); - g_free(buffer); - -} - -__attribute__((visibility("default"))) void afl_frida_start(void) { - - afl_print_cmdline(); - afl_print_env(); - - /* Configure */ - entry_config(); - instrument_config(); - js_config(); - lib_config(); - output_config(); - persistent_config(); - prefetch_config(); - ranges_config(); - stalker_config(); - stats_config(); - - js_start(); - - /* Initialize */ - output_init(); +void afl_frida_start() { embedded_init(); + stalker_init(); + lib_init(); entry_init(); instrument_init(); - lib_init(); + output_init(); persistent_init(); prefetch_init(); - stalker_init(); ranges_init(); stats_init(); - /* Start */ + void *fork_addr = + GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); + intercept(fork_addr, on_fork, NULL); + stalker_start(); - entry_start(); + entry_run(); } @@ -205,7 +116,7 @@ static int *on_main(int argc, char **argv, char **envp) { on_main_os(argc, argv, envp); - intercept_unhook_self(); + unintercept_self(); afl_frida_start(); @@ -219,7 +130,7 @@ extern int *main(int argc, char **argv, char **envp); static void intercept_main(void) { main_fn = main; - intercept_hook(main, on_main, NULL); + intercept(main, on_main, NULL); } @@ -232,7 +143,7 @@ static void intercept_main(void) { OKF("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry); void *main = GSIZE_TO_POINTER(entry); main_fn = main; - intercept_hook(main, on_main, NULL); + intercept(main, on_main, NULL); } @@ -243,8 +154,8 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, void(*stack_end)) { main_fn = main; - intercept_unhook_self(); - intercept_hook(main, on_main, NULL); + unintercept_self(); + intercept(main, on_main, NULL); return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end); @@ -252,7 +163,7 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, static void intercept_main(void) { - intercept_hook(__libc_start_main, on_libc_start_main, NULL); + intercept(__libc_start_main, on_libc_start_main, NULL); } diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c index e2b744e7..8a222b25 100644 --- a/frida_mode/src/output.c +++ b/frida_mode/src/output.c @@ -2,17 +2,17 @@ #include <fcntl.h> #include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" #include "output.h" -char *output_stdout = NULL; -char *output_stderr = NULL; +static int output_fd = -1; -static void output_redirect(int fd, char *filename) { +static void output_redirect(int fd, char *variable) { + char *filename = getenv(variable); char *path = NULL; if (filename == NULL) { return; } @@ -21,8 +21,8 @@ static void output_redirect(int fd, char *filename) { OKF("Redirect %d -> '%s'", fd, path); - int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); g_free(path); @@ -34,24 +34,12 @@ static void output_redirect(int fd, char *filename) { } - close(output_fd); - -} - -void output_config(void) { - - output_stdout = getenv("AFL_FRIDA_OUTPUT_STDOUT"); - output_stderr = getenv("AFL_FRIDA_OUTPUT_STDERR"); - } void output_init(void) { - OKF("Output - StdOut: %s", output_stdout); - OKF("Output - StdErr: %s", output_stderr); - - output_redirect(STDOUT_FILENO, output_stdout); - output_redirect(STDERR_FILENO, output_stderr); + output_redirect(STDOUT_FILENO, "AFL_FRIDA_OUTPUT_STDOUT"); + output_redirect(STDERR_FILENO, "AFL_FRIDA_OUTPUT_STDERR"); } diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 639a694e..2ec5b9cc 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -1,31 +1,30 @@ #include <dlfcn.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" -#include "entry.h" #include "persistent.h" -#include "ranges.h" -#include "stalker.h" #include "util.h" -int __afl_sharedmem_fuzzing = 0; -static char *hook_name = NULL; - -afl_persistent_hook_fn persistent_hook = NULL; +int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; guint64 persistent_ret = 0; +guint64 persistent_ret_offset = 0; gboolean persistent_debug = FALSE; -void persistent_config(void) { +void persistent_init(void) { + + char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); - hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR"); persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT"); persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET"); + persistent_ret_offset = + util_read_address("AFL_FRIDA_PERSISTENT_RETADDR_OFFSET"); if (getenv("AFL_FRIDA_PERSISTENT_DEBUG") != NULL) { persistent_debug = TRUE; } @@ -37,11 +36,6 @@ void persistent_config(void) { } - if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; - - if (persistent_start != 0 && !persistent_is_supported()) - FATAL("Persistent mode not supported on this architecture"); - if (persistent_ret != 0 && persistent_start == 0) { FATAL( @@ -50,28 +44,21 @@ void persistent_config(void) { } - if (hook_name == NULL) { return; } + if (persistent_ret_offset != 0 && persistent_ret == 0) { - void *hook_obj = dlopen(hook_name, RTLD_NOW); - if (hook_obj == NULL) - FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); - - int (*afl_persistent_hook_init_ptr)(void) = - dlsym(hook_obj, "afl_persistent_hook_init"); - if (afl_persistent_hook_init_ptr == NULL) - FATAL("Failed to find afl_persistent_hook_init in %s", hook_name); + FATAL( + "AFL_FRIDA_PERSISTENT_RET must be specified if " + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET is"); - if (afl_persistent_hook_init_ptr() == 0) - FATAL("afl_persistent_hook_init returned a failure"); + } - persistent_hook = - (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); - if (persistent_hook == NULL) - FATAL("Failed to find afl_persistent_hook in %s", hook_name); + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; -} + if (persistent_count != 0 && persistent_count < 100) + WARNF("Persistent count out of recommended range (<100)"); -void persistent_init(void) { + if (persistent_start != 0 && !persistent_is_supported()) + FATAL("Persistent mode not supported on this architecture"); OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); @@ -81,25 +68,30 @@ void persistent_init(void) { OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_ret == 0 ? ' ' : 'X', persistent_ret); + OKF("Instrumentation - persistent ret offset [%c] (%" G_GINT64_MODIFIER "d)", + persistent_ret_offset == 0 ? ' ' : 'X', persistent_ret_offset); - if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; } + if (hook_name != NULL) { -} + void *hook_obj = dlopen(hook_name, RTLD_NOW); + if (hook_obj == NULL) + FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); -void persistent_prologue(GumStalkerOutput *output) { + int (*afl_persistent_hook_init_ptr)(void) = + dlsym(hook_obj, "afl_persistent_hook_init"); + if (afl_persistent_hook_init_ptr == NULL) + FATAL("Failed to find afl_persistent_hook_init in %s", hook_name); - OKF("AFL_FRIDA_PERSISTENT_ADDR reached"); - entry_reached = TRUE; - ranges_exclude(); - stalker_trust(); - persistent_prologue_arch(output); + if (afl_persistent_hook_init_ptr() == 0) + FATAL("afl_persistent_hook_init returned a failure"); -} + hook = (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); + if (hook == NULL) + FATAL("Failed to find afl_persistent_hook in %s", hook_name); -void persistent_epilogue(GumStalkerOutput *output) { + __afl_sharedmem_fuzzing = 1; - OKF("AFL_FRIDA_PERSISTENT_RET reached"); - persistent_epilogue_arch(output); + } } diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 769f1505..6a3c06fa 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -61,14 +61,14 @@ gboolean persistent_is_supported(void) { } -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 3cd61cd5..1215d8da 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -1,383 +1,120 @@ -#include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" #include "instrument.h" -#include "persistent.h" #include "util.h" #if defined(__aarch64__) -typedef struct { - GumCpuContext ctx; - uint64_t rflags; +struct arm64_regs { -} persistent_ctx_t; + uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; -static persistent_ctx_t saved_regs = {0}; -static gpointer saved_lr = NULL; + union { -gboolean persistent_is_supported(void) { - - return true; - -} - -static void instrument_persitent_save_regs(GumArm64Writer * cw, - persistent_ctx_t *regs) { - - GumAddress regs_address = GUM_ADDRESS(regs); - const guint32 mrs_x1_nzcv = 0xd53b4201; - - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), - GUM_INDEX_PRE_ADJUST); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, - ARM64_REG_SP, -(16), - GUM_INDEX_PRE_ADJUST); - - gum_arm64_writer_put_instruction(cw, mrs_x1_nzcv); - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(regs_address)); - - /* Skip x0 & x1 we'll do that later */ - - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0, - offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0, - offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0, - offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0, - offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0, - offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0, - offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0, - offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0, - offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0, - offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0, - offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0, - offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0, - offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0, - offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET); - - /* LR (x30) */ - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0, - offsetof(GumCpuContext, x[30])); - - /* PC & Adjusted SP (31) */ - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, - GUM_ADDRESS(persistent_start)); - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_SP, - (GUM_RED_ZONE_SIZE + 32)); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, offsetof(GumCpuContext, pc), - GUM_INDEX_SIGNED_OFFSET); - - /* CPSR */ - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(persistent_ctx_t, rflags)); - - /* Q */ - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0, - offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, - offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0, - offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0, - offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET); - - /* x0 & x1 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, - ARM64_REG_SP, 16, - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET); - - /* Pop the saved values */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_SP, 16, GUM_INDEX_POST_ADJUST); - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, - GUM_INDEX_POST_ADJUST); - -} - -static void instrument_persitent_restore_regs(GumArm64Writer * cw, - persistent_ctx_t *regs) { - - GumAddress regs_address = GUM_ADDRESS(regs); - const guint32 msr_nzcv_x1 = 0xd51b4201; - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(regs_address)); - - /* Skip x0 - x3 we'll do that last */ - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0, - offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0, - offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0, - offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0, - offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0, - offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0, - offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0, - offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0, - offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0, - offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0, - offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0, - offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0, - offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0, - offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET); - - /* LR (x30) */ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0, - offsetof(GumCpuContext, x[30])); - - /* Adjusted SP (31) (use x1 as clobber)*/ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(GumCpuContext, sp)); - gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_SP, ARM64_REG_X1); - - /* CPSR */ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(persistent_ctx_t, rflags)); - gum_arm64_writer_put_instruction(cw, msr_nzcv_x1); - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0, - offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, - offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0, - offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0, - offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET); - - /* x2 & x3 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET); - /* x0 & x1 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X0, - offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET); - -} - -static void instrument_exit(GumArm64Writer *cw) { + uint64_t x11; + uint32_t fp_32; - gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM64_REG_X0); + }; -} - -static int instrument_afl_persistent_loop_func(void) { + union { - int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; - return ret; + uint64_t x12; + uint32_t ip_32; -} + }; -static void instrument_afl_persistent_loop(GumArm64Writer *cw) { + union { - gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); + uint64_t x13; + uint32_t sp_32; -} + }; -static void persistent_prologue_hook(GumArm64Writer * cw, - persistent_ctx_t *regs) { + union { - if (persistent_hook == NULL) return; + uint64_t x14; + uint32_t lr_32; - gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, - GUM_ADDRESS(&__afl_fuzz_len)); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); + }; - gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2, - G_MAXULONG); + union { - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1, - GUM_ADDRESS(&__afl_fuzz_ptr)); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X1, 0); + uint64_t x15; + uint32_t pc_32; - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, ARM64_REG_X1, GUM_ARG_REGISTER, - ARM64_REG_X2); + }; - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); + union { -} + uint64_t x16; + uint64_t ip0; -static void instrument_persitent_save_lr(GumArm64Writer *cw) { + }; - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), - GUM_INDEX_PRE_ADJUST); + union { - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(&saved_lr)); + uint64_t x17; + uint64_t ip1; - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0); + }; - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, - GUM_INDEX_POST_ADJUST); + uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; -} + union { -void persistent_prologue_arch(GumStalkerOutput *output) { + uint64_t x29; + uint64_t fp; - /* - * SAVE REGS - * SAVE RET - * POP RET - * loop: - * CALL instrument_afl_persistent_loop - * TEST EAX, EAX - * JZ end: - * call hook (optionally) - * RESTORE REGS - * call original - * jmp loop: - * - * end: - * JMP SAVED RET - * - * original: - * INSTRUMENTED PERSISTENT FUNC - */ + }; - GumArm64Writer *cw = output->writer.arm64; + union { - gconstpointer loop = cw->code + 1; + uint64_t x30; + uint64_t lr; - OKF("Persistent loop reached"); + }; - instrument_persitent_save_regs(cw, &saved_regs); + union { - /* loop: */ - gum_arm64_writer_put_label(cw, loop); + uint64_t x31; + uint64_t sp; - /* call instrument_prologue_func */ - instrument_afl_persistent_loop(cw); + }; - /* jz done */ - gconstpointer done = cw->code + 1; - gum_arm64_writer_put_cmp_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); - gum_arm64_writer_put_b_cond_label(cw, ARM64_CC_EQ, done); + // the zero register is not saved here ofc - /* Optionally call the persistent hook */ - persistent_prologue_hook(cw, &saved_regs); + uint64_t pc; - instrument_persitent_restore_regs(cw, &saved_regs); - gconstpointer original = cw->code + 1; - /* call original */ + uint32_t cpsr; - gum_arm64_writer_put_bl_label(cw, original); + uint8_t vfp_zregs[32][16 * 16]; + uint8_t vfp_pregs[17][32]; + uint32_t vfp_xregs[16]; - /* jmp loop */ - gum_arm64_writer_put_b_label(cw, loop); +}; - /* done: */ - gum_arm64_writer_put_label(cw, done); +typedef struct arm64_regs arch_api_regs; - instrument_exit(cw); - - /* original: */ - gum_arm64_writer_put_label(cw, original); - - instrument_persitent_save_lr(cw); +gboolean persistent_is_supported(void) { - if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } + return false; } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { - GumArm64Writer *cw = output->writer.arm64; + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); - if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(&saved_lr)); +} - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0); +void persistent_epilogue(GumStalkerOutput *output) { - gum_arm64_writer_put_br_reg(cw, ARM64_REG_X0); + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index c0bd9a09..4cb960fc 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,5 +1,5 @@ #include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" @@ -10,15 +10,39 @@ #if defined(__x86_64__) -typedef struct { +struct x86_64_regs { - GumCpuContext ctx; - uint64_t rflags; + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; -} persistent_ctx_t; + union { -static persistent_ctx_t saved_regs = {0}; -static gpointer saved_ret = NULL; + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +typedef struct x86_64_regs arch_api_regs; + +static arch_api_regs saved_regs = {0}; gboolean persistent_is_supported(void) { @@ -26,8 +50,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + struct x86_64_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, @@ -39,60 +63,60 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rbx), GUM_REG_RBX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rcx), GUM_REG_RCX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rdx), GUM_REG_RDX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rdi), GUM_REG_RDI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rsi), GUM_REG_RSI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rbp), GUM_REG_RBP); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r8), GUM_REG_R8); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r9), GUM_REG_R9); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r10), GUM_REG_R10); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r11), GUM_REG_R11); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r12), GUM_REG_R12); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r13), GUM_REG_R13); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r14), GUM_REG_R14); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 1), + GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 2), + GUM_REG_RCX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 3), + GUM_REG_RDX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 4), + GUM_REG_RDI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 5), + GUM_REG_RSI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 6), + GUM_REG_RBP); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 7), + GUM_REG_R8); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 8), + GUM_REG_R9); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 9), + GUM_REG_R10); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 10), + GUM_REG_R11); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 11), + GUM_REG_R12); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 12), + GUM_REG_R13); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 13), + GUM_REG_R14); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 14), + GUM_REG_R15); /* Store RIP */ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RBX, GUM_ADDRESS(persistent_start)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 15), + GUM_REG_RBX); /* Store adjusted RSP */ gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP); /* RED_ZONE + Saved flags, RAX, alignment */ gum_x86_writer_put_add_reg_imm(cw, GUM_REG_RBX, - GUM_RED_ZONE_SIZE + (0x8 * 2)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), GUM_REG_RBX); + GUM_RED_ZONE_SIZE + (0x8 * 3)); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 16), + GUM_REG_RBX); /* Save the flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x8); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 17), + GUM_REG_RBX); /* Save the RAX */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x0); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 0), + GUM_REG_RBX); /* Pop the saved values */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10); @@ -102,56 +126,54 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, } -static void instrument_persitent_restore_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + struct x86_64_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RAX, - offsetof(GumCpuContext, rcx)); + (0x8 * 2)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX, - offsetof(GumCpuContext, rdx)); + (0x8 * 3)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX, - offsetof(GumCpuContext, rdi)); + (0x8 * 4)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX, - offsetof(GumCpuContext, rsi)); + (0x8 * 5)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX, - offsetof(GumCpuContext, rbp)); + (0x8 * 6)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX, - offsetof(GumCpuContext, r8)); + (0x8 * 7)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX, - offsetof(GumCpuContext, r9)); + (0x8 * 8)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX, - offsetof(GumCpuContext, r10)); + (0x8 * 9)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX, - offsetof(GumCpuContext, r11)); + (0x8 * 10)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX, - offsetof(GumCpuContext, r12)); + (0x8 * 11)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX, - offsetof(GumCpuContext, r13)); + (0x8 * 12)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX, - offsetof(GumCpuContext, r14)); + (0x8 * 13)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX, - offsetof(GumCpuContext, r15)); + (0x8 * 14)); - /* Don't restore RIP */ - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX, - offsetof(GumCpuContext, rsp)); + /* Don't restore RIP or RSP */ /* Restore RBX, RAX & Flags */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(GumCpuContext, rbx)); + (0x8 * 1)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(GumCpuContext, rax)); + (0x8 * 0)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(persistent_ctx_t, rflags)); + (0x8 * 17)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_popfx(cw); @@ -174,7 +196,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + previous_pc = 0; return ret; } @@ -192,59 +214,35 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { +static void persistent_prologue_hook(GumX86Writer * cw, + struct x86_64_regs *regs) { - if (persistent_hook == NULL) return; + if (hook == NULL) return; gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RCX, GUM_ADDRESS(&__afl_fuzz_len)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0); gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff); - gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI); + gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI); - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, GUM_ADDRESS(&__afl_fuzz_ptr)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RSI, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_RSI, GUM_ARG_REGISTER, - GUM_REG_RDX); + cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, + GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, + GUM_REG_RDX, GUM_ARG_REGISTER, GUM_REG_RCX); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (GUM_RED_ZONE_SIZE)); } -static void instrument_persitent_save_ret(GumX86Writer *cw) { - - /* Stack usage by this function */ - gssize offset = GUM_RED_ZONE_SIZE + (3 * 8); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - -(GUM_RED_ZONE_SIZE)); - - gum_x86_writer_put_pushfx(cw); - gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, - offset); - gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_RAX, GUM_REG_RBX); - - gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_popfx(cw); - - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - (GUM_RED_ZONE_SIZE)); - -} - -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { /* * SAVE REGS @@ -270,13 +268,12 @@ void persistent_prologue_arch(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; - OKF("Persistent loop reached"); - - /* Pop the return value */ - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8); - + /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); + /* pop the return value */ + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (8)); + /* loop: */ gum_x86_writer_put_label(cw, loop); @@ -307,27 +304,21 @@ void persistent_prologue_arch(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); - instrument_persitent_save_ret(cw); - if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); + } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - /* The stack should be aligned when we re-enter our loop */ - gconstpointer zero = cw->code + 1; - gum_x86_writer_put_test_reg_u32(cw, GUM_REG_RSP, 0xF); - gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, zero, GUM_NO_HINT); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -8); - gum_x86_writer_put_label(cw, zero); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_RAX); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + persistent_ret_offset); + gum_x86_writer_put_ret(cw); } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index b911676a..b30dfadf 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -1,23 +1,44 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" -#include "debug.h" #include "instrument.h" #include "persistent.h" #if defined(__i386__) -typedef struct { +struct x86_regs { - GumCpuContext ctx; - uint32_t eflags; + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; -} persistent_ctx_t; + union { -static persistent_ctx_t saved_regs = {0}; + uint32_t eip; + uint32_t pc; -static gpointer saved_ret = NULL; + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +typedef struct x86_regs arch_api_regs; + +static arch_api_regs saved_regs = {0}; gboolean persistent_is_supported(void) { @@ -25,8 +46,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + struct x86_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); @@ -36,80 +57,78 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ebx), GUM_REG_EBX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ecx), GUM_REG_ECX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, edx), GUM_REG_EDX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, edi), GUM_REG_EDI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, esi), GUM_REG_ESI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 1), + GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 2), + GUM_REG_ECX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 3), + GUM_REG_EDX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 4), + GUM_REG_EDI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 5), + GUM_REG_ESI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 6), + GUM_REG_EBP); /* Store RIP */ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX, GUM_ADDRESS(persistent_start)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 7), + GUM_REG_EBX); /* Store adjusted RSP */ gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP); /* RED_ZONE + Saved flags, RAX */ gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 8), + GUM_REG_EBX); /* Save the flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 9), + GUM_REG_EBX); /* Save the RAX */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x0); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 0), + GUM_REG_EBX); /* Pop the saved values */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8); } -static void instrument_persitent_restore_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + struct x86_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX, - offsetof(GumCpuContext, ecx)); + (0x4 * 2)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX, - offsetof(GumCpuContext, edx)); + (0x4 * 3)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX, - offsetof(GumCpuContext, edi)); + (0x4 * 4)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX, - offsetof(GumCpuContext, esi)); + (0x4 * 5)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX, - offsetof(GumCpuContext, ebp)); + (0x4 * 6)); - /* Don't restore RIP */ - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX, - offsetof(GumCpuContext, esp)); + /* Don't restore RIP or RSP */ /* Restore RBX, RAX & Flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(GumCpuContext, ebx)); + (0x4 * 1)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(GumCpuContext, eax)); + (0x4 * 0)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(persistent_ctx_t, eflags)); + (0x4 * 9)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_popfx(cw); @@ -130,7 +149,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + previous_pc = 0; return ret; } @@ -143,9 +162,9 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { +static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { - if (persistent_hook == NULL) return; + if (hook == NULL) return; gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, GUM_ADDRESS(&__afl_fuzz_len)); @@ -158,33 +177,14 @@ static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { /* Base address is 64-bits (hence two zero arguments) */ gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER, + cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 5, GUM_ARG_ADDRESS, + GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS, + GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER, GUM_REG_ECX); } -static void instrument_persitent_save_ret(GumX86Writer *cw) { - - /* Stack usage by this function */ - gssize offset = (3 * 4); - - gum_x86_writer_put_pushfx(cw); - gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, - offset); - gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_EAX, GUM_REG_EBX); - - gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_popfx(cw); - -} - -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { /* * SAVE REGS @@ -210,12 +210,11 @@ void persistent_prologue_arch(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; - OKF("Persistent loop reached"); + /* Stack must be 16-byte aligned per ABI */ + instrument_persitent_save_regs(cw, &saved_regs); /* Pop the return value */ - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4); - - instrument_persitent_save_regs(cw, &saved_regs); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, (4)); /* loop: */ gum_x86_writer_put_label(cw, loop); @@ -245,20 +244,22 @@ void persistent_prologue_arch(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); - instrument_persitent_save_ret(cw); - if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); + } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_EAX); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, + persistent_ret_offset); + + gum_x86_writer_put_ret(cw); } diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 50d10c9e..65c09fba 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -2,11 +2,10 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" -#include "intercept.h" #include "prefetch.h" #include "stalker.h" @@ -21,10 +20,9 @@ typedef struct { } prefetch_data_t; -gboolean prefetch_enable = TRUE; - static prefetch_data_t *prefetch_data = NULL; -static int prefetch_shm_id = -1; + +static int prefetch_shm_id = -1; /* * We do this from the transformer since we need one anyway for coverage, this @@ -74,33 +72,14 @@ void prefetch_read(void) { } -void prefetch_config(void) { - - prefetch_enable = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); - -} - -static int prefetch_on_fork(void) { - - prefetch_read(); - return fork(); - -} - -static void prefetch_hook_fork(void) { - - void *fork_addr = - GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); - intercept_hook(fork_addr, prefetch_on_fork, NULL); - -} - void prefetch_init(void) { g_assert_cmpint(sizeof(prefetch_data_t), ==, PREFETCH_SIZE); - OKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' '); + gboolean prefetch = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); - if (!prefetch_enable) { return; } + OKF("Instrumentation - prefetch [%c]", prefetch ? 'X' : ' '); + + if (!prefetch) { return; } /* * Make our shared memory, we can attach before we fork, just like AFL does * with the coverage bitmap region and fork will take care of ensuring both @@ -129,7 +108,5 @@ void prefetch_init(void) { /* Clear it, not sure it's necessary, just seems like good practice */ memset(prefetch_data, '\0', sizeof(prefetch_data_t)); - prefetch_hook_fork(); - } diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 6fdd65a7..ef25b371 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -17,16 +17,11 @@ typedef struct { } convert_name_ctx_t; -gboolean ranges_debug_maps = FALSE; -gboolean ranges_inst_libs = FALSE; -gboolean ranges_inst_jit = FALSE; - -static GArray *module_ranges = NULL; -static GArray *libs_ranges = NULL; -static GArray *jit_ranges = NULL; -static GArray *include_ranges = NULL; -static GArray *exclude_ranges = NULL; -static GArray *ranges = NULL; +GArray *module_ranges = NULL; +GArray *libs_ranges = NULL; +GArray *include_ranges = NULL; +GArray *exclude_ranges = NULL; +GArray *ranges = NULL; static void convert_address_token(gchar *token, GumMemoryRange *range) { @@ -147,13 +142,11 @@ static void convert_name_token(gchar *token, GumMemoryRange *range) { static void convert_token(gchar *token, GumMemoryRange *range) { - if (g_str_has_prefix(token, "0x")) { + if (g_strrstr(token, "-")) { convert_address_token(token, range); - } - - else { + } else { convert_name_token(token, range); @@ -176,27 +169,19 @@ static gboolean print_ranges_callback(const GumRangeDetails *details, gpointer user_data) { UNUSED_PARAMETER(user_data); - if (details->file == NULL) { - OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER - "X %c%c%c", + OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER "X", details->range->base_address, - details->range->base_address + details->range->size, - details->protection & GUM_PAGE_READ ? 'R' : '-', - details->protection & GUM_PAGE_WRITE ? 'W' : '-', - details->protection & GUM_PAGE_EXECUTE ? 'X' : '-'); + details->range->base_address + details->range->size); } else { OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER - "X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)", + "X %s(0x%016" G_GINT64_MODIFIER "x)", details->range->base_address, details->range->base_address + details->range->size, - details->protection & GUM_PAGE_READ ? 'R' : '-', - details->protection & GUM_PAGE_WRITE ? 'W' : '-', - details->protection & GUM_PAGE_EXECUTE ? 'X' : '-', details->file->path, - details->file->offset); + details->file->path, details->file->offset); } @@ -240,43 +225,6 @@ static GArray *collect_module_ranges(void) { } -static void check_for_overlaps(GArray *array) { - - for (guint i = 1; i < array->len; i++) { - - GumMemoryRange *prev = &g_array_index(array, GumMemoryRange, i - 1); - GumMemoryRange *curr = &g_array_index(array, GumMemoryRange, i); - GumAddress prev_limit = prev->base_address + prev->size; - GumAddress curr_limit = curr->base_address + curr->size; - if (prev_limit > curr->base_address) { - - FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER - "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER - "x-0x%016" G_GINT64_MODIFIER "x", - prev->base_address, prev_limit, curr->base_address, curr_limit); - - } - - } - -} - -void ranges_add_include(GumMemoryRange *range) { - - g_array_append_val(include_ranges, *range); - g_array_sort(include_ranges, range_sort); - check_for_overlaps(include_ranges); - -} - -void ranges_add_exclude(GumMemoryRange *range) { - - g_array_append_val(exclude_ranges, *range); - g_array_sort(exclude_ranges, range_sort); - check_for_overlaps(exclude_ranges); - -} - static GArray *collect_ranges(char *env_key) { char * env_val; @@ -305,7 +253,23 @@ static GArray *collect_ranges(char *env_key) { g_array_sort(result, range_sort); - check_for_overlaps(result); + /* Check for overlaps */ + for (i = 1; i < token_count; i++) { + + GumMemoryRange *prev = &g_array_index(result, GumMemoryRange, i - 1); + GumMemoryRange *curr = &g_array_index(result, GumMemoryRange, i); + GumAddress prev_limit = prev->base_address + prev->size; + GumAddress curr_limit = curr->base_address + curr->size; + if (prev_limit > curr->base_address) { + + FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER + "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER + "x-0x%016" G_GINT64_MODIFIER "x", + prev->base_address, prev_limit, curr->base_address, curr_limit); + + } + + } print_ranges(env_key, result); @@ -321,15 +285,15 @@ static GArray *collect_libs_ranges(void) { GumMemoryRange range; result = g_array_new(false, false, sizeof(GumMemoryRange)); - if (ranges_inst_libs) { + if (getenv("AFL_INST_LIBS") == NULL) { - range.base_address = 0; - range.size = G_MAXULONG; + range.base_address = lib_get_text_base(); + range.size = lib_get_text_limit() - lib_get_text_base(); } else { - range.base_address = lib_get_text_base(); - range.size = lib_get_text_limit() - lib_get_text_base(); + range.base_address = 0; + range.size = G_MAXULONG; } @@ -341,39 +305,6 @@ static GArray *collect_libs_ranges(void) { } -static gboolean collect_jit_ranges_callback(const GumRangeDetails *details, - gpointer user_data) { - - GArray *ranges = (GArray *)user_data; - - /* If the executable code isn't backed by a file, it's probably JIT */ - if (details->file == NULL) { - - GumMemoryRange range = *details->range; - g_array_append_val(ranges, range); - - } - - return TRUE; - -} - -static GArray *collect_jit_ranges(void) { - - GArray *result; - result = g_array_new(false, false, sizeof(GumMemoryRange)); - if (!ranges_inst_jit) { - - gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, collect_jit_ranges_callback, - result); - - } - - print_ranges("JIT", result); - return result; - -} - static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra, GumMemoryRange *rb) { @@ -549,21 +480,30 @@ static GArray *merge_ranges(GArray *a) { } -void ranges_config(void) { +static gboolean exclude_ranges_callback(const GumRangeDetails *details, + gpointer user_data) { - 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; } + UNUSED_PARAMETER(user_data); + gchar * name; + gboolean found; + GumStalker *stalker; + if (details->file == NULL) { return TRUE; } + name = g_path_get_basename(details->file->path); - if (ranges_debug_maps) { + found = (g_strcmp0(name, "afl-frida-trace.so") == 0); + g_free(name); + if (!found) { return TRUE; } - gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, - NULL); + stalker = stalker_get(); + gum_stalker_exclude(stalker, details->range); - } + return FALSE; - include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); - exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); +} + +static void ranges_exclude_self(void) { + + gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, exclude_ranges_callback, NULL); } @@ -574,22 +514,17 @@ void ranges_init(void) { GArray * step2; GArray * step3; GArray * step4; - GArray * step5; - OKF("Ranges - Instrument jit [%c]", ranges_inst_jit ? 'X' : ' '); - OKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' '); + if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { - print_ranges("AFL_FRIDA_INST_RANGES", include_ranges); - print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges); - - OKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' '); + gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, + NULL); - print_ranges("AFL_FRIDA_INST_RANGES", include_ranges); - print_ranges("AFL_FRIDA_EXCLUDE_RANGES", exclude_ranges); + } module_ranges = collect_module_ranges(); libs_ranges = collect_libs_ranges(); - jit_ranges = collect_jit_ranges(); + include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); /* If include ranges is empty, then assume everything is included */ if (include_ranges->len == 0) { @@ -600,6 +535,8 @@ void ranges_init(void) { } + exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); + /* Intersect with .text section of main executable unless AFL_INST_LIBS */ step1 = intersect_ranges(module_ranges, libs_ranges); print_ranges("step1", step1); @@ -612,25 +549,25 @@ void ranges_init(void) { step3 = subtract_ranges(step2, exclude_ranges); print_ranges("step3", step3); - step4 = subtract_ranges(step3, jit_ranges); - print_ranges("step4", step4); - /* - * After step4, we have the total ranges to be instrumented, we now subtract + * After step3, we have the total ranges to be instrumented, we now subtract * that from the original ranges of the modules to configure stalker. */ - step5 = subtract_ranges(module_ranges, step4); - print_ranges("step5", step5); - ranges = merge_ranges(step5); + step4 = subtract_ranges(module_ranges, step3); + print_ranges("step4", step4); + + ranges = merge_ranges(step4); print_ranges("final", ranges); - g_array_free(step5, TRUE); g_array_free(step4, TRUE); g_array_free(step3, TRUE); g_array_free(step2, TRUE); g_array_free(step1, TRUE); + /* *NEVER* stalk the stalker, only bad things will ever come of this! */ + ranges_exclude_self(); + ranges_exclude(); } diff --git a/frida_mode/src/stalker.c b/frida_mode/src/stalker.c index 5df0386f..63f3c529 100644 --- a/frida_mode/src/stalker.c +++ b/frida_mode/src/stalker.c @@ -2,46 +2,17 @@ #include "instrument.h" #include "stalker.h" -#include "util.h" static GumStalker *stalker = NULL; -void stalker_config(void) { +void stalker_init(void) { if (!gum_stalker_is_supported()) { FATAL("Failed to initialize embedded"); } -} - -static gboolean stalker_exclude_self(const GumRangeDetails *details, - gpointer user_data) { - - UNUSED_PARAMETER(user_data); - gchar * name; - gboolean found; - GumStalker *stalker; - if (details->file == NULL) { return TRUE; } - name = g_path_get_basename(details->file->path); - - found = (g_strcmp0(name, "afl-frida-trace.so") == 0); - g_free(name); - if (!found) { return TRUE; } - - stalker = stalker_get(); - gum_stalker_exclude(stalker, details->range); - - return FALSE; - -} - -void stalker_init(void) { - stalker = gum_stalker_new(); if (stalker == NULL) { FATAL("Failed to initialize stalker"); } - gum_stalker_set_trust_threshold(stalker, -1); - - /* *NEVER* stalk the stalker, only bad things will ever come of this! */ - gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, stalker_exclude_self, NULL); + gum_stalker_set_trust_threshold(stalker, 0); } @@ -59,9 +30,3 @@ void stalker_start(void) { } -void stalker_trust(void) { - - gum_stalker_set_trust_threshold(stalker, 0); - -} - diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c index 91a58741..662fb6d5 100644 --- a/frida_mode/src/stats/stats.c +++ b/frida_mode/src/stats/stats.c @@ -5,7 +5,7 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" @@ -17,16 +17,15 @@ stats_data_header_t *stats_data = NULL; -static int stats_parent_pid = -1; -static int stats_fd = -1; +static int stats_parent_pid = -1; +static int stats_fd = -1; +static gboolean stats_transitions = FALSE; +static guint64 stats_interval = 0; -char * stats_filename = NULL; -guint64 stats_interval = 0; -gboolean stats_transitions = FALSE; - -void stats_config(void) { +void stats_init(void) { - stats_filename = getenv("AFL_FRIDA_STATS_FILE"); + stats_parent_pid = getpid(); + char *filename = getenv("AFL_FRIDA_STATS_FILE"); stats_interval = util_read_num("AFL_FRIDA_STATS_INTERVAL"); if (getenv("AFL_FRIDA_STATS_TRANSITIONS") != NULL) { @@ -34,16 +33,10 @@ void stats_config(void) { } -} - -void stats_init(void) { - - stats_parent_pid = getpid(); - - OKF("Stats - file [%s]", stats_filename); + OKF("Stats - file [%s]", filename); OKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval); - if (stats_interval != 0 && stats_filename == NULL) { + if (stats_interval != 0 && filename == NULL) { FATAL( "AFL_FRIDA_STATS_FILE must be specified if " @@ -53,7 +46,7 @@ void stats_init(void) { if (stats_interval == 0) { stats_interval = 10; } - if (stats_filename == NULL) { return; } + if (filename == NULL) { return; } if (!stats_is_supported_arch()) { @@ -63,11 +56,11 @@ void stats_init(void) { char *path = NULL; - if (stats_filename == NULL) { return; } + if (filename == NULL) { return; } if (stats_transitions) { gum_stalker_set_counters_enabled(TRUE); } - path = g_canonicalize_filename(stats_filename, g_get_current_dir()); + path = g_canonicalize_filename(filename, g_get_current_dir()); OKF("Stats - path [%s]", path); @@ -103,6 +96,7 @@ void stats_init(void) { void stats_vprint(int fd, char *format, va_list ap) { char buffer[4096] = {0}; + int ret; int len; if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; } @@ -178,12 +172,10 @@ void stats_write(void) { } -void stats_on_fork(void) { +static void stats_maybe_write(void) { guint64 current_time; - if (stats_filename == NULL) { return; } - if (stats_interval == 0) { return; } current_time = g_get_monotonic_time(); @@ -210,5 +202,7 @@ void stats_collect(const cs_insn *instr, gboolean begin) { stats_collect_arch(instr); + stats_maybe_write(); + } diff --git a/frida_mode/src/stats/stats_arm.c b/frida_mode/src/stats/stats_arm.c new file mode 100644 index 00000000..7eea7f91 --- /dev/null +++ b/frida_mode/src/stats/stats_arm.c @@ -0,0 +1,36 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "stats.h" +#include "util.h" + +#if defined(__arm__) + +gboolean stats_is_supported_arch(void) { + + return FALSE; + +} + +size_t stats_data_size_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_write_arch(void) { + + FATAL("Stats not supported on this architecture"); + +} + +void stats_collect_arch(const cs_insn *instr) { + + UNUSED_PARAMETER(instr); + FATAL("Stats not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/stats/stats_arm64.c b/frida_mode/src/stats/stats_arm64.c index d9d374a4..592af87a 100644 --- a/frida_mode/src/stats/stats_arm64.c +++ b/frida_mode/src/stats/stats_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_x64.c b/frida_mode/src/stats/stats_x64.c index 11464a2a..c3e8742a 100644 --- a/frida_mode/src/stats/stats_x64.c +++ b/frida_mode/src/stats/stats_x64.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -31,9 +31,6 @@ typedef struct { guint64 num_rip_relative; - guint64 num_rip_relative_type[X86_INS_ENDING]; - char name_rip_relative_type[X86_INS_ENDING][CS_MNEMONIC_SIZE]; - } stats_data_arch_t; gboolean stats_is_supported_arch(void) { @@ -139,18 +136,6 @@ void stats_write_arch(void) { stats_data_arch->num_rip_relative, (stats_data_arch->num_rip_relative * 100 / num_instructions)); - for (size_t i = 0; i < X86_INS_ENDING; i++) { - - if (stats_data_arch->num_rip_relative_type[i] != 0) { - - stats_print(" %10d %s\n", - stats_data_arch->num_rip_relative_type[i], - stats_data_arch->name_rip_relative_type[i]); - - } - - } - stats_print("\n"); stats_print("\n"); @@ -271,9 +256,6 @@ static void stats_collect_rip_relative_arch(const cs_insn *instr) { if (rm != 5) { return; } stats_data_arch->num_rip_relative++; - stats_data_arch->num_rip_relative_type[instr->id]++; - memcpy(stats_data_arch->name_rip_relative_type[instr->id], instr->mnemonic, - CS_MNEMONIC_SIZE); } diff --git a/frida_mode/src/stats/stats_x86.c b/frida_mode/src/stats/stats_x86.c index d9c4f652..1906e809 100644 --- a/frida_mode/src/stats/stats_x86.c +++ b/frida_mode/src/stats/stats_x86.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" |