diff options
| author | van Hauser <vh@thc.org> | 2021-07-19 10:54:12 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-19 10:54:12 +0200 |
| commit | 815161827689c339d335233b7b232ac9b120b79b (patch) | |
| tree | 4e686574ccf1f47cea79fc24514c8455e3a1fbc1 /frida_mode/src/persistent/persistent_arm64.c | |
| parent | 9321a24e682b5c8bf6278961bd014cb883b87295 (diff) | |
| parent | cc57cc5f463e9b79980c2087d19b4a1e1360ec52 (diff) | |
| download | afl++-815161827689c339d335233b7b232ac9b120b79b.tar.gz | |
Merge branch 'release' into stable
Diffstat (limited to 'frida_mode/src/persistent/persistent_arm64.c')
| -rw-r--r-- | frida_mode/src/persistent/persistent_arm64.c | 385 |
1 files changed, 61 insertions, 324 deletions
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"); } |
