about summary refs log tree commit diff
path: root/docs/fuzzing_binary-only_targets.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/fuzzing_binary-only_targets.md')
-rw-r--r--docs/fuzzing_binary-only_targets.md69
1 files changed, 36 insertions, 33 deletions
diff --git a/docs/fuzzing_binary-only_targets.md b/docs/fuzzing_binary-only_targets.md
index 290c9bec..5434a22c 100644
--- a/docs/fuzzing_binary-only_targets.md
+++ b/docs/fuzzing_binary-only_targets.md
@@ -12,18 +12,19 @@ fuzzed with AFL++.
 
 ## TL;DR:
 
-Qemu_mode in persistent mode is the fastest - if the stability is high enough.
+QEMU mode in persistent mode is the fastest - if the stability is high enough.
 Otherwise, try RetroWrite, Dyninst, and if these fail, too, then try standard
-qemu_mode with AFL_ENTRYPOINT to where you need it.
+QEMU mode with `AFL_ENTRYPOINT` to where you need it.
 
-If your target is a library, then use frida_mode.
+If your target is a library, then use FRIDA mode.
 
 If your target is non-linux, then use unicorn_mode.
 
 ## Fuzzing binary-only targets with AFL++
-### Qemu_mode
 
-Qemu_mode is the "native" solution to the program. It is available in the
+### QEMU mode
+
+QEMU mode is the "native" solution to the program. It is available in the
 ./qemu_mode/ directory and, once compiled, it can be accessed by the afl-fuzz -Q
 command line option. It is the easiest to use alternative and even works for
 cross-platform binaries.
@@ -37,11 +38,12 @@ cd qemu_mode
 ./build_qemu_support.sh
 ```
 
-The following setup to use qemu_mode is recommended:
+The following setup to use QEMU mode is recommended:
+
 * run 1 afl-fuzz -Q instance with CMPLOG (`-c 0` + `AFL_COMPCOV_LEVEL=2`)
 * run 1 afl-fuzz -Q instance with QASAN (`AFL_USE_QASAN=1`)
 * run 1 afl-fuzz -Q instance with LAF (`AFL_PRELOAD=libcmpcov.so` +
-  `AFL_COMPCOV_LEVEL=2`), alternatively you can use frida_mode, just switch `-Q`
+  `AFL_COMPCOV_LEVEL=2`), alternatively you can use FRIDA mode, just switch `-Q`
   with `-O` and remove the LAF instance
 
 Then run as many instances as you have cores left with either -Q mode or - even
@@ -49,16 +51,16 @@ better - use a binary rewriter like Dyninst, RetroWrite, ZAFL, etc.
 
 If [afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) works for your
 binary, then you can use afl-fuzz normally and it will have twice the speed
-compared to qemu_mode (but slower than qemu persistent mode). Note that several
+compared to QEMU mode (but slower than QEMU persistent mode). Note that several
 other binary rewriters exist, all with their advantages and caveats.
 
-The speed decrease of qemu_mode is at about 50%. However, various options exist
+The speed decrease of QEMU mode is at about 50%. However, various options exist
 to increase the speed:
 - using AFL_ENTRYPOINT to move the forkserver entry to a later basic block in
   the binary (+5-10% speed)
 - using persistent mode
   [qemu_mode/README.persistent.md](../qemu_mode/README.persistent.md) this will
-  result in a 150-300% overall speed increase - so 3-8x the original qemu_mode
+  result in a 150-300% overall speed increase - so 3-8x the original QEMU mode
   speed!
 - using AFL_CODE_START/AFL_CODE_END to only instrument specific parts
 
@@ -71,7 +73,7 @@ conducive to parallelization.
 
 Note that there is also honggfuzz:
 [https://github.com/google/honggfuzz](https://github.com/google/honggfuzz) which
-now has a qemu_mode, but its performance is just 1.5% ...
+now has a QEMU mode, but its performance is just 1.5% ...
 
 If you like to code a customized fuzzer without much work, we highly recommend
 to check out our sister project libafl which supports QEMU, too:
@@ -84,16 +86,17 @@ Wine, python3, and the pefile python package installed.
 
 It is included in AFL++.
 
-For more information, see [qemu_mode/README.wine.md](../qemu_mode/README.wine.md).
+For more information, see
+[qemu_mode/README.wine.md](../qemu_mode/README.wine.md).
 
-### Frida_mode
+### FRIDA mode
 
-In frida_mode, you can fuzz binary-only targets as easily as with QEMU.
-Frida_mode is sometimes faster and sometimes slower than Qemu_mode. It is also
+In FRIDA mode, you can fuzz binary-only targets as easily as with QEMU mode.
+FRIDA mode is sometimes faster and sometimes slower than QEMU mode. It is also
 newer, lacks COMPCOV, and has the advantage that it works on MacOS (both intel
 and M1).
 
-To build frida_mode:
+To build FRIDA mode:
 
 ```shell
 cd frida_mode
