From 39ad3b89467d6de12cbb9d08ccd77d331c0d1f9e Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Wed, 28 Apr 2021 09:25:26 +0100 Subject: Frida persistent (#880) * Added x64 support for persistent mode (function call only), in-memory teest cases and complog * Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC * Various minor fixes and finished support for AFL_INST_LIBS * Review changes Co-authored-by: Your Name --- frida_mode/src/persistent/persistent.c | 68 ++++++ frida_mode/src/persistent/persistent_arm32.c | 70 ++++++ frida_mode/src/persistent/persistent_arm64.c | 113 +++++++++ frida_mode/src/persistent/persistent_x64.c | 337 +++++++++++++++++++++++++++ frida_mode/src/persistent/persistent_x86.c | 53 +++++ 5 files changed, 641 insertions(+) create mode 100644 frida_mode/src/persistent/persistent.c create mode 100644 frida_mode/src/persistent/persistent_arm32.c create mode 100644 frida_mode/src/persistent/persistent_arm64.c create mode 100644 frida_mode/src/persistent/persistent_x64.c create mode 100644 frida_mode/src/persistent/persistent_x86.c (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c new file mode 100644 index 00000000..fe3a1d20 --- /dev/null +++ b/frida_mode/src/persistent/persistent.c @@ -0,0 +1,68 @@ +#include + +#include "frida-gum.h" + +#include "config.h" +#include "debug.h" + +#include "persistent.h" +#include "util.h" + +int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; +guint64 persistent_start = 0; +guint64 persistent_count = 0; + +void persistent_init(void) { + + char *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"); + + if (persistent_count != 0 && persistent_start == 0) + FATAL( + "AFL_FRIDA_PERSISTENT_ADDR must be specified if " + "AFL_FRIDA_PERSISTENT_CNT is"); + + 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)"); + + if (persistent_count > 10000) + WARNF("Persistent count out of recommended range (<10000)"); + + if (persistent_start != 0 && !persistent_is_supported()) + FATAL("Persistent mode not supported on this architecture"); + + OKF("Instrumentation - persistent mode [%c] (0x%016lX)", + persistent_start == 0 ? ' ' : 'X', persistent_start); + OKF("Instrumentation - persistent count [%c] (%ld)", + persistent_start == 0 ? ' ' : 'X', persistent_count); + OKF("Instrumentation - hook [%s]", hook_name); + + 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; + + } + +} + diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c new file mode 100644 index 00000000..10dab3b2 --- /dev/null +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -0,0 +1,70 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "persistent.h" + +#if defined(__arm__) + +struct arm_regs { + + uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10; + + union { + + uint32_t r11; + uint32_t fp; + + }; + + union { + + uint32_t r12; + uint32_t ip; + + }; + + union { + + uint32_t r13; + uint32_t sp; + + }; + + union { + + uint32_t r14; + uint32_t lr; + + }; + + union { + + uint32_t r15; + uint32_t pc; + + }; + + uint32_t cpsr; + + uint8_t vfp_zregs[32][16]; + uint32_t vfp_xregs[16]; + +}; + +typedef struct arm_regs arch_api_regs; + +gboolean persistent_is_supported(void) { + + return false; + +} + +void persistent_prologue(GumStalkerOutput *output) { + + FATAL("Persistent mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c new file mode 100644 index 00000000..5a18ac2c --- /dev/null +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -0,0 +1,113 @@ +#include "frida-gum.h" + +#include "config.h" +#include "debug.h" + +#include "instrument.h" + +#if defined(__aarch64__) + +struct arm64_regs { + + uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10; + + 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; + +gboolean persistent_is_supported(void) { + + return false; + +} + +void persistent_prologue(GumStalkerOutput *output) { + + FATAL("Persistent mode not supported on this architecture"); + +} + +#endif + diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c new file mode 100644 index 00000000..0cabbf24 --- /dev/null +++ b/frida_mode/src/persistent/persistent_x64.c @@ -0,0 +1,337 @@ +#include "frida-gum.h" + +#include "config.h" + +#include "instrument.h" +#include "persistent.h" + +#if defined(__x86_64__) + +struct x86_64_regs { + + uint64_t rax, rbx, rcx, rdx, rdi, rsi, rbp, r8, r9, r10, r11, r12, r13, r14, + r15; + + union { + + 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 void * saved_return = NULL; + +gboolean persistent_is_supported(void) { + + return true; + +} + +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, + -(GUM_RED_ZONE_SIZE)); + + /* Should be pushing FPU here, but meh */ + gum_x86_writer_put_pushfx(cw); + gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); + + 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); + + /* 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); + + /* 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); + + /* 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); + + /* 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); + + /* Pop the saved values */ + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, 0x10); + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + (GUM_RED_ZONE_SIZE)); + +} + +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, + (0x8 * 2)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDX, GUM_REG_RAX, + (0x8 * 3)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RDI, GUM_REG_RAX, + (0x8 * 4)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RSI, GUM_REG_RAX, + (0x8 * 5)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBP, GUM_REG_RAX, + (0x8 * 6)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R8, GUM_REG_RAX, + (0x8 * 7)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R9, GUM_REG_RAX, + (0x8 * 8)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R10, GUM_REG_RAX, + (0x8 * 9)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R11, GUM_REG_RAX, + (0x8 * 10)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R12, GUM_REG_RAX, + (0x8 * 11)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R13, GUM_REG_RAX, + (0x8 * 12)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R14, GUM_REG_RAX, + (0x8 * 13)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_R15, GUM_REG_RAX, + (0x8 * 14)); + + /* 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, + (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, + (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, + (0x8 * 17)); + gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); + + gum_x86_writer_put_popfx(cw); + gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); + gum_x86_writer_put_pop_reg(cw, GUM_REG_RBX); + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + (GUM_RED_ZONE_SIZE)); + +} + +static void instrument_save_ret(GumX86Writer *cw, void **saved_return_ptr) { + + GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + -(GUM_RED_ZONE_SIZE)); + gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); + gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); + + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, saved_return_address); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, + GUM_RED_ZONE_SIZE + 0x10); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, 0, 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_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + (GUM_RED_ZONE_SIZE)); + +} + +static void instrument_jump_ret(GumX86Writer *cw, void **saved_return_ptr) { + + GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + -(GUM_RED_ZONE_SIZE)); + + /* Place holder for ret */ + gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); + gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); + + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, saved_return_address); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RAX, GUM_REG_RAX, 0); + + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RSP, 0x8, GUM_REG_RAX); + gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); + gum_x86_writer_put_ret_imm(cw, GUM_RED_ZONE_SIZE); + +} + +static int instrument_afl_persistent_loop_func(void) { + + int ret = __afl_persistent_loop(persistent_count); + previous_pc = 0; + return ret; + +} + +static int instrument_afl_persistent_loop(GumX86Writer *cw) { + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + -(GUM_RED_ZONE_SIZE)); + gum_x86_writer_put_call_address_with_arguments( + cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); + gum_x86_writer_put_test_reg_reg(cw, GUM_REG_RAX, GUM_REG_RAX); + + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, + (GUM_RED_ZONE_SIZE)); + +} + +static void persistent_prologue_hook(GumX86Writer * cw, + struct x86_64_regs *regs) { + + 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_RCX, + 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_u64(cw, GUM_REG_RDI, 0xffffffff); + gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI); + + 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_ADDRESS, + GUM_ADDRESS(__afl_fuzz_ptr), 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)); + +} + +void persistent_prologue(GumStalkerOutput *output) { + + /* + * 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 + */ + + GumX86Writer *cw = output->writer.x86; + + gconstpointer loop = cw->code + 1; + // gum_x86_writer_put_breakpoint(cw); + + /* Stack must be 16-byte aligned per ABI */ + instrument_persitent_save_regs(cw, &saved_regs); + + /* Stash and pop the return value */ + instrument_save_ret(cw, &saved_return); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (8)); + + /* loop: */ + gum_x86_writer_put_label(cw, loop); + + /* call instrument_prologue_func */ + instrument_afl_persistent_loop(cw); + + /* jz done */ + gconstpointer done = cw->code + 1; + gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, done, GUM_UNLIKELY); + + /* Optionally call the persistent hook */ + persistent_prologue_hook(cw, &saved_regs); + + instrument_persitent_restore_regs(cw, &saved_regs); + gconstpointer original = cw->code + 1; + /* call original */ + gum_x86_writer_put_call_near_label(cw, original); + /* jmp loop */ + gum_x86_writer_put_jmp_near_label(cw, loop); + + /* done: */ + gum_x86_writer_put_label(cw, done); + + instrument_jump_ret(cw, &saved_return); + + /* original: */ + gum_x86_writer_put_label(cw, original); + + gum_x86_writer_flush(cw); + +} + +#endif + diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c new file mode 100644 index 00000000..4daa61a9 --- /dev/null +++ b/frida_mode/src/persistent/persistent_x86.c @@ -0,0 +1,53 @@ +#include "frida-gum.h" + +#include "debug.h" + +#include "persistent.h" + +#if defined(__i386__) + +struct x86_regs { + + uint32_t eax, ebx, ecx, edx, edi, esi, ebp; + + union { + + uint32_t eip; + uint32_t pc; + + }; + + 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; + +gboolean persistent_is_supported(void) { + + return false; + +} + +void persistent_prologue(GumStalkerOutput *output) { + + FATAL("Persistent mode not supported on this architecture"); + +} + +#endif + -- cgit v1.2.3 From da65eef57279dae7b652c40bdb31bc6cd749f63d Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 28 Apr 2021 12:57:29 +0200 Subject: fix frida mode --- frida_mode/src/persistent/persistent.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index fe3a1d20..34e4093e 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -9,9 +9,6 @@ #include "util.h" int __afl_sharedmem_fuzzing = 0; -afl_persistent_hook_fn hook = NULL; -guint64 persistent_start = 0; -guint64 persistent_count = 0; void persistent_init(void) { -- cgit v1.2.3 From 3a0d4fe0d0a585d152a59ca4601d1981cedbf113 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Wed, 28 Apr 2021 18:26:19 +0100 Subject: Bumped warnings up to the max and fixed remaining issues (#890) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent.c | 3 +++ frida_mode/src/persistent/persistent_x64.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 34e4093e..fe3a1d20 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -9,6 +9,9 @@ #include "util.h" int __afl_sharedmem_fuzzing = 0; +afl_persistent_hook_fn hook = NULL; +guint64 persistent_start = 0; +guint64 persistent_count = 0; void persistent_init(void) { diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 0cabbf24..5b8493b2 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -231,7 +231,7 @@ static int instrument_afl_persistent_loop_func(void) { } -static int instrument_afl_persistent_loop(GumX86Writer *cw) { +static void instrument_afl_persistent_loop(GumX86Writer *cw) { gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, -(GUM_RED_ZONE_SIZE)); -- cgit v1.2.3 From 423c32969c0111f5fdc666a159497dff805bff89 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 28 Apr 2021 22:48:43 +0200 Subject: nit --- frida_mode/src/persistent/persistent.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index fe3a1d20..5aad3724 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -30,9 +30,6 @@ void persistent_init(void) { if (persistent_count != 0 && persistent_count < 100) WARNF("Persistent count out of recommended range (<100)"); - if (persistent_count > 10000) - WARNF("Persistent count out of recommended range (<10000)"); - if (persistent_start != 0 && !persistent_is_supported()) FATAL("Persistent mode not supported on this architecture"); -- cgit v1.2.3 From 26b84e3521936ec11b7615bb833310d62795020e Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 29 Apr 2021 08:06:14 +0100 Subject: Fixes for aarch64, OSX and other minor issues (#891) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent.c | 4 ++-- frida_mode/src/persistent/persistent_arm32.c | 2 ++ frida_mode/src/persistent/persistent_arm64.c | 2 ++ frida_mode/src/persistent/persistent_x86.c | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 5aad3724..918ff153 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -33,9 +33,9 @@ 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%016lX)", + OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)", persistent_start == 0 ? ' ' : 'X', persistent_start); - OKF("Instrumentation - persistent count [%c] (%ld)", + OKF("Instrumentation - persistent count [%c] (%" G_GINT64_MODIFIER "d)", persistent_start == 0 ? ' ' : 'X', persistent_count); OKF("Instrumentation - hook [%s]", hook_name); diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index 10dab3b2..bc021ff3 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -3,6 +3,7 @@ #include "debug.h" #include "persistent.h" +#include "util.h" #if defined(__arm__) @@ -62,6 +63,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(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 5a18ac2c..c198da69 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -4,6 +4,7 @@ #include "debug.h" #include "instrument.h" +#include "util.h" #if defined(__aarch64__) @@ -105,6 +106,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(GumStalkerOutput *output) { + UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 4daa61a9..9d39c4e9 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -3,6 +3,7 @@ #include "debug.h" #include "persistent.h" +#include "util.h" #if defined(__i386__) @@ -45,6 +46,7 @@ gboolean persistent_is_supported(void) { void persistent_prologue(GumStalkerOutput *output) { + UNUSED_PARAMETER(output); FATAL("Persistent mode not supported on this architecture"); } -- cgit v1.2.3 From c6e8314446344d3a65b828feb31f627ce11ba352 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Fri, 30 Apr 2021 22:42:50 +0100 Subject: Support for AFL_ENTRYPOINT (#898) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent_x64.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 5b8493b2..49f1988c 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -252,15 +252,20 @@ static void persistent_prologue_hook(GumX86Writer * cw, -(GUM_RED_ZONE_SIZE)); gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RCX, - GUM_ADDRESS(__afl_fuzz_len)); + 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_u64(cw, GUM_REG_RDI, 0xffffffff); gum_x86_writer_put_and_reg_reg(cw, GUM_REG_RCX, GUM_REG_RDI); + 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_RDX, GUM_REG_RDX, 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_ADDRESS, - GUM_ADDRESS(__afl_fuzz_ptr), GUM_ARG_REGISTER, GUM_REG_RCX); + 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)); -- cgit v1.2.3 From d0af55e78f85427983ddafd0af07dff654b3ea65 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Mon, 17 May 2021 20:14:40 +0100 Subject: Support for x86 (#920) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent_x86.c | 233 ++++++++++++++++++++++++++++- 1 file changed, 228 insertions(+), 5 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 9d39c4e9..bd7171b9 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -1,9 +1,9 @@ #include "frida-gum.h" -#include "debug.h" +#include "config.h" +#include "instrument.h" #include "persistent.h" -#include "util.h" #if defined(__i386__) @@ -38,16 +38,239 @@ struct x86_regs { typedef struct x86_regs arch_api_regs; +static arch_api_regs saved_regs = {0}; +static void * saved_return = NULL; + gboolean persistent_is_supported(void) { - return false; + return true; + +} + +static void instrument_persitent_save_regs(GumX86Writer * cw, + struct x86_regs *regs) { + + GumAddress regs_address = GUM_ADDRESS(regs); + + /* Should be pushing FPU here, but meh */ + gum_x86_writer_put_pushfx(cw); + gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); + + 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); + + /* 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); + + /* 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); + + /* 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); + + /* 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); + + /* 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) { + + 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)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EAX, + (0x4 * 3)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDI, GUM_REG_EAX, + (0x4 * 4)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ESI, GUM_REG_EAX, + (0x4 * 5)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBP, GUM_REG_EAX, + (0x4 * 6)); + + /* 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, + (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, + (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, + (0x4 * 9)); + gum_x86_writer_put_push_reg(cw, GUM_REG_EBX); + + gum_x86_writer_put_popfx(cw); + gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); + gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); + +} + +static void instrument_save_ret(GumX86Writer *cw, void **saved_return_ptr) { + + GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); + + 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, saved_return_address); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x8); + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, 0, GUM_REG_EBX); + + gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); + gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); + +} + +static void instrument_jump_ret(GumX86Writer *cw, void **saved_return_ptr) { + + GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); + + /* Place holder for ret */ + gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); + gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); + + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, saved_return_address); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EAX, GUM_REG_EAX, 0); + + gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_ESP, 0x4, GUM_REG_EAX); + gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); + gum_x86_writer_put_ret(cw); + +} + +static int instrument_afl_persistent_loop_func(void) { + + int ret = __afl_persistent_loop(persistent_count); + previous_pc = 0; + return ret; + +} + +static void instrument_afl_persistent_loop(GumX86Writer *cw) { + + gum_x86_writer_put_call_address_with_arguments( + cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); + gum_x86_writer_put_test_reg_reg(cw, GUM_REG_EAX, GUM_REG_EAX); + +} + +static void persistent_prologue_hook(GumX86Writer *cw, struct x86_regs *regs) { + + if (hook == NULL) return; + + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_ECX, + GUM_ADDRESS(&__afl_fuzz_len)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_ECX, GUM_REG_ECX, 0); + + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EDX, + GUM_ADDRESS(&__afl_fuzz_ptr)); + gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EDX, GUM_REG_EDX, 0); + + /* 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, + GUM_REG_ECX); } void persistent_prologue(GumStalkerOutput *output) { - UNUSED_PARAMETER(output); - FATAL("Persistent mode not supported on this architecture"); + /* + * 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 + */ + + GumX86Writer *cw = output->writer.x86; + + gconstpointer loop = cw->code + 1; + + /* Stack must be 16-byte aligned per ABI */ + instrument_persitent_save_regs(cw, &saved_regs); + + /* Stash and pop the return value */ + instrument_save_ret(cw, &saved_return); + gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, (4)); + + /* loop: */ + gum_x86_writer_put_label(cw, loop); + + /* call instrument_prologue_func */ + instrument_afl_persistent_loop(cw); + + /* jz done */ + gconstpointer done = cw->code + 1; + gum_x86_writer_put_jcc_near_label(cw, X86_INS_JE, done, GUM_UNLIKELY); + + /* Optionally call the persistent hook */ + persistent_prologue_hook(cw, &saved_regs); + + instrument_persitent_restore_regs(cw, &saved_regs); + gconstpointer original = cw->code + 1; + /* call original */ + gum_x86_writer_put_call_near_label(cw, original); + /* jmp loop */ + gum_x86_writer_put_jmp_near_label(cw, loop); + + /* done: */ + gum_x86_writer_put_label(cw, done); + + instrument_jump_ret(cw, &saved_return); + + /* original: */ + gum_x86_writer_put_label(cw, original); + + gum_x86_writer_flush(cw); } -- cgit v1.2.3 From a1458ea6715e8801bf28fec0ac66f06b96eb1e66 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 20 May 2021 18:16:58 +0100 Subject: Changes to have persistent mode exit at the end of the loop (#928) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent_x64.c | 46 ++++-------------------------- frida_mode/src/persistent/persistent_x86.c | 40 +++++--------------------- 2 files changed, 13 insertions(+), 73 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 49f1988c..aa772b7f 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -40,7 +40,6 @@ struct x86_64_regs { typedef struct x86_64_regs arch_api_regs; static arch_api_regs saved_regs = {0}; -static void * saved_return = NULL; gboolean persistent_is_supported(void) { @@ -183,43 +182,11 @@ static void instrument_persitent_restore_regs(GumX86Writer * cw, } -static void instrument_save_ret(GumX86Writer *cw, void **saved_return_ptr) { +static void instrument_exit(GumX86Writer *cw) { - GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - -(GUM_RED_ZONE_SIZE)); - gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_RBX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, saved_return_address); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RBX, GUM_REG_RSP, - GUM_RED_ZONE_SIZE + 0x10); - gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RAX, 0, 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_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - (GUM_RED_ZONE_SIZE)); - -} - -static void instrument_jump_ret(GumX86Writer *cw, void **saved_return_ptr) { - - GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); - gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, - -(GUM_RED_ZONE_SIZE)); - - /* Place holder for ret */ - gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_RAX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, saved_return_address); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_RAX, GUM_REG_RAX, 0); - - gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_RSP, 0x8, GUM_REG_RAX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_RAX); - gum_x86_writer_put_ret_imm(cw, GUM_RED_ZONE_SIZE); + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_RAX, GUM_ADDRESS(_exit)); + gum_x86_writer_put_mov_reg_u32(cw, GUM_REG_RDI, 0); + gum_x86_writer_put_call_reg(cw, GUM_REG_RAX); } @@ -302,8 +269,7 @@ void persistent_prologue(GumStalkerOutput *output) { /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); - /* Stash and pop the return value */ - instrument_save_ret(cw, &saved_return); + /* pop the return value */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_RSP, GUM_REG_RSP, (8)); /* loop: */ @@ -329,7 +295,7 @@ void persistent_prologue(GumStalkerOutput *output) { /* done: */ gum_x86_writer_put_label(cw, done); - instrument_jump_ret(cw, &saved_return); + instrument_exit(cw); /* original: */ gum_x86_writer_put_label(cw, original); diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index bd7171b9..20a3dc42 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -39,7 +39,6 @@ struct x86_regs { typedef struct x86_regs arch_api_regs; static arch_api_regs saved_regs = {0}; -static void * saved_return = NULL; gboolean persistent_is_supported(void) { @@ -138,36 +137,12 @@ static void instrument_persitent_restore_regs(GumX86Writer * cw, } -static void instrument_save_ret(GumX86Writer *cw, void **saved_return_ptr) { +static void instrument_exit(GumX86Writer *cw) { - GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); - - 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, saved_return_address); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EBX, GUM_REG_ESP, 0x8); - gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_EAX, 0, GUM_REG_EBX); - - gum_x86_writer_put_pop_reg(cw, GUM_REG_EBX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); - -} - -static void instrument_jump_ret(GumX86Writer *cw, void **saved_return_ptr) { - - GumAddress saved_return_address = GUM_ADDRESS(saved_return_ptr); - - /* Place holder for ret */ - gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_push_reg(cw, GUM_REG_EAX); - - gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, saved_return_address); - gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_REG_EAX, GUM_REG_EAX, 0); - - gum_x86_writer_put_mov_reg_offset_ptr_reg(cw, GUM_REG_ESP, 0x4, GUM_REG_EAX); - gum_x86_writer_put_pop_reg(cw, GUM_REG_EAX); - gum_x86_writer_put_ret(cw); + gum_x86_writer_put_mov_reg_address(cw, GUM_REG_EAX, GUM_ADDRESS(_exit)); + gum_x86_writer_put_mov_reg_u32(cw, GUM_REG_EDI, 0); + gum_x86_writer_put_push_reg(cw, GUM_REG_EDI); + gum_x86_writer_put_call_reg(cw, GUM_REG_EAX); } @@ -238,8 +213,7 @@ void persistent_prologue(GumStalkerOutput *output) { /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); - /* Stash and pop the return value */ - instrument_save_ret(cw, &saved_return); + /* Pop the return value */ gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_REG_ESP, GUM_REG_ESP, (4)); /* loop: */ @@ -265,7 +239,7 @@ void persistent_prologue(GumStalkerOutput *output) { /* done: */ gum_x86_writer_put_label(cw, done); - instrument_jump_ret(cw, &saved_return); + instrument_exit(cw); /* original: */ gum_x86_writer_put_label(cw, original); -- cgit v1.2.3 From f677be5e86a096edbba74cb8c739e8b10850a379 Mon Sep 17 00:00:00 2001 From: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com> Date: Thu, 27 May 2021 21:33:44 +0100 Subject: Support for AFL_FRIDA_PERSISTENT_RET (#941) Co-authored-by: Your Name --- frida_mode/src/persistent/persistent.c | 34 +++++++++++++++++++++++++++- frida_mode/src/persistent/persistent_arm32.c | 7 ++++++ frida_mode/src/persistent/persistent_arm64.c | 7 ++++++ frida_mode/src/persistent/persistent_x64.c | 19 +++++++++++++++- frida_mode/src/persistent/persistent_x86.c | 15 ++++++++++++ 5 files changed, 80 insertions(+), 2 deletions(-) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent.c b/frida_mode/src/persistent/persistent.c index 918ff153..2ec5b9cc 100644 --- a/frida_mode/src/persistent/persistent.c +++ b/frida_mode/src/persistent/persistent.c @@ -12,6 +12,9 @@ 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_init(void) { @@ -19,12 +22,36 @@ void persistent_init(void) { 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; } + + if (persistent_count != 0 && persistent_start == 0) { - if (persistent_count != 0 && persistent_start == 0) FATAL( "AFL_FRIDA_PERSISTENT_ADDR must be specified if " "AFL_FRIDA_PERSISTENT_CNT is"); + } + + if (persistent_ret != 0 && persistent_start == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_ADDR must be specified if " + "AFL_FRIDA_PERSISTENT_RET is"); + + } + + if (persistent_ret_offset != 0 && persistent_ret == 0) { + + FATAL( + "AFL_FRIDA_PERSISTENT_RET must be specified if " + "AFL_FRIDA_PERSISTENT_RETADDR_OFFSET is"); + + } + if (persistent_start != 0 && persistent_count == 0) persistent_count = 1000; if (persistent_count != 0 && persistent_count < 100) @@ -39,6 +66,11 @@ void persistent_init(void) { persistent_start == 0 ? ' ' : 'X', persistent_count); OKF("Instrumentation - hook [%s]", hook_name); + 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 (hook_name != NULL) { void *hook_obj = dlopen(hook_name, RTLD_NOW); diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index bc021ff3..6a3c06fa 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -68,5 +68,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_arm64.c b/frida_mode/src/persistent/persistent_arm64.c index c198da69..1215d8da 100644 --- a/frida_mode/src/persistent/persistent_arm64.c +++ b/frida_mode/src/persistent/persistent_arm64.c @@ -111,5 +111,12 @@ void persistent_prologue(GumStalkerOutput *output) { } +void persistent_epilogue(GumStalkerOutput *output) { + + UNUSED_PARAMETER(output); + FATAL("Persistent mode not supported on this architecture"); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index aa772b7f..4c495d47 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,9 +1,11 @@ #include "frida-gum.h" #include "config.h" +#include "debug.h" #include "instrument.h" #include "persistent.h" +#include "util.h" #if defined(__x86_64__) @@ -264,7 +266,6 @@ void persistent_prologue(GumStalkerOutput *output) { GumX86Writer *cw = output->writer.x86; gconstpointer loop = cw->code + 1; - // gum_x86_writer_put_breakpoint(cw); /* Stack must be 16-byte aligned per ABI */ instrument_persitent_save_regs(cw, &saved_regs); @@ -288,7 +289,9 @@ void persistent_prologue(GumStalkerOutput *output) { instrument_persitent_restore_regs(cw, &saved_regs); gconstpointer original = cw->code + 1; /* call original */ + gum_x86_writer_put_call_near_label(cw, original); + /* jmp loop */ gum_x86_writer_put_jmp_near_label(cw, loop); @@ -300,9 +303,23 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(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); + +} + #endif diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c index 20a3dc42..b30dfadf 100644 --- a/frida_mode/src/persistent/persistent_x86.c +++ b/frida_mode/src/persistent/persistent_x86.c @@ -244,9 +244,24 @@ void persistent_prologue(GumStalkerOutput *output) { /* original: */ gum_x86_writer_put_label(cw, original); + if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); } + gum_x86_writer_flush(cw); } +void persistent_epilogue(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_ESP, GUM_REG_ESP, + persistent_ret_offset); + + gum_x86_writer_put_ret(cw); + +} + #endif -- cgit v1.2.3 From 1a2da67ed0505c9ac0aa1048ba3d607f3c1aa639 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sun, 30 May 2021 21:21:37 +0200 Subject: add missing include for _exit() --- frida_mode/src/persistent/persistent_x64.c | 1 + 1 file changed, 1 insertion(+) (limited to 'frida_mode/src/persistent') diff --git a/frida_mode/src/persistent/persistent_x64.c b/frida_mode/src/persistent/persistent_x64.c index 4c495d47..4cb960fc 100644 --- a/frida_mode/src/persistent/persistent_x64.c +++ b/frida_mode/src/persistent/persistent_x64.c @@ -1,3 +1,4 @@ +#include #include "frida-gum.h" #include "config.h" -- cgit v1.2.3