diff options
-rw-r--r-- | docs/ChangeLog | 1 | ||||
-rwxr-xr-x | qemu_mode/build_qemu_support.sh | 1 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-common.h | 8 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-inl.h | 3 | ||||
-rw-r--r-- | qemu_mode/patches/afl-qemu-cpu-translate-inl.h | 36 | ||||
-rw-r--r-- | qemu_mode/patches/arm-translate.diff | 134 | ||||
-rw-r--r-- | unicorn_mode/patches/compcov.diff | 138 |
7 files changed, 301 insertions, 20 deletions
diff --git a/docs/ChangeLog b/docs/ChangeLog index 205330b3..75f07ce6 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -39,6 +39,7 @@ Version ++2.54d (dev): - added man page for afl-clang-fast[++] - updated documentation - Wine mode to run Win32 binaries with the QEMU instrumentation (-W) + - CompareCoverage for ARM target in QEMU/Unicorn -------------------------- diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 901ed210..55d72e0d 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -149,6 +149,7 @@ patch -p1 <../patches/syscall.diff || exit 1 patch -p1 <../patches/translate-all.diff || exit 1 patch -p1 <../patches/tcg.diff || exit 1 patch -p1 <../patches/i386-translate.diff || exit 1 +patch -p1 <../patches/arm-translate.diff || exit 1 echo "[+] Patching done." diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index e435c62f..c86b5b45 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -33,6 +33,12 @@ #include "../../config.h" +#ifndef CPU_NB_REGS +#define AFL_REGS_NUM 1000 +#else +#define AFL_REGS_NUM CPU_NB_REGS +#endif + /* NeverZero */ #if (defined(__x86_64__) || defined(__i386__)) && defined(AFL_QEMU_NOT_ZERO) @@ -60,7 +66,7 @@ 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[CPU_NB_REGS]; +extern target_ulong persistent_saved_gpr[AFL_REGS_NUM]; extern int persisent_retaddr_offset; extern __thread abi_ulong afl_prev_loc; diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h index 209944ee..8660ba23 100644 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-inl.h @@ -33,6 +33,7 @@ #include <sys/shm.h> #include "../../config.h" +#include "afl-qemu-common.h" #define PERSISTENT_DEFAULT_MAX_CNT 1000 @@ -89,7 +90,7 @@ unsigned char is_persistent; target_long persistent_stack_offset; unsigned char persistent_first_pass; unsigned char persistent_save_gpr; -target_ulong persistent_saved_gpr[CPU_NB_REGS]; +target_ulong persistent_saved_gpr[AFL_REGS_NUM]; int persisent_retaddr_offset; /* Instrumentation ratio: */ diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h index 126cf255..29cf0ab8 100644 --- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h @@ -40,7 +40,7 @@ static void afl_compcov_log_16(target_ulong cur_loc, target_ulong arg1, register uintptr_t idx = cur_loc; - if ((arg1 & 0xff) == (arg2 & 0xff)) { INC_AFL_AREA(idx); } + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } } @@ -49,13 +49,13 @@ static void afl_compcov_log_32(target_ulong cur_loc, target_ulong arg1, register uintptr_t idx = cur_loc; - if ((arg1 & 0xff) == (arg2 & 0xff)) { + if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - INC_AFL_AREA(idx); - if ((arg1 & 0xffff) == (arg2 & 0xffff)) { + INC_AFL_AREA(idx +2); + if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { INC_AFL_AREA(idx + 1); - if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { INC_AFL_AREA(idx + 2); } + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { INC_AFL_AREA(idx); } } @@ -68,27 +68,27 @@ static void afl_compcov_log_64(target_ulong cur_loc, target_ulong arg1, register uintptr_t idx = cur_loc; - if ((arg1 & 0xff) == (arg2 & 0xff)) { + if ((arg1 & 0xff00000000000000) == (arg2 & 0xff00000000000000)) { - INC_AFL_AREA(idx); - if ((arg1 & 0xffff) == (arg2 & 0xffff)) { + INC_AFL_AREA(idx +6); + if ((arg1 & 0xff000000000000) == (arg2 & 0xff000000000000)) { - INC_AFL_AREA(idx + 1); - if ((arg1 & 0xffffff) == (arg2 & 0xffffff)) { + INC_AFL_AREA(idx + 5); + if ((arg1 & 0xff0000000000) == (arg2 & 0xff0000000000)) { - INC_AFL_AREA(idx + 2); - if ((arg1 & 0xffffffff) == (arg2 & 0xffffffff)) { + INC_AFL_AREA(idx + 4); + if ((arg1 & 0xff00000000) == (arg2 & 0xff00000000)) { INC_AFL_AREA(idx + 3); - if ((arg1 & 0xffffffffff) == (arg2 & 0xffffffffff)) { + if ((arg1 & 0xff000000) == (arg2 & 0xff000000)) { - INC_AFL_AREA(idx + 4); - if ((arg1 & 0xffffffffffff) == (arg2 & 0xffffffffffff)) { + INC_AFL_AREA(idx + 2); + if ((arg1 & 0xff0000) == (arg2 & 0xff0000)) { - INC_AFL_AREA(idx + 5); - if ((arg1 & 0xffffffffffffff) == (arg2 & 0xffffffffffffff)) { + INC_AFL_AREA(idx + 1); + if ((arg1 & 0xff00) == (arg2 & 0xff00)) { - INC_AFL_AREA(idx + 6); + INC_AFL_AREA(idx); } diff --git a/qemu_mode/patches/arm-translate.diff b/qemu_mode/patches/arm-translate.diff new file mode 100644 index 00000000..58b4a873 --- /dev/null +++ b/qemu_mode/patches/arm-translate.diff @@ -0,0 +1,134 @@ +diff --git a/target/arm/translate.c b/target/arm/translate.c +index 7c4675ff..0f0928b6 100644 +--- a/target/arm/translate.c ++++ b/target/arm/translate.c +@@ -59,6 +59,8 @@ + #define IS_USER(s) (s->user) + #endif + ++#include "../patches/afl-qemu-cpu-translate-inl.h" ++ + /* We reuse the same 64-bit temporaries for efficiency. */ + static TCGv_i64 cpu_V0, cpu_V1, cpu_M0; + static TCGv_i32 cpu_R[16]; +@@ -9541,6 +9543,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) + } else { + if (set_cc) { + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } else { + tcg_gen_sub_i32(tmp, tmp, tmp2); + } +@@ -9550,6 +9553,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) + case 0x03: + if (set_cc) { + gen_sub_CC(tmp, tmp2, tmp); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } else { + tcg_gen_sub_i32(tmp, tmp2, tmp); + } +@@ -9604,6 +9608,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) + case 0x0a: + if (set_cc) { + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } + tcg_temp_free_i32(tmp); + break; +@@ -10565,7 +10570,7 @@ thumb2_logic_op(int op) + + static int + gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, +- TCGv_i32 t0, TCGv_i32 t1) ++ TCGv_i32 t0, TCGv_i32 t1, int has_imm) + { + int logic_cc; + +@@ -10611,15 +10616,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, + } + break; + case 13: /* sub */ +- if (conds) ++ if (conds) { + gen_sub_CC(t0, t0, t1); +- else ++ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); ++ } else + tcg_gen_sub_i32(t0, t0, t1); + break; + case 14: /* rsb */ +- if (conds) ++ if (conds) { + gen_sub_CC(t0, t1, t0); +- else ++ afl_gen_compcov(s->pc, t0, t1, MO_32, has_imm); ++ } else + tcg_gen_sub_i32(t0, t1, t0); + break; + default: /* 5, 6, 7, 9, 12, 15. */ +@@ -11085,7 +11092,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) + conds = (insn & (1 << 20)) != 0; + logic_cc = (conds && thumb2_logic_op(op)); + gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); +- if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) ++ if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10))) + goto illegal_op; + tcg_temp_free_i32(tmp2); + if (rd == 13 && +@@ -11955,7 +11962,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) + } + op = (insn >> 21) & 0xf; + if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, +- shifter_out, tmp, tmp2)) ++ shifter_out, tmp, tmp2, insn & (1 << 10))) + goto illegal_op; + tcg_temp_free_i32(tmp2); + rd = (insn >> 8) & 0xf; +@@ -12206,8 +12213,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) + if (insn & (1 << 9)) { + if (s->condexec_mask) + tcg_gen_sub_i32(tmp, tmp, tmp2); +- else ++ else { + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, insn & (1 << 10)); ++ } + } else { + if (s->condexec_mask) + tcg_gen_add_i32(tmp, tmp, tmp2); +@@ -12247,6 +12256,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) + switch (op) { + case 1: /* cmp */ + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); + tcg_temp_free_i32(tmp); + tcg_temp_free_i32(tmp2); + break; +@@ -12261,8 +12271,10 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) + case 3: /* sub */ + if (s->condexec_mask) + tcg_gen_sub_i32(tmp, tmp, tmp2); +- else ++ else { + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 1); ++ } + tcg_temp_free_i32(tmp2); + store_reg(s, rd, tmp); + break; +@@ -12308,6 +12320,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) + tmp = load_reg(s, rd); + tmp2 = load_reg(s, rm); + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); + tcg_temp_free_i32(tmp2); + tcg_temp_free_i32(tmp); + break; +@@ -12466,6 +12479,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) + break; + case 0xa: /* cmp */ + gen_sub_CC(tmp, tmp, tmp2); ++ afl_gen_compcov(s->pc, tmp, tmp2, MO_32, 0); + rd = 16; + break; + case 0xb: /* cmn */ diff --git a/unicorn_mode/patches/compcov.diff b/unicorn_mode/patches/compcov.diff index 8ec867d1..4e71f465 100644 --- a/unicorn_mode/patches/compcov.diff +++ b/unicorn_mode/patches/compcov.diff @@ -15,6 +15,144 @@ index 22f494e..1aa7b3a 100644 }; // Metadata stub for the variable-size cpu context used with uc_context_*() +diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c +index 4995eda..06c7e63 100644 +--- a/qemu/target-arm/translate.c ++++ b/qemu/target-arm/translate.c +@@ -63,6 +63,12 @@ static TCGv_i64 cpu_exclusive_test; + static TCGv_i32 cpu_exclusive_info; + #endif + ++#if defined(UNICORN_AFL) ++#include "../../afl-unicorn-cpu-translate-inl.h" ++#else ++#define afl_gen_compcov(a,b,c,d,e,f) do {} while (0) ++#endif ++ + + static const char *regnames[] = + { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", +@@ -8214,6 +8220,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq + } else { + if (set_cc) { + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } else { + tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); + } +@@ -8223,6 +8230,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq + case 0x03: + if (set_cc) { + gen_sub_CC(s, tmp, tmp2, tmp); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } else { + tcg_gen_sub_i32(tcg_ctx, tmp, tmp2, tmp); + } +@@ -8277,6 +8285,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq + case 0x0a: + if (set_cc) { + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 25)); + } + tcg_temp_free_i32(tcg_ctx, tmp); + break; +@@ -9148,7 +9157,7 @@ thumb2_logic_op(int op) + + static int + gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, +- TCGv_i32 t0, TCGv_i32 t1) ++ TCGv_i32 t0, TCGv_i32 t1, int has_imm) + { + TCGContext *tcg_ctx = s->uc->tcg_ctx; + int logic_cc; +@@ -9195,15 +9204,17 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, + } + break; + case 13: /* sub */ +- if (conds) ++ if (conds) { + gen_sub_CC(s, t0, t0, t1); +- else ++ afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm); ++ } else + tcg_gen_sub_i32(tcg_ctx, t0, t0, t1); + break; + case 14: /* rsb */ +- if (conds) ++ if (conds) { + gen_sub_CC(s, t0, t1, t0); +- else ++ afl_gen_compcov(tcg_ctx, s->pc, t0, t1, MO_32, has_imm); ++ } else + tcg_gen_sub_i32(tcg_ctx, t0, t1, t0); + break; + default: /* 5, 6, 7, 9, 12, 15. */ +@@ -9572,7 +9583,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw + conds = (insn & (1 << 20)) != 0; + logic_cc = (conds && thumb2_logic_op(op)); + gen_arm_shift_im(s, tmp2, shiftop, shift, logic_cc); +- if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) ++ if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2, insn & (1 << 10))) + goto illegal_op; + tcg_temp_free_i32(tcg_ctx, tmp2); + if (rd != 15) { +@@ -10215,7 +10226,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw + } + op = (insn >> 21) & 0xf; + if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, +- shifter_out, tmp, tmp2)) ++ shifter_out, tmp, tmp2, insn & (1 << 10))) + goto illegal_op; + tcg_temp_free_i32(tcg_ctx, tmp2); + rd = (insn >> 8) & 0xf; +@@ -10471,8 +10482,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq + if (insn & (1 << 9)) { + if (s->condexec_mask) + tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); +- else ++ else { + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, insn & (1 << 10)); ++ } + } else { + if (s->condexec_mask) + tcg_gen_add_i32(tcg_ctx, tmp, tmp, tmp2); +@@ -10509,6 +10522,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq + switch (op) { + case 1: /* cmp */ + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1); + tcg_temp_free_i32(tcg_ctx, tmp); + tcg_temp_free_i32(tcg_ctx, tmp2); + break; +@@ -10523,8 +10537,10 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq + case 3: /* sub */ + if (s->condexec_mask) + tcg_gen_sub_i32(tcg_ctx, tmp, tmp, tmp2); +- else ++ else { + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 1); ++ } + tcg_temp_free_i32(tcg_ctx, tmp2); + store_reg(s, rd, tmp); + break; +@@ -10562,6 +10578,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq + tmp = load_reg(s, rd); + tmp2 = load_reg(s, rm); + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0); + tcg_temp_free_i32(tcg_ctx, tmp2); + tcg_temp_free_i32(tcg_ctx, tmp); + break; +@@ -10680,6 +10697,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq + break; + case 0xa: /* cmp */ + gen_sub_CC(s, tmp, tmp, tmp2); ++ afl_gen_compcov(tcg_ctx, s->pc, tmp, tmp2, MO_32, 0); + rd = 16; + break; + case 0xb: /* cmn */ diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 36fae09..196d346 100644 --- a/qemu/target-i386/translate.c |