diff options
Diffstat (limited to 'frida_mode/src')
-rw-r--r-- | frida_mode/src/asan/asan.c | 12 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_arm32.c | 55 | ||||
-rw-r--r-- | frida_mode/src/instrument/instrument_coverage.c | 2 | ||||
-rw-r--r-- | frida_mode/src/persistent/persistent_arm32.c | 31 | ||||
-rw-r--r-- | frida_mode/src/shm.c | 17 |
5 files changed, 94 insertions, 23 deletions
diff --git a/frida_mode/src/asan/asan.c b/frida_mode/src/asan/asan.c index bd4062be..ad171337 100644 --- a/frida_mode/src/asan/asan.c +++ b/frida_mode/src/asan/asan.c @@ -8,17 +8,23 @@ static gboolean asan_enabled = FALSE; gboolean asan_initialized = FALSE; void asan_config(void) { + if (getenv("AFL_USE_FASAN") != NULL) { asan_enabled = TRUE; } + } void asan_init(void) { + FOKF(cBLU "Instrumentation" cRST " - " cGRN "asan:" cYEL " [%c]", asan_enabled ? 'X' : ' '); if (asan_enabled) { + asan_arch_init(); asan_initialized = TRUE; + } + } static gboolean asan_exclude_module(const GumModuleDetails *details, @@ -34,13 +40,19 @@ static gboolean asan_exclude_module(const GumModuleDetails *details, * then ignore it */ if (address < details->range->base_address) { return TRUE; } if (address > (details->range->base_address + details->range->size)) { + return TRUE; + } ranges_add_exclude((GumMemoryRange *)details->range); return FALSE; + } void asan_exclude_module_by_symbol(gchar *symbol_name) { + gum_process_enumerate_modules(asan_exclude_module, symbol_name); + } + diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c index 0ff69952..f2e825ee 100644 --- a/frida_mode/src/instrument/instrument_arm32.c +++ b/frida_mode/src/instrument/instrument_arm32.c @@ -17,61 +17,63 @@ __attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE]; #pragma pack(push, 1) typedef struct { + // cur_location = (block_address >> 4) ^ (block_address << 8); // shared_mem[cur_location ^ prev_location]++; // prev_location = cur_location >> 1; /* We can remove this branch when we add support for branch suppression */ - uint32_t b_code; /* b imm */ - uint8_t * shared_mem; + uint32_t b_code; /* b imm */ + uint8_t *shared_mem; uint64_t *prev_location; /* code */ /* save regs */ - uint32_t str_r0_sp_rz; /* str r0, [sp - RED_ZONE] */ - uint32_t str_r1_sp_rz_4; /* str r1, [sp - (RED_ZONE + 4)] */ + uint32_t str_r0_sp_rz; /* str r0, [sp - RED_ZONE] */ + uint32_t str_r1_sp_rz_4; /* str r1, [sp - (RED_ZONE + 4)] */ /* load prev */ - uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */ - uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */ + uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */ + uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */ /* load curr */ - uint32_t mov_r0_block_id; /* mov r0, #imm16 */ + uint32_t mov_r0_block_id; /* mov r0, #imm16 */ /* calculate new */ - uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */ + uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */ /* load map */ - uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */ + uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */ /* calculate offset */ - uint32_t add_r1_r1_r0; /* add r1, r1, r0 */ + uint32_t add_r1_r1_r0; /* add r1, r1, r0 */ /* Load the value */ - uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */ + uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */ /* Increment the value */ - uint32_t add_r0_r0_1; /* add r0, r0, #1 */ - uint32_t add_r0_r0_r0_lsr_8; /* add r0, r0, r0, lsr #8 */ + uint32_t add_r0_r0_1; /* add r0, r0, #1 */ + uint32_t add_r0_r0_r0_lsr_8; /* add r0, r0, r0, lsr #8 */ /* Save the value */ - uint32_t strb_r0_r1; /* strb r0, [r1] */ + uint32_t strb_r0_r1; /* strb r0, [r1] */ /* load curr shifted */ - uint32_t mov_r0_block_id_shr_1; /* mov r0, #imm16 >> 1*/ + uint32_t mov_r0_block_id_shr_1; /* mov r0, #imm16 >> 1*/ /* Update prev */ - uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */ - uint32_t strh_r0_r1; /* strh r0, [r1] */ + uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */ + uint32_t strh_r0_r1; /* strh r0, [r1] */ /* restore regs */ - uint32_t ldr_r1_sp_rz_4; /* ldr r1, [sp - (RED_ZONE + 4)] */ - uint32_t ldr_r0_sp_rz; /* ldr r0, [sp - RED_ZONE] */ + uint32_t ldr_r1_sp_rz_4; /* ldr r1, [sp - (RED_ZONE + 4)] */ + uint32_t ldr_r0_sp_rz; /* ldr r0, [sp - RED_ZONE] */ } afl_log_code_asm_t; typedef union { + afl_log_code_asm_t code; uint8_t bytes[0]; @@ -81,6 +83,7 @@ typedef union { static const afl_log_code_asm_t template = { + .b_code = GUINT32_TO_LE(0xea000001), .shared_mem = (uint8_t *)GUINT32_TO_LE(0xcefaadde), .prev_location = (uint64_t *)GUINT32_TO_LE(0xadba0df0), @@ -101,25 +104,31 @@ static const afl_log_code_asm_t template = .strh_r0_r1 = GUINT32_TO_LE(0xe1c100b0), .ldr_r1_sp_rz_4 = GUINT32_TO_LE(0xe51d1084), .ldr_r0_sp_rz = GUINT32_TO_LE(0xe51d0080), + } ; gboolean instrument_is_coverage_optimize_supported(void) { + return true; + } static void patch_t3_insn(uint32_t *insn, uint16_t val) { + uint32_t orig = GUINT32_FROM_LE(*insn); uint32_t imm12 = (val & 0xfff); uint32_t imm4 = (val >> 12); orig |= imm12; orig |= (imm4 << 16); *insn = GUINT32_TO_LE(orig); + } void instrument_coverage_optimize(const cs_insn *instr, GumStalkerOutput *output) { + afl_log_code code = {0}; GumArmWriter *cw = output->writer.arm; gpointer block_start; @@ -149,6 +158,7 @@ void instrument_coverage_optimize(const cs_insn *instr, // gum_arm_writer_put_breakpoint(cw); gum_arm_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); + } void instrument_coverage_optimize_insn(const cs_insn *instr, @@ -156,26 +166,33 @@ void instrument_coverage_optimize_insn(const cs_insn *instr, UNUSED_PARAMETER(instr); UNUSED_PARAMETER(output); + } void instrument_coverage_optimize_init(void) { + char *shm_env = getenv(SHM_ENV_VAR); FVERBOSE("SHM_ENV_VAR: %s", shm_env); if (shm_env == NULL) { + FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes"); __afl_area_ptr = area_ptr_dummy; memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy)); + } FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr); if (instrument_previous_pc_addr == NULL) { + instrument_previous_pc_addr = &instrument_previous_pc; *instrument_previous_pc_addr = instrument_hash_zero; FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr); + } + } void instrument_flush(GumStalkerOutput *output) { diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c index 25913585..ff2f4024 100644 --- a/frida_mode/src/instrument/instrument_coverage.c +++ b/frida_mode/src/instrument/instrument_coverage.c @@ -242,7 +242,7 @@ static void instrument_coverage_mark_first(void *key, void *value, void *user_data) { UNUSED_PARAMETER(key); - coverage_range_t * module = (coverage_range_t *)user_data; + coverage_range_t *module = (coverage_range_t *)user_data; normal_coverage_data_t *val = (normal_coverage_data_t *)value; val->module = module; diff --git a/frida_mode/src/persistent/persistent_arm32.c b/frida_mode/src/persistent/persistent_arm32.c index a2b63652..dbe51eb5 100644 --- a/frida_mode/src/persistent/persistent_arm32.c +++ b/frida_mode/src/persistent/persistent_arm32.c @@ -7,6 +7,7 @@ #if defined(__arm__) // struct _GumArmCpuContext { + // guint32 pc; // guint32 sp; // guint32 cpsr; @@ -35,11 +36,14 @@ static GumCpuContext saved_regs = {0}; static gpointer saved_lr = NULL; gboolean persistent_is_supported(void) { + return true; + } -static void instrument_persitent_save_regs(GumArmWriter * cw, +static void instrument_persitent_save_regs(GumArmWriter *cw, GumCpuContext *regs) { + /* Save Regs */ gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP, GUM_RED_ZONE_SIZE); @@ -50,8 +54,10 @@ static void instrument_persitent_save_regs(GumArmWriter * cw, /* Save r1-r7 */ for (size_t i = ARM_REG_R1; i < ARM_REG_R8; i++) { + gum_arm_writer_put_str_reg_reg_offset( cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0])); + } /* Save r8-r12 */ @@ -94,10 +100,12 @@ static void instrument_persitent_save_regs(GumArmWriter * cw, GUM_RED_ZONE_SIZE + sizeof(guint32)); gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP, GUM_RED_ZONE_SIZE); + } -static void instrument_persitent_restore_regs(GumArmWriter * cw, +static void instrument_persitent_restore_regs(GumArmWriter *cw, GumCpuContext *regs) { + gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs)); /* Restore CPSR */ @@ -125,37 +133,49 @@ static void instrument_persitent_restore_regs(GumArmWriter * cw, /* Restore r7-r0 */ for (size_t i = ARM_REG_R7; i >= ARM_REG_R0; i--) { + gum_arm_writer_put_ldr_reg_reg_offset( cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0])); + } + } static void instrument_exit(GumArmWriter *cw) { + gum_arm_writer_put_sub_reg_reg_reg(cw, ARM_REG_R0, ARM_REG_R0, ARM_REG_R0); gum_arm_writer_put_call_address_with_arguments(cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM_REG_R0); + } static int instrument_afl_persistent_loop_func(void) { + int ret = __afl_persistent_loop(persistent_count); if (instrument_previous_pc_addr == NULL) { + FATAL("instrument_previous_pc_addr uninitialized"); + } *instrument_previous_pc_addr = instrument_hash_zero; return ret; + } static void instrument_afl_persistent_loop(GumArmWriter *cw) { + gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP, GUM_RED_ZONE_SIZE); gum_arm_writer_put_call_address_with_arguments( cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0); gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP, GUM_RED_ZONE_SIZE); + } static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) { + if (persistent_hook == NULL) return; gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP, @@ -175,9 +195,11 @@ static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) { gum_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP, GUM_RED_ZONE_SIZE); + } static void instrument_persitent_save_lr(GumArmWriter *cw) { + gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP, GUM_RED_ZONE_SIZE); @@ -186,9 +208,11 @@ static void instrument_persitent_save_lr(GumArmWriter *cw) { gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP, GUM_RED_ZONE_SIZE); + } void persistent_prologue_arch(GumStalkerOutput *output) { + /* * SAVE REGS * SAVE RET @@ -251,9 +275,11 @@ void persistent_prologue_arch(GumStalkerOutput *output) { instrument_persitent_save_lr(cw); if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); } + } void persistent_epilogue_arch(GumStalkerOutput *output) { + GumArmWriter *cw = output->writer.arm; if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); } @@ -263,6 +289,7 @@ void persistent_epilogue_arch(GumStalkerOutput *output) { gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_R0, 0); gum_arm_writer_put_bx_reg(cw, ARM_REG_R0); + } #endif diff --git a/frida_mode/src/shm.c b/frida_mode/src/shm.c index 5b885b04..282526e8 100644 --- a/frida_mode/src/shm.c +++ b/frida_mode/src/shm.c @@ -16,24 +16,31 @@ #define ASHMEM_DEVICE "/dev/ashmem" void *shm_create(size_t size) { + int fd = -1; char ourkey[11] = {0}; - void * addr = MAP_FAILED; + void *addr = MAP_FAILED; struct ashmem_pin pin = {0, size}; fd = open(ASHMEM_DEVICE, O_RDWR); if (fd < 0) { FFATAL("Failed open /dev/ashmem: %d", errno); } if (snprintf(ourkey, sizeof(ourkey) - 1, "%d", IPC_PRIVATE) < 0) { + FFATAL("Failed to generate key: %d", errno); + } if (ioctl(fd, ASHMEM_SET_NAME, ourkey) < 0) { + FFATAL("ioctl(ASHMEM_SET_NAME) errno: %d\n", errno); + } if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) { + FFATAL("ioctl(ASHMEM_SET_SIZE) errno: %d\n", errno); + } addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); @@ -46,9 +53,12 @@ void *shm_create(size_t size) { close(fd); return addr; + } + #else void *shm_create(size_t size) { + int shm_id = shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR); if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); } @@ -61,12 +71,17 @@ void *shm_create(size_t size) { * dies. */ if (shmctl(shm_id, IPC_RMID, NULL) < 0) { + FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno); + } /* Clear it, not sure it's necessary, just seems like good practice */ memset(addr, '\0', size); return addr; + } + #endif + |