diff options
Diffstat (limited to 'qemu_mode/patches')
-rw-r--r-- | qemu_mode/patches/afl-qemu-common.h | 6 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-inl.h | 35 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 112 | ||||
-rw-r--r-- | qemu_mode/patches/configure.diff | 26 |
4 files changed, 126 insertions, 53 deletions
diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index 18c36f73..de6c7b73 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -59,6 +59,8 @@ #define INC_AFL_AREA(loc) afl_area_ptr[loc]++ #endif +typedef void (*afl_persistent_hook_fn)(uint64_t* regs, uint64_t guest_base); + /* Declared in afl-qemu-cpu-inl.h */ extern unsigned char *afl_area_ptr; @@ -72,9 +74,11 @@ extern unsigned char is_persistent; extern target_long persistent_stack_offset; extern unsigned char persistent_first_pass; extern unsigned char persistent_save_gpr; -extern target_ulong persistent_saved_gpr[AFL_REGS_NUM]; +extern uint64_t persistent_saved_gpr[AFL_REGS_NUM]; extern int persisent_retaddr_offset; +extern afl_persistent_hook_fn afl_persistent_hook_ptr; + extern __thread abi_ulong afl_prev_loc; extern struct cmp_map* __afl_cmp_map; diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h index 9a98fde3..7ef54d78 100644 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-inl.h @@ -34,6 +34,10 @@ #include <sys/shm.h> #include "afl-qemu-common.h" +#ifndef AFL_QEMU_STATIC_BUILD +#include <dlfcn.h> +#endif + /*************************** * VARIOUS AUXILIARY STUFF * ***************************/ @@ -95,6 +99,8 @@ unsigned char persistent_save_gpr; target_ulong persistent_saved_gpr[AFL_REGS_NUM]; int persisent_retaddr_offset; +afl_persistent_hook_fn afl_persistent_hook_ptr; + /* Instrumentation ratio: */ unsigned int afl_inst_rms = MAP_SIZE; /* Exported for afl_gen_trace */ @@ -192,7 +198,7 @@ static void afl_setup(void) { __afl_cmp_map = shmat(shm_id, NULL, 0); - if (__afl_cmp_map == (void*)-1) _exit(1); + if (__afl_cmp_map == (void*)-1) exit(1); } @@ -240,6 +246,33 @@ static void afl_setup(void) { if (getenv("AFL_QEMU_PERSISTENT_GPR")) persistent_save_gpr = 1; + if (getenv("AFL_QEMU_PERSISTENT_HOOK")) { + +#ifdef AFL_QEMU_STATIC_BUILD + + fprintf(stderr, "[AFL] ERROR: you cannot use AFL_QEMU_PERSISTENT_HOOK when afl-qemu-trace is static\n"); + exit(1); + +#else + + persistent_save_gpr = 1; + + void* plib = dlopen(getenv("AFL_QEMU_PERSISTENT_HOOK"), RTLD_NOW); + if (!plib) { + fprintf(stderr, "[AFL] ERROR: invalid AFL_QEMU_PERSISTENT_HOOK=%s\n", getenv("AFL_QEMU_PERSISTENT_HOOK")); + exit(1); + } + + afl_persistent_hook_ptr = dlsym(plib, "afl_persistent_hook"); + if (!afl_persistent_hook_ptr) { + fprintf(stderr, "[AFL] ERROR: failed to find the function \"afl_persistent_hook\" in %s\n", getenv("AFL_QEMU_PERSISTENT_HOOK")); + exit(1); + } + +#endif + + } + if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET")) persisent_retaddr_offset = strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 0); diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index 9f032feb..d081060f 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -254,62 +254,71 @@ static void log_x86_sp_content(void) { }*/ -#define I386_RESTORE_STATE_FOR_PERSISTENT \ - do { \ - \ - if (persistent_save_gpr) { \ - \ - int i; \ - TCGv_ptr gpr_sv; \ - \ - TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); \ - TCGv first_pass = tcg_temp_local_new(); \ - TCGv one = tcg_const_tl(1); \ - tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); \ - \ - TCGLabel *lbl_save_gpr = gen_new_label(); \ - TCGLabel *lbl_finish_restore_gpr = gen_new_label(); \ - tcg_gen_brcond_tl(TCG_COND_EQ, first_pass, one, lbl_save_gpr); \ - \ - for (i = 0; i < CPU_NB_REGS; ++i) { \ - \ - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \ - tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); \ - \ - } \ - \ - tcg_gen_br(lbl_finish_restore_gpr); \ - \ - gen_set_label(lbl_save_gpr); \ - \ - for (i = 0; i < CPU_NB_REGS; ++i) { \ - \ - gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); \ - tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); \ - \ - } \ - \ - gen_set_label(lbl_finish_restore_gpr); \ - tcg_temp_free(first_pass); \ - \ - } else if (afl_persistent_ret_addr == 0) { \ - \ - TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); \ - TCGv stack_off = tcg_temp_new(); \ - tcg_gen_ld_tl(stack_off, stack_off_ptr, 0); \ - tcg_gen_sub_tl(cpu_regs[R_ESP], cpu_regs[R_ESP], stack_off); \ - tcg_temp_free(stack_off); \ - \ - } \ - \ - } while (0) + +static void callback_to_persistent_hook(void) { + + afl_persistent_hook_ptr(persistent_saved_gpr, guest_base); + +} + +static void i386_restore_state_for_persistent(TCGv* cpu_regs) { + + if (persistent_save_gpr) { + + int i; + TCGv_ptr gpr_sv; + + TCGv_ptr first_pass_ptr = tcg_const_ptr(&persistent_first_pass); + TCGv first_pass = tcg_temp_local_new(); + TCGv one = tcg_const_tl(1); + tcg_gen_ld8u_tl(first_pass, first_pass_ptr, 0); + + TCGLabel *lbl_restore_gpr = gen_new_label(); + tcg_gen_brcond_tl(TCG_COND_NE, first_pass, one, lbl_restore_gpr); + + // save GRP registers + for (i = 0; i < CPU_NB_REGS; ++i) { + + gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); + tcg_gen_st_tl(cpu_regs[i], gpr_sv, 0); + + } + + gen_set_label(lbl_restore_gpr); + + tcg_gen_afl_call0(&afl_persistent_loop); + + if (afl_persistent_hook_ptr) + tcg_gen_afl_call0(callback_to_persistent_hook); + + // restore GRP registers + for (i = 0; i < CPU_NB_REGS; ++i) { + + gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); + tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); + + } + + tcg_temp_free(first_pass); + + } else if (afl_persistent_ret_addr == 0) { + + TCGv_ptr stack_off_ptr = tcg_const_ptr(&persistent_stack_offset); + TCGv stack_off = tcg_temp_new(); + tcg_gen_ld_tl(stack_off, stack_off_ptr, 0); + tcg_gen_sub_tl(cpu_regs[R_ESP], cpu_regs[R_ESP], stack_off); + tcg_temp_free(stack_off); + + } + +} #define AFL_QEMU_TARGET_i386_SNIPPET \ if (is_persistent) { \ \ if (s->pc == afl_persistent_addr) { \ \ - I386_RESTORE_STATE_FOR_PERSISTENT; \ + i386_restore_state_for_persistent(cpu_regs); \ /*tcg_gen_afl_call0(log_x86_saved_gpr); \ tcg_gen_afl_call0(log_x86_sp_content);*/ \ \ @@ -319,7 +328,8 @@ static void log_x86_sp_content(void) { tcg_gen_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset); \ \ } \ - tcg_gen_afl_call0(&afl_persistent_loop); \ + \ + if (!persistent_save_gpr) tcg_gen_afl_call0(&afl_persistent_loop); \ /*tcg_gen_afl_call0(log_x86_sp_content);*/ \ \ } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ diff --git a/qemu_mode/patches/configure.diff b/qemu_mode/patches/configure.diff new file mode 100644 index 00000000..acb96294 --- /dev/null +++ b/qemu_mode/patches/configure.diff @@ -0,0 +1,26 @@ +diff --git a/configure b/configure +index 1c9f609..3edc9a7 100755 +--- a/configure ++++ b/configure +@@ -4603,6 +4603,21 @@ if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \ + libs_softmmu="-lutil $libs_softmmu" + fi + ++########################################## ++cat > $TMPC << EOF ++#include <dlfcn.h> ++#include <stdlib.h> ++int main(int argc, char **argv) { return dlopen("libc.so", RTLD_NOW) != NULL; } ++EOF ++if compile_prog "" "" ; then ++ : ++elif compile_prog "" "-ldl" ; then ++ LIBS="-ldl $LIBS" ++ libs_qga="-ldl $libs_qga" ++else ++ error_exit "libdl check failed" ++fi ++ + ########################################## + # spice probe + if test "$spice" != "no" ; then |