aboutsummaryrefslogtreecommitdiff
path: root/frida_mode/src
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src')
-rw-r--r--frida_mode/src/asan/asan.c12
-rw-r--r--frida_mode/src/instrument/instrument_arm32.c55
-rw-r--r--frida_mode/src/instrument/instrument_coverage.c2
-rw-r--r--frida_mode/src/persistent/persistent_arm32.c31
-rw-r--r--frida_mode/src/shm.c17
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
+