diff options
Diffstat (limited to 'frida_mode/src')
42 files changed, 1283 insertions, 728 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c index f78f690c..b2e763ca 100644 --- a/frida_mode/src/asan/asan.c +++ b/frida_mode/src/asan/asan.c @@ -1,18 +1,18 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "asan.h" -gboolean asan_initialized = FALSE; +static gboolean asan_enabled = FALSE; +gboolean asan_initialized = FALSE; -void asan_init(void) { +void asan_config(void) { if (getenv("AFL_USE_FASAN") != NULL) { OKF("Frida ASAN mode enabled"); - asan_arch_init(); - asan_initialized = TRUE; + asan_enabled = TRUE; } else { @@ -22,3 +22,14 @@ void asan_init(void) { } +void asan_init(void) { + + if (asan_enabled) { + + asan_arch_init(); + asan_initialized = TRUE; + + } + +} + diff --git a/frida_mode/src/asan/asan_arm32.c b/frida_mode/src/asan/asan_arm32.c index 79475ced..f5fa4713 100644 --- a/frida_mode/src/asan/asan_arm32.c +++ b/frida_mode/src/asan/asan_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_arm64.c b/frida_mode/src/asan/asan_arm64.c index 66138e42..65524e03 100644 --- a/frida_mode/src/asan/asan_arm64.c +++ b/frida_mode/src/asan/asan_arm64.c @@ -1,5 +1,5 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_x64.c b/frida_mode/src/asan/asan_x64.c index a2eabe3c..5c12669f 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-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/asan/asan_x86.c b/frida_mode/src/asan/asan_x86.c index 8490b490..6d2f9e2b 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-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/cmplog/cmplog.c b/frida_mode/src/cmplog/cmplog.c index 3df7d13d..a2609c8e 100644 --- a/frida_mode/src/cmplog/cmplog.c +++ b/frida_mode/src/cmplog/cmplog.c @@ -1,27 +1,32 @@ #include <errno.h> #include <fcntl.h> #include <limits.h> -#include <syscall.h> +#include <sys/mman.h> +#include <sys/syscall.h> +#include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "util.h" #define DEFAULT_MMAP_MIN_ADDR (32UL << 10) -#define FD_TMP_MAX_SIZE 65536 +#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 GArray *cmplog_ranges = NULL; -static int fd_tmp = -1; -static ssize_t fd_tmp_size = 0; +static long page_size = 0; +static long page_offset_mask = 0; +static long page_mask = 0; static gboolean cmplog_range(const GumRangeDetails *details, gpointer user_data) { - UNUSED_PARAMETER(user_data); + GArray * cmplog_ranges = (GArray *)user_data; GumMemoryRange range = *details->range; g_array_append_val(cmplog_ranges, range); return TRUE; @@ -35,70 +40,98 @@ static gint cmplog_sort(gconstpointer a, gconstpointer b) { } -static int cmplog_create_temp(void) { +static void cmplog_get_ranges(void) { - const char *tmpdir = g_get_tmp_dir(); - OKF("CMPLOG Temporary directory: %s", tmpdir); - gchar *fname = g_strdup_printf("%s/frida-cmplog-XXXXXX", tmpdir); - OKF("CMPLOG Temporary file template: %s", fname); - int fd = mkstemp(fname); - OKF("CMPLOG Temporary file: %s", fname); + OKF("CMPLOG - Collecting ranges"); - if (fd < 0) { + 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); - FATAL("Failed to create temp file: %s, errno: %d", fname, errno); +} - } +void cmplog_config(void) { - if (unlink(fname) < 0) { +} + +void cmplog_init(void) { - FATAL("Failed to unlink temp file: %s (%d), errno: %d", fname, fd, errno); + if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } + + cmplog_get_ranges(); + + 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); } - if (ftruncate(fd, 0) < 0) { + 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 ftruncate temp file: %s (%d), errno: %d", fname, fd, - errno); + FATAL("Failed to g_hash_table_new, errno: %d", errno); } - g_free(fname); + 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); - return fd; + } } -void cmplog_init(void) { +static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit, + GumAddress outer_base, GumAddress outer_limit) { - if (__afl_cmp_map != NULL) { OKF("CMPLOG mode enabled"); } + return (inner_base >= outer_base && inner_limit <= outer_limit); - 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++) { +gboolean cmplog_test_addr(guint64 addr, size_t size) { - GumMemoryRange *range = &g_array_index(cmplog_ranges, GumMemoryRange, i); - OKF("CMPLOG Range - 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER - "X", - range->base_address, range->base_address + range->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; } /* - * We can't use /dev/null or /dev/zero for this since it appears that they - * don't validate the input buffer. Persumably as an optimization because they - * don't actually write any data. The file will be deleted on close. + * Our address map can change (e.g. stack growth), use msync as a fallback to + * validate our address. */ - fd_tmp = cmplog_create_temp(); + if (msync(page_addr, page_offset + size, MS_ASYNC) < 0) { -} + if (!g_hash_table_add(hash_no, GSIZE_TO_POINTER(addr))) { -static gboolean cmplog_contains(GumAddress inner_base, GumAddress inner_limit, - GumAddress outer_base, GumAddress outer_limit) { + FATAL("Failed - g_hash_table_add"); - return (inner_base >= outer_base && inner_limit <= outer_limit); + } + + return false; + + } else { + + if (!g_hash_table_add(hash_yes, GSIZE_TO_POINTER(addr))) { + + FATAL("Failed - g_hash_table_add"); + + } + + return true; + + } } @@ -125,45 +158,16 @@ gboolean cmplog_is_readable(guint64 addr, size_t 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; } - /* - * Our address map can change (e.g. stack growth), use write as a fallback to - * validate our address. - */ - ssize_t written = syscall(__NR_write, fd_tmp, (void *)addr, size); - - /* - * If the write succeeds, then the buffer must be valid otherwise it would - * return EFAULT - */ - if (written > 0) { - - fd_tmp_size += written; - if (fd_tmp_size > FD_TMP_MAX_SIZE) { - - /* - * Truncate the file, we don't want our temp file to continue growing! - */ - if (ftruncate(fd_tmp, 0) < 0) { - - FATAL("Failed to truncate fd_tmp (%d), errno: %d", fd_tmp, errno); - - } - - fd_tmp_size = 0; - - } - - if ((size_t)written == size) { return true; } - - } + if (cmplog_test_addr(addr, size)) { return true; } return false; diff --git a/frida_mode/src/cmplog/cmplog_arm32.c b/frida_mode/src/cmplog/cmplog_arm32.c index 5af28f3f..ac703408 100644 --- a/frida_mode/src/cmplog/cmplog_arm32.c +++ b/frida_mode/src/cmplog/cmplog_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/cmplog/cmplog_arm64.c b/frida_mode/src/cmplog/cmplog_arm64.c index 04631ff8..dd97f38d 100644 --- a/frida_mode/src/cmplog/cmplog_arm64.c +++ b/frida_mode/src/cmplog/cmplog_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/cmplog/cmplog_x64.c b/frida_mode/src/cmplog/cmplog_x64.c index 9f56c32a..0d18767a 100644 --- a/frida_mode/src/cmplog/cmplog_x64.c +++ b/frida_mode/src/cmplog/cmplog_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.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 - 1; + k &= CMP_MAP_W - 7; __afl_cmp_map->headers[k].type = CMP_TYPE_INS; @@ -198,8 +198,6 @@ 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; } @@ -233,6 +231,15 @@ 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; @@ -247,13 +254,8 @@ static void cmplog_instrument_cmp_sub(const cs_insn * instr, if (operand1->type == X86_OP_INVALID) return; if (operand2->type == X86_OP_INVALID) 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; + /* Both operands are the same size */ + if (operand1->size == 1) { 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 a27df0af..dd666c34 100644 --- a/frida_mode/src/cmplog/cmplog_x86.c +++ b/frida_mode/src/cmplog/cmplog_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "cmplog.h" diff --git a/frida_mode/src/ctx/ctx_arm32.c b/frida_mode/src/ctx/ctx_arm32.c index a5c6f6d4..a354c117 100644 --- a/frida_mode/src/ctx/ctx_arm32.c +++ b/frida_mode/src/ctx/ctx_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/ctx/ctx_arm64.c b/frida_mode/src/ctx/ctx_arm64.c index d09896af..a735401b 100644 --- a/frida_mode/src/ctx/ctx_arm64.c +++ b/frida_mode/src/ctx/ctx_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/ctx/ctx_x64.c b/frida_mode/src/ctx/ctx_x64.c index c5900533..da5cb13a 100644 --- a/frida_mode/src/ctx/ctx_x64.c +++ b/frida_mode/src/ctx/ctx_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -49,9 +49,18 @@ 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) @@ -62,14 +71,23 @@ 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_BP, ctx->rbp) + 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_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 45308272..1a587702 100644 --- a/frida_mode/src/ctx/ctx_x86.c +++ b/frida_mode/src/ctx/ctx_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -42,6 +42,7 @@ 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) @@ -55,14 +56,15 @@ 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 e71386a0..e95b923b 100644 --- a/frida_mode/src/entry.c +++ b/frida_mode/src/entry.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -9,27 +9,33 @@ extern void __afl_manual_init(); -guint64 entry_start = 0; +guint64 entry_point = 0; static void entry_launch(void) { + OKF("Entry point reached"); __afl_manual_init(); /* Child here */ - previous_pc = 0; + instrument_previous_pc = 0; + +} + +void entry_config(void) { + + entry_point = util_read_address("AFL_ENTRYPOINT"); } void entry_init(void) { - entry_start = util_read_address("AFL_ENTRYPOINT"); - OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_start); + OKF("entry_point: 0x%016" G_GINT64_MODIFIER "X", entry_point); } -void entry_run(void) { +void entry_start(void) { - if (entry_start == 0) { entry_launch(); } + if (entry_point == 0) { entry_launch(); } } diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index ba82b89f..2a217d96 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -2,7 +2,7 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -11,6 +11,7 @@ #include "entry.h" #include "frida_cmplog.h" #include "instrument.h" +#include "js.h" #include "persistent.h" #include "prefetch.h" #include "ranges.h" @@ -18,12 +19,13 @@ #include "stats.h" #include "util.h" -static gboolean tracing = false; -static gboolean optimize = false; -static gboolean unique = false; +gboolean instrument_tracing = false; +gboolean instrument_optimize = false; +gboolean instrument_unique = false; + static GumStalkerTransformer *transformer = NULL; -__thread uint64_t previous_pc = 0; +__thread uint64_t instrument_previous_pc = 0; static GumAddress previous_rip = 0; static u8 * edges_notified = NULL; @@ -61,7 +63,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, current_pc = (current_rip >> 4) ^ (current_rip << 8); current_pc &= MAP_SIZE - 1; - edge = current_pc ^ previous_pc; + edge = current_pc ^ instrument_previous_pc; cursor = &__afl_area_ptr[edge]; value = *cursor; @@ -77,11 +79,11 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } *cursor = value; - previous_pc = current_pc >> 1; + instrument_previous_pc = current_pc >> 1; - if (unlikely(tracing)) { + if (unlikely(instrument_tracing)) { - if (!unique || edges_notified[edge] == 0) { + if (!instrument_unique || edges_notified[edge] == 0) { trace_debug("TRACE: edge: %10" G_GINT64_MODIFIER "d, current_rip: 0x%016" G_GINT64_MODIFIER @@ -90,7 +92,7 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } - if (unique) { edges_notified[edge] = 1; } + if (instrument_unique) { edges_notified[edge] = 1; } previous_rip = current_rip; @@ -98,8 +100,9 @@ __attribute__((hot)) static void on_basic_block(GumCpuContext *context, } -static void instr_basic_block(GumStalkerIterator *iterator, - GumStalkerOutput *output, gpointer user_data) { +static void instrument_basic_block(GumStalkerIterator *iterator, + GumStalkerOutput * output, + gpointer user_data) { UNUSED_PARAMETER(user_data); @@ -111,7 +114,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (unlikely(begin)) { instrument_debug_start(instr->address, output); } - if (instr->address == entry_start) { entry_prologue(iterator, output); } + if (instr->address == entry_point) { entry_prologue(iterator, output); } if (instr->address == persistent_start) { persistent_prologue(output); } if (instr->address == persistent_ret) { persistent_epilogue(output); } @@ -150,7 +153,7 @@ static void instr_basic_block(GumStalkerIterator *iterator, if (likely(!excluded)) { - if (likely(optimize)) { + if (likely(instrument_optimize)) { instrument_coverage_optimize(instr, output); @@ -163,8 +166,6 @@ static void instr_basic_block(GumStalkerIterator *iterator, } - begin = FALSE; - } instrument_debug_instruction(instr->address, instr->size); @@ -176,7 +177,13 @@ static void instr_basic_block(GumStalkerIterator *iterator, } - gum_stalker_iterator_keep(iterator); + if (js_stalker_callback(instr, begin, excluded, output)) { + + gum_stalker_iterator_keep(iterator); + + } + + begin = FALSE; } @@ -185,31 +192,39 @@ static void instr_basic_block(GumStalkerIterator *iterator, } -void instrument_init(void) { +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_debug_config(); + asan_config(); + cmplog_config(); - optimize = (getenv("AFL_FRIDA_INST_NO_OPTIMIZE") == NULL); - tracing = (getenv("AFL_FRIDA_INST_TRACE") != NULL); - unique = (getenv("AFL_FRIDA_INST_TRACE_UNIQUE") != NULL); +} + +void instrument_init(void) { - if (!instrument_is_coverage_optimize_supported()) optimize = false; + if (!instrument_is_coverage_optimize_supported()) instrument_optimize = false; - OKF("Instrumentation - optimize [%c]", optimize ? 'X' : ' '); - OKF("Instrumentation - tracing [%c]", tracing ? 'X' : ' '); - OKF("Instrumentation - unique [%c]", unique ? 'X' : ' '); + OKF("Instrumentation - optimize [%c]", instrument_optimize ? 'X' : ' '); + OKF("Instrumentation - tracing [%c]", instrument_tracing ? 'X' : ' '); + OKF("Instrumentation - unique [%c]", instrument_unique ? 'X' : ' '); - if (tracing && optimize) { + if (instrument_tracing && instrument_optimize) { FATAL("AFL_FRIDA_INST_TRACE requires AFL_FRIDA_INST_NO_OPTIMIZE"); } - if (unique && optimize) { + if (instrument_unique && instrument_optimize) { FATAL("AFL_FRIDA_INST_TRACE_UNIQUE requires AFL_FRIDA_INST_NO_OPTIMIZE"); } - if (unique) { tracing = TRUE; } + if (instrument_unique) { instrument_tracing = TRUE; } if (__afl_map_size != 0x10000) { @@ -217,10 +232,10 @@ void instrument_init(void) { } - transformer = - gum_stalker_transformer_make_from_callback(instr_basic_block, NULL, NULL); + transformer = gum_stalker_transformer_make_from_callback( + instrument_basic_block, NULL, NULL); - if (unique) { + 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); } diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 450a69a3..0e15940a 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 49ee86a2..17f97c97 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -72,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 = &previous_pc; + uint64_t *afl_prev_loc_ptr = &instrument_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, diff --git a/frida_mode/src/instrument/instrument_debug.c b/frida_mode/src/instrument/instrument_debug.c index 0ce26a1c..b8cca634 100644 --- a/frida_mode/src/instrument/instrument_debug.c +++ b/frida_mode/src/instrument/instrument_debug.c @@ -3,7 +3,7 @@ #include <stdio.h> #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -13,6 +13,8 @@ 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; @@ -79,18 +81,25 @@ static void instrument_disasm(guint8 *start, guint8 *end) { } +void instrument_debug_config(void) { + + instrument_debug_filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); + +} + void instrument_debug_init(void) { - char *filename = getenv("AFL_FRIDA_INST_DEBUG_FILE"); - OKF("Instrumentation debugging - enabled [%c]", filename == NULL ? ' ' : 'X'); + OKF("Instrumentation debugging - enabled [%c]", + instrument_debug_filename == NULL ? ' ' : 'X'); - if (filename == NULL) { return; } + if (instrument_debug_filename == NULL) { return; } - OKF("Instrumentation debugging - file [%s]", filename); + OKF("Instrumentation debugging - file [%s]", instrument_debug_filename); - if (filename == NULL) { return; } + if (instrument_debug_filename == NULL) { return; } - char *path = g_canonicalize_filename(filename, g_get_current_dir()); + char *path = + g_canonicalize_filename(instrument_debug_filename, g_get_current_dir()); OKF("Instrumentation debugging - path [%s]", path); diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index 7000e65d..a38b5b14 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" @@ -68,7 +68,7 @@ void instrument_coverage_optimize(const cs_insn * instr, current_log_impl = cw->pc; gum_x86_writer_put_bytes(cw, afl_log_code, sizeof(afl_log_code)); - uint64_t *afl_prev_loc_ptr = &previous_pc; + uint64_t *afl_prev_loc_ptr = &instrument_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, diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index 04a19e08..3c3dc272 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.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(&previous_pc)); + GUM_ADDRESS(&instrument_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); diff --git a/frida_mode/src/interceptor.c b/frida_mode/src/intercept.c index d2802752..ed8d27bd 100644 --- a/frida_mode/src/interceptor.c +++ b/frida_mode/src/intercept.c @@ -1,10 +1,10 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" -#include "interceptor.h" +#include "intercept.h" -void intercept(void *address, gpointer replacement, gpointer user_data) { +void intercept_hook(void *address, gpointer replacement, gpointer user_data) { GumInterceptor *interceptor = gum_interceptor_obtain(); gum_interceptor_begin_transaction(interceptor); @@ -15,7 +15,7 @@ void intercept(void *address, gpointer replacement, gpointer user_data) { } -void unintercept(void *address) { +void intercept_unhook(void *address) { GumInterceptor *interceptor = gum_interceptor_obtain(); @@ -26,10 +26,10 @@ void unintercept(void *address) { } -void unintercept_self(void) { +void intercept_unhook_self(void) { GumInvocationContext *ctx = gum_interceptor_get_current_invocation(); - unintercept(ctx->function); + intercept_unhook(ctx->function); } diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js new file mode 100644 index 00000000..4cb04704 --- /dev/null +++ b/frida_mode/src/js/api.js @@ -0,0 +1,243 @@ +"use strict"; +class Afl { + /** + * This is equivalent to setting a value in `AFL_FRIDA_EXCLUDE_RANGES`, + * it takes as arguments a `NativePointer` and a `number`. It can be + * called multiple times to exclude several ranges. + */ + static addExcludedRange(addressess, size) { + Afl.jsApiAddExcludeRange(addressess, size); + } + /** + * This is equivalent to setting a value in `AFL_FRIDA_INST_RANGES`, + * it takes as arguments a `NativePointer` and a `number`. It can be + * called multiple times to include several ranges. + */ + static addIncludedRange(addressess, size) { + Afl.jsApiAddIncludeRange(addressess, size); + } + /** + * This must always be called at the end of your script. This lets + * FRIDA mode know that your configuration is finished and that + * execution has reached the end of your script. Failure to call + * this will result in a fatal error. + */ + static done() { + Afl.jsApiDone(); + } + /** + * This function can be called within your script to cause FRIDA + * mode to trigger a fatal error. This is useful if for example you + * discover a problem you weren't expecting and want everything to + * stop. The user will need to enable `AFL_DEBUG_CHILD=1` to view + * this error message. + */ + static error(msg) { + const buf = Memory.allocUtf8String(msg); + Afl.jsApiError(buf); + } + /** + * Function used to provide access to `__afl_fuzz_ptr`, which contains the length of + * fuzzing data when using in-memory test case fuzzing. + */ + static getAflFuzzLen() { + return Afl.jsApiGetSymbol("__afl_fuzz_len"); + } + /** + * Function used to provide access to `__afl_fuzz_ptr`, which contains the fuzzing + * data when using in-memory test case fuzzing. + */ + static getAflFuzzPtr() { + return Afl.jsApiGetSymbol("__afl_fuzz_ptr"); + } + /** + * Print a message to the STDOUT. This should be preferred to + * FRIDA's `console.log` since FRIDA will queue it's log messages. + * If `console.log` is used in a callback in particular, then there + * may no longer be a thread running to service this queue. + */ + static print(msg) { + const STDOUT_FILENO = 2; + const log = `${msg}\n`; + const buf = Memory.allocUtf8String(log); + Afl.jsApiWrite(STDOUT_FILENO, buf, log.length); + } + /** + * See `AFL_FRIDA_DEBUG_MAPS`. + */ + static setDebugMaps() { + Afl.jsApiSetDebugMaps(); + } + /** + * This has the same effect as setting `AFL_ENTRYPOINT`, but has the + * convenience of allowing you to use FRIDAs APIs to determine the + * address you would like to configure, rather than having to grep + * the output of `readelf` or something similarly ugly. This + * function should be called with a `NativePointer` as its + * argument. + */ + static setEntryPoint(address) { + Afl.jsApiSetEntryPoint(address); + } + /** + * Function used to enable in-memory test cases for fuzzing. + */ + static setInMemoryFuzzing() { + Afl.jsApiAflSharedMemFuzzing.writeInt(1); + } + /** + * See `AFL_FRIDA_INST_DEBUG_FILE`. This function takes a single `string` as + * an argument. + */ + static setInstrumentDebugFile(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetInstrumentDebugFile(buf); + } + /** + * See `AFL_FRIDA_INST_TRACE`. + */ + static setInstrumentEnableTracing() { + Afl.jsApiSetInstrumentTrace(); + } + /** + * See `AFL_INST_LIBS`. + */ + static setInstrumentLibraries() { + Afl.jsApiSetInstrumentLibraries(); + } + /** + * See `AFL_FRIDA_INST_NO_OPTIMIZE` + */ + static setInstrumentNoOptimize() { + Afl.jsApiSetInstrumentNoOptimize(); + } + /** + * See `AFL_FRIDA_INST_TRACE_UNIQUE`. + */ + static setInstrumentTracingUnique() { + Afl.jsApiSetInstrumentTraceUnique(); + } + /** + * This is equivalent to setting `AFL_FRIDA_PERSISTENT_ADDR`, again a + * `NativePointer` should be provided as it's argument. + */ + static setPersistentAddress(address) { + Afl.jsApiSetPersistentAddress(address); + } + /** + * This is equivalent to setting `AFL_FRIDA_PERSISTENT_CNT`, a + * `number` should be provided as it's argument. + */ + static setPersistentCount(count) { + Afl.jsApiSetPersistentCount(count); + } + /** + * See `AFL_FRIDA_PERSISTENT_DEBUG`. + */ + static setPersistentDebug() { + Afl.jsApiSetPersistentDebug(); + } + /** + * See `AFL_FRIDA_PERSISTENT_ADDR`. This function takes a NativePointer as an + * argument. See above for examples of use. + */ + static setPersistentHook(address) { + Afl.jsApiSetPersistentHook(address); + } + /** + * This is equivalent to setting `AFL_FRIDA_PERSISTENT_RET`, again a + * `NativePointer` should be provided as it's argument. + */ + static setPersistentReturn(address) { + Afl.jsApiSetPersistentReturn(address); + } + /** + * See `AFL_FRIDA_INST_NO_PREFETCH`. + */ + static setPrefetchDisable() { + Afl.jsApiSetPrefetchDisable(); + } + /* + * Set a function to be called for each instruction which is instrumented + * by AFL FRIDA mode. + */ + static setStalkerCallback(callback) { + Afl.jsApiSetStalkerCallback(callback); + } + /** + * See `AFL_FRIDA_STATS_FILE`. This function takes a single `string` as + * an argument. + */ + static setStatsFile(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetStatsFile(buf); + } + /** + * See `AFL_FRIDA_STATS_INTERVAL`. This function takes a `number` as an + * argument + */ + static setStatsInterval(interval) { + Afl.jsApiSetStatsInterval(interval); + } + /** + * See `AFL_FRIDA_STATS_TRANSITIONS` + */ + static setStatsTransitions() { + Afl.jsApiSetStatsTransitions(); + } + /** + * See `AFL_FRIDA_OUTPUT_STDERR`. This function takes a single `string` as + * an argument. + */ + static setStdErr(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetStdErr(buf); + } + /** + * See `AFL_FRIDA_OUTPUT_STDOUT`. This function takes a single `string` as + * an argument. + */ + static setStdOut(file) { + const buf = Memory.allocUtf8String(file); + Afl.jsApiSetStdOut(buf); + } + static jsApiGetFunction(name, retType, argTypes) { + const addr = Afl.module.getExportByName(name); + return new NativeFunction(addr, retType, argTypes); + } + static jsApiGetSymbol(name) { + return Afl.module.getExportByName(name); + } +} +/** + * Field containing the `Module` object for `afl-frida-trace.so` (the FRIDA mode + * implementation). + */ +Afl.module = Process.getModuleByName("afl-frida-trace.so"); +Afl.jsApiAddExcludeRange = Afl.jsApiGetFunction("js_api_add_exclude_range", "void", ["pointer", "size_t"]); +Afl.jsApiAddIncludeRange = Afl.jsApiGetFunction("js_api_add_include_range", "void", ["pointer", "size_t"]); +Afl.jsApiAflSharedMemFuzzing = Afl.jsApiGetSymbol("__afl_sharedmem_fuzzing"); +Afl.jsApiDone = Afl.jsApiGetFunction("js_api_done", "void", []); +Afl.jsApiError = Afl.jsApiGetFunction("js_api_error", "void", ["pointer"]); +Afl.jsApiSetDebugMaps = Afl.jsApiGetFunction("js_api_set_debug_maps", "void", []); +Afl.jsApiSetEntryPoint = Afl.jsApiGetFunction("js_api_set_entrypoint", "void", ["pointer"]); +Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_debug_file", "void", ["pointer"]); +Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); +Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); +Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); +Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []); +Afl.jsApiSetPersistentAddress = Afl.jsApiGetFunction("js_api_set_persistent_address", "void", ["pointer"]); +Afl.jsApiSetPersistentCount = Afl.jsApiGetFunction("js_api_set_persistent_count", "void", ["uint64"]); +Afl.jsApiSetPersistentDebug = Afl.jsApiGetFunction("js_api_set_persistent_debug", "void", []); +Afl.jsApiSetPersistentHook = Afl.jsApiGetFunction("js_api_set_persistent_hook", "void", ["pointer"]); +Afl.jsApiSetPersistentReturn = Afl.jsApiGetFunction("js_api_set_persistent_return", "void", ["pointer"]); +Afl.jsApiSetPrefetchDisable = Afl.jsApiGetFunction("js_api_set_prefetch_disable", "void", []); +Afl.jsApiSetStalkerCallback = Afl.jsApiGetFunction("js_api_set_stalker_callback", "void", ["pointer"]); +Afl.jsApiSetStatsFile = Afl.jsApiGetFunction("js_api_set_stats_file", "void", ["pointer"]); +Afl.jsApiSetStatsInterval = Afl.jsApiGetFunction("js_api_set_stats_interval", "void", ["uint64"]); +Afl.jsApiSetStatsTransitions = Afl.jsApiGetFunction("js_api_set_stats_transitions", "void", []); +Afl.jsApiSetStdErr = Afl.jsApiGetFunction("js_api_set_stderr", "void", ["pointer"]); +Afl.jsApiSetStdOut = Afl.jsApiGetFunction("js_api_set_stdout", "void", ["pointer"]); +Afl.jsApiWrite = new NativeFunction( +/* tslint:disable-next-line:no-null-keyword */ +Module.getExportByName(null, "write"), "int", ["int", "pointer", "int"]); diff --git a/frida_mode/src/js/js.c b/frida_mode/src/js/js.c new file mode 100644 index 00000000..ed378d2c --- /dev/null +++ b/frida_mode/src/js/js.c @@ -0,0 +1,122 @@ +#include "frida-gumjs.h" + +#include "debug.h" + +#include "js.h" +#include "util.h" + +static char * js_script = NULL; +gboolean js_done = FALSE; +js_api_stalker_callback_t js_user_callback = NULL; + +static gchar * filename = "afl.js"; +static gchar * contents; +static GumScriptBackend *backend; +static GCancellable * cancellable = NULL; +static GError * error = NULL; +static GumScript * script; + +static void js_msg(GumScript *script, const gchar *message, GBytes *data, + gpointer user_data) { + + UNUSED_PARAMETER(script); + UNUSED_PARAMETER(data); + UNUSED_PARAMETER(user_data); + OKF("%s", message); + +} + +void js_config(void) { + + js_script = getenv("AFL_FRIDA_JS_SCRIPT"); + +} + +static gchar *js_get_script() { + + gsize length; + if (js_script != NULL) { filename = js_script; } + + filename = g_canonicalize_filename(filename, g_get_current_dir()); + + if (!g_file_get_contents(filename, &contents, &length, NULL)) { + + if (js_script == NULL) { + + return NULL; + + } else { + + FATAL("Could not load script file: %s", filename); + + } + + } else { + + OKF("Loaded AFL script: %s, %" G_GSIZE_MODIFIER "d bytes", filename, + length); + + gchar *source = g_malloc0(api_js_len + length + 1); + memcpy(source, api_js, api_js_len); + memcpy(&source[api_js_len], contents, length); + + return source; + + } + +} + +static void js_print_script(gchar *source) { + + gchar **split = g_strsplit(source, "\n", 0); + + for (size_t i = 0; split[i] != NULL; i++) { + + OKF("%3" G_GSIZE_MODIFIER "d. %s", i + 1, split[i]); + + } + + g_strfreev(split); + +} + +void js_start(void) { + + GMainContext *context; + + gchar *source = js_get_script(); + if (source == NULL) { return; } + js_print_script(source); + + backend = gum_script_backend_obtain_qjs(); + + script = gum_script_backend_create_sync(backend, "example", source, + cancellable, &error); + + if (error != NULL) { + + g_printerr("%s\n", error->message); + FATAL("Error processing script"); + + } + + gum_script_set_message_handler(script, js_msg, NULL, NULL); + + gum_script_load_sync(script, cancellable); + + context = g_main_context_get_thread_default(); + while (g_main_context_pending(context)) + g_main_context_iteration(context, FALSE); + + if (!js_done) { FATAL("Script didn't call Afl.done()"); } + +} + +gboolean js_stalker_callback(const cs_insn *insn, gboolean begin, + gboolean excluded, GumStalkerOutput *output) { + + if (js_user_callback == NULL) { return TRUE; } + return js_user_callback(insn, begin, excluded, output); + +} + diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c new file mode 100644 index 00000000..91dccab2 --- /dev/null +++ b/frida_mode/src/js/js_api.c @@ -0,0 +1,152 @@ +#include "debug.h" + +#include "entry.h" +#include "instrument.h" +#include "js.h" +#include "output.h" +#include "persistent.h" +#include "prefetch.h" +#include "ranges.h" +#include "stats.h" +#include "util.h" + +void js_api_done() { + + js_done = TRUE; + +} + +void js_api_error(char *msg) { + + FATAL("%s", msg); + +} + +void js_api_set_entrypoint(void *address) { + + entry_point = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_address(void *address) { + + persistent_start = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_return(void *address) { + + persistent_ret = GPOINTER_TO_SIZE(address); + +} + +void js_api_set_persistent_count(uint64_t count) { + + persistent_count = count; + +} + +void js_api_set_persistent_debug() { + + persistent_debug = TRUE; + +} + +void js_api_set_debug_maps() { + + ranges_debug_maps = TRUE; + +} + +void js_api_add_include_range(void *address, gsize size) { + + GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size}; + ranges_add_include(&range); + +} + +void js_api_add_exclude_range(void *address, gsize size) { + + GumMemoryRange range = {.base_address = GUM_ADDRESS(address), .size = size}; + ranges_add_exclude(&range); + +} + +void js_api_set_instrument_libraries() { + + ranges_inst_libs = TRUE; + +} + +void js_api_set_instrument_debug_file(char *path) { + + instrument_debug_filename = g_strdup(path); + +} + +void js_api_set_prefetch_disable(void) { + + prefetch_enable = FALSE; + +} + +void js_api_set_instrument_no_optimize(void) { + + instrument_optimize = FALSE; + +} + +void js_api_set_instrument_trace(void) { + + instrument_tracing = TRUE; + +} + +void js_api_set_instrument_trace_unique(void) { + + instrument_unique = TRUE; + +} + +void js_api_set_stdout(char *file) { + + output_stdout = g_strdup(file); + +} + +void js_api_set_stderr(char *file) { + + output_stderr = g_strdup(file); + +} + +void js_api_set_stats_file(char *file) { + + stats_filename = g_strdup(file); + +} + +void js_api_set_stats_interval(uint64_t interval) { + + stats_interval = interval; + +} + +void js_api_set_stats_transitions() { + + stats_transitions = TRUE; + +} + +void js_api_set_persistent_hook(void *address) { + + persistent_hook = address; + +} + +void js_api_set_stalker_callback(const js_api_stalker_callback_t callback) { + + js_user_callback = callback; + +} + diff --git a/frida_mode/src/lib/lib.c b/frida_mode/src/lib/lib.c index 13a7d1e7..59a3fcf9 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-gum.h" + #include "frida-gumjs.h" #include "debug.h" @@ -151,6 +151,10 @@ 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 8f863861..2aa48a13 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-gum.h" + #include "frida-gumjs.h" #include "debug.h" @@ -56,6 +56,10 @@ 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 7ff23755..85b0bbf3 100644 --- a/frida_mode/src/main.c +++ b/frida_mode/src/main.c @@ -11,14 +11,15 @@ #include <sys/personality.h> #endif -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" #include "entry.h" #include "instrument.h" -#include "interceptor.h" +#include "intercept.h" +#include "js.h" #include "lib.h" #include "output.h" #include "persistent.h" @@ -44,13 +45,6 @@ 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) { @@ -101,7 +95,8 @@ static void afl_print_cmdline(void) { if (fd < 0) { - FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno); + WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); + return; } @@ -138,7 +133,8 @@ static void afl_print_env(void) { if (fd < 0) { - FATAL("Failed to open /proc/self/cmdline, errno: (%d)", errno); + WARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno); + return; } @@ -172,23 +168,36 @@ 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(); + embedded_init(); - stalker_init(); - lib_init(); entry_init(); instrument_init(); - output_init(); + lib_init(); persistent_init(); prefetch_init(); + stalker_init(); ranges_init(); stats_init(); - void *fork_addr = - GSIZE_TO_POINTER(gum_module_find_export_by_name(NULL, "fork")); - intercept(fork_addr, on_fork, NULL); - + /* Start */ stalker_start(); - entry_run(); + entry_start(); } @@ -196,7 +205,7 @@ static int *on_main(int argc, char **argv, char **envp) { on_main_os(argc, argv, envp); - unintercept_self(); + intercept_unhook_self(); afl_frida_start(); @@ -210,7 +219,7 @@ extern int *main(int argc, char **argv, char **envp); static void intercept_main(void) { main_fn = main; - intercept(main, on_main, NULL); + intercept_hook(main, on_main, NULL); } @@ -223,7 +232,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(main, on_main, NULL); + intercept_hook(main, on_main, NULL); } @@ -234,8 +243,8 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, void(*stack_end)) { main_fn = main; - unintercept_self(); - intercept(main, on_main, NULL); + intercept_unhook_self(); + intercept_hook(main, on_main, NULL); return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini, stack_end); @@ -243,7 +252,7 @@ static int on_libc_start_main(int *(main)(int, char **, char **), int argc, static void intercept_main(void) { - intercept(__libc_start_main, on_libc_start_main, NULL); + intercept_hook(__libc_start_main, on_libc_start_main, NULL); } diff --git a/frida_mode/src/output.c b/frida_mode/src/output.c index 8a222b25..e2b744e7 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-gum.h" +#include "frida-gumjs.h" #include "debug.h" #include "output.h" -static int output_fd = -1; +char *output_stdout = NULL; +char *output_stderr = NULL; -static void output_redirect(int fd, char *variable) { +static void output_redirect(int fd, char *filename) { - char *filename = getenv(variable); char *path = NULL; if (filename == NULL) { return; } @@ -21,8 +21,8 @@ static void output_redirect(int fd, char *variable) { OKF("Redirect %d -> '%s'", fd, path); - output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + int output_fd = open(path, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); g_free(path); @@ -34,12 +34,24 @@ static void output_redirect(int fd, char *variable) { } + 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) { - output_redirect(STDOUT_FILENO, "AFL_FRIDA_OUTPUT_STDOUT"); - output_redirect(STDERR_FILENO, "AFL_FRIDA_OUTPUT_STDERR"); + OKF("Output - StdOut: %s", output_stdout); + OKF("Output - StdErr: %s", output_stderr); + + output_redirect(STDOUT_FILENO, output_stdout); + output_redirect(STDERR_FILENO, output_stderr); } diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 243d501d..bcc59ea7 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -1,6 +1,6 @@ #include <dlfcn.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -8,17 +8,18 @@ #include "persistent.h" #include "util.h" -int __afl_sharedmem_fuzzing = 0; -afl_persistent_hook_fn hook = NULL; +int __afl_sharedmem_fuzzing = 0; +static char *hook_name = NULL; + +afl_persistent_hook_fn persistent_hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; guint64 persistent_ret = 0; gboolean persistent_debug = FALSE; -void persistent_init(void) { - - char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); +void persistent_config(void) { + 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"); @@ -33,6 +34,11 @@ void persistent_init(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( @@ -41,13 +47,28 @@ void persistent_init(void) { } - if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; + if (hook_name == NULL) { return; } - if (persistent_count != 0 && persistent_count < 100) - WARNF("Persistent count out of recommended range (<100)"); + void *hook_obj = dlopen(hook_name, RTLD_NOW); + if (hook_obj == NULL) + FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); - if (persistent_start != 0 && !persistent_is_supported()) - FATAL("Persistent mode not supported on this architecture"); + 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); + + 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); + +} + +void persistent_init(void) { OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); @@ -58,27 +79,7 @@ void persistent_init(void) { OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_ret == 0 ? ' ' : 'X', persistent_ret); - 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); - - 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); - - 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); - - __afl_sharedmem_fuzzing = 1; - - } + if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; } } diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 6a3c06fa..f12f1af8 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index d7c6c76b..003f058a 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -1,5 +1,5 @@ #include <unistd.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -9,99 +9,15 @@ #include "util.h" #if defined(__aarch64__) +typedef struct { -struct arm64_regs { + GumCpuContext ctx; + uint64_t rflags; - uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; +} persistent_ctx_t; - union { - - uint64_t x11; - uint32_t fp_32; - - }; - - union { - - uint64_t x12; - uint32_t ip_32; - - }; - - union { - - uint64_t x13; - uint32_t sp_32; - - }; - - union { - - uint64_t x14; - uint32_t lr_32; - - }; - - union { - - uint64_t x15; - uint32_t pc_32; - - }; - - union { - - uint64_t x16; - uint64_t ip0; - - }; - - union { - - uint64_t x17; - uint64_t ip1; - - }; - - uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; - - union { - - uint64_t x29; - uint64_t fp; - - }; - - union { - - uint64_t x30; - uint64_t lr; - - }; - - union { - - uint64_t x31; - uint64_t sp; - - }; - - // the zero register is not saved here ofc - - uint64_t pc; - - uint32_t cpsr; - - uint8_t vfp_zregs[32][16 * 16]; - uint8_t vfp_pregs[17][32]; - uint32_t vfp_xregs[16]; - -}; - -typedef struct arm64_regs arch_api_regs; - -static arch_api_regs saved_regs = {0}; -static gpointer saved_lr = NULL; +static persistent_ctx_t saved_regs = {0}; +static gpointer saved_lr = NULL; gboolean persistent_is_supported(void) { @@ -109,8 +25,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumArm64Writer * cw, - struct arm64_regs *regs) { +static void instrument_persitent_save_regs(GumArm64Writer * cw, + persistent_ctx_t *regs) { GumAddress regs_address = GUM_ADDRESS(regs); const guint32 mrs_x1_nzcv = 0xd53b4201; @@ -129,83 +45,87 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw, /* 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, (16 * 1), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X4, ARM64_REG_X5, - ARM64_REG_X0, (16 * 2), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7, - ARM64_REG_X0, (16 * 3), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9, - ARM64_REG_X0, (16 * 4), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11, - ARM64_REG_X0, (16 * 5), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13, - ARM64_REG_X0, (16 * 6), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15, - ARM64_REG_X0, (16 * 7), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17, - ARM64_REG_X0, (16 * 8), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19, - ARM64_REG_X0, (16 * 9), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21, - ARM64_REG_X0, (16 * 10), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23, - ARM64_REG_X0, (16 * 11), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25, - ARM64_REG_X0, (16 * 12), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27, - ARM64_REG_X0, (16 * 13), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29, - ARM64_REG_X0, (16 * 14), - 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[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 & Adjusted SP */ - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_SP, - (GUM_RED_ZONE_SIZE + 32)); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X2, - ARM64_REG_X0, (16 * 15), - 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 & CPSR */ + /* PC & Adjusted SP (31) */ gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, GUM_ADDRESS(persistent_start)); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1, - ARM64_REG_X0, (16 * 16), - GUM_INDEX_SIGNED_OFFSET); + 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); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q0, ARM64_REG_Q1, - ARM64_REG_X0, (16 * 17), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3, - ARM64_REG_X0, (16 * 18), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5, - ARM64_REG_X0, (16 * 19), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7, - ARM64_REG_X0, (16 * 20), - 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, (16 * 0), - 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( @@ -217,8 +137,8 @@ static void instrument_persitent_save_regs(GumArm64Writer * cw, } -static void instrument_persitent_restore_regs(GumArm64Writer * cw, - struct arm64_regs *regs) { +static void instrument_persitent_restore_regs(GumArm64Writer * cw, + persistent_ctx_t *regs) { GumAddress regs_address = GUM_ADDRESS(regs); const guint32 msr_nzcv_x1 = 0xd51b4201; @@ -228,82 +148,81 @@ static void instrument_persitent_restore_regs(GumArm64Writer * cw, /* 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, (16 * 2), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X6, ARM64_REG_X7, - ARM64_REG_X0, (16 * 3), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X8, ARM64_REG_X9, - ARM64_REG_X0, (16 * 4), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X10, ARM64_REG_X11, - ARM64_REG_X0, (16 * 5), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X12, ARM64_REG_X13, - ARM64_REG_X0, (16 * 6), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X14, ARM64_REG_X15, - ARM64_REG_X0, (16 * 7), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X16, ARM64_REG_X17, - ARM64_REG_X0, (16 * 8), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X18, ARM64_REG_X19, - ARM64_REG_X0, (16 * 9), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X20, ARM64_REG_X21, - ARM64_REG_X0, (16 * 10), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X22, ARM64_REG_X23, - ARM64_REG_X0, (16 * 11), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X24, ARM64_REG_X25, - ARM64_REG_X0, (16 * 12), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X26, ARM64_REG_X27, - ARM64_REG_X0, (16 * 13), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X28, ARM64_REG_X29, - ARM64_REG_X0, (16 * 14), - GUM_INDEX_SIGNED_OFFSET); + 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 & Adjusted SP (use x1 as clobber) */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X1, - ARM64_REG_X0, (16 * 15), - 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); - /* Don't restore RIP use x1-x3 as clobber */ - - /* PC (x2) & CPSR (x1) */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X1, - ARM64_REG_X0, (16 * 16), - GUM_INDEX_SIGNED_OFFSET); + /* 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, (16 * 17), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q2, ARM64_REG_Q3, - ARM64_REG_X0, (16 * 18), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q4, ARM64_REG_Q5, - ARM64_REG_X0, (16 * 19), - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_Q6, ARM64_REG_Q7, - ARM64_REG_X0, (16 * 20), - GUM_INDEX_SIGNED_OFFSET); + 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, (16 * 1), - GUM_INDEX_SIGNED_OFFSET); + 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, (16 * 0), - GUM_INDEX_SIGNED_OFFSET); + 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); } @@ -318,7 +237,7 @@ static void instrument_exit(GumArm64Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -334,29 +253,29 @@ static void instrument_afl_persistent_loop(GumArm64Writer *cw) { } -static void persistent_prologue_hook(GumArm64Writer * cw, - struct arm64_regs *regs) { +static void persistent_prologue_hook(GumArm64Writer * cw, + persistent_ctx_t *regs) { - if (hook == NULL) return; + if (persistent_hook == NULL) return; 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_X3, + 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_X3, ARM64_REG_X3, 0); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X3, ARM64_REG_X3, 0); + 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_X3, ARM64_REG_X3, + gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2, G_MAXULONG); - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, + 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_X2, ARM64_REG_X2, 0); + gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X1, 0); gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, GUM_ADDRESS(regs), - GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, ARM64_REG_X2, - GUM_ARG_REGISTER, ARM64_REG_X3); + 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); @@ -406,6 +325,8 @@ void persistent_prologue(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; + OKF("Persistent loop reached"); + instrument_persitent_save_regs(cw, &saved_regs); /* loop: */ diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 653acefe..b2186db1 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-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -10,40 +10,15 @@ #if defined(__x86_64__) -struct x86_64_regs { +typedef struct { - uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, - r15; + GumCpuContext ctx; + uint64_t rflags; - union { +} persistent_ctx_t; - 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}; -static gpointer saved_ret = NULL; +static persistent_ctx_t saved_regs = {0}; +static gpointer saved_ret = NULL; gboolean persistent_is_supported(void) { @@ -51,8 +26,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - struct x86_64_regs *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + persistent_ctx_t *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, @@ -64,41 +39,41 @@ 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, (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); + 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); /* 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, (0x8 * 15), - GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX); /* Store adjusted RSP */ gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP); @@ -106,18 +81,18 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, /* 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, (0x8 * 16), - GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), 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, (0x8 * 17), - GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), 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, (0x8 * 0), - GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX); /* Pop the saved values */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10); @@ -127,56 +102,56 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, } -static void instrument_persitent_restore_regs(GumX86Writer * cw, - struct x86_64_regs *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + persistent_ctx_t *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, - (0x8 * 2)); + offsetof(GumCpuContext, rcx)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX, - (0x8 * 3)); + offsetof(GumCpuContext, rdx)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX, - (0x8 * 4)); + offsetof(GumCpuContext, rdi)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX, - (0x8 * 5)); + offsetof(GumCpuContext, rsi)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX, - (0x8 * 6)); + offsetof(GumCpuContext, rbp)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX, - (0x8 * 7)); + offsetof(GumCpuContext, r8)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX, - (0x8 * 8)); + offsetof(GumCpuContext, r9)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX, - (0x8 * 9)); + offsetof(GumCpuContext, r10)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX, - (0x8 * 10)); + offsetof(GumCpuContext, r11)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX, - (0x8 * 11)); + offsetof(GumCpuContext, r12)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX, - (0x8 * 12)); + offsetof(GumCpuContext, r13)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX, - (0x8 * 13)); + offsetof(GumCpuContext, r14)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX, - (0x8 * 14)); + offsetof(GumCpuContext, r15)); /* Don't restore RIP */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX, - (0x8 * 16)); + offsetof(GumCpuContext, 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, - (0x8 * 1)); + offsetof(GumCpuContext, rbx)); 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, - (0x8 * 0)); + offsetof(GumCpuContext, rax)); 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, - (0x8 * 17)); + offsetof(persistent_ctx_t, rflags)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_popfx(cw); @@ -199,7 +174,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -217,28 +192,27 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer * cw, - struct x86_64_regs *regs) { +static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { - if (hook == NULL) return; + if (persistent_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_RCX, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, GUM_ADDRESS(&__afl_fuzz_len)); - 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_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_u64(cw, GUM_REG_RDI, 0xffffffff); - gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI); + gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI); - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI, GUM_ADDRESS(&__afl_fuzz_ptr)); - 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_RSI, GUM_REG_RSI, 0); gum_x86_writer_put_call_address_with_arguments( - 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); + 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); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (GUM_RED_ZONE_SIZE)); @@ -296,6 +270,8 @@ void persistent_prologue(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); diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 7add6e99..f50bccb0 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -1,45 +1,23 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "config.h" +#include "debug.h" #include "instrument.h" #include "persistent.h" #if defined(__i386__) -struct x86_regs { +typedef struct { - uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + GumCpuContext ctx; + uint32_t eflags; - union { +} persistent_ctx_t; - uint32_t eip; - uint32_t pc; +static persistent_ctx_t saved_regs = {0}; - }; - - 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}; -static gpointer saved_ret = NULL; +static gpointer saved_ret = NULL; gboolean persistent_is_supported(void) { @@ -47,8 +25,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - struct x86_regs *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + persistent_ctx_t *regs) { GumAddress regs_address = GUM_ADDRESS(regs); @@ -58,80 +36,80 @@ 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, (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); + 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); /* 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, (0x4 * 7), - GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), 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, (0x4 * 8), - GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), 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, (0x4 * 9), - GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), 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, (0x4 * 0), - GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg( + cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), 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, - struct x86_regs *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + persistent_ctx_t *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, - (0x4 * 2)); + offsetof(GumCpuContext, ecx)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX, - (0x4 * 3)); + offsetof(GumCpuContext, edx)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX, - (0x4 * 4)); + offsetof(GumCpuContext, edi)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX, - (0x4 * 5)); + offsetof(GumCpuContext, esi)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX, - (0x4 * 6)); + offsetof(GumCpuContext, ebp)); /* Don't restore RIP */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX, - (0x4 * 8)); + offsetof(GumCpuContext, esp)); /* Restore RBX, RAX & Flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - (0x4 * 1)); + offsetof(GumCpuContext, ebx)); 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, - (0x4 * 0)); + offsetof(GumCpuContext, eax)); 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, - (0x4 * 9)); + offsetof(persistent_ctx_t, eflags)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_popfx(cw); @@ -152,7 +130,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - previous_pc = 0; + instrument_previous_pc = 0; return ret; } @@ -165,9 +143,9 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { +static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { - if (hook == NULL) return; + if (persistent_hook == NULL) return; gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, GUM_ADDRESS(&__afl_fuzz_len)); @@ -180,9 +158,8 @@ static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { /* Base address is 64-bits (hence two zero arguments) */ gum_x86_writer_put_call_address_with_arguments( - 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, + 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, GUM_REG_ECX); } @@ -233,6 +210,8 @@ void persistent_prologue(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_ESP, GUM_REG_ESP, 4); diff --git a/frida_mode/src/prefetch.c b/frida_mode/src/prefetch.c index 65c09fba..50d10c9e 100644 --- a/frida_mode/src/prefetch.c +++ b/frida_mode/src/prefetch.c @@ -2,10 +2,11 @@ #include <sys/shm.h> #include <sys/mman.h> -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" +#include "intercept.h" #include "prefetch.h" #include "stalker.h" @@ -20,9 +21,10 @@ typedef struct { } prefetch_data_t; -static prefetch_data_t *prefetch_data = NULL; +gboolean prefetch_enable = TRUE; -static int prefetch_shm_id = -1; +static prefetch_data_t *prefetch_data = NULL; +static int prefetch_shm_id = -1; /* * We do this from the transformer since we need one anyway for coverage, this @@ -72,14 +74,33 @@ 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); - gboolean prefetch = (getenv("AFL_FRIDA_INST_NO_PREFETCH") == NULL); + OKF("Instrumentation - prefetch [%c]", prefetch_enable ? 'X' : ' '); - OKF("Instrumentation - prefetch [%c]", prefetch ? 'X' : ' '); - - if (!prefetch) { return; } + if (!prefetch_enable) { 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 @@ -108,5 +129,7 @@ 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 ef25b371..534f202b 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" @@ -17,11 +17,14 @@ typedef struct { } convert_name_ctx_t; -GArray *module_ranges = NULL; -GArray *libs_ranges = NULL; -GArray *include_ranges = NULL; -GArray *exclude_ranges = NULL; -GArray *ranges = NULL; +gboolean ranges_debug_maps = FALSE; +gboolean ranges_inst_libs = FALSE; + +static GArray *module_ranges = NULL; +static GArray *libs_ranges = NULL; +static GArray *include_ranges = NULL; +static GArray *exclude_ranges = NULL; +static GArray *ranges = NULL; static void convert_address_token(gchar *token, GumMemoryRange *range) { @@ -225,6 +228,43 @@ 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; @@ -253,23 +293,7 @@ static GArray *collect_ranges(char *env_key) { g_array_sort(result, range_sort); - /* 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); - - } - - } + check_for_overlaps(result); print_ranges(env_key, result); @@ -285,15 +309,15 @@ static GArray *collect_libs_ranges(void) { GumMemoryRange range; result = g_array_new(false, false, sizeof(GumMemoryRange)); - if (getenv("AFL_INST_LIBS") == NULL) { + if (ranges_inst_libs) { - 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; } else { - 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(); } @@ -480,30 +504,13 @@ static GArray *merge_ranges(GArray *a) { } -static gboolean exclude_ranges_callback(const GumRangeDetails *details, - gpointer user_data) { +void ranges_config(void) { - 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; + if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; } + if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; } -} - -static void ranges_exclude_self(void) { - - gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, exclude_ranges_callback, NULL); + include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); + exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); } @@ -515,16 +522,20 @@ void ranges_init(void) { GArray * step3; GArray * step4; - if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { + if (ranges_debug_maps) { gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL); } + OKF("Ranges - Instrument libraries [%c]", ranges_inst_libs ? 'X' : ' '); + + 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(); - include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); /* If include ranges is empty, then assume everything is included */ if (include_ranges->len == 0) { @@ -535,8 +546,6 @@ 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); @@ -565,9 +574,6 @@ void ranges_init(void) { 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 63f3c529..98483cde 100644 --- a/frida_mode/src/stalker.c +++ b/frida_mode/src/stalker.c @@ -2,18 +2,47 @@ #include "instrument.h" #include "stalker.h" +#include "util.h" static GumStalker *stalker = NULL; -void stalker_init(void) { +void stalker_config(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, 0); + /* *NEVER* stalk the stalker, only bad things will ever come of this! */ + gum_process_enumerate_ranges(GUM_PAGE_EXECUTE, stalker_exclude_self, NULL); + } GumStalker *stalker_get(void) { diff --git a/frida_mode/src/stats/stats.c b/frida_mode/src/stats/stats.c index 0d7b9fb0..0dd8be70 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-gum.h" +#include "frida-gumjs.h" #include "config.h" #include "debug.h" @@ -17,15 +17,16 @@ stats_data_header_t *stats_data = NULL; -static int stats_parent_pid = -1; -static int stats_fd = -1; -static gboolean stats_transitions = FALSE; -static guint64 stats_interval = 0; +static int stats_parent_pid = -1; +static int stats_fd = -1; -void stats_init(void) { +char * stats_filename = NULL; +guint64 stats_interval = 0; +gboolean stats_transitions = FALSE; - stats_parent_pid = getpid(); - char *filename = getenv("AFL_FRIDA_STATS_FILE"); +void stats_config(void) { + + stats_filename = getenv("AFL_FRIDA_STATS_FILE"); stats_interval = util_read_num("AFL_FRIDA_STATS_INTERVAL"); if (getenv("AFL_FRIDA_STATS_TRANSITIONS") != NULL) { @@ -33,10 +34,16 @@ void stats_init(void) { } - OKF("Stats - file [%s]", filename); +} + +void stats_init(void) { + + stats_parent_pid = getpid(); + + OKF("Stats - file [%s]", stats_filename); OKF("Stats - interval [%" G_GINT64_MODIFIER "u]", stats_interval); - if (stats_interval != 0 && filename == NULL) { + if (stats_interval != 0 && stats_filename == NULL) { FATAL( "AFL_FRIDA_STATS_FILE must be specified if " @@ -46,7 +53,7 @@ void stats_init(void) { if (stats_interval == 0) { stats_interval = 10; } - if (filename == NULL) { return; } + if (stats_filename == NULL) { return; } if (!stats_is_supported_arch()) { @@ -56,11 +63,11 @@ void stats_init(void) { char *path = NULL; - if (filename == NULL) { return; } + if (stats_filename == NULL) { return; } if (stats_transitions) { gum_stalker_set_counters_enabled(TRUE); } - path = g_canonicalize_filename(filename, g_get_current_dir()); + path = g_canonicalize_filename(stats_filename, g_get_current_dir()); OKF("Stats - path [%s]", path); diff --git a/frida_mode/src/stats/stats_arm32.c b/frida_mode/src/stats/stats_arm32.c index 7eea7f91..71953af3 100644 --- a/frida_mode/src/stats/stats_arm32.c +++ b/frida_mode/src/stats/stats_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_arm64.c b/frida_mode/src/stats/stats_arm64.c index 592af87a..d9d374a4 100644 --- a/frida_mode/src/stats/stats_arm64.c +++ b/frida_mode/src/stats/stats_arm64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_x64.c b/frida_mode/src/stats/stats_x64.c index c3e8742a..7c3a90d7 100644 --- a/frida_mode/src/stats/stats_x64.c +++ b/frida_mode/src/stats/stats_x64.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" diff --git a/frida_mode/src/stats/stats_x86.c b/frida_mode/src/stats/stats_x86.c index 1906e809..d9c4f652 100644 --- a/frida_mode/src/stats/stats_x86.c +++ b/frida_mode/src/stats/stats_x86.c @@ -1,4 +1,4 @@ -#include "frida-gum.h" +#include "frida-gumjs.h" #include "debug.h" |