From c83e8e1e6255374b085292ba8673efdca7388d76 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Sat, 19 Oct 2019 18:23:01 +0200 Subject: Remove lcamtuf's old email from Google (not valid anymore), also remove maintainance from him. --- qemu_mode/patches/afl-qemu-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'qemu_mode/patches/afl-qemu-common.h') diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index c86b5b45..1da3359d 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -3,7 +3,7 @@ ------------------------------------------------------------------- Originally written by Andrew Griffiths and - Michal Zalewski + Michal Zalewski TCG instrumentation and block chaining support by Andrea Biondo -- cgit 1.4.1 From 297e9e3cf59540f16b8260a01ef7c6cd01d9e554 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Wed, 23 Oct 2019 19:48:18 +0200 Subject: move is_valid_addr in afl-qemu-common.h --- qemu_mode/patches/afl-qemu-common.h | 18 ++++++++++++++++++ qemu_mode/patches/afl-qemu-cpu-inl.h | 18 ------------------ 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'qemu_mode/patches/afl-qemu-common.h') diff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h index 1da3359d..409a7eab 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -81,3 +81,21 @@ void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, void tcg_gen_afl_maybe_log_call(target_ulong cur_loc); + +/* Check if an address is valid in the current mapping */ + +static inline int is_valid_addr(target_ulong addr) { + + int l, flags; + target_ulong page; + void * p; + + page = addr & TARGET_PAGE_MASK; + l = (page + TARGET_PAGE_SIZE) - addr; + + flags = page_get_flags(page); + if (!(flags & PAGE_VALID) || !(flags & PAGE_READ)) return 0; + + return 1; + +} diff --git a/qemu_mode/patches/afl-qemu-cpu-inl.h b/qemu_mode/patches/afl-qemu-cpu-inl.h index 7358fc3b..f4c474d8 100644 --- a/qemu_mode/patches/afl-qemu-cpu-inl.h +++ b/qemu_mode/patches/afl-qemu-cpu-inl.h @@ -451,24 +451,6 @@ static void afl_request_tsl(target_ulong pc, target_ulong cb, uint32_t flags, } -/* Check if an address is valid in the current mapping */ - -static inline int is_valid_addr(target_ulong addr) { - - int l, flags; - target_ulong page; - void * p; - - page = addr & TARGET_PAGE_MASK; - l = (page + TARGET_PAGE_SIZE) - addr; - - flags = page_get_flags(page); - if (!(flags & PAGE_VALID) || !(flags & PAGE_READ)) return 0; - - return 1; - -} - /* This is the other side of the same channel. Since timeouts are handled by afl-fuzz simply killing the child, we can just wait until the pipe breaks. */ -- cgit 1.4.1 From 4ec4e5b394dfa4e40a26574e3053a9bd7eaa8d37 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Fri, 25 Oct 2019 20:04:16 +0200 Subject: floating point compcov --- qemu_mode/build_qemu_support.sh | 3 + qemu_mode/patches/afl-qemu-common.h | 12 ++ qemu_mode/patches/afl-qemu-floats.h | 217 +++++++++++++++++++++++++++++++++ qemu_mode/patches/i386-fpu_helper.diff | 54 ++++++++ qemu_mode/patches/i386-ops_sse.diff | 61 +++++++++ qemu_mode/patches/softfloat.diff | 10 ++ 6 files changed, 357 insertions(+) create mode 100644 qemu_mode/patches/afl-qemu-floats.h create mode 100644 qemu_mode/patches/i386-fpu_helper.diff create mode 100644 qemu_mode/patches/i386-ops_sse.diff create mode 100644 qemu_mode/patches/softfloat.diff (limited to 'qemu_mode/patches/afl-qemu-common.h') diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index f18cbdf3..6b9f91f9 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -150,6 +150,9 @@ 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 +patch -p1 <../patches/i386-ops_sse.diff || exit 1 +patch -p1 <../patches/i386-fpu_helper.diff || exit 1 +patch -p1 <../patches/softfloat.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 409a7eab..d4024353 100644 --- a/qemu_mode/patches/afl-qemu-common.h +++ b/qemu_mode/patches/afl-qemu-common.h @@ -31,6 +31,9 @@ */ +#ifndef __AFL_QEMU_COMMON +#define __AFL_QEMU_COMMON + #include "../../config.h" #ifndef CPU_NB_REGS @@ -81,6 +84,12 @@ void tcg_gen_afl_compcov_log_call(void *func, target_ulong cur_loc, void tcg_gen_afl_maybe_log_call(target_ulong cur_loc); +void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, + void *status); +void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, + void *status); +void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, + floatx80 arg2); /* Check if an address is valid in the current mapping */ @@ -99,3 +108,6 @@ static inline int is_valid_addr(target_ulong addr) { return 1; } + +#endif + diff --git a/qemu_mode/patches/afl-qemu-floats.h b/qemu_mode/patches/afl-qemu-floats.h new file mode 100644 index 00000000..765deb74 --- /dev/null +++ b/qemu_mode/patches/afl-qemu-floats.h @@ -0,0 +1,217 @@ +/* + american fuzzy lop++ - high-performance binary-only instrumentation + ------------------------------------------------------------------- + + Originally written by Andrew Griffiths and + Michal Zalewski + + TCG instrumentation and block chaining support by Andrea Biondo + + + QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero + counters by Andrea Fioraldi + + Copyright 2015, 2016, 2017 Google Inc. All rights reserved. + Copyright 2019 AFLplusplus Project. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This code is a shim patched into the separately-distributed source + code of QEMU 3.1.0. It leverages the built-in QEMU tracing functionality + to implement AFL-style instrumentation and to take care of the remaining + parts of the AFL fork server logic. + + The resulting QEMU binary is essentially a standalone instrumentation + tool; for an example of how to leverage it for other purposes, you can + have a look at afl-showmap.c. + + */ + +#include "tcg.h" +#include "afl-qemu-common.h" + +union afl_float32 { + float64 f; + struct { + u64 sign : 1; + u64 exp : 7; + u64 frac : 24; + }; +}; + + +union afl_float64 { + float64 f; + struct { + u64 sign : 1; + u64 exp : 11; + u64 frac : 52; + }; +}; + + +// TODO 16 and 128 bits floats +// TODO figure out why float*_unpack_canonical does not work + +void afl_float_compcov_log_32(target_ulong cur_loc, float32 arg1, float32 arg2, + void* status) { + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= MAP_SIZE - 7; + + if (cur_loc >= afl_inst_rms) return; + + //float_status* s = (float_status*)status; + //FloatParts a = float32_unpack_canonical(arg1, s); + //FloatParts b = float32_unpack_canonical(arg2, s); + union afl_float32 a = { .f = arg1 }; + union afl_float32 b = { .f = arg2 }; + + // if (is_nan(a.cls) || is_nan(b.cls)) return; + + register uintptr_t idx = cur_loc; + + if (a.sign != b.sign) return; + INC_AFL_AREA(idx); + if (a.exp != b.exp) return; + INC_AFL_AREA(idx + 1); + + if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { + + INC_AFL_AREA(idx + 2); + if ((a.frac & 0xff00) == (b.frac & 0xff00)) { INC_AFL_AREA(idx + 3); } + + } + +} + +void afl_float_compcov_log_64(target_ulong cur_loc, float64 arg1, float64 arg2, + void* status) { + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= MAP_SIZE - 7; + + if (cur_loc >= afl_inst_rms) return; + + //float_status* s = (float_status*)status; + //FloatParts a = float64_unpack_canonical(arg1, s); + //FloatParts b = float64_unpack_canonical(arg2, s); + union afl_float64 a = { .f = arg1 }; + union afl_float64 b = { .f = arg2 }; + + // if (is_nan(a.cls) || is_nan(b.cls)) return; + + register uintptr_t idx = cur_loc; + + if (a.sign == b.sign) INC_AFL_AREA(idx); + if ((a.exp & 0xff00) == (b.exp & 0xff00)) { + + INC_AFL_AREA(idx + 1); + if ((a.exp & 0xff) == (b.exp & 0xff)) INC_AFL_AREA(idx + 2); + + } + + if ((a.frac & 0xff000000000000) == (b.frac & 0xff000000000000)) { + + INC_AFL_AREA(idx + 3); + if ((a.frac & 0xff0000000000) == (b.frac & 0xff0000000000)) { + + INC_AFL_AREA(idx + 4); + if ((a.frac & 0xff00000000) == (b.frac & 0xff00000000)) { + + INC_AFL_AREA(idx + 5); + if ((a.frac & 0xff000000) == (b.frac & 0xff000000)) { + + INC_AFL_AREA(idx + 6); + if ((a.frac & 0xff0000) == (b.frac & 0xff0000)) { + + INC_AFL_AREA(idx + 7); + if ((a.frac & 0xff00) == (b.frac & 0xff00)) INC_AFL_AREA(idx + 8); + + } + + } + + } + + } + + } + +} + +void afl_float_compcov_log_80(target_ulong cur_loc, floatx80 arg1, + floatx80 arg2) { + + cur_loc = (cur_loc >> 4) ^ (cur_loc << 8); + cur_loc &= MAP_SIZE - 7; + + if (cur_loc >= afl_inst_rms) return; + + if (floatx80_invalid_encoding(arg1) || floatx80_invalid_encoding(arg2)) + return; + + flag a_sign = extractFloatx80Sign(arg1); + flag b_sign = extractFloatx80Sign(arg2); + + /*if (((extractFloatx80Exp(arg1) == 0x7fff) && + (extractFloatx80Frac(arg1) << 1)) || + ((extractFloatx80Exp(arg2) == 0x7fff) && + (extractFloatx80Frac(arg2) << 1))) + return;*/ + + register uintptr_t idx = cur_loc; + + if (a_sign == b_sign) INC_AFL_AREA(idx); + + if ((arg1.high & 0x7f00) == (arg2.high & 0x7f00)) { + + INC_AFL_AREA(idx + 1); + if ((arg1.high & 0xff) == (arg2.high & 0xff)) INC_AFL_AREA(idx + 2); + + } + + if ((arg1.low & 0xff00000000000000) == (arg2.low & 0xff00000000000000)) { + + INC_AFL_AREA(idx + 3); + if ((arg1.low & 0xff000000000000) == (arg2.low & 0xff000000000000)) { + + INC_AFL_AREA(idx + 4); + if ((arg1.low & 0xff0000000000) == (arg2.low & 0xff0000000000)) { + + INC_AFL_AREA(idx + 5); + if ((arg1.low & 0xff00000000) == (arg2.low & 0xff00000000)) { + + INC_AFL_AREA(idx + 6); + if ((arg1.low & 0xff000000) == (arg2.low & 0xff000000)) { + + INC_AFL_AREA(idx + 7); + if ((arg1.low & 0xff0000) == (arg2.low & 0xff0000)) { + + INC_AFL_AREA(idx + 8); + if ((arg1.low & 0xff00) == (arg2.low & 0xff00)) { + + INC_AFL_AREA(idx + 9); + //if ((arg1.low & 0xff) == (arg2.low & 0xff)) + // INC_AFL_AREA(idx + 10); + + } + + } + + } + + } + + } + + } + + } + +} + diff --git a/qemu_mode/patches/i386-fpu_helper.diff b/qemu_mode/patches/i386-fpu_helper.diff new file mode 100644 index 00000000..3bd09d9c --- /dev/null +++ b/qemu_mode/patches/i386-fpu_helper.diff @@ -0,0 +1,54 @@ +diff --git a/target/i386/fpu_helper.c b/target/i386/fpu_helper.c +index ea5a0c48..89901315 100644 +--- a/target/i386/fpu_helper.c ++++ b/target/i386/fpu_helper.c +@@ -384,10 +384,16 @@ void helper_fxchg_ST0_STN(CPUX86State *env, int st_index) + + static const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; + ++#include "../patches/afl-qemu-common.h" ++ + void helper_fcom_ST0_FT0(CPUX86State *env) + { + int ret; + ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_80(env->eip, ST0, FT0); ++ + ret = floatx80_compare(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; + } +@@ -396,6 +402,10 @@ void helper_fucom_ST0_FT0(CPUX86State *env) + { + int ret; + ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_80(env->eip, ST0, FT0); ++ + ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; + } +@@ -407,6 +417,10 @@ void helper_fcomi_ST0_FT0(CPUX86State *env) + int eflags; + int ret; + ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_80(env->eip, ST0, FT0); ++ + ret = floatx80_compare(ST0, FT0, &env->fp_status); + eflags = cpu_cc_compute_all(env, CC_OP); + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; +@@ -418,6 +432,10 @@ void helper_fucomi_ST0_FT0(CPUX86State *env) + int eflags; + int ret; + ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_80(env->eip, ST0, FT0); ++ + ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status); + eflags = cpu_cc_compute_all(env, CC_OP); + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; diff --git a/qemu_mode/patches/i386-ops_sse.diff b/qemu_mode/patches/i386-ops_sse.diff new file mode 100644 index 00000000..d2779ea8 --- /dev/null +++ b/qemu_mode/patches/i386-ops_sse.diff @@ -0,0 +1,61 @@ +diff --git a/target/i386/ops_sse.h b/target/i386/ops_sse.h +index ed059897..a5296caa 100644 +--- a/target/i386/ops_sse.h ++++ b/target/i386/ops_sse.h +@@ -997,6 +997,8 @@ SSE_HELPER_CMP(cmpord, FPU_CMPORD) + + static const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; + ++#include "../patches/afl-qemu-common.h" ++ + void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) + { + int ret; +@@ -1004,6 +1006,11 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s) + + s0 = d->ZMM_S(0); + s1 = s->ZMM_S(0); ++ ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); ++ + ret = float32_compare_quiet(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; + } +@@ -1015,6 +1022,11 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s) + + s0 = d->ZMM_S(0); + s1 = s->ZMM_S(0); ++ ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_32(env->eip, s0, s1, &env->sse_status); ++ + ret = float32_compare(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; + } +@@ -1026,6 +1038,11 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s) + + d0 = d->ZMM_D(0); + d1 = s->ZMM_D(0); ++ ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); ++ + ret = float64_compare_quiet(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; + } +@@ -1037,6 +1054,11 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s) + + d0 = d->ZMM_D(0); + d1 = s->ZMM_D(0); ++ ++ if (afl_compcov_level > 2 && env->eip < afl_end_code && ++ env->eip >= afl_start_code) ++ afl_float_compcov_log_64(env->eip, d0, d1, &env->sse_status); ++ + ret = float64_compare(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; + } diff --git a/qemu_mode/patches/softfloat.diff b/qemu_mode/patches/softfloat.diff new file mode 100644 index 00000000..86ffb97f --- /dev/null +++ b/qemu_mode/patches/softfloat.diff @@ -0,0 +1,10 @@ +diff --git a/fpu/softfloat.c b/fpu/softfloat.c +index e1eef954..2f8d0d62 100644 +--- a/fpu/softfloat.c ++++ b/fpu/softfloat.c +@@ -7205,3 +7205,5 @@ float128 float128_scalbn(float128 a, int n, float_status *status) + , status); + + } ++ ++#include "../../patches/afl-qemu-floats.h" -- cgit 1.4.1