diff options
Diffstat (limited to 'qemu_mode/patches/afl-qemu-cpu-translate-inl.h')
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 273 |
1 files changed, 207 insertions, 66 deletions
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index 6d42bf3d..6f526d92 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -102,31 +102,101 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1, } +static void afl_cmplog_16(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + // if (!__afl_cmp_map->headers[k].cnt) + // __afl_cmp_map->headers[k].cnt = __afl_cmp_counter++; + + __afl_cmp_map->headers[k].shape = 1; + //__afl_cmp_map->headers[k].type = CMP_TYPE_INS; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +static void afl_cmplog_32(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 3; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + +static void afl_cmplog_64(target_ulong cur_loc, target_ulong arg1, + target_ulong arg2) { + + register uintptr_t k = (uintptr_t)cur_loc; + + u32 hits = __afl_cmp_map->headers[k].hits; + __afl_cmp_map->headers[k].hits = hits + 1; + + __afl_cmp_map->headers[k].shape = 7; + + hits &= CMP_MAP_H - 1; + __afl_cmp_map->log[k][hits].v0 = arg1; + __afl_cmp_map->log[k][hits].v1 = arg2; + +} + static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2, TCGMemOp ot, int is_imm) { void *func; - if (!afl_compcov_level || cur_loc > afl_end_code || cur_loc < afl_start_code) - return; + if (cur_loc > afl_end_code || cur_loc < afl_start_code) return; - if (!is_imm && afl_compcov_level < 2) return; + if (__afl_cmp_map) { - switch (ot) { + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= CMP_MAP_W - 1; - case MO_64: func = &afl_compcov_log_64; break; - case MO_32: func = &afl_compcov_log_32; break; - case MO_16: func = &afl_compcov_log_16; break; - default: return; + switch (ot) { - } + case MO_64: func = &afl_cmplog_64; break; + case MO_32: func = &afl_cmplog_32; break; + case MO_16: func = &afl_cmplog_16; break; + default: return; - cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); - cur_loc &= MAP_SIZE - 7; + } + + tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + + } else if (afl_compcov_level) { + + if (!is_imm && afl_compcov_level < 2) return; + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= MAP_SIZE - 7; + + if (cur_loc >= afl_inst_rms) return; - if (cur_loc >= afl_inst_rms) return; + switch (ot) { - tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + case MO_64: func = &afl_compcov_log_64; break; + case MO_32: func = &afl_compcov_log_32; break; + case MO_16: func = &afl_compcov_log_16; break; + default: return; + + } + + tcg_gen_afl_compcov_log_call(func, cur_loc, arg1, arg2); + + } } @@ -182,62 +252,77 @@ 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) - -#define AFL_QEMU_TARGET_i386_SNIPPET \ +static void callback_to_persistent_hook(void) { + + afl_persistent_hook_ptr(persistent_saved_gpr, guest_base); + +} + +static void gpr_saving(TCGv *cpu_regs, int regs_num) { + + 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 GPR registers + for (i = 0; i < regs_num; ++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 GPR registers + for (i = 0; i < regs_num; ++i) { + + gpr_sv = tcg_const_ptr(&persistent_saved_gpr[i]); + tcg_gen_ld_tl(cpu_regs[i], gpr_sv, 0); + + } + + tcg_temp_free_ptr(first_pass_ptr); + tcg_temp_free(first_pass); + tcg_temp_free(one); + +} + +static void restore_state_for_persistent(TCGv *cpu_regs, int regs_num, int sp) { + + if (persistent_save_gpr) { + + gpr_saving(cpu_regs, regs_num); + + } 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[sp], cpu_regs[sp], 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; \ + restore_state_for_persistent(cpu_regs, AFL_REGS_NUM, R_ESP); \ /*tcg_gen_afl_call0(log_x86_saved_gpr); \ tcg_gen_afl_call0(log_x86_sp_content);*/ \ \ @@ -245,9 +330,11 @@ static void log_x86_sp_content(void) { \ TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ tcg_gen_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset); \ + tcg_temp_free_ptr(paddr); \ \ } \ - 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) { \ @@ -259,3 +346,57 @@ static void log_x86_sp_content(void) { \ } +// SP = 13, LINK = 14 + +#define AFL_QEMU_TARGET_ARM_SNIPPET \ + if (is_persistent) { \ + \ + if (dc->pc == afl_persistent_addr) { \ + \ + if (persistent_save_gpr) gpr_saving(cpu_R, AFL_REGS_NUM); \ + \ + if (afl_persistent_ret_addr == 0) { \ + \ + TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ + tcg_gen_mov_i32(cpu_R[14], paddr); \ + tcg_temp_free_ptr(paddr); \ + \ + } \ + \ + if (!persistent_save_gpr) tcg_gen_afl_call0(&afl_persistent_loop); \ + \ + } else if (afl_persistent_ret_addr && dc->pc == afl_persistent_ret_addr) { \ + \ + gen_bx_im(dc, afl_persistent_addr); \ + \ + } \ + \ + } + +// SP = 31, LINK = 30 + +#define AFL_QEMU_TARGET_ARM64_SNIPPET \ + if (is_persistent) { \ + \ + if (s->pc == afl_persistent_addr) { \ + \ + if (persistent_save_gpr) gpr_saving(cpu_X, AFL_REGS_NUM); \ + \ + if (afl_persistent_ret_addr == 0) { \ + \ + TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr); \ + tcg_gen_mov_i32(cpu_X[30], paddr); \ + tcg_temp_free_ptr(paddr); \ + \ + } \ + \ + if (!persistent_save_gpr) tcg_gen_afl_call0(&afl_persistent_loop); \ + \ + } else if (afl_persistent_ret_addr && s->pc == afl_persistent_ret_addr) { \ + \ + gen_goto_tb(s, 0, afl_persistent_addr); \ + \ + } \ + \ + } + |