about summary refs log tree commit diff
path: root/qemu_mode
diff options
context:
space:
mode:
Diffstat (limited to 'qemu_mode')
-rw-r--r--qemu_mode/README.md67
-rwxr-xr-xqemu_mode/build_qemu_support.sh2
-rwxr-xr-xqemu_mode/libcompcov/compcovtestbin8624 -> 0 bytes
-rw-r--r--qemu_mode/patches/afl-qemu-common.h1
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-inl.h4
-rw-r--r--qemu_mode/patches/afl-qemu-cpu-translate-inl.h2
-rw-r--r--qemu_mode/unsigaction/Makefile34
-rw-r--r--qemu_mode/unsigaction/README.md7
-rw-r--r--qemu_mode/unsigaction/unsigaction.c3
9 files changed, 98 insertions, 22 deletions
diff --git a/qemu_mode/README.md b/qemu_mode/README.md
index 54fbf874..b994e4c6 100644
--- a/qemu_mode/README.md
+++ b/qemu_mode/README.md
@@ -19,7 +19,7 @@ Andrea Fioraldi. Special thanks to abiondo that re-enabled TCG chaining.
 
 ## 2) How to use
 
-The feature is implemented with a patch to QEMU 3.1.0. The simplest way
+The feature is implemented with a patch to QEMU 3.1.1. The simplest way
 to build it is to run ./build_qemu_support.sh. The script will download,
 configure, and compile the QEMU binary for you.
 
@@ -44,25 +44,19 @@ Note: if you want the QEMU helper to be installed on your system for all
 users, you need to build it before issuing 'make install' in the parent
 directory.
 
-## 3) Options
+## 3) Bonus feature #1: deferred initialization
 
-There is ./libcompcov/ which implements laf-intel (splitting memcmp,
-strncmp, etc. to make these conditions easier solvable by afl-fuzz).
-Highly recommended.
+As for LLVM mode (referes to its README for mode details) QEMU mode support
+the deferred initialization.
 
-The option that enables QEMU CompareCoverage is AFL_COMPCOV_LEVEL.
-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. Comparison instructions are currently instrumented only
-on the x86 and x86_64 targets.
-
-Another option is the environment variable AFL_ENTRYPOINT which allows
-move the forkserver to a different part, e.g. just before the file is
+This can be enabled setting the environment variable AFL_ENTRYPOINT which allows
+to move the forkserver to a different part, e.g. just before the file is
 opened (e.g. way after command line parsing and config file loading, etc)
 which can be a huge speed improvement. Note that the specified address
 must be an address of a basic block.
 
+## 4) Bonus feature #2: persistent mode
+
 QEMU mode support also persistent mode for x86 and x86_64 targets.
 The environment variable to enable it is AFL_QEMU_PERSISTENT_ADDR=`start addr`.
 In this variable you must specify the address of the function that
@@ -78,11 +72,42 @@ Note that the format of the addresses in such variables is hex.
 
 Note that the base address of PIE binaries in QEMU user is 0x4000000000.
 
-Warning: in x86_64 parameters are passed via registers and so the target
-function of persistent mode cannot make use of arguments. An option to restore
-the state of each GPR each iteration of the loop is planned.
+With the env variable AFL_QEMU_PERSISTENT_GPR you can tell QEMU to save the
+original value of general purpose registers and restore them ech cycle.
+This allow to use as persistent loop functions that make use of arguments on 
+x86_64.
+
+With AFL_QEMU_PERSISTENT_RETADDR_OFFSET you can specify the offset from the
+stack pointer in which QEME can find the return address when `start addr` is
+hitted.
+
+Use this mode with caution, problably will not work at first shot.
+
+## 5) Bonus feature #3: CompareCoverage
+
+CompareCoverage is a sub-instrumentation with effects similar to laf-intel.
+
+The option 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).
+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. Comparison instructions are currently instrumented only
+on the x86 and x86_64 targets.
+
+Highly recommended.
+
+## 6) Bonus feature #3: Wine mode
+
+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 GUI and must be patched.
+
+For examples look [here](https://github.com/andreafioraldi/WineAFLplusplusDEMO).
 
-## 4) Notes on linking
+## 7) Notes on linking
 
 The feature is supported only on Linux. Supporting BSD may amount to porting
 the changes made to linux-user/elfload.c and applying them to
@@ -103,7 +128,7 @@ practice, this means two things:
 Setting AFL_INST_LIBS=1 can be used to circumvent the .text detection logic
 and instrument every basic block encountered.
 
-## 5) Benchmarking
+## 8) Benchmarking
 
 If you want to compare the performance of the QEMU instrumentation with that of
 afl-gcc compiled code against the same target, you need to build the
@@ -118,7 +143,7 @@ Comparative measurements of execution speed or instrumentation coverage will be
 fairly meaningless if the optimization levels or instrumentation scopes don't
 match.
 
-## 6) Gotchas, feedback, bugs
+## 9) Gotchas, feedback, bugs
 
 If you need to fix up checksums or do other cleanup on mutated test cases, see
 experimental/post_library/ for a viable solution.
@@ -139,7 +164,7 @@ with -march=core2, can help.
 Beyond that, this is an early-stage mechanism, so fields reports are welcome.
 You can send them to <afl-users@googlegroups.com>.
 
-## 7) Alternatives: static rewriting
+## 10) Alternatives: static rewriting
 
 Statically rewriting binaries just once, instead of attempting to translate
 them at run time, can be a faster alternative. That said, static rewriting is
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index 0ca3f494..02379eb2 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -212,6 +212,8 @@ fi
 
 echo "[+] Building libcompcov ..."
 make -C libcompcov
+echo "[+] Building unsigaction ..."
+make -C unsigaction
 echo "[+] libcompcov ready"
 echo "[+] All done for qemu_mode, enjoy!"
 
diff --git a/qemu_mode/libcompcov/compcovtest b/qemu_mode/libcompcov/compcovtest
deleted file mode 100755
index 0bb68d60..00000000
--- a/qemu_mode/libcompcov/compcovtest
+++ /dev/null
Binary files differdiff --git a/qemu_mode/patches/afl-qemu-common.h b/qemu_mode/patches/afl-qemu-common.h
index 2b7bd51c..e435c62f 100644
--- a/qemu_mode/patches/afl-qemu-common.h
+++ b/qemu_mode/patches/afl-qemu-common.h
@@ -61,6 +61,7 @@ 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 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 ee7d12e0..cfea04d6 100644
--- a/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -90,6 +90,7 @@ target_long   persistent_stack_offset;
 unsigned char persistent_first_pass;
 unsigned char persistent_save_gpr;
 target_ulong  persistent_saved_gpr[CPU_NB_REGS];
+int           persisent_retaddr_offset;
 
 /* Instrumentation ratio: */
 
@@ -218,6 +219,9 @@ static void afl_setup(void) {
   
   if (getenv("AFL_QEMU_PERSISTENT_GPR"))
     persistent_save_gpr = 1;
+  
+  if (getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"))
+    persisent_retaddr_offset = strtoll(getenv("AFL_QEMU_PERSISTENT_RETADDR_OFFSET"), NULL, 16);
 
   if (getenv("AFL_QEMU_PERSISTENT_CNT"))
     afl_persistent_cnt = strtoll(getenv("AFL_QEMU_PERSISTENT_CNT"), NULL, 16);
diff --git a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
index 48b11c64..126cf255 100644
--- a/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
+++ b/qemu_mode/patches/afl-qemu-cpu-translate-inl.h
@@ -195,7 +195,7 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv_i64 arg1, TCGv_i64 arg2,
       if (afl_persistent_ret_addr == 0) {                                     \
                                                                               \
         TCGv_ptr paddr = tcg_const_ptr(afl_persistent_addr);                  \
-        tcg_gen_st_tl(paddr, cpu_regs[R_ESP], 0);                             \
+        tcg_gen_st_tl(paddr, cpu_regs[R_ESP], persisent_retaddr_offset);      \
                                                                               \
       }                                                                       \
       tcg_gen_afl_call0(&afl_persistent_loop);                                \
diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile
new file mode 100644
index 00000000..9aa96330
--- /dev/null
+++ b/qemu_mode/unsigaction/Makefile
@@ -0,0 +1,34 @@
+#
+# american fuzzy lop - unsigaction
+# --------------------------------
+#
+# Written by Andrea Fioraldi <andreafioraldi@gmail.com>
+#
+# Copyright 2019 Andrea Fioraldi. 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
+#
+
+ifndef AFL_NO_X86
+
+all: lib_i386 lib_amd64
+
+lib_i386:
+	$(CC) -m32 -fPIC -shared unsigaction.c -o unsigaction32.so
+
+lib_amd64:
+	$(CC) -fPIC -shared unsigaction.c -o unsigaction64.so
+
+clean:
+	rm -f unsigaction32.so unsigaction64.so
+
+else
+
+all:
+	@echo "[!] Note: skipping compilation of unsigaction (AFL_NO_X86 set)."
+
+endif
diff --git a/qemu_mode/unsigaction/README.md b/qemu_mode/unsigaction/README.md
new file mode 100644
index 00000000..0f3707fd
--- /dev/null
+++ b/qemu_mode/unsigaction/README.md
@@ -0,0 +1,7 @@
+# unsigation
+
+This library disable sigaction when preloaded.
+
+Mainly needed by Wine mode but can be used as a separate tool.
+
+A similar solution can be found in is [preeny](https://github.com/zardus/preeny).
diff --git a/qemu_mode/unsigaction/unsigaction.c b/qemu_mode/unsigaction/unsigaction.c
new file mode 100644
index 00000000..004084f9
--- /dev/null
+++ b/qemu_mode/unsigaction/unsigaction.c
@@ -0,0 +1,3 @@
+int sigaction(int signum, void *act, void *oldact) {
+  return 0;
+}