mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 10:08:07 +00:00
Fixes for arm/arm64
This commit is contained in:
@ -214,6 +214,9 @@ all: $(FRIDA_TRACE) $(FRIDA_TRACE_LIB) $(AFLPP_FRIDA_DRIVER_HOOK_OBJ) $(AFLPP_QE
|
|||||||
arm:
|
arm:
|
||||||
CFLAGS="-marm" LDFLAGS="-marm" ARCH="armhf" TARGET_CC=arm-linux-gnueabihf-gcc TARGET_CXX=arm-linux-gnueabihf-g++ make all
|
CFLAGS="-marm" LDFLAGS="-marm" ARCH="armhf" TARGET_CC=arm-linux-gnueabihf-gcc TARGET_CXX=arm-linux-gnueabihf-g++ make all
|
||||||
|
|
||||||
|
arm64:
|
||||||
|
ARCH="arm64" TARGET_CC=aarch64-linux-gnu-gcc TARGET_CXX=aarch64-linux-gnu-g++ make all
|
||||||
|
|
||||||
$(BUILD_DIR):
|
$(BUILD_DIR):
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
// r15 - pc
|
// r15 - pc
|
||||||
|
|
||||||
static GumCpuContext saved_regs = {0};
|
static GumCpuContext saved_regs = {0};
|
||||||
static gpointer saved_lr = NULL;
|
static gpointer persistent_loop = NULL;
|
||||||
|
|
||||||
gboolean persistent_is_supported(void) {
|
gboolean persistent_is_supported(void) {
|
||||||
|
|
||||||
@ -141,17 +141,10 @@ static void instrument_persitent_restore_regs(GumArmWriter *cw,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_exit(GumArmWriter *cw) {
|
static void instrument_afl_persistent_loop_func(void) {
|
||||||
|
|
||||||
gum_arm_writer_put_sub_reg_reg_reg(cw, ARM_REG_R0, ARM_REG_R0, ARM_REG_R0);
|
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); }
|
||||||
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) {
|
if (instrument_previous_pc_addr == NULL) {
|
||||||
|
|
||||||
FATAL("instrument_previous_pc_addr uninitialized");
|
FATAL("instrument_previous_pc_addr uninitialized");
|
||||||
@ -159,7 +152,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +195,8 @@ 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);
|
||||||
|
|
||||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
|
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0,
|
||||||
|
GUM_ADDRESS(&persistent_ret));
|
||||||
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0, 0);
|
gum_arm_writer_put_str_reg_reg_offset(cw, ARM_REG_LR, ARM_REG_R0, 0);
|
||||||
|
|
||||||
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,
|
||||||
@ -214,65 +207,35 @@ static void instrument_persitent_save_lr(GumArmWriter *cw) {
|
|||||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||||
* SAVE REGS
|
* SAVE REGS
|
||||||
* SAVE RET
|
* loop: (Save address of where the eiplogue should jump back to)
|
||||||
* POP RET
|
|
||||||
* loop:
|
|
||||||
* CALL instrument_afl_persistent_loop
|
* CALL instrument_afl_persistent_loop
|
||||||
* TEST EAX, EAX
|
* CALL hook (optionally)
|
||||||
* JZ end:
|
|
||||||
* call hook (optionally)
|
|
||||||
* RESTORE REGS
|
* RESTORE REGS
|
||||||
* call original
|
|
||||||
* jmp loop:
|
|
||||||
*
|
|
||||||
* end:
|
|
||||||
* JMP SAVED RET
|
|
||||||
*
|
|
||||||
* original:
|
|
||||||
* INSTRUMENTED PERSISTENT FUNC
|
* INSTRUMENTED PERSISTENT FUNC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GumArmWriter *cw = output->writer.arm;
|
GumArmWriter *cw = output->writer.arm;
|
||||||
|
|
||||||
gconstpointer loop = cw->code + 1;
|
|
||||||
|
|
||||||
FVERBOSE("Persistent loop reached");
|
FVERBOSE("Persistent loop reached");
|
||||||
|
|
||||||
|
if (persistent_ret == 0) { instrument_persitent_save_lr(cw); }
|
||||||
|
|
||||||
|
/* Save the current context */
|
||||||
instrument_persitent_save_regs(cw, &saved_regs);
|
instrument_persitent_save_regs(cw, &saved_regs);
|
||||||
|
|
||||||
/* loop: */
|
/* Store a pointer to where we should return for our next iteration */
|
||||||
gum_arm_writer_put_label(cw, loop);
|
persistent_loop = gum_arm_writer_cur(cw);
|
||||||
|
|
||||||
/* call instrument_prologue_func */
|
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||||
instrument_afl_persistent_loop(cw);
|
instrument_afl_persistent_loop(cw);
|
||||||
|
|
||||||
/* jz done */
|
|
||||||
gconstpointer done = cw->code + 1;
|
|
||||||
gum_arm_writer_put_cmp_reg_imm(cw, ARM_REG_R0, 0);
|
|
||||||
gum_arm_writer_put_b_cond_label(cw, ARM_CC_EQ, done);
|
|
||||||
|
|
||||||
/* Optionally call the persistent hook */
|
/* Optionally call the persistent hook */
|
||||||
persistent_prologue_hook(cw, &saved_regs);
|
persistent_prologue_hook(cw, &saved_regs);
|
||||||
|
|
||||||
|
/* Restore our CPU context before we continue execution */
|
||||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||||
gconstpointer original = cw->code + 1;
|
|
||||||
/* call original */
|
|
||||||
|
|
||||||
gum_arm_writer_put_bl_label(cw, original);
|
|
||||||
|
|
||||||
/* jmp loop */
|
|
||||||
gum_arm_writer_put_b_label(cw, loop);
|
|
||||||
|
|
||||||
/* done: */
|
|
||||||
gum_arm_writer_put_label(cw, done);
|
|
||||||
|
|
||||||
instrument_exit(cw);
|
|
||||||
|
|
||||||
/* original: */
|
|
||||||
gum_arm_writer_put_label(cw, original);
|
|
||||||
|
|
||||||
instrument_persitent_save_lr(cw);
|
|
||||||
|
|
||||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
||||||
|
|
||||||
@ -284,7 +247,8 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
|||||||
|
|
||||||
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
if (persistent_debug) { gum_arm_writer_put_breakpoint(cw); }
|
||||||
|
|
||||||
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0, GUM_ADDRESS(&saved_lr));
|
gum_arm_writer_put_ldr_reg_address(cw, ARM_REG_R0,
|
||||||
|
GUM_ADDRESS(&persistent_loop));
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ typedef struct {
|
|||||||
} persistent_ctx_t;
|
} persistent_ctx_t;
|
||||||
|
|
||||||
static persistent_ctx_t saved_regs = {0};
|
static persistent_ctx_t saved_regs = {0};
|
||||||
static gpointer saved_lr = NULL;
|
static gpointer persistent_loop = NULL;
|
||||||
|
|
||||||
gboolean persistent_is_supported(void) {
|
gboolean persistent_is_supported(void) {
|
||||||
|
|
||||||
@ -216,17 +216,10 @@ static void instrument_persitent_restore_regs(GumArm64Writer *cw,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void instrument_exit(GumArm64Writer *cw) {
|
static void instrument_afl_persistent_loop_func(void) {
|
||||||
|
|
||||||
gum_arm64_writer_put_mov_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR);
|
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); }
|
||||||
gum_arm64_writer_put_call_address_with_arguments(
|
|
||||||
cw, GUM_ADDRESS(_exit), 1, GUM_ARG_REGISTER, ARM64_REG_X0);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static int instrument_afl_persistent_loop_func(void) {
|
|
||||||
|
|
||||||
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");
|
||||||
@ -234,7 +227,6 @@ static int instrument_afl_persistent_loop_func(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*instrument_previous_pc_addr = instrument_hash_zero;
|
*instrument_previous_pc_addr = instrument_hash_zero;
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,7 +276,7 @@ static void instrument_persitent_save_lr(GumArm64Writer *cw) {
|
|||||||
GUM_INDEX_PRE_ADJUST);
|
GUM_INDEX_PRE_ADJUST);
|
||||||
|
|
||||||
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
||||||
GUM_ADDRESS(&saved_lr));
|
GUM_ADDRESS(&persistent_ret));
|
||||||
|
|
||||||
gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0);
|
gum_arm64_writer_put_str_reg_reg_offset(cw, ARM64_REG_LR, ARM64_REG_X0, 0);
|
||||||
|
|
||||||
@ -297,65 +289,35 @@ static void instrument_persitent_save_lr(GumArm64Writer *cw) {
|
|||||||
void persistent_prologue_arch(GumStalkerOutput *output) {
|
void persistent_prologue_arch(GumStalkerOutput *output) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* SAVE RET (Used to write the epilogue if persistent_ret is not set)
|
||||||
* SAVE REGS
|
* SAVE REGS
|
||||||
* SAVE RET
|
* loop: (Save address of where the eiplogue should jump back to)
|
||||||
* POP RET
|
|
||||||
* loop:
|
|
||||||
* CALL instrument_afl_persistent_loop
|
* CALL instrument_afl_persistent_loop
|
||||||
* TEST EAX, EAX
|
* CALL hook (optionally)
|
||||||
* JZ end:
|
|
||||||
* call hook (optionally)
|
|
||||||
* RESTORE REGS
|
* RESTORE REGS
|
||||||
* call original
|
|
||||||
* jmp loop:
|
|
||||||
*
|
|
||||||
* end:
|
|
||||||
* JMP SAVED RET
|
|
||||||
*
|
|
||||||
* original:
|
|
||||||
* INSTRUMENTED PERSISTENT FUNC
|
* INSTRUMENTED PERSISTENT FUNC
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GumArm64Writer *cw = output->writer.arm64;
|
GumArm64Writer *cw = output->writer.arm64;
|
||||||
|
|
||||||
gconstpointer loop = cw->code + 1;
|
|
||||||
|
|
||||||
FVERBOSE("Persistent loop reached");
|
FVERBOSE("Persistent loop reached");
|
||||||
|
|
||||||
|
if (persistent_ret == 0) { instrument_persitent_save_lr(cw); }
|
||||||
|
|
||||||
|
/* Save the current context */
|
||||||
instrument_persitent_save_regs(cw, &saved_regs);
|
instrument_persitent_save_regs(cw, &saved_regs);
|
||||||
|
|
||||||
/* loop: */
|
/* Store a pointer to where we should return for our next iteration */
|
||||||
gum_arm64_writer_put_label(cw, loop);
|
persistent_loop = gum_arm64_writer_cur(cw);
|
||||||
|
|
||||||
/* call instrument_prologue_func */
|
/* call __afl_persistent_loop and _exit if zero. Also reset our previous_pc */
|
||||||
instrument_afl_persistent_loop(cw);
|
instrument_afl_persistent_loop(cw);
|
||||||
|
|
||||||
/* jz done */
|
|
||||||
gconstpointer done = cw->code + 1;
|
|
||||||
gum_arm64_writer_put_cmp_reg_reg(cw, ARM64_REG_X0, ARM64_REG_XZR);
|
|
||||||
gum_arm64_writer_put_b_cond_label(cw, ARM64_CC_EQ, done);
|
|
||||||
|
|
||||||
/* Optionally call the persistent hook */
|
/* Optionally call the persistent hook */
|
||||||
persistent_prologue_hook(cw, &saved_regs);
|
persistent_prologue_hook(cw, &saved_regs);
|
||||||
|
|
||||||
|
/* Restore our CPU context before we continue execution */
|
||||||
instrument_persitent_restore_regs(cw, &saved_regs);
|
instrument_persitent_restore_regs(cw, &saved_regs);
|
||||||
gconstpointer original = cw->code + 1;
|
|
||||||
/* call original */
|
|
||||||
|
|
||||||
gum_arm64_writer_put_bl_label(cw, original);
|
|
||||||
|
|
||||||
/* jmp loop */
|
|
||||||
gum_arm64_writer_put_b_label(cw, loop);
|
|
||||||
|
|
||||||
/* done: */
|
|
||||||
gum_arm64_writer_put_label(cw, done);
|
|
||||||
|
|
||||||
instrument_exit(cw);
|
|
||||||
|
|
||||||
/* original: */
|
|
||||||
gum_arm64_writer_put_label(cw, original);
|
|
||||||
|
|
||||||
instrument_persitent_save_lr(cw);
|
|
||||||
|
|
||||||
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
||||||
|
|
||||||
@ -368,7 +330,7 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
|||||||
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
if (persistent_debug) { gum_arm64_writer_put_brk_imm(cw, 0); }
|
||||||
|
|
||||||
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
gum_arm64_writer_put_ldr_reg_address(cw, ARM64_REG_X0,
|
||||||
GUM_ADDRESS(&saved_lr));
|
GUM_ADDRESS(&persistent_loop));
|
||||||
|
|
||||||
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0);
|
gum_arm64_writer_put_ldr_reg_reg_offset(cw, ARM64_REG_X0, ARM64_REG_X0, 0);
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ static void instrument_persitent_restore_regs(GumX86Writer *cw,
|
|||||||
|
|
||||||
static void instrument_afl_persistent_loop_func(void) {
|
static void instrument_afl_persistent_loop_func(void) {
|
||||||
|
|
||||||
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0);};
|
if (__afl_persistent_loop(persistent_count) == 0) { _exit(0); };
|
||||||
|
|
||||||
if (instrument_previous_pc_addr == NULL) {
|
if (instrument_previous_pc_addr == NULL) {
|
||||||
|
|
||||||
@ -135,6 +135,7 @@ static void instrument_afl_persistent_loop(GumX86Writer *cw) {
|
|||||||
|
|
||||||
gum_x86_writer_put_call_address_with_arguments(
|
gum_x86_writer_put_call_address_with_arguments(
|
||||||
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
|
cw, GUM_CALL_CAPI, GUM_ADDRESS(instrument_afl_persistent_loop_func), 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
|
static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
|
||||||
@ -167,7 +168,8 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
|
|||||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
|
gum_x86_writer_put_push_reg(cw, GUM_X86_EAX);
|
||||||
gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
|
gum_x86_writer_put_push_reg(cw, GUM_X86_EBX);
|
||||||
|
|
||||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&persistent_ret));
|
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX,
|
||||||
|
GUM_ADDRESS(&persistent_ret));
|
||||||
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP,
|
gum_x86_writer_put_mov_reg_reg_offset_ptr(cw, GUM_X86_EBX, GUM_X86_ESP,
|
||||||
offset);
|
offset);
|
||||||
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_EAX, GUM_X86_EBX);
|
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_EAX, GUM_X86_EBX);
|
||||||
@ -218,6 +220,7 @@ void persistent_prologue_arch(GumStalkerOutput *output) {
|
|||||||
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
||||||
|
|
||||||
/* The original instrumented code is emitted here. */
|
/* The original instrumented code is emitted here. */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
void persistent_epilogue_arch(GumStalkerOutput *output) {
|
||||||
@ -227,10 +230,11 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
|
|||||||
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
|
||||||
|
|
||||||
/* The stack should be aligned when we re-enter our loop */
|
/* The stack should be aligned when we re-enter our loop */
|
||||||
gum_x86_writer_put_and_reg_u32 (cw, GUM_X86_ESP, 0xfffffff0);
|
gum_x86_writer_put_and_reg_u32(cw, GUM_X86_ESP, 0xfffffff0);
|
||||||
gum_x86_writer_put_sub_reg_imm (cw, GUM_X86_ESP, 0x4);
|
gum_x86_writer_put_sub_reg_imm(cw, GUM_X86_ESP, 0x4);
|
||||||
|
|
||||||
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&persistent_loop));
|
gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX,
|
||||||
|
GUM_ADDRESS(&persistent_loop));
|
||||||
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_EAX);
|
gum_x86_writer_put_jmp_reg_ptr(cw, GUM_X86_EAX);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user