AFL Runner is built around the concept of a harness — a collection of up to five binary variants of your target that are compiled with different AFL++ instrumentation passes and orchestrated together during a campaign. Rather than running every fuzzer instance against a single binary, AFL Runner assigns the right binary to the right instance automatically: the CMPLOG binary only goes to instances that will use it, the CMPCOV binary only where the coverage gain is worth the overhead, and the sanitizer binary only where crash sensitivity matters. You compile each variant once and point AFL Runner at each path; it handles the rest. All binary variants except the standard AFL++ binary are optional — omitting any of them causes those instances to fall back to the standard binary.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/0xricksanchez/AFL_Runner/llms.txt
Use this file to discover all available pages before exploring further.
SAN, CMPLOG, and CMPCOV binaries are all optional. If you provide only the standard AFL++ binary, AFL Runner launches all instances against that single binary with no degradation in correctness — you simply forgo the additional bug-detection and comparison-solving capabilities those variants provide.
Standard AFL++ binary
CLI flag:-t / --targetConfig key:
target.path
The standard AFL++ binary is the only required binary. It must be compiled with AFL++‘s compiler wrapper so that AFL++‘s coverage feedback instrumentation is embedded. Every fuzzer instance that is not assigned a CMPCOV binary will use this binary as its target.
Compiling
AFL_HARDEN=1 enables compile-time hardening checks (stack canaries, fortify source) that give AFL++ a better chance of catching memory errors that do not rise to the level of a crash without sanitizers, at a small performance cost.
Usage
AddressSanitizer binary
CLI flag:-s / --san-targetConfig key:
target.san_path
The sanitizer binary is compiled with one or more of AFL++‘s sanitizer integration environment variables. AFL Runner assigns this binary to a subset of secondary fuzzer instances, giving those instances much higher sensitivity to memory safety violations that produce no observable crash in the standard binary (use-after-free reads, heap overflows that overwrite non-critical memory, etc.).
Compiling
Usage
CMPLOG binary
CLI flag:-c / --cmpl-targetConfig key:
target.cmpl_path
The CMPLOG binary is compiled with AFL++‘s AFL_LLVM_CMPLOG=1 pass, which instruments every comparison operation in the target to log the two operands being compared. AFL++ uses this data to automatically satisfy magic byte checks, checksums, and multi-byte string comparisons — cases that pure random mutation struggles to solve. AFL Runner assigns the CMPLOG binary to approximately 30% of runner instances, distributing three CMPLOG analysis modes across them for maximum coverage.
CMPLOG modes
| Mode | AFL++ flag | Share of CMPLOG slots | Purpose |
|---|---|---|---|
| Standard | -l 2 | ~70% | Logs integer and string comparisons |
| Extended | -l 3 | ~10% | Logs all Standard comparisons plus additional checks |
| Transforms | -l 2AT | ~20% | Applies arithmetic transforms and automatic dictionary extraction |
| CMPLOG instances | Modes applied |
|---|---|
| 1 | Transforms only (-l 2AT) |
| 2 | Standard + Transforms |
| 3 | Standard + Extended + Transforms |
Compiling
Usage
CMPLOG is incompatible with AFL++ Nyx mode. If
nyx_mode = true is set, AFL Runner will reject a CMPLOG binary at startup with an error.CMPCOV / Laf-intel binary
CLI flag:-l / --cmpc-targetConfig key:
target.cmpc_path
The CMPCOV binary is compiled with AFL_LLVM_LAF_ALL=1, which activates AFL++‘s Laf-intel instrumentation. Laf-intel transforms multi-byte comparison operations into chains of single-byte comparisons, making it far easier for AFL++‘s byte-level mutations to incrementally satisfy complex conditions (for example, matching a 4-byte magic number one byte at a time). AFL Runner replaces the standard binary with the CMPCOV binary for a small fixed number of instances:
| Total runners | CMPCOV instances |
|---|---|
| 0 – 2 | 0 |
| 3 – 7 | 1 |
| 8 – 15 | 2 |
| 16+ | 3 |
-c) assigned, since both target the comparison-solving problem and combining them on the same instance provides no additional benefit.
Compiling
Usage
Coverage binary
CLI flag: used withaflr cov -tConfig key:
target.cov_path
The coverage binary is used exclusively by the aflr cov command to generate LLVM source-level coverage reports from the test cases in the AFL++ output directory. It is never passed to afl-fuzz and plays no role in fuzzing itself. aflr cov walks each fuzzer’s queue directory and replays every test case through the coverage binary to accumulate .profraw data, then invokes llvm-profdata merge and llvm-cov to produce the final report.
Compiling
llvm-profdata and llvm-cov (matching the clang version used to compile) must be on PATH when running aflr cov.
Usage
Coverage instrumentation is incompatible with AFL++ Nyx mode. If
nyx_mode = true is set, AFL Runner will reject a coverage binary at startup.Complete compile example
The following builds all five binary variants of a hypotheticaltarget.c in a single workflow.
aflr run invocation:
Nyx mode
AFL++ Nyx mode (--nyx-mode / nyx_mode = true) is a snapshot-based fuzzing mode that uses KVM virtualization for extremely high throughput on targets that are difficult to reset between runs. When Nyx mode is enabled, the --target path must point to a Nyx share directory (a directory containing the Nyx configuration and snapshot artifacts) rather than an executable binary. AFL Runner validates that the path is a directory and rejects non-directory paths at startup.