aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frida_mode/hook/frida_hook.c4
-rw-r--r--frida_mode/src/persistent/persistent_x86.c79
2 files changed, 25 insertions, 58 deletions
diff --git a/frida_mode/hook/frida_hook.c b/frida_mode/hook/frida_hook.c
index da1a59b2..59a92e7e 100644
--- a/frida_mode/hook/frida_hook.c
+++ b/frida_mode/hook/frida_hook.c
@@ -31,8 +31,8 @@ __attribute__((visibility("default"))) void afl_persistent_hook(
// do a length check matching the target!
void **esp = (void **)regs->esp;
- void *arg1 = esp[0];
- void **arg2 = &esp[1];
+ void *arg1 = esp[1];
+ void **arg2 = &esp[2];
memcpy(arg1, input_buf, input_buf_len);
*arg2 = (void *)input_buf_len;
diff --git a/frida_mode/src/persistent/persistent_x86.c b/frida_mode/src/persistent/persistent_x86.c
index e9bde3d2..af21889c 100644
--- a/frida_mode/src/persistent/persistent_x86.c
+++ b/frida_mode/src/persistent/persistent_x86.c
@@ -16,8 +16,7 @@ typedef struct {
} persistent_ctx_t;
static persistent_ctx_t saved_regs = {0};
-
-static gpointer saved_ret = NULL;
+static gpointer persistent_loop = NULL;
gboolean persistent_is_supported(void) {
@@ -118,18 +117,10 @@ static void instrument_persitent_restore_regs(GumX86Writer *cw,
}
-static void instrument_exit(GumX86Writer *cw) {
-
- gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(_exit));
- gum_x86_writer_put_mov_reg_u32(cw, GUM_X86_EDI, 0);
- gum_x86_writer_put_push_reg(cw, GUM_X86_EDI);
- gum_x86_writer_put_call_reg(cw, GUM_X86_EAX);
-
-}
+static void instrument_afl_persistent_loop_func(void) {
-static int instrument_afl_persistent_loop_func(void) {
+ if (__afl_persistent_loop(persistent_count) == 0) { _exit(0);};
- int ret = __afl_persistent_loop(persistent_count);
if (instrument_previous_pc_addr == NULL) {
FATAL("instrument_previous_pc_addr uninitialized");
@@ -137,7 +128,6 @@ static int instrument_afl_persistent_loop_func(void) {
}
*instrument_previous_pc_addr = instrument_hash_zero;
- return ret;
}
@@ -145,8 +135,6 @@ 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_X86_EAX, GUM_X86_EAX);
-
}
static void persistent_prologue_hook(GumX86Writer *cw, persistent_ctx_t *regs) {
@@ -179,7 +167,7 @@ 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_EBX);
- gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_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,
offset);
gum_x86_writer_put_mov_reg_ptr_reg(cw, GUM_X86_EAX, GUM_X86_EBX);
@@ -193,68 +181,43 @@ static void instrument_persitent_save_ret(GumX86Writer *cw) {
void persistent_prologue_arch(GumStalkerOutput *output) {
/*
+ * SAVE RET (Used to write the epilogue if persistent_ret is not set)
* SAVE REGS
- * SAVE RET
- * POP RET
- * loop:
+ * loop: (Save address of where the eiplogue should jump back to)
* CALL instrument_afl_persistent_loop
- * TEST EAX, EAX
- * JZ end:
- * call hook (optionally)
+ * 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;
-
FVERBOSE("Persistent loop reached");
- /* Pop the return value */
- gum_x86_writer_put_lea_reg_reg_offset(cw, GUM_X86_ESP, GUM_X86_ESP, 4);
+ /*
+ * If we haven't set persistent_ret, then assume that we are dealing with a
+ * function and we should loop when that function returns.
+ */
+ if (persistent_ret == 0) { instrument_persitent_save_ret(cw); }
+ /* Save the current context */
instrument_persitent_save_regs(cw, &saved_regs);
- /* loop: */
- gum_x86_writer_put_label(cw, loop);
+ /* Store a pointer to where we should return for our next iteration */
+ persistent_loop = gum_x86_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);
- /* 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);
+ /* Restore our CPU context before we continue execution */
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_exit(cw);
-
- /* original: */
- gum_x86_writer_put_label(cw, original);
-
- instrument_persitent_save_ret(cw);
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
+ /* The original instrumented code is emitted here. */
}
void persistent_epilogue_arch(GumStalkerOutput *output) {
@@ -263,7 +226,11 @@ void persistent_epilogue_arch(GumStalkerOutput *output) {
if (persistent_debug) { gum_x86_writer_put_breakpoint(cw); }
- gum_x86_writer_put_mov_reg_address(cw, GUM_X86_EAX, GUM_ADDRESS(&saved_ret));
+ /* 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_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_jmp_reg_ptr(cw, GUM_X86_EAX);
}