mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 18:18:07 +00:00
code format
This commit is contained in:
@ -19,6 +19,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- Adacore submitted CMPLOG support to the gcc_plugin! :-)
|
- Adacore submitted CMPLOG support to the gcc_plugin! :-)
|
||||||
- llvm_mode:
|
- llvm_mode:
|
||||||
- laf cmp splitting fixed for more comparison types
|
- laf cmp splitting fixed for more comparison types
|
||||||
|
- frida_mode:
|
||||||
|
- now works on Android!
|
||||||
|
|
||||||
|
|
||||||
### Version ++4.01c (release)
|
### Version ++4.01c (release)
|
||||||
|
@ -8,17 +8,23 @@ static gboolean asan_enabled = FALSE;
|
|||||||
gboolean asan_initialized = FALSE;
|
gboolean asan_initialized = FALSE;
|
||||||
|
|
||||||
void asan_config(void) {
|
void asan_config(void) {
|
||||||
|
|
||||||
if (getenv("AFL_USE_FASAN") != NULL) { asan_enabled = TRUE; }
|
if (getenv("AFL_USE_FASAN") != NULL) { asan_enabled = TRUE; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void asan_init(void) {
|
void asan_init(void) {
|
||||||
|
|
||||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "asan:" cYEL " [%c]",
|
FOKF(cBLU "Instrumentation" cRST " - " cGRN "asan:" cYEL " [%c]",
|
||||||
asan_enabled ? 'X' : ' ');
|
asan_enabled ? 'X' : ' ');
|
||||||
|
|
||||||
if (asan_enabled) {
|
if (asan_enabled) {
|
||||||
|
|
||||||
asan_arch_init();
|
asan_arch_init();
|
||||||
asan_initialized = TRUE;
|
asan_initialized = TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean asan_exclude_module(const GumModuleDetails *details,
|
static gboolean asan_exclude_module(const GumModuleDetails *details,
|
||||||
@ -34,13 +40,19 @@ static gboolean asan_exclude_module(const GumModuleDetails *details,
|
|||||||
* then ignore it */
|
* then ignore it */
|
||||||
if (address < details->range->base_address) { return TRUE; }
|
if (address < details->range->base_address) { return TRUE; }
|
||||||
if (address > (details->range->base_address + details->range->size)) {
|
if (address > (details->range->base_address + details->range->size)) {
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ranges_add_exclude((GumMemoryRange *)details->range);
|
ranges_add_exclude((GumMemoryRange *)details->range);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void asan_exclude_module_by_symbol(gchar *symbol_name) {
|
void asan_exclude_module_by_symbol(gchar *symbol_name) {
|
||||||
|
|
||||||
gum_process_enumerate_modules(asan_exclude_module, symbol_name);
|
gum_process_enumerate_modules(asan_exclude_module, symbol_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,61 +17,63 @@ __attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
|
|||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
||||||
// cur_location = (block_address >> 4) ^ (block_address << 8);
|
// cur_location = (block_address >> 4) ^ (block_address << 8);
|
||||||
// shared_mem[cur_location ^ prev_location]++;
|
// shared_mem[cur_location ^ prev_location]++;
|
||||||
// prev_location = cur_location >> 1;
|
// prev_location = cur_location >> 1;
|
||||||
|
|
||||||
/* We can remove this branch when we add support for branch suppression */
|
/* We can remove this branch when we add support for branch suppression */
|
||||||
uint32_t b_code; /* b imm */
|
uint32_t b_code; /* b imm */
|
||||||
uint8_t * shared_mem;
|
uint8_t *shared_mem;
|
||||||
uint64_t *prev_location;
|
uint64_t *prev_location;
|
||||||
|
|
||||||
/* code */
|
/* code */
|
||||||
|
|
||||||
/* save regs */
|
/* save regs */
|
||||||
uint32_t str_r0_sp_rz; /* str r0, [sp - RED_ZONE] */
|
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_r1_sp_rz_4; /* str r1, [sp - (RED_ZONE + 4)] */
|
||||||
|
|
||||||
/* load prev */
|
/* load prev */
|
||||||
uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */
|
uint32_t ldr_r0_pprev; /* ldr r0, [pc-x] */
|
||||||
uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */
|
uint32_t ldrh_r1_r0; /* ldrh r1, [r0] */
|
||||||
|
|
||||||
/* load curr */
|
/* load curr */
|
||||||
uint32_t mov_r0_block_id; /* mov r0, #imm16 */
|
uint32_t mov_r0_block_id; /* mov r0, #imm16 */
|
||||||
|
|
||||||
/* calculate new */
|
/* calculate new */
|
||||||
uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */
|
uint32_t eor_r0_r0_r1; /* eor r0, r0, r1 */
|
||||||
|
|
||||||
/* load map */
|
/* load map */
|
||||||
uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */
|
uint32_t ldr_r1_pmap; /* ldr r1, [pc-x] */
|
||||||
|
|
||||||
/* calculate offset */
|
/* 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 */
|
/* Load the value */
|
||||||
uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */
|
uint32_t ldrb_r0_r1; /* ldrb r0, [r1] */
|
||||||
|
|
||||||
/* Increment the value */
|
/* Increment the value */
|
||||||
uint32_t add_r0_r0_1; /* add r0, r0, #1 */
|
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_r0_lsr_8; /* add r0, r0, r0, lsr #8 */
|
||||||
|
|
||||||
/* Save the value */
|
/* Save the value */
|
||||||
uint32_t strb_r0_r1; /* strb r0, [r1] */
|
uint32_t strb_r0_r1; /* strb r0, [r1] */
|
||||||
|
|
||||||
/* load curr shifted */
|
/* 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 */
|
/* Update prev */
|
||||||
uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */
|
uint32_t ldr_r1_pprev; /* ldr r1, [pc-x] */
|
||||||
uint32_t strh_r0_r1; /* strh r0, [r1] */
|
uint32_t strh_r0_r1; /* strh r0, [r1] */
|
||||||
|
|
||||||
/* restore regs */
|
/* restore regs */
|
||||||
uint32_t ldr_r1_sp_rz_4; /* ldr r1, [sp - (RED_ZONE + 4)] */
|
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_r0_sp_rz; /* ldr r0, [sp - RED_ZONE] */
|
||||||
|
|
||||||
} afl_log_code_asm_t;
|
} afl_log_code_asm_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
|
|
||||||
afl_log_code_asm_t code;
|
afl_log_code_asm_t code;
|
||||||
uint8_t bytes[0];
|
uint8_t bytes[0];
|
||||||
|
|
||||||
@ -81,6 +83,7 @@ typedef union {
|
|||||||
|
|
||||||
static const afl_log_code_asm_t template =
|
static const afl_log_code_asm_t template =
|
||||||
{
|
{
|
||||||
|
|
||||||
.b_code = GUINT32_TO_LE(0xea000001),
|
.b_code = GUINT32_TO_LE(0xea000001),
|
||||||
.shared_mem = (uint8_t *)GUINT32_TO_LE(0xcefaadde),
|
.shared_mem = (uint8_t *)GUINT32_TO_LE(0xcefaadde),
|
||||||
.prev_location = (uint64_t *)GUINT32_TO_LE(0xadba0df0),
|
.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),
|
.strh_r0_r1 = GUINT32_TO_LE(0xe1c100b0),
|
||||||
.ldr_r1_sp_rz_4 = GUINT32_TO_LE(0xe51d1084),
|
.ldr_r1_sp_rz_4 = GUINT32_TO_LE(0xe51d1084),
|
||||||
.ldr_r0_sp_rz = GUINT32_TO_LE(0xe51d0080),
|
.ldr_r0_sp_rz = GUINT32_TO_LE(0xe51d0080),
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
gboolean instrument_is_coverage_optimize_supported(void) {
|
gboolean instrument_is_coverage_optimize_supported(void) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void patch_t3_insn(uint32_t *insn, uint16_t val) {
|
static void patch_t3_insn(uint32_t *insn, uint16_t val) {
|
||||||
|
|
||||||
uint32_t orig = GUINT32_FROM_LE(*insn);
|
uint32_t orig = GUINT32_FROM_LE(*insn);
|
||||||
uint32_t imm12 = (val & 0xfff);
|
uint32_t imm12 = (val & 0xfff);
|
||||||
uint32_t imm4 = (val >> 12);
|
uint32_t imm4 = (val >> 12);
|
||||||
orig |= imm12;
|
orig |= imm12;
|
||||||
orig |= (imm4 << 16);
|
orig |= (imm4 << 16);
|
||||||
*insn = GUINT32_TO_LE(orig);
|
*insn = GUINT32_TO_LE(orig);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize(const cs_insn *instr,
|
void instrument_coverage_optimize(const cs_insn *instr,
|
||||||
GumStalkerOutput *output) {
|
GumStalkerOutput *output) {
|
||||||
|
|
||||||
afl_log_code code = {0};
|
afl_log_code code = {0};
|
||||||
GumArmWriter *cw = output->writer.arm;
|
GumArmWriter *cw = output->writer.arm;
|
||||||
gpointer block_start;
|
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_breakpoint(cw);
|
||||||
gum_arm_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
|
gum_arm_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize_insn(const cs_insn *instr,
|
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(instr);
|
||||||
UNUSED_PARAMETER(output);
|
UNUSED_PARAMETER(output);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instrument_coverage_optimize_init(void) {
|
void instrument_coverage_optimize_init(void) {
|
||||||
|
|
||||||
char *shm_env = getenv(SHM_ENV_VAR);
|
char *shm_env = getenv(SHM_ENV_VAR);
|
||||||
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
|
FVERBOSE("SHM_ENV_VAR: %s", shm_env);
|
||||||
|
|
||||||
if (shm_env == NULL) {
|
if (shm_env == NULL) {
|
||||||
|
|
||||||
FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
|
FWARNF("SHM_ENV_VAR not set, using dummy for debugging purposes");
|
||||||
|
|
||||||
__afl_area_ptr = area_ptr_dummy;
|
__afl_area_ptr = area_ptr_dummy;
|
||||||
memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
|
memset(area_ptr_dummy, '\0', sizeof(area_ptr_dummy));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
|
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
|
||||||
|
|
||||||
if (instrument_previous_pc_addr == NULL) {
|
if (instrument_previous_pc_addr == NULL) {
|
||||||
|
|
||||||
instrument_previous_pc_addr = &instrument_previous_pc;
|
instrument_previous_pc_addr = &instrument_previous_pc;
|
||||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||||
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
|
FVERBOSE("instrument_previous_pc_addr: %p", instrument_previous_pc_addr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void instrument_flush(GumStalkerOutput *output) {
|
void instrument_flush(GumStalkerOutput *output) {
|
||||||
|
@ -242,7 +242,7 @@ static void instrument_coverage_mark_first(void *key, void *value,
|
|||||||
void *user_data) {
|
void *user_data) {
|
||||||
|
|
||||||
UNUSED_PARAMETER(key);
|
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;
|
normal_coverage_data_t *val = (normal_coverage_data_t *)value;
|
||||||
|
|
||||||
val->module = module;
|
val->module = module;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#if defined(__arm__)
|
#if defined(__arm__)
|
||||||
|
|
||||||
// struct _GumArmCpuContext {
|
// struct _GumArmCpuContext {
|
||||||
|
|
||||||
// guint32 pc;
|
// guint32 pc;
|
||||||
// guint32 sp;
|
// guint32 sp;
|
||||||
// guint32 cpsr;
|
// guint32 cpsr;
|
||||||
@ -35,11 +36,14 @@ static GumCpuContext saved_regs = {0};
|
|||||||
static gpointer saved_lr = NULL;
|
static gpointer saved_lr = NULL;
|
||||||
|
|
||||||
gboolean persistent_is_supported(void) {
|
gboolean persistent_is_supported(void) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_persitent_save_regs(GumArmWriter * cw,
|
static void instrument_persitent_save_regs(GumArmWriter *cw,
|
||||||
GumCpuContext *regs) {
|
GumCpuContext *regs) {
|
||||||
|
|
||||||
/* Save Regs */
|
/* Save Regs */
|
||||||
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
@ -50,8 +54,10 @@ static void instrument_persitent_save_regs(GumArmWriter * cw,
|
|||||||
|
|
||||||
/* Save r1-r7 */
|
/* Save r1-r7 */
|
||||||
for (size_t i = ARM_REG_R1; i < ARM_REG_R8; i++) {
|
for (size_t i = ARM_REG_R1; i < ARM_REG_R8; i++) {
|
||||||
|
|
||||||
gum_arm_writer_put_str_reg_reg_offset(
|
gum_arm_writer_put_str_reg_reg_offset(
|
||||||
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
|
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save r8-r12 */
|
/* Save r8-r12 */
|
||||||
@ -94,10 +100,12 @@ static void instrument_persitent_save_regs(GumArmWriter * cw,
|
|||||||
GUM_RED_ZONE_SIZE + sizeof(guint32));
|
GUM_RED_ZONE_SIZE + sizeof(guint32));
|
||||||
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
gum_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_persitent_restore_regs(GumArmWriter * cw,
|
static void instrument_persitent_restore_regs(GumArmWriter *cw,
|
||||||
GumCpuContext *regs) {
|
GumCpuContext *regs) {
|
||||||
|
|
||||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
|
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(regs));
|
||||||
|
|
||||||
/* Restore CPSR */
|
/* Restore CPSR */
|
||||||
@ -125,37 +133,49 @@ static void instrument_persitent_restore_regs(GumArmWriter * cw,
|
|||||||
|
|
||||||
/* Restore r7-r0 */
|
/* Restore r7-r0 */
|
||||||
for (size_t i = ARM_REG_R7; i >= ARM_REG_R0; i--) {
|
for (size_t i = ARM_REG_R7; i >= ARM_REG_R0; i--) {
|
||||||
|
|
||||||
gum_arm_writer_put_ldr_reg_reg_offset(
|
gum_arm_writer_put_ldr_reg_reg_offset(
|
||||||
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
|
cw, i, ARM_REG_R0, offsetof(GumCpuContext, r[i - ARM_REG_R0]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_exit(GumArmWriter *cw) {
|
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_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_arm_writer_put_call_address_with_arguments(cw, GUM_ADDRESS(_exit), 1,
|
||||||
GUM_ARG_REGISTER, ARM_REG_R0);
|
GUM_ARG_REGISTER, ARM_REG_R0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int instrument_afl_persistent_loop_func(void) {
|
static int instrument_afl_persistent_loop_func(void) {
|
||||||
|
|
||||||
int ret = __afl_persistent_loop(persistent_count);
|
int ret = __afl_persistent_loop(persistent_count);
|
||||||
if (instrument_previous_pc_addr == NULL) {
|
if (instrument_previous_pc_addr == NULL) {
|
||||||
|
|
||||||
FATAL("instrument_previous_pc_addr uninitialized");
|
FATAL("instrument_previous_pc_addr uninitialized");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_afl_persistent_loop(GumArmWriter *cw) {
|
static void instrument_afl_persistent_loop(GumArmWriter *cw) {
|
||||||
|
|
||||||
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
|
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
gum_arm_writer_put_call_address_with_arguments(
|
gum_arm_writer_put_call_address_with_arguments(
|
||||||
cw, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
|
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_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) {
|
static void persistent_prologue_hook(GumArmWriter *cw, GumCpuContext *regs) {
|
||||||
|
|
||||||
if (persistent_hook == NULL) return;
|
if (persistent_hook == NULL) return;
|
||||||
|
|
||||||
gum_arm_writer_put_sub_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
|
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_arm_writer_put_add_reg_reg_imm(cw, ARM_REG_SP, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_persitent_save_lr(GumArmWriter *cw) {
|
static void instrument_persitent_save_lr(GumArmWriter *cw) {
|
||||||
|
|
||||||
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
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_arm_writer_put_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_SP,
|
||||||
GUM_RED_ZONE_SIZE);
|
GUM_RED_ZONE_SIZE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SAVE REGS
|
* SAVE REGS
|
||||||
* SAVE RET
|
* SAVE RET
|
||||||
@ -251,9 +275,11 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
|
|||||||
instrument_persitent_save_lr(cw);
|
instrument_persitent_save_lr(cw);
|
||||||
|
|
||||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||||
|
|
||||||
GumArmWriter *cw = output->writer.arm;
|
GumArmWriter *cw = output->writer.arm;
|
||||||
|
|
||||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
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_ldr_reg_reg_offset(cw, ARM_REG_R0, ARM_REG_R0, 0);
|
||||||
|
|
||||||
gum_arm_writer_put_bx_reg(cw, ARM_REG_R0);
|
gum_arm_writer_put_bx_reg(cw, ARM_REG_R0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,24 +16,31 @@
|
|||||||
#define ASHMEM_DEVICE "/dev/ashmem"
|
#define ASHMEM_DEVICE "/dev/ashmem"
|
||||||
|
|
||||||
void *shm_create(size_t size) {
|
void *shm_create(size_t size) {
|
||||||
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
char ourkey[11] = {0};
|
char ourkey[11] = {0};
|
||||||
void * addr = MAP_FAILED;
|
void *addr = MAP_FAILED;
|
||||||
struct ashmem_pin pin = {0, size};
|
struct ashmem_pin pin = {0, size};
|
||||||
|
|
||||||
fd = open(ASHMEM_DEVICE, O_RDWR);
|
fd = open(ASHMEM_DEVICE, O_RDWR);
|
||||||
if (fd < 0) { FFATAL("Failed open /dev/ashmem: %d", errno); }
|
if (fd < 0) { FFATAL("Failed open /dev/ashmem: %d", errno); }
|
||||||
|
|
||||||
if (snprintf(ourkey, sizeof(ourkey) - 1, "%d", IPC_PRIVATE) < 0) {
|
if (snprintf(ourkey, sizeof(ourkey) - 1, "%d", IPC_PRIVATE) < 0) {
|
||||||
|
|
||||||
FFATAL("Failed to generate key: %d", errno);
|
FFATAL("Failed to generate key: %d", errno);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, ASHMEM_SET_NAME, ourkey) < 0) {
|
if (ioctl(fd, ASHMEM_SET_NAME, ourkey) < 0) {
|
||||||
|
|
||||||
FFATAL("ioctl(ASHMEM_SET_NAME) errno: %d\n", errno);
|
FFATAL("ioctl(ASHMEM_SET_NAME) errno: %d\n", errno);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
|
if (ioctl(fd, ASHMEM_SET_SIZE, size) < 0) {
|
||||||
|
|
||||||
FFATAL("ioctl(ASHMEM_SET_SIZE) errno: %d\n", errno);
|
FFATAL("ioctl(ASHMEM_SET_SIZE) errno: %d\n", errno);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
@ -46,9 +53,12 @@ void *shm_create(size_t size) {
|
|||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
void *shm_create(size_t size) {
|
void *shm_create(size_t size) {
|
||||||
|
|
||||||
int shm_id =
|
int shm_id =
|
||||||
shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
|
shmget(IPC_PRIVATE, size, IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);
|
||||||
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
|
if (shm_id < 0) { FFATAL("shm_id < 0 - errno: %d\n", errno); }
|
||||||
@ -61,12 +71,17 @@ void *shm_create(size_t size) {
|
|||||||
* dies.
|
* dies.
|
||||||
*/
|
*/
|
||||||
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
|
if (shmctl(shm_id, IPC_RMID, NULL) < 0) {
|
||||||
|
|
||||||
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
|
FFATAL("shmctl (IPC_RMID) < 0 - errno: %d\n", errno);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear it, not sure it's necessary, just seems like good practice */
|
/* Clear it, not sure it's necessary, just seems like good practice */
|
||||||
memset(addr, '\0', size);
|
memset(addr, '\0', size);
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user