diff options
author | hexcoder <hexcoder-@users.noreply.github.com> | 2021-05-31 19:18:24 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-31 19:18:24 +0200 |
commit | 97a1f89881878db9bd6b4cd666b3447a63818dcf (patch) | |
tree | 46e844356f7cf88c08f9f9907caa11656a24f416 /qemu_mode | |
parent | b246de789105750558f3d6f884ba61e54cb98441 (diff) | |
parent | 1a2da67ed0505c9ac0aa1048ba3d607f3c1aa639 (diff) | |
download | afl++-97a1f89881878db9bd6b4cd666b3447a63818dcf.tar.gz |
Merge branch 'dev' into going_atomic
Diffstat (limited to 'qemu_mode')
-rw-r--r-- | qemu_mode/README.md | 27 | ||||
-rw-r--r-- | qemu_mode/README.wine.md | 21 | ||||
-rwxr-xr-x | qemu_mode/build_qemu_support.sh | 5 | ||||
-rw-r--r-- | qemu_mode/libqasan/hooks.c | 10 | ||||
-rw-r--r-- | qemu_mode/libqasan/libqasan.c | 13 |
5 files changed, 53 insertions, 23 deletions
diff --git a/qemu_mode/README.md b/qemu_mode/README.md index a14cbe64..d28479d9 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -110,22 +110,23 @@ takes priority over any included ranges or AFL_INST_LIBS. CompareCoverage is a sub-instrumentation with effects similar to laf-intel. -The environment variable that enables QEMU CompareCoverage is AFL_COMPCOV_LEVEL. -There is also ./libcompcov/ which implements CompareCoverage for *cmp functions -(splitting memcmp, strncmp, etc. to make these conditions easier solvable by -afl-fuzz). +You have to set `AFL_PRELOAD=/path/to/libcompcov.so` together with +setting the AFL_COMPCOV_LEVEL you want to enable it. AFL_COMPCOV_LEVEL=1 is to instrument comparisons with only immediate -values / read-only memory. AFL_COMPCOV_LEVEL=2 instruments all -comparison instructions and memory comparison functions when libcompcov -is preloaded. -AFL_COMPCOV_LEVEL=3 has the same effects of AFL_COMPCOV_LEVEL=2 but enables also -the instrumentation of the floating-point comparisons on x86 and x86_64 (experimental). +values / read-only memory. + +AFL_COMPCOV_LEVEL=2 instruments all comparison instructions and memory +comparison functions when libcompcov is preloaded. + +AFL_COMPCOV_LEVEL=3 has the same effects of AFL_COMPCOV_LEVEL=2 but enables +also the instrumentation of the floating-point comparisons on x86 and x86_64 +(experimental). Integer comparison instructions are currently instrumented only on the x86, x86_64, arm and aarch64 targets. -Highly recommended. +Recommended, but not as good as CMPLOG mode (see below). ## 8) CMPLOG mode @@ -141,7 +142,7 @@ To enable it you must pass on the command line of afl-fuzz: ## 9) Wine mode -AFL++ QEMU can use Wine to fuzz WIn32 PE binaries. Use the -W flag of afl-fuzz. +AFL++ QEMU can use Wine to fuzz Win32 PE binaries. Use the -W flag of afl-fuzz. Note that some binaries require user interaction with the GUI and must be patched. @@ -190,8 +191,8 @@ handlers of the target. ## 13) Gotchas, feedback, bugs -If you need to fix up checksums or do other cleanup on mutated test cases, see -utils/custom_mutators/ for a viable solution. +If you need to fix up checksums or do other cleanups on mutated test cases, see +`afl_custom_post_process` in custom_mutators/examples/example.c for a viable solution. Do not mix QEMU mode with ASAN, MSAN, or the likes; QEMU doesn't appreciate the "shadow VM" trick employed by the sanitizers and will probably just diff --git a/qemu_mode/README.wine.md b/qemu_mode/README.wine.md new file mode 100644 index 00000000..567901cd --- /dev/null +++ b/qemu_mode/README.wine.md @@ -0,0 +1,21 @@ +# How to troubleshoot AFL++'s wine mode + +## 1) Debugging +To turn on wine debugging use the `WINEDEBUG` environment variable, +e.g. `WINEDEBUG=+timestamp,+tid,+loaddll`. + +## 2) LoadLibraryA workaround +The forked process fails to load libraries loaded via `LoadLibrary` +if the load happens after the entry point (error code: 87). To resolve +this issue, one needs to load any external libraries before the fork happens. + +An early DLL load can be achieved by adding the DLL name into the `Import Directory` +in the PE file. Such an entry can be added manually in any PE editor. + +Alternativly, one can generate a `.lib` file from the DLL exports and link +them together with the harness to create an entry in the `Import Directory`. +Use `dumpbin /exports <filename>.dll` to extract the exports and paste the +exported function names into a `.def` file. Use `lib /def:<deffile> /OUT:<libfile>` +to generate a `.lib` and add the library to the linker options. Once the usage of +an export is detected (`__declspec(dllimport)`), the +linker adds the early DLL load. \ No newline at end of file diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index 6436d43a..84f144be 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -9,7 +9,7 @@ # TCG instrumentation and block chaining support by Andrea Biondo # <andrea.biondo965@gmail.com> # -# QEMU 3.1.1 port, TCG thread-safety, CompareCoverage and NeverZero +# QEMU 5+ port, TCG thread-safety, CompareCoverage and NeverZero # counters by Andrea Fioraldi <andreafioraldi@gmail.com> # # Copyright 2015, 2016, 2017 Google Inc. All rights reserved. @@ -211,8 +211,9 @@ if [ "$STATIC" = "1" ]; then echo Building STATIC binary + # static PIE causes https://github.com/AFLplusplus/AFLplusplus/issues/892 QEMU_CONF_FLAGS="$QEMU_CONF_FLAGS \ - --static \ + --static --disable-pie \ --extra-cflags=-DAFL_QEMU_STATIC_BUILD=1 \ " diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c index 0e6c3e08..c542521c 100644 --- a/qemu_mode/libqasan/hooks.c +++ b/qemu_mode/libqasan/hooks.c @@ -25,9 +25,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "libqasan.h" #include "map_macro.h" +#include <unistd.h> +#include <sys/syscall.h> -ssize_t (*__lq_libc_write)(int, const void *, size_t); -ssize_t (*__lq_libc_read)(int, void *, size_t); char *(*__lq_libc_fgets)(char *, int, FILE *); int (*__lq_libc_atoi)(const char *); long (*__lq_libc_atol)(const char *); @@ -37,8 +37,6 @@ void __libqasan_init_hooks(void) { __libqasan_init_malloc(); - __lq_libc_write = ASSERT_DLSYM(write); - __lq_libc_read = ASSERT_DLSYM(read); __lq_libc_fgets = ASSERT_DLSYM(fgets); __lq_libc_atoi = ASSERT_DLSYM(atoi); __lq_libc_atol = ASSERT_DLSYM(atol); @@ -52,7 +50,7 @@ ssize_t write(int fd, const void *buf, size_t count) { QASAN_DEBUG("%14p: write(%d, %p, %zu)\n", rtv, fd, buf, count); QASAN_LOAD(buf, count); - ssize_t r = __lq_libc_write(fd, buf, count); + ssize_t r = syscall(SYS_write, fd, buf, count); QASAN_DEBUG("\t\t = %zd\n", r); return r; @@ -65,7 +63,7 @@ ssize_t read(int fd, void *buf, size_t count) { QASAN_DEBUG("%14p: read(%d, %p, %zu)\n", rtv, fd, buf, count); QASAN_STORE(buf, count); - ssize_t r = __lq_libc_read(fd, buf, count); + ssize_t r = syscall(SYS_read, fd, buf, count); QASAN_DEBUG("\t\t = %zd\n", r); return r; diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c index 9fc4ef7a..d4742e3e 100644 --- a/qemu_mode/libqasan/libqasan.c +++ b/qemu_mode/libqasan/libqasan.c @@ -61,9 +61,19 @@ void __libqasan_print_maps(void) { } -/*__attribute__((constructor))*/ void __libqasan_init() { +int __libqasan_is_initialized = 0; + +__attribute__((constructor)) void __libqasan_init() { + + if (__libqasan_is_initialized) return; + __libqasan_is_initialized = 1; __libqasan_init_hooks(); + + if (getenv("AFL_INST_LIBS") || getenv("QASAN_HOTPACH")) + __libqasan_hotpatch(); + + if (getenv("AFL_INST_LIBS") || getenv("QASAN_HOTPACH")) __libqasan_hotpatch(); #ifdef DEBUG __qasan_debug = getenv("QASAN_DEBUG") != NULL; @@ -86,7 +96,6 @@ int __libc_start_main(int (*main)(int, char **, char **), int argc, char **argv, typeof(&__libc_start_main) orig = dlsym(RTLD_NEXT, "__libc_start_main"); __libqasan_init(); - if (getenv("AFL_INST_LIBS")) __libqasan_hotpatch(); return orig(main, argc, argv, init, fini, rtld_fini, stack_end); |