@@ -104,16 +107,16 @@ For additional instructions and caveats, see
 [frida_mode/README.md](../frida_mode/README.md).
 
 If possible, you should use the persistent mode, see
-[qemu_frida/README.md](../qemu_frida/README.md). The mode is approximately 2-5x
-slower than compile-time instrumentation, and is less conducive to
-parallelization. But for binary-only fuzzing, it gives a huge speed improvement
-if it is possible to use.
+[instrumentation/README.persistent_mode.md](../instrumentation/README.persistent_mode.md).
+The mode is approximately 2-5x slower than compile-time instrumentation, and is
+less conducive to parallelization. But for binary-only fuzzing, it gives a huge
+speed improvement if it is possible to use.
 
 If you want to fuzz a binary-only library, then you can fuzz it with frida-gum
 via frida_mode/. You will have to write a harness to call the target function in
 the library, use afl-frida.c as a template.
 
-You can also perform remote fuzzing with frida, e.g. if you want to fuzz on
+You can also perform remote fuzzing with frida, e.g., if you want to fuzz on
 iPhone or Android devices, for this you can use
 [https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) as
 an intermediate that uses AFL++ for fuzzing.
@@ -129,8 +132,7 @@ Unicorn is a fork of QEMU. The instrumentation is, therefore, very similar. In
 contrast to QEMU, Unicorn does not offer a full system or even userland
 emulation. Runtime environment and/or loaders have to be written from scratch,
 if needed. On top, block chaining has been removed. This means the speed boost
-introduced in the patched QEMU Mode of AFL++ cannot simply be ported over to
-Unicorn.
+introduced in the patched QEMU Mode of AFL++ cannot be ported over to Unicorn.
 
 For non-Linux binaries, you can use AFL++'s unicorn_mode which can emulate
 anything you want - for the price of speed and user written scripts.
@@ -149,11 +151,11 @@ For further information, check out
 
 If the goal is to fuzz a dynamic library, then there are two options available.
 For both, you need to write a small harness that loads and calls the library.
-Then you fuzz this with either frida_mode or qemu_mode and either use
+Then you fuzz this with either FRIDA mode or QEMU mode and either use
 `AFL_INST_LIBS=1` or `AFL_QEMU/FRIDA_INST_RANGES`.
 
 Another, less precise and slower option is to fuzz it with utils/afl_untracer/
-and use afl-untracer.c as a template. It is slower than frida_mode.
+and use afl-untracer.c as a template. It is slower than FRIDA mode.
 
 For more information, see
 [utils/afl_untracer/README.md](../utils/afl_untracer/README.md).
@@ -170,9 +172,11 @@ Fore more information, see
 
 ## Binary rewriters
 
-An alternative solution are binary rewriters. They are faster then the solutions native to AFL++ but don't always work.
+An alternative solution are binary rewriters. They are faster than the solutions
+native to AFL++ but don't always work.
 
 ### ZAFL
+
 ZAFL is a static rewriting platform supporting x86-64 C/C++,
 stripped/unstripped, and PIE/non-PIE binaries. Beyond conventional
 instrumentation, ZAFL's API enables transformation passes (e.g., laf-Intel,
@@ -199,13 +203,13 @@ It is at about 80-85% performance.
 Dyninst is a binary instrumentation framework similar to Pintool and DynamoRIO.
 However, whereas Pintool and DynamoRIO work at runtime, Dyninst instruments the
 target at load time and then let it run - or save the binary with the changes.
-This is great for some things, e.g. fuzzing, and not so effective for others,
-e.g. malware analysis.
+This is great for some things, e.g., fuzzing, and not so effective for others,
+e.g., malware analysis.
 
-So, what we can do with Dyninst is taking every basic block and put AFL++'s
-instrumentation code in there - and then save the binary. Afterwards, we can
-just fuzz the newly saved target binary with afl-fuzz. Sounds great? It is. The
-issue though - it is a non-trivial problem to insert instructions, which change
+So, what you can do with Dyninst is taking every basic block and putting AFL++'s
+instrumentation code in there - and then save the binary. Afterwards, just fuzz
+the newly saved target binary with afl-fuzz. Sounds great? It is. The issue
+though - it is a non-trivial problem to insert instructions, which change
 addresses in the process space, so that everything is still working afterwards.
 Hence, more often than not binaries crash when they are run.
 
@@ -275,7 +279,6 @@ There are many binary-only fuzzing frameworks. Some are great for CTFs but don't
 work with large binaries, others are very slow but have good path discovery,
 some are very hard to set-up...
 
-
 * Jackalope:
   [https://github.com/googleprojectzero/Jackalope](https://github.com/googleprojectzero/Jackalope)
 * Manticore: