about summary refs log tree commit diff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/Changelog.md31
-rw-r--r--docs/FAQ.md126
-rw-r--r--docs/binaryonly_fuzzing.md19
-rw-r--r--docs/custom_mutators.md2
-rw-r--r--docs/env_variables.md38
-rw-r--r--docs/parallel_fuzzing.md14
-rw-r--r--docs/screenshot.pngbin0 -> 117199 bytes
7 files changed, 211 insertions, 19 deletions
diff --git a/docs/Changelog.md b/docs/Changelog.md
index afb9dea6..ae7377f2 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,6 +9,37 @@ Want to stay in the loop on major new features? Join our mailing list by
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 
+### Version ++2.66d (devel)
+  - Support for improved afl++ snapshot module:
+    https://github.com/AFLplusplus/AFL-Snapshot-LKM
+  - afl-fuzz:
+     - added -F option to allow -M main fuzzers to sync to foreign fuzzers,
+       e.g. honggfuzz or libfuzzer
+     - added -b option to bind to a specific CPU
+     - eliminated CPU affinity race condition for -S/-M runs
+     - expanded havoc mode added, on no cycle finds add extra splicing and
+       MOpt into the mix
+     - fixed a bug in redqueen for strings
+  - llvm_mode:
+     - now supports llvm 12!
+     - fixes for laf-intel float splitting (thanks to mark-griffin for
+       reporting)
+     - LTO: autodictionary mode is a default
+     - LTO: instrim instrumentation disabled, only classic support used
+            as it is always better
+     - LTO: env var AFL_LLVM_DOCUMENT_IDS=file will document which edge ID
+            was given to which function during compilation
+     - LTO: single block functions were not implemented by default, fixed
+     - LTO: AFL_LLVM_SKIP_NEVERZERO behaviour was inversed, fixed
+     - setting AFL_LLVM_LAF_SPLIT_FLOATS now activates
+       AFL_LLVM_LAF_SPLIT_COMPARES
+  - added honggfuzz mangle as a custom mutator in custom_mutators/honggfuzz
+  - added afl-frida gum solution to examples/afl_frida (mostly imported
+    from https://github.com/meme/hotwax/)
+  - small fixes to afl-plot, afl-whatsup and man page creation
+  - new README, added FAQ
+
+
 ### Version ++2.66c (release)
   - renamed the main branch on Github to "stable"
   - renamed master/slave to main/secondary
diff --git a/docs/FAQ.md b/docs/FAQ.md
new file mode 100644
index 00000000..c15cd484
--- /dev/null
+++ b/docs/FAQ.md
@@ -0,0 +1,126 @@
+# Frequently asked questions about afl++
+
+## Contents
+
+  1. [How to improve the fuzzing speed?](#how-to-improve-the-fuzzing-speed)
+  2. [What is an edge?](#what-is-an-edge)
+  3. [Why is my stability below 100%?](#why-is-my-stability-below-100)
+  4. [How can I improve the stability value](#how-can-i-improve-the-stability-value)
+
+If you find an interesting or important question missing, submit it via
+[https://github.com/AFLplusplus/AFLplusplus/issues](https://github.com/AFLplusplus/AFLplusplus/issues)
+
+## How to improve the fuzzing speed
+
+  1. use [llvm_mode](docs/llvm_mode/README.md): afl-clang-lto (llvm >= 11) or afl-clang-fast (llvm >= 9 recommended)
+  2. Use [persistent mode](llvm_mode/README.persistent_mode.md) (x2-x20 speed increase)
+  3. Use the [afl++ snapshot module](https://github.com/AFLplusplus/AFL-Snapshot-LKM) (x2 speed increase)
+  4. If you do not use shmem persistent mode, use `AFL_TMPDIR` to point the input file on a tempfs location, see [docs/env_variables.md](docs/env_variables.md)
+  5. Improve kernel performance: modify `/etc/default/grub`, set `GRUB_CMDLINE_LINUX_DEFAULT="ibpb=off ibrs=off kpti=off l1tf=off mds=off mitigations=off no_stf_barrier noibpb noibrs nopcid nopti nospec_store_bypass_disable nospectre_v1 nospectre_v2 pcid=off pti=off spec_store_bypass_disable=off spectre_v2=off stf_barrier=off"`; then `update-grub` and `reboot` (warning: makes the system more insecure)
+  6. Running on an `ext2` filesystem with `noatime` mount option will be a bit faster than on any other journaling filesystem
+  7. Use your cores! [README.md:3.b) Using multiple cores/threads](../README.md#b-using-multiple-coresthreads)
+
+## What is an "edge"
+
+A program contains `functions`, `functions` contain the compiled machine code.
+The compiled machine code in a `function` can be in a single or many `basic blocks`.
+A `basic block` is the largest possible number of subsequent machine code
+instructions that runs independent, meaning it does not split up to different
+locations nor is it jumped into it from a different location:
+```
+function() {
+  A:
+    some
+    code
+  B:
+    if (x) goto C; else goto D;
+  C:
+    some code
+    goto D
+  D:
+    some code
+    goto B
+  E:
+    return
+}
+```
+Every code block between two jump locations is a `basic block`.
+
+An `edge` is then the unique relationship between two `basic blocks` (from the
+code example above):
+```
+              Block A
+                |
+                v
+              Block B  <------+
+             /        \       |
+            v          v      |
+         Block C    Block D --+
+             \
+              v
+              Block E
+```
+Every line between two blocks is an `edge`.
+
+## Why is my stability below 100
+
+Stability is measured by how many percent of the edges in the target are
+"stable". Sending the same input again and again should take the exact same
+path through the target every time. If that is the case, the stability is 100%.
+
+If however randomness happens, e.g. a thread reading from shared memory,
+reaction to timing, etc. then in some of the re-executions with the same data
+will result in the edge information being different accross runs.
+Those edges that change are then flagged "unstable".
+
+The more "unstable" edges, the more difficult for afl++ to identify valid new
+paths.
+
+A value above 90% is usually fine and a value above 80% is also still ok, and
+even above 20% can still result in successful finds of bugs.
+However, it is recommended that below 90% or 80% you should take measures to
+improve the stability.
+
+## How can I improve the stability value
+
+Four steps are required to do this and requires quite some knowledge of
+coding and/or disassembly and it is only effectively possible with
+afl-clang-fast PCGUARD and afl-clang-lto LTO instrumentation!
+
+  1. First step: Identify which edge ID numbers are unstable
+
+     run the target with `export AFL_DEBUG=1` for a few minutes then terminate.
+     The out/fuzzer_stats file will then show the edge IDs that were identified
+     as unstable.
+
+  2. Second step: Find the responsible function.
+
+     a) For LTO instrumented binaries this can be documented during compile
+        time, just set `export AFL_LLVM_DOCUMENT_IDS=/path/to/afile`.
+        This file will have one assigned edge ID and the corresponding function
+        per line.
+
+     b) For PCGUARD instrumented binaries it is much more difficult. Here you
+        can either modify the __sanitizer_cov_trace_pc_guard function in
+        llvm_mode/afl-llvm-rt.o.c to write a backtrace to a file if the ID in
+        __afl_area_ptr[*guard] is one of the unstable edge IDs.
+        (Example code is already there).
+        Then recompile and reinstall llvm_mode and rebuild your target.
+        Run the recompiled target with afl-fuzz for a while and then check the
+        file that you wrote with the backtrace information.
+        Alternatively you can use `gdb` to hook __sanitizer_cov_trace_pc_guard_init
+        on start, check to which memory address the edge ID value is written
+        and set a write breakpoint to that address (`watch 0x.....`).
+
+  3. Third step: create a text file with the filenames
+
+     Identify which source code files contain the functions that you need to
+     remove from instrumentation.
+
+     Simply follow this document on how to do this: [llvm_mode/README.instrument_file.md](llvm_mode/README.instrument_file.md)
+     If PCGUARD is used, then you need to follow this guide (needs llvm 12+!):
+     [http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation](http://clang.llvm.org/docs/SanitizerCoverage.html#partially-disabling-instrumentation)
+
+  4. Fourth step: recompile the target
+
+     Recompile, fuzz it, be happy :)
diff --git a/docs/binaryonly_fuzzing.md b/docs/binaryonly_fuzzing.md
index 7c9be418..a3d3330f 100644
--- a/docs/binaryonly_fuzzing.md
+++ b/docs/binaryonly_fuzzing.md
@@ -8,12 +8,17 @@
 
   The following is a description of how these binaries can be fuzzed with afl++
 
+
 ## TL;DR:
 
   qemu_mode in persistent mode is the fastest - if the stability is
   high enough. Otherwise try retrowrite, afl-dyninst and if these
   fail too then standard qemu_mode with AFL_ENTRYPOINT to where you need it.
 
+  If your target is a library use examples/afl_frida/.
+
+  If your target is non-linux then use unicorn_mode/.
+
 
 ## QEMU
 
@@ -57,6 +62,20 @@
   As it is included in afl++ this needs no URL.
 
 
+## AFL FRIDA
+
+   If you want to fuzz a binary-only shared library then you can fuzz it with
+   frida-gum via examples/afl_frida/, you will have to write a harness to
+   call the target function in the library, use afl-frida.c as a template.
+
+
+## AFL UNTRACER
+
+   If you want to fuzz a binary-only shared library then you can fuzz it with
+   examples/afl_untracer/, use afl-untracer.c as a template.
+   It is slower than AFL FRIDA (see above).
+
+
 ## DYNINST
 
   Dyninst is a binary instrumentation framework similar to Pintool and
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 464acbee..a22c809b 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -36,7 +36,7 @@ size_t afl_custom_fuzz(void *data, uint8_t *buf, size_t buf_size, u8 **out_buf,
 size_t afl_custom_post_process(void *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf);
 int32_t afl_custom_init_trim(void *data, uint8_t *buf, size_t buf_size);
 size_t afl_custom_trim(void *data, uint8_t **out_buf);
-int32_t afl_custom_post_trim(void *data, int success) {
+int32_t afl_custom_post_trim(void *data, int success);
 size_t afl_custom_havoc_mutation(void *data, u8 *buf, size_t buf_size, u8 **out_buf, size_t max_size);
 uint8_t afl_custom_havoc_mutation_probability(void *data);
 uint8_t afl_custom_queue_get(void *data, const uint8_t *filename);
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 87344331..811c5658 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -121,18 +121,16 @@ Then there are a few specific features that are only available in llvm_mode:
     built if LLVM 11 or newer is used.
 
    - AFL_LLVM_INSTRUMENT=CFG will use Control Flow Graph instrumentation.
-     (recommended)
-
-   - AFL_LLVM_LTO_AUTODICTIONARY will generate a dictionary in the target
-     binary based on string compare and memory compare functions.
-     afl-fuzz will automatically get these transmitted when starting to
-     fuzz.
+     (not recommended!)
 
     None of the following options are necessary to be used and are rather for
     manual use (which only ever the author of this LTO implementation will use).
     These are used if several seperated instrumentation are performed which
     are then later combined.
 
+   - AFL_LLVM_DOCUMENT_IDS=file will document to a file which edge ID was given
+     to which function. This helps to identify functions with variable bytes
+     or which functions were touched by an input.
    - AFL_LLVM_MAP_ADDR sets the fixed map address to a different address than
      the default 0x10000. A value of 0 or empty sets the map address to be
      dynamic (the original afl way, which is slower)
@@ -254,15 +252,6 @@ checks or alter some of the more exotic semantics of the tool:
     useful if you can't change the defaults (e.g., no root access to the
     system) and are OK with some performance loss.
 
-  - Setting AFL_NO_FORKSRV disables the forkserver optimization, reverting to
-    fork + execve() call for every tested input. This is useful mostly when
-    working with unruly libraries that create threads or do other crazy
-    things when initializing (before the instrumentation has a chance to run).
-
-    Note that this setting inhibits some of the user-friendly diagnostics
-    normally done when starting up the forkserver and causes a pretty
-    significant performance drop.
-
   - AFL_EXIT_WHEN_DONE causes afl-fuzz to terminate when all existing paths
     have been fuzzed and there were no new finds for a while. This would be
     normally indicated by the cycle counter in the UI turning green. May be
@@ -273,6 +262,9 @@ checks or alter some of the more exotic semantics of the tool:
     the target. This must be equal or larger than the size the target was
     compiled with.
 
+  - Setting AFL_DISABLE_TRIM tells afl-fuzz to no trim test cases. This is
+    usually a bad idea!
+
   - Setting AFL_NO_AFFINITY disables attempts to bind to a specific CPU core
     on Linux systems. This slows things down, but lets you run more instances
     of afl-fuzz than would be prudent (if you really want to).
@@ -338,6 +330,13 @@ checks or alter some of the more exotic semantics of the tool:
 
   - In QEMU mode (-Q), AFL_PATH will be searched for afl-qemu-trace.
 
+  - Setting AFL_CYCLE_SCHEDULES will switch to a different schedule everytime
+    a cycle is finished.
+
+  - Setting AFL_EXPAND_HAVOC_NOW will start in the extended havoc mode that
+    includes costly mutations. afl-fuzz automatically enables this mode when
+    deemed useful otherwise.
+
   - Setting AFL_PRELOAD causes AFL to set LD_PRELOAD for the target binary
     without disrupting the afl-fuzz process itself. This is useful, among other
     things, for bootstrapping libdislocator.so.
@@ -365,6 +364,15 @@ checks or alter some of the more exotic semantics of the tool:
     for an existing out folder, even if a different `-i` was provided.
     Without this setting, afl-fuzz will refuse execution for a long-fuzzed out dir.
 
+  - Setting AFL_NO_FORKSRV disables the forkserver optimization, reverting to
+    fork + execve() call for every tested input. This is useful mostly when
+    working with unruly libraries that create threads or do other crazy
+    things when initializing (before the instrumentation has a chance to run).
+
+    Note that this setting inhibits some of the user-friendly diagnostics
+    normally done when starting up the forkserver and causes a pretty
+    significant performance drop.
+
   - Outdated environment variables that are that not supported anymore:
     AFL_DEFER_FORKSRV
     AFL_PERSISTENT
diff --git a/docs/parallel_fuzzing.md b/docs/parallel_fuzzing.md
index 271f8369..2ab1466c 100644
--- a/docs/parallel_fuzzing.md
+++ b/docs/parallel_fuzzing.md
@@ -99,7 +99,15 @@ example may be:
 This is not a concern if you use @@ without -f and let afl-fuzz come up with the
 file name.
 
-## 3) Multi-system parallelization
+## 3) Syncing with non-afl fuzzers or independant instances
+
+A -M main node can be told with the `-F other_fuzzer_queue_directory` option
+to sync results from other fuzzers, e.g. libfuzzer or honggfuzz.
+
+Only the specified directory will by synced into afl, not subdirectories.
+The specified directories do not need to exist yet at the start of afl.
+
+## 4) Multi-system parallelization
 
 The basic operating principle for multi-system parallelization is similar to
 the mechanism explained in section 2. The key difference is that you need to
@@ -176,7 +184,7 @@ It is *not* advisable to skip the synchronization script and run the fuzzers
 directly on a network filesystem; unexpected latency and unkillable processes
 in I/O wait state can mess things up.
 
-## 4) Remote monitoring and data collection
+## 5) Remote monitoring and data collection
 
 You can use screen, nohup, tmux, or something equivalent to run remote
 instances of afl-fuzz. If you redirect the program's output to a file, it will
@@ -200,7 +208,7 @@ Keep in mind that crashing inputs are *not* automatically propagated to the
 main instance, so you may still want to monitor for crashes fleet-wide
 from within your synchronization or health checking scripts (see afl-whatsup).
 
-## 5) Asymmetric setups
+## 6) Asymmetric setups
 
 It is perhaps worth noting that all of the following is permitted:
 
diff --git a/docs/screenshot.png b/docs/screenshot.png
new file mode 100644
index 00000000..7b4dd7e4
--- /dev/null
+++ b/docs/screenshot.png
Binary files differ