Skip to main content

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.

This guide walks you through launching a complete multi-core AFLPlusPlus campaign using AFL Runner from scratch. By the end you will have generated a full set of afl-fuzz invocations, started them in a tmux session, and attached the built-in TUI to monitor progress in real time — all using a single tool.
1

Prepare your prerequisites

Before invoking aflr, you need two things in place:
  1. An AFL++-instrumented target binary. Compile your target at least once with afl-clang-fast (or afl-clang-lto, afl-gcc-fast, etc.). For best results in multiple-cores mode, compile additional variants with Address Sanitizer (-fsanitize=address), CMPLOG (AFL_LLVM_CMPLOG=1), and CMPCOV (AFL_LLVM_LAF_ALL=1).
  2. A seed corpus directory. Create a directory containing at least one non-empty, representative input file for your target. Even a single valid sample is enough to get started.
# Example: compile a plain AFL++ instrumented binary
CC=afl-clang-fast ./configure --prefix=/tmp/target_build
make -j$(nproc)

# Prepare a minimal corpus
mkdir -p ./corpus
echo "hello" > ./corpus/seed1
If no -i / --input-dir flag is provided, AFL Runner defaults to /tmp/afl_input as the corpus directory, and /tmp/afl_output as the output directory.
2

Generate the fuzzing commands with aflr gen

Use aflr gen to produce and inspect the full set of afl-fuzz invocations before executing anything. This is the safest first step — it lets you verify runner count, mode, and binary assignments without touching your system.
aflr gen -t ./target_afl -i ./corpus -o /tmp/afl_out -n 8
FlagMeaning
-t / --targetPath to the AFL++-instrumented target binary
-i / --input-dirSeed corpus directory
-o / --output-dirAFL++ output directory (crashes, queue, stats)
-n / --runnersNumber of parallel afl-fuzz processes to launch
The default mode is multiple-cores, which automatically assigns one process as the main fuzzer (-M) and distributes the remaining n-1 processes as secondaries (-S) with varied power schedules. To explicitly set the mode:
aflr gen -t ./target_afl -i ./corpus -o /tmp/afl_out -n 8 --mode multiple-cores
If you have additional instrumented binaries, supply them directly:
aflr gen \
  -t ./target_afl \
  -s ./target_asan \
  -c ./target_cmplog \
  -l ./target_cmpcov \
  -i ./corpus \
  -o /tmp/afl_out \
  -n 8
AFL Runner routes each binary type to the appropriate runner slot automatically.
3

Run the campaign with aflr run

When you are satisfied with the generated commands, use aflr run to execute them. It accepts the same flags as aflr gen and additionally manages the tmux (or screen) session. Add --tui to launch the monitoring interface immediately alongside the fuzzers.
aflr run -t ./target_afl -i ./corpus -o /tmp/afl_out -n 8 --tui
AFL Runner creates a tmux session (named automatically, or set with --session-name), opens a window for each fuzzer, and starts every afl-fuzz process. With --tui the terminal transitions directly into the status dashboard.To preview the commands that would be run without actually executing them, use --dry-run:
aflr run -t ./target_afl -i ./corpus -o /tmp/afl_out -n 8 --dry-run
To start the campaign in the background with no attached terminal, use --detached:
aflr run -t ./target_afl -i ./corpus -o /tmp/afl_out -n 8 --detached
4

Monitor with the TUI

If you launched without --tui, or if you want to reconnect to the dashboard at any point, run:
aflr tui /tmp/afl_out
Pass the AFL++ output directory as the sole argument. The TUI reads the fuzzer_stats files written by each running instance and displays aggregate and per-fuzzer metrics — total execs, paths found, crashes, hangs, and exec speed — refreshed in real time. It is a full replacement for afl-whatsup.
The TUI works against any AFL++ output directory, whether the fuzzers were started by AFL Runner or invoked manually. It does not need to be connected to an active tmux session.
5

Stop the campaign

When you are ready to stop fuzzing, kill the entire session — and every afl-fuzz process inside it — with:
aflr kill <session-name>
If you did not set a custom --session-name, use tab-completion (requires the completion feature) or check your tmux session list to find the auto-generated name:
tmux list-sessions
Then kill it:
aflr kill my_aflr_session

Using a Config File

Repeatedly typing long flag lists is error-prone and makes campaign setups hard to reproduce. AFL Runner supports TOML configuration files that capture all settings for a project.
Copy the provided AFLR_CFG_TEMPL.toml from the repository into your project root, rename it aflr_cfg.toml, and fill in your paths. AFL Runner automatically reads aflr_cfg.toml from the current working directory whenever --config is not explicitly specified — no extra flags needed.
A minimal aflr_cfg.toml for the campaign above looks like this:
[target]
path = "./target_afl"
san_path  = "./target_asan"
cmpl_path = "./target_cmplog"
cmpc_path = "./target_cmpcov"

[afl_cfg]
runners     = 8
seed_dir    = "./corpus"
solution_dir = "/tmp/afl_out"
mode        = "MultipleCores"

[session]
runner = "tmux"
name   = "my_project_fuzz"

[misc]
tui = true
With the config file in place you can launch a full campaign with just:
aflr run
Or load a named config explicitly:
aflr run --config /path/to/project.toml
CLI flags always take precedence over config file values. You can keep a shared project config and override specific settings per invocation — for example, changing the runner count without editing the file: aflr run -n 16.

Build docs developers (and LLMs) love