From fdc364046e8349652d857e5f5decd8a09b89831e Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 2 Nov 2020 13:56:24 +0100 Subject: doc for qemuafl --- examples/qemu_persistent_hook/read_into_rdi.c | 52 +++++++-------------------- 1 file changed, 13 insertions(+), 39 deletions(-) (limited to 'examples/qemu_persistent_hook') diff --git a/examples/qemu_persistent_hook/read_into_rdi.c b/examples/qemu_persistent_hook/read_into_rdi.c index bd6d3f45..15647cb4 100644 --- a/examples/qemu_persistent_hook/read_into_rdi.c +++ b/examples/qemu_persistent_hook/read_into_rdi.c @@ -1,53 +1,28 @@ -#include +#include "../../qemu_mode/qemuafl/qemuafl/api.h" + #include -#include #include +void afl_persistent_hook(struct x86_64_regs *regs, + uint64_t guest_base, + uint8_t *input_buf, + uint32_t input_buf_len) { + #define g2h(x) ((void *)((unsigned long)(x) + guest_base)) #define h2g(x) ((uint64_t)(x)-guest_base) -enum { - - R_EAX = 0, - R_ECX = 1, - R_EDX = 2, - R_EBX = 3, - R_ESP = 4, - R_EBP = 5, - R_ESI = 6, - R_EDI = 7, - R_R8 = 8, - R_R9 = 9, - R_R10 = 10, - R_R11 = 11, - R_R12 = 12, - R_R13 = 13, - R_R14 = 14, - R_R15 = 15, - - R_AL = 0, - R_CL = 1, - R_DL = 2, - R_BL = 3, - R_AH = 4, - R_CH = 5, - R_DH = 6, - R_BH = 7, - -}; - -void afl_persistent_hook(uint64_t *regs, uint64_t guest_base, - uint8_t *input_buf, uint32_t input_len) { - // In this example the register RDI is pointing to the memory location // of the target buffer, and the length of the input is in RSI. // This can be seen with a debugger, e.g. gdb (and "disass main") - printf("placing input into %p\n", regs[R_EDI]); + printf("Placing input into %p\n", regs->rdi); if (input_len > 1024) input_len = 1024; - memcpy(g2h(regs[R_EDI]), input_buf, input_len); - regs[R_ESI] = input_len; + memcpy(g2h(regs->rdi), input_buf, input_len); + regs->rsi = input_len; + +#undef g2h +#undef h2g } @@ -58,4 +33,3 @@ int afl_persistent_hook_init(void) { return 1; } - -- cgit 1.4.1 From a260d34b4997d86ec158843c2362dae009e3bcf7 Mon Sep 17 00:00:00 2001 From: Andrea Fioraldi Date: Mon, 2 Nov 2020 14:15:44 +0100 Subject: persistent hook example --- README.md | 2 +- examples/qemu_persistent_hook/Makefile | 6 ++++++ examples/qemu_persistent_hook/README.md | 3 +-- examples/qemu_persistent_hook/read_into_rdi.c | 8 ++++---- qemu_mode/README.md | 23 ++++++++++++++++------- qemu_mode/build_qemu_support.sh | 2 +- 6 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 examples/qemu_persistent_hook/Makefile (limited to 'examples/qemu_persistent_hook') diff --git a/README.md b/README.md index 26a81d9d..f955aedd 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ If you want to build afl++ yourself you have many options. The easiest choice is to build and install everything: ```shell -sudo apt install build-essential libtool-bin python3-dev automake flex bison libglib2.0-dev libpixman-1-dev clang python3-setuptools llvm +sudo apt install build-essential python3-dev automake flex bison libglib2.0-dev libpixman-1-dev clang python3-setuptools llvm make distrib sudo make install ``` diff --git a/examples/qemu_persistent_hook/Makefile b/examples/qemu_persistent_hook/Makefile new file mode 100644 index 00000000..85db1b46 --- /dev/null +++ b/examples/qemu_persistent_hook/Makefile @@ -0,0 +1,6 @@ +all: + $(CC) -no-pie test.c -o test + $(CC) -fPIC -shared read_into_rdi.c -o read_into_rdi.so + +clean: + rm -rf in out test read_into_rdi.so diff --git a/examples/qemu_persistent_hook/README.md b/examples/qemu_persistent_hook/README.md index 3278b60c..3f908c22 100644 --- a/examples/qemu_persistent_hook/README.md +++ b/examples/qemu_persistent_hook/README.md @@ -3,8 +3,7 @@ Compile the test binary and the library: ``` -gcc -no-pie test.c -o test -gcc -fPIC -shared read_into_rdi.c -o read_into_rdi.so +make ``` Fuzz with: diff --git a/examples/qemu_persistent_hook/read_into_rdi.c b/examples/qemu_persistent_hook/read_into_rdi.c index 15647cb4..1977c89f 100644 --- a/examples/qemu_persistent_hook/read_into_rdi.c +++ b/examples/qemu_persistent_hook/read_into_rdi.c @@ -15,11 +15,11 @@ void afl_persistent_hook(struct x86_64_regs *regs, // of the target buffer, and the length of the input is in RSI. // This can be seen with a debugger, e.g. gdb (and "disass main") - printf("Placing input into %p\n", regs->rdi); + printf("Placing input into 0x%lx\n", regs->rdi); - if (input_len > 1024) input_len = 1024; - memcpy(g2h(regs->rdi), input_buf, input_len); - regs->rsi = input_len; + if (input_buf_len > 1024) input_buf_len = 1024; + memcpy(g2h(regs->rdi), input_buf, input_buf_len); + regs->rsi = input_buf_len; #undef g2h #undef h2g diff --git a/qemu_mode/README.md b/qemu_mode/README.md index 9bbeeb19..348f5bbc 100644 --- a/qemu_mode/README.md +++ b/qemu_mode/README.md @@ -90,7 +90,16 @@ fork() mode but, opposed to fork(), it can scale better with multicore. If the AFL++ Snaphsot kernel module is loaded, qemuafl will use it and, in this case, the speed is better than fork() and also the scaling capabilities. -## 6) CompareCoverage +## 6) Partial instrumentation + +You can tell QEMU to instrument only a part of the address space. + +Just set AFL_QEMU_INST_RANGES=A,B,C... + +The format of the iterms in the list is either a range of addresses like 0x123-0x321 +or a module name like module.so (that is mathed in the mapped object filename). + +## 7) CompareCoverage CompareCoverage is a sub-instrumentation with effects similar to laf-intel. @@ -111,7 +120,7 @@ on the x86, x86_64, arm and aarch64 targets. Highly recommended. -## 7) CMPLOG mode +## 8) CMPLOG mode Another new feature is CMPLOG, which is based on the redqueen project. Here all immidiates in CMP instructions are learned and put into a dynamic @@ -123,7 +132,7 @@ and aarch64. To enable it you must pass on the command line of afl-fuzz: -c /path/to/your/target -## 8) Wine mode +## 9) Wine mode AFL++ QEMU can use Wine to fuzz WIn32 PE binaries. Use the -W flag of afl-fuzz. @@ -131,7 +140,7 @@ Note that some binaries require user interaction with the GUI and must be patche For examples look [here](https://github.com/andreafioraldi/WineAFLplusplusDEMO). -## 9) Notes on linking +## 10) 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 @@ -152,7 +161,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. -## 10) Benchmarking +## 11) 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 @@ -167,7 +176,7 @@ Comparative measurements of execution speed or instrumentation coverage will be fairly meaningless if the optimization levels or instrumentation scopes don't match. -## 11) Gotchas, feedback, bugs +## 12) Gotchas, feedback, bugs If you need to fix up checksums or do other cleanup on mutated test cases, see examples/custom_mutators/ for a viable solution. @@ -188,7 +197,7 @@ with -march=core2, can help. Beyond that, this is an early-stage mechanism, so fields reports are welcome. You can send them to . -## 12) Alternatives: static rewriting +## 13) 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 9561ea34..683026bb 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -60,7 +60,7 @@ if [ ! -f "../afl-showmap" ]; then fi PREREQ_NOTFOUND= -for i in libtool wget automake autoconf sha384sum bison flex iconv patch pkg-config; do +for i in git wget sha384sum bison flex iconv patch pkg-config; do T=`command -v "$i" 2>/dev/null` -- cgit 1.4.1 From 050354a9deeece1249f3f5a8172328b4523c5b7f Mon Sep 17 00:00:00 2001 From: van Hauser Date: Mon, 2 Nov 2020 17:34:58 +0100 Subject: code-format --- examples/qemu_persistent_hook/read_into_rdi.c | 9 ++++----- instrumentation/SanitizerCoveragePCGUARD.so.cc | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) (limited to 'examples/qemu_persistent_hook') diff --git a/examples/qemu_persistent_hook/read_into_rdi.c b/examples/qemu_persistent_hook/read_into_rdi.c index 1977c89f..f4a8ae59 100644 --- a/examples/qemu_persistent_hook/read_into_rdi.c +++ b/examples/qemu_persistent_hook/read_into_rdi.c @@ -3,11 +3,9 @@ #include #include -void afl_persistent_hook(struct x86_64_regs *regs, - uint64_t guest_base, - uint8_t *input_buf, - uint32_t input_buf_len) { - +void afl_persistent_hook(struct x86_64_regs *regs, uint64_t guest_base, + uint8_t *input_buf, uint32_t input_buf_len) { +\ #define g2h(x) ((void *)((unsigned long)(x) + guest_base)) #define h2g(x) ((uint64_t)(x)-guest_base) @@ -33,3 +31,4 @@ int afl_persistent_hook_init(void) { return 1; } + diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 934db3de..772a6f60 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -70,15 +70,17 @@ class ModuleSanitizerCoveragePass if (AllowlistFiles.size() > 0) Allowlist = SpecialCaseList::createOrDie(AllowlistFiles #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - , *vfs::getRealFileSystem() + , + *vfs::getRealFileSystem() #endif - ); + ); if (BlocklistFiles.size() > 0) Blocklist = SpecialCaseList::createOrDie(BlocklistFiles #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - , *vfs::getRealFileSystem() + , + *vfs::getRealFileSystem() #endif - ); + ); } @@ -253,7 +255,7 @@ SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) { Options.CoverageType = SanitizerCoverageOptions::SCK_Edge; // std::max(Options.CoverageType, // CLOpts.CoverageType); - Options.IndirectCalls = false; // CLOpts.IndirectCalls; + Options.IndirectCalls = false; // CLOpts.IndirectCalls; Options.TraceCmp = false; //|= ClCMPTracing; Options.TraceDiv = false; //|= ClDIVTracing; Options.TraceGep = false; //|= ClGEPTracing; @@ -379,15 +381,17 @@ class ModuleSanitizerCoverageLegacyPass : public ModulePass { if (AllowlistFiles.size() > 0) Allowlist = SpecialCaseList::createOrDie(AllowlistFiles #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - , *vfs::getRealFileSystem() + , + *vfs::getRealFileSystem() #endif - ); + ); if (BlocklistFiles.size() > 0) Blocklist = SpecialCaseList::createOrDie(BlocklistFiles #if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) - , *vfs::getRealFileSystem() + , + *vfs::getRealFileSystem() #endif - ); + ); initializeModuleSanitizerCoverageLegacyPassPass( *PassRegistry::getPassRegistry()); -- cgit 1.4.1