diff options
| author | vanhauser-thc <vh@thc.org> | 2021-07-19 10:58:19 +0200 |
|---|---|---|
| committer | vanhauser-thc <vh@thc.org> | 2021-07-19 10:58:19 +0200 |
| commit | 32a0d6ac31554a47dca591f8978982758fb87677 (patch) | |
| tree | be2ffd03f136dbecd408c73e4bc250ae249a4180 /frida_mode/src/persistent/persistent_x64.c | |
| parent | 815161827689c339d335233b7b232ac9b120b79b (diff) | |
| download | afl++-32a0d6ac31554a47dca591f8978982758fb87677.tar.gz | |
Revert "Merge branch 'release' into stable"
This reverts commit 815161827689c339d335233b7b232ac9b120b79b, reversing changes made to 9321a24e682b5c8bf6278961bd014cb883b87295.
Diffstat (limited to 'frida_mode/src/persistent/persistent_x64.c')
| -rw-r--r-- | frida_mode/src/persistent/persistent_x64.c | 235 |
1 files changed, 122 insertions, 113 deletions
diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 4cb960fc..c0bd9a09 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,39 +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 persistent_ctx_t saved_regs = {0}; +static gpointer saved_ret = NULL; gboolean persistent_is_supported(void) { @@ -50,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, @@ -63,60 +39,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, (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); /* RED_ZONE + Saved flags, RAX, alignment */ gum_x86_writer_put_add_reg_imm(cw, 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); + 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); /* 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); @@ -126,54 +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 or RSP */ + /* Don't restore RIP */ + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSP, GUM_REG_RAX, + 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); @@ -196,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 = instrument_hash_zero; return ret; } @@ -214,35 +192,59 @@ 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)); } -void persistent_prologue(GumStalkerOutput *output) { +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) { /* * SAVE REGS @@ -268,11 +270,12 @@ void persistent_prologue(GumStalkerOutput *output) { gconstpointer loop = cw->code + 1; - /* Stack must be 16-byte aligned per ABI */ - instrument_persitent_save_regs(cw, &saved_regs); + OKF("Persistent loop reached"); + + /* Pop the return value */ + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 8); - /* pop the return value */ - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (8)); + instrument_persitent_save_regs(cw, &saved_regs); /* loop: */ gum_x86_writer_put_label(cw, loop); @@ -304,21 +307,27 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); - if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + instrument_persitent_save_ret(cw); - gum_x86_writer_flush(cw); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } } -void persistent_epilogue(GumStalkerOutput *output) { +void persistent_epilogue_arch(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - persistent_ret_offset); - gum_x86_writer_put_ret(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); } |
