diff options
Diffstat (limited to 'frida_mode/src/persistent')
-rw-r--r-- | frida_mode/src/persistent/persistent.c | 80 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_arm32.c | 6 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_arm64.c | 385 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x64.c | 235 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_x86.c | 157 |
5 files changed, 292 insertions, 571 deletions
diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 639a694e..2ec5b9cc 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -1,31 +1,30 @@ #include <dlfcn.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" -#include "entry.h" #include "persistent.h" -#include "ranges.h" -#include "stalker.h" #include "util.h" -int __afl_sharedmem_fuzzing = 0; -static char *hook_name = NULL; - -afl_persistent_hook_fn persistent_hook = NULL; +int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; guint64 persistent_start = 0; guint64 persistent_count = 0; guint64 persistent_ret = 0; +guint64 persistent_ret_offset = 0; gboolean persistent_debug = FALSE; -void persistent_config(void) { +void persistent_init(void) { + + char *hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); - hook_name = getenv("AFL_FRIDA_PERSISTENT_HOOK"); persistent_start = util_read_address("AFL_FRIDA_PERSISTENT_ADDR"); persistent_count = util_read_num("AFL_FRIDA_PERSISTENT_CNT"); persistent_ret = util_read_address("AFL_FRIDA_PERSISTENT_RET"); + persistent_ret_offset = + util_read_address("AFL_FRIDA_PERSISTENT_RETADDR_OFFSET"); if (getenv("AFL_FRIDA_PERSISTENT_DEBUG") != NULL) { persistent_debug = TRUE; } @@ -37,11 +36,6 @@ void persistent_config(void) { } - if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; - - if (persistent_start != 0 && !persistent_is_supported()) - FATAL("Persistent mode not supported on this architecture"); - if (persistent_ret != 0 && persistent_start == 0) { FATAL( @@ -50,28 +44,21 @@ void persistent_config(void) { } - if (hook_name == NULL) { return; } + if (persistent_ret_offset != 0 && persistent_ret == 0) { - void *hook_obj = dlopen(hook_name, RTLD_NOW); - if (hook_obj == NULL) - FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); - - int (*afl_persistent_hook_init_ptr)(void) = - dlsym(hook_obj, "afl_persistent_hook_init"); - if (afl_persistent_hook_init_ptr == NULL) - FATAL("Failed to find afl_persistent_hook_init in %s", hook_name); + FATAL( + "AFL_FRIDA_PERSISTENT_RET must be specified if " + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET is"); - if (afl_persistent_hook_init_ptr() == 0) - FATAL("afl_persistent_hook_init returned a failure"); + } - persistent_hook = - (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); - if (persistent_hook == NULL) - FATAL("Failed to find afl_persistent_hook in %s", hook_name); + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; -} + if (persistent_count != 0 && persistent_count < 100) + WARNF("Persistent count out of recommended range (<100)"); -void persistent_init(void) { + if (persistent_start != 0 && !persistent_is_supported()) + FATAL("Persistent mode not supported on this architecture"); OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); @@ -81,25 +68,30 @@ void persistent_init(void) { OKF("Instrumentation - persistent ret [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_ret == 0 ? ' ' : 'X', persistent_ret); + OKF("Instrumentation - persistent ret offset [%c] (%" G_GINT64_MODIFIER "d)", + persistent_ret_offset == 0 ? ' ' : 'X', persistent_ret_offset); - if (persistent_hook != NULL) { __afl_sharedmem_fuzzing = 1; } + if (hook_name != NULL) { -} + void *hook_obj = dlopen(hook_name, RTLD_NOW); + if (hook_obj == NULL) + FATAL("Failed to load AFL_FRIDA_PERSISTENT_HOOK (%s)", hook_name); -void persistent_prologue(GumStalkerOutput *output) { + int (*afl_persistent_hook_init_ptr)(void) = + dlsym(hook_obj, "afl_persistent_hook_init"); + if (afl_persistent_hook_init_ptr == NULL) + FATAL("Failed to find afl_persistent_hook_init in %s", hook_name); - OKF("AFL_FRIDA_PERSISTENT_ADDR reached"); - entry_reached = TRUE; - ranges_exclude(); - stalker_trust(); - persistent_prologue_arch(output); + if (afl_persistent_hook_init_ptr() == 0) + FATAL("afl_persistent_hook_init returned a failure"); -} + hook = (afl_persistent_hook_fn)dlsym(hook_obj, "afl_persistent_hook"); + if (hook == NULL) + FATAL("Failed to find afl_persistent_hook in %s", hook_name); -void persistent_epilogue(GumStalkerOutput *output) { + __afl_sharedmem_fuzzing = 1; - OKF("AFL_FRIDA_PERSISTENT_RET reached"); - persistent_epilogue_arch(output); + } } diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 769f1505..6a3c06fa 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -1,4 +1,4 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "debug.h" @@ -61,14 +61,14 @@ gboolean persistent_is_supported(void) { } -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index 3cd61cd5..1215d8da 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -1,383 +1,120 @@ -#include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" #include "instrument.h" -#include "persistent.h" #include "util.h" #if defined(__aarch64__) -typedef struct { - GumCpuContext ctx; - uint64_t rflags; +struct arm64_regs { -} persistent_ctx_t; + uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; -static persistent_ctx_t saved_regs = {0}; -static gpointer saved_lr = NULL; + union { -gboolean persistent_is_supported(void) { - - return true; - -} - -static void instrument_persitent_save_regs(GumArm64Writer * cw, - persistent_ctx_t *regs) { - - GumAddress regs_address = GUM_ADDRESS(regs); - const guint32 mrs_x1_nzcv = 0xd53b4201; - - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), - GUM_INDEX_PRE_ADJUST); - gum_arm64_writer_put_stp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, - ARM64_REG_SP, -(16), - GUM_INDEX_PRE_ADJUST); - - gum_arm64_writer_put_instruction(cw, mrs_x1_nzcv); - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(regs_address)); - - /* Skip x0 & x1 we'll do that later */ - - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0, - offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0, - offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0, - offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0, - offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0, - offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0, - offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0, - offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0, - offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0, - offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0, - offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0, - offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0, - offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0, - offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET); - - /* LR (x30) */ - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0, - offsetof(GumCpuContext, x[30])); - - /* PC & Adjusted SP (31) */ - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, - GUM_ADDRESS(persistent_start)); - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_X3, ARM64_REG_SP, - (GUM_RED_ZONE_SIZE + 32)); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, offsetof(GumCpuContext, pc), - GUM_INDEX_SIGNED_OFFSET); - - /* CPSR */ - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(persistent_ctx_t, rflags)); - - /* Q */ - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0, - offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, - offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0, - offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0, - offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET); - - /* x0 & x1 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X3, - ARM64_REG_SP, 16, - GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET); - - /* Pop the saved values */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_SP, 16, GUM_INDEX_POST_ADJUST); - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, - GUM_INDEX_POST_ADJUST); - -} - -static void instrument_persitent_restore_regs(GumArm64Writer * cw, - persistent_ctx_t *regs) { - - GumAddress regs_address = GUM_ADDRESS(regs); - const guint32 msr_nzcv_x1 = 0xd51b4201; - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(regs_address)); - - /* Skip x0 - x3 we'll do that last */ - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X4, ARM64_REG_X5, ARM64_REG_X0, - offsetof(GumCpuContext, x[4]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X6, ARM64_REG_X7, ARM64_REG_X0, - offsetof(GumCpuContext, x[6]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X8, ARM64_REG_X9, ARM64_REG_X0, - offsetof(GumCpuContext, x[8]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X10, ARM64_REG_X11, ARM64_REG_X0, - offsetof(GumCpuContext, x[10]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X12, ARM64_REG_X13, ARM64_REG_X0, - offsetof(GumCpuContext, x[12]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X14, ARM64_REG_X15, ARM64_REG_X0, - offsetof(GumCpuContext, x[14]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X16, ARM64_REG_X17, ARM64_REG_X0, - offsetof(GumCpuContext, x[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X18, ARM64_REG_X19, ARM64_REG_X0, - offsetof(GumCpuContext, x[18]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X20, ARM64_REG_X21, ARM64_REG_X0, - offsetof(GumCpuContext, x[20]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X22, ARM64_REG_X23, ARM64_REG_X0, - offsetof(GumCpuContext, x[22]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X24, ARM64_REG_X25, ARM64_REG_X0, - offsetof(GumCpuContext, x[24]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X26, ARM64_REG_X27, ARM64_REG_X0, - offsetof(GumCpuContext, x[26]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X28, ARM64_REG_X29, ARM64_REG_X0, - offsetof(GumCpuContext, x[28]), GUM_INDEX_SIGNED_OFFSET); - - /* LR (x30) */ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X30, ARM64_REG_X0, - offsetof(GumCpuContext, x[30])); - - /* Adjusted SP (31) (use x1 as clobber)*/ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(GumCpuContext, sp)); - gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_SP, ARM64_REG_X1); - - /* CPSR */ - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X0, - offsetof(persistent_ctx_t, rflags)); - gum_arm64_writer_put_instruction(cw, msr_nzcv_x1); - - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q0, ARM64_REG_Q1, ARM64_REG_X0, - offsetof(GumCpuContext, q[0]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q2, ARM64_REG_Q3, ARM64_REG_X0, - offsetof(GumCpuContext, q[16]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q4, ARM64_REG_Q5, ARM64_REG_X0, - offsetof(GumCpuContext, q[32]), GUM_INDEX_SIGNED_OFFSET); - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_Q6, ARM64_REG_Q7, ARM64_REG_X0, - offsetof(GumCpuContext, q[48]), GUM_INDEX_SIGNED_OFFSET); - - /* x2 & x3 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X2, ARM64_REG_X3, ARM64_REG_X0, - offsetof(GumCpuContext, x[2]), GUM_INDEX_SIGNED_OFFSET); - /* x0 & x1 */ - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_X0, - offsetof(GumCpuContext, x[0]), GUM_INDEX_SIGNED_OFFSET); - -} - -static void instrument_exit(GumArm64Writer *cw) { + uint64_t x11; + uint32_t fp_32; - gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM64_REG_X0); + }; -} - -static int instrument_afl_persistent_loop_func(void) { + union { - int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; - return ret; + uint64_t x12; + uint32_t ip_32; -} + }; -static void instrument_afl_persistent_loop(GumArm64Writer *cw) { + union { - gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); + uint64_t x13; + uint32_t sp_32; -} + }; -static void persistent_prologue_hook(GumArm64Writer * cw, - persistent_ctx_t *regs) { + union { - if (persistent_hook == NULL) return; + uint64_t x14; + uint32_t lr_32; - gum_arm64_writer_put_sub_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X2, - GUM_ADDRESS(&__afl_fuzz_len)); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X2, ARM64_REG_X2, 0); + }; - gum_arm64_writer_put_and_reg_reg_imm(cw, ARM64_REG_X2, ARM64_REG_X2, - G_MAXULONG); + union { - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X1, - GUM_ADDRESS(&__afl_fuzz_ptr)); - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X1, ARM64_REG_X1, 0); + uint64_t x15; + uint32_t pc_32; - gum_arm64_writer_put_call_address_with_arguments( - cw, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, ARM64_REG_X1, GUM_ARG_REGISTER, - ARM64_REG_X2); + }; - gum_arm64_writer_put_add_reg_reg_imm(cw, ARM64_REG_SP, ARM64_REG_SP, - GUM_RED_ZONE_SIZE); + union { -} + uint64_t x16; + uint64_t ip0; -static void instrument_persitent_save_lr(GumArm64Writer *cw) { + }; - gum_arm64_writer_put_stp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, -(16 + GUM_RED_ZONE_SIZE), - GUM_INDEX_PRE_ADJUST); + union { - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(&saved_lr)); + uint64_t x17; + uint64_t ip1; - gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0); + }; - gum_arm64_writer_put_ldp_reg_reg_reg_offset( - cw, ARM64_REG_X0, ARM64_REG_X1, ARM64_REG_SP, 16 + GUM_RED_ZONE_SIZE, - GUM_INDEX_POST_ADJUST); + uint64_t x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28; -} + union { -void persistent_prologue_arch(GumStalkerOutput *output) { + uint64_t x29; + uint64_t fp; - /* - * SAVE REGS - * SAVE RET - * POP RET - * loop: - * CALL instrument_afl_persistent_loop - * TEST EAX, EAX - * JZ end: - * call hook (optionally) - * RESTORE REGS - * call original - * jmp loop: - * - * end: - * JMP SAVED RET - * - * original: - * INSTRUMENTED PERSISTENT FUNC - */ + }; - GumArm64Writer *cw = output->writer.arm64; + union { - gconstpointer loop = cw->code + 1; + uint64_t x30; + uint64_t lr; - OKF("Persistent loop reached"); + }; - instrument_persitent_save_regs(cw, &saved_regs); + union { - /* loop: */ - gum_arm64_writer_put_label(cw, loop); + uint64_t x31; + uint64_t sp; - /* call instrument_prologue_func */ - instrument_afl_persistent_loop(cw); + }; - /* jz done */ - gconstpointer done = cw->code + 1; - gum_arm64_writer_put_cmp_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR); - gum_arm64_writer_put_b_cond_label(cw, ARM64_CC_EQ, done); + // the zero register is not saved here ofc - /* Optionally call the persistent hook */ - persistent_prologue_hook(cw, &saved_regs); + uint64_t pc; - instrument_persitent_restore_regs(cw, &saved_regs); - gconstpointer original = cw->code + 1; - /* call original */ + uint32_t cpsr; - gum_arm64_writer_put_bl_label(cw, original); + uint8_t vfp_zregs[32][16 * 16]; + uint8_t vfp_pregs[17][32]; + uint32_t vfp_xregs[16]; - /* jmp loop */ - gum_arm64_writer_put_b_label(cw, loop); +}; - /* done: */ - gum_arm64_writer_put_label(cw, done); +typedef struct arm64_regs arch_api_regs; - instrument_exit(cw); - - /* original: */ - gum_arm64_writer_put_label(cw, original); - - instrument_persitent_save_lr(cw); +gboolean persistent_is_supported(void) { - if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } + return false; } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { - GumArm64Writer *cw = output->writer.arm64; + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); - if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); } - - gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0, - GUM_ADDRESS(&saved_lr)); +} - gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0); +void persistent_epilogue(GumStalkerOutput *output) { - gum_arm64_writer_put_br_reg(cw, ARM64_REG_X0); + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index c0bd9a09..4cb960fc 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,5 +1,5 @@ #include <unistd.h> -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" #include "debug.h" @@ -10,15 +10,39 @@ #if defined(__x86_64__) -typedef struct { +struct x86_64_regs { - GumCpuContext ctx; - uint64_t rflags; + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; -} persistent_ctx_t; + union { -static persistent_ctx_t saved_regs = {0}; -static gpointer saved_ret = NULL; + uint64_t rip; + uint64_t pc; + + }; + + union { + + uint64_t rsp; + uint64_t sp; + + }; + + union { + + uint64_t rflags; + uint64_t flags; + + }; + + uint8_t zmm_regs[32][64]; + +}; + +typedef struct x86_64_regs arch_api_regs; + +static arch_api_regs saved_regs = {0}; gboolean persistent_is_supported(void) { @@ -26,8 +50,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + struct x86_64_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, @@ -39,60 +63,60 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rbx), GUM_REG_RBX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rcx), GUM_REG_RCX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rdx), GUM_REG_RDX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rdi), GUM_REG_RDI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rsi), GUM_REG_RSI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rbp), GUM_REG_RBP); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r8), GUM_REG_R8); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r9), GUM_REG_R9); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r10), GUM_REG_R10); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r11), GUM_REG_R11); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r12), GUM_REG_R12); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r13), GUM_REG_R13); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r14), GUM_REG_R14); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, r15), GUM_REG_R15); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 1), + GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 2), + GUM_REG_RCX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 3), + GUM_REG_RDX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 4), + GUM_REG_RDI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 5), + GUM_REG_RSI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 6), + GUM_REG_RBP); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 7), + GUM_REG_R8); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 8), + GUM_REG_R9); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 9), + GUM_REG_R10); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 10), + GUM_REG_R11); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 11), + GUM_REG_R12); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 12), + GUM_REG_R13); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 13), + GUM_REG_R14); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 14), + GUM_REG_R15); /* Store RIP */ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RBX, GUM_ADDRESS(persistent_start)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rip), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 15), + GUM_REG_RBX); /* Store adjusted RSP */ gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_RBX, GUM_REG_RSP); /* RED_ZONE + Saved flags, RAX, alignment */ gum_x86_writer_put_add_reg_imm(cw, GUM_REG_RBX, - GUM_RED_ZONE_SIZE + (0x8 * 2)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rsp), GUM_REG_RBX); + GUM_RED_ZONE_SIZE + (0x8 * 3)); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 16), + GUM_REG_RBX); /* Save the flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x8); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(persistent_ctx_t, rflags), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 17), + GUM_REG_RBX); /* Save the RAX */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, 0x0); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_RAX, offsetof(GumCpuContext, rax), GUM_REG_RBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, (0x8 * 0), + GUM_REG_RBX); /* Pop the saved values */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10); @@ -102,56 +126,54 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, } -static void instrument_persitent_restore_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + struct x86_64_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, regs_address); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RAX, - offsetof(GumCpuContext, rcx)); + (0x8 * 2)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX, - offsetof(GumCpuContext, rdx)); + (0x8 * 3)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX, - offsetof(GumCpuContext, rdi)); + (0x8 * 4)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX, - offsetof(GumCpuContext, rsi)); + (0x8 * 5)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX, - offsetof(GumCpuContext, rbp)); + (0x8 * 6)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX, - offsetof(GumCpuContext, r8)); + (0x8 * 7)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX, - offsetof(GumCpuContext, r9)); + (0x8 * 8)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX, - offsetof(GumCpuContext, r10)); + (0x8 * 9)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX, - offsetof(GumCpuContext, r11)); + (0x8 * 10)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX, - offsetof(GumCpuContext, r12)); + (0x8 * 11)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX, - offsetof(GumCpuContext, r13)); + (0x8 * 12)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX, - offsetof(GumCpuContext, r14)); + (0x8 * 13)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX, - offsetof(GumCpuContext, r15)); + (0x8 * 14)); - /* Don't restore RIP */ - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX, - offsetof(GumCpuContext, rsp)); + /* Don't restore RIP or RSP */ /* Restore RBX, RAX & Flags */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(GumCpuContext, rbx)); + (0x8 * 1)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(GumCpuContext, rax)); + (0x8 * 0)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RAX, - offsetof(persistent_ctx_t, rflags)); + (0x8 * 17)); gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); gum_x86_writer_put_popfx(cw); @@ -174,7 +196,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + previous_pc = 0; return ret; } @@ -192,59 +214,35 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { +static void persistent_prologue_hook(GumX86Writer * cw, + struct x86_64_regs *regs) { - if (persistent_hook == NULL) return; + if (hook == NULL) return; gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RCX, GUM_ADDRESS(&__afl_fuzz_len)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RCX, GUM_REG_RCX, 0); gum_x86_writer_put_mov_reg_u64(cw, GUM_REG_RDI, 0xffffffff); - gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RDX, GUM_REG_RDI); + gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI); - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RSI, + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RDX, GUM_ADDRESS(&__afl_fuzz_ptr)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RSI, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RDX, 0); gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_RSI, GUM_ARG_REGISTER, - GUM_REG_RDX); + cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 4, GUM_ARG_ADDRESS, + GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_REGISTER, + GUM_REG_RDX, GUM_ARG_REGISTER, GUM_REG_RCX); gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (GUM_RED_ZONE_SIZE)); } -static void instrument_persitent_save_ret(GumX86Writer *cw) { - - /* Stack usage by this function */ - gssize offset = GUM_RED_ZONE_SIZE + (3 * 8); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - -(GUM_RED_ZONE_SIZE)); - - gum_x86_writer_put_pushfx(cw); - gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, - offset); - gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_RAX, GUM_REG_RBX); - - gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_popfx(cw); - - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - (GUM_RED_ZONE_SIZE)); - -} - -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { /* * SAVE REGS @@ -270,13 +268,12 @@ void persistent_prologue_arch(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; - OKF("Persistent loop reached"); - - /* Pop the return value */ - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8); - + /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); + /* pop the return value */ + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (8)); + /* loop: */ gum_x86_writer_put_label(cw, loop); @@ -307,27 +304,21 @@ void persistent_prologue_arch(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); - instrument_persitent_save_ret(cw); - if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); + } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - /* The stack should be aligned when we re-enter our loop */ - gconstpointer zero = cw->code + 1; - gum_x86_writer_put_test_reg_u32(cw, GUM_REG_RSP, 0xF); - gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, zero, GUM_NO_HINT); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -8); - gum_x86_writer_put_label(cw, zero); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_RAX); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + persistent_ret_offset); + gum_x86_writer_put_ret(cw); } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index b911676a..b30dfadf 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -1,23 +1,44 @@ -#include "frida-gumjs.h" +#include "frida-gum.h" #include "config.h" -#include "debug.h" #include "instrument.h" #include "persistent.h" #if defined(__i386__) -typedef struct { +struct x86_regs { - GumCpuContext ctx; - uint32_t eflags; + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; -} persistent_ctx_t; + union { -static persistent_ctx_t saved_regs = {0}; + uint32_t eip; + uint32_t pc; -static gpointer saved_ret = NULL; + }; + + union { + + uint32_t esp; + uint32_t sp; + + }; + + union { + + uint32_t eflags; + uint32_t flags; + + }; + + uint8_t xmm_regs[8][16]; + +}; + +typedef struct x86_regs arch_api_regs; + +static arch_api_regs saved_regs = {0}; gboolean persistent_is_supported(void) { @@ -25,8 +46,8 @@ gboolean persistent_is_supported(void) { } -static void instrument_persitent_save_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_save_regs(GumX86Writer * cw, + struct x86_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); @@ -36,80 +57,78 @@ static void instrument_persitent_save_regs(GumX86Writer * cw, gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ebx), GUM_REG_EBX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ecx), GUM_REG_ECX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, edx), GUM_REG_EDX); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, edi), GUM_REG_EDI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, esi), GUM_REG_ESI); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, ebp), GUM_REG_EBP); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 1), + GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 2), + GUM_REG_ECX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 3), + GUM_REG_EDX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 4), + GUM_REG_EDI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 5), + GUM_REG_ESI); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 6), + GUM_REG_EBP); /* Store RIP */ gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EBX, GUM_ADDRESS(persistent_start)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, eip), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 7), + GUM_REG_EBX); /* Store adjusted RSP */ gum_x86_writer_put_mov_reg_reg(cw, GUM_REG_EBX, GUM_REG_ESP); /* RED_ZONE + Saved flags, RAX */ gum_x86_writer_put_add_reg_imm(cw, GUM_REG_EBX, (0x4 * 2)); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, esp), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 8), + GUM_REG_EBX); /* Save the flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x4); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(persistent_ctx_t, eflags), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 9), + GUM_REG_EBX); /* Save the RAX */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x0); - gum_x86_writer_put_mov_reg_offset_ptr_reg( - cw, GUM_REG_EAX, offsetof(GumCpuContext, eax), GUM_REG_EBX); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, (0x4 * 0), + GUM_REG_EBX); /* Pop the saved values */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 0x8); } -static void instrument_persitent_restore_regs(GumX86Writer * cw, - persistent_ctx_t *regs) { +static void instrument_persitent_restore_regs(GumX86Writer * cw, + struct x86_regs *regs) { GumAddress regs_address = GUM_ADDRESS(regs); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, regs_address); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_EAX, - offsetof(GumCpuContext, ecx)); + (0x4 * 2)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX, - offsetof(GumCpuContext, edx)); + (0x4 * 3)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX, - offsetof(GumCpuContext, edi)); + (0x4 * 4)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX, - offsetof(GumCpuContext, esi)); + (0x4 * 5)); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX, - offsetof(GumCpuContext, ebp)); + (0x4 * 6)); - /* Don't restore RIP */ - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESP, GUM_REG_EAX, - offsetof(GumCpuContext, esp)); + /* Don't restore RIP or RSP */ /* Restore RBX, RAX & Flags */ gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(GumCpuContext, ebx)); + (0x4 * 1)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(GumCpuContext, eax)); + (0x4 * 0)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_EAX, - offsetof(persistent_ctx_t, eflags)); + (0x4 * 9)); gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); gum_x86_writer_put_popfx(cw); @@ -130,7 +149,7 @@ static void instrument_exit(GumX86Writer *cw) { static int instrument_afl_persistent_loop_func(void) { int ret = __afl_persistent_loop(persistent_count); - instrument_previous_pc = instrument_hash_zero; + previous_pc = 0; return ret; } @@ -143,9 +162,9 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) { } -static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { +static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { - if (persistent_hook == NULL) return; + if (hook == NULL) return; gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, GUM_ADDRESS(&__afl_fuzz_len)); @@ -158,33 +177,14 @@ static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) { /* Base address is 64-bits (hence two zero arguments) */ gum_x86_writer_put_call_address_with_arguments( - cw, GUM_CALL_CAPI, GUM_ADDRESS(persistent_hook), 3, GUM_ARG_ADDRESS, - GUM_ADDRESS(®s->ctx), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER, + cw, GUM_CALL_CAPI, GUM_ADDRESS(hook), 5, GUM_ARG_ADDRESS, + GUM_ADDRESS(regs), GUM_ARG_ADDRESS, GUM_ADDRESS(0), GUM_ARG_ADDRESS, + GUM_ADDRESS(0), GUM_ARG_REGISTER, GUM_REG_EDX, GUM_ARG_REGISTER, GUM_REG_ECX); } -static void instrument_persitent_save_ret(GumX86Writer *cw) { - - /* Stack usage by this function */ - gssize offset = (3 * 4); - - gum_x86_writer_put_pushfx(cw); - gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, - offset); - gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_REG_EAX, GUM_REG_EBX); - - gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_popfx(cw); - -} - -void persistent_prologue_arch(GumStalkerOutput *output) { +void persistent_prologue(GumStalkerOutput *output) { /* * SAVE REGS @@ -210,12 +210,11 @@ void persistent_prologue_arch(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; - OKF("Persistent loop reached"); + /* Stack must be 16-byte aligned per ABI */ + instrument_persitent_save_regs(cw, &saved_regs); /* Pop the return value */ - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, 4); - - instrument_persitent_save_regs(cw, &saved_regs); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, (4)); /* loop: */ gum_x86_writer_put_label(cw, loop); @@ -245,20 +244,22 @@ void persistent_prologue_arch(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); - instrument_persitent_save_ret(cw); - if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); + } -void persistent_epilogue_arch(GumStalkerOutput *output) { +void persistent_epilogue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(&saved_ret)); - gum_x86_writer_put_jmp_reg_ptr(cw, GUM_REG_EAX); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, + persistent_ret_offset); + + gum_x86_writer_put_ret(cw); } |