Custom mutators allow you to implement domain-specific mutations beyond AFL++‘s built-in strategies. This enables structure-aware fuzzing for complex formats like XML, protobuf, or grammar-based inputs.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AFLplusplus/AFLplusplus/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Custom mutators are passed toafl-fuzz via environment variables and must export specific functions. AFL++ supports:
- C/C++ libraries (
.sofiles) - Python modules
- Rust (experimental support in
custom_mutators/rust)
Multiple Mutators
You can chain multiple custom mutators together:API Reference
C/C++ API
Python API
Function Details
init (optional in Python)
Seeds RNG and sets up buffers and state when AFL++ starts.queue_get (optional)
Determines whether AFL++ should fuzz the current queue entry with all mutators.fuzz_count (optional)
Overrides AFL++‘s calculation of fuzzing attempts for a queue entry. Most useful when not usingAFL_CUSTOM_MUTATOR_ONLY.
splice_optout (optional)
If this function exists (never called, just needs to be present), no splicing target is passed tofuzz(). Saves time if splicing data isn’t needed.
fuzz (optional)
Performs your custom mutations. Theadd_buf can be used for splicing or ignored (define splice_optout if ignoring). Returning length 0 skips this mutation result.
For non-Python: the returned output buffer is under your memory management!
describe (optional)
Describes the current test case generated by the last mutation. Called to name crash files, helping reproduce crashing mutations.havoc_mutation & havoc_mutation_probability (optional)
havoc_mutation performs a single custom mutation stacked with others in havoc. havoc_mutation_probability returns the probability (default 6%) that it’s called.
post_process (optional)
Transforms mutated data into the format expected by the target. For example, converting protobuf format to plain text.fuzz_send (optional)
Send data to the target yourself (e.g., via IPC). Replaces some usage ofutils/afl_proxy but requires starting the target with afl-fuzz.
Set AFL_CUSTOM_MUTATOR_LATE_SEND to call afl_custom_fuzz_send() after the target restarts (needed for TCP services).
Example: custom_mutators/examples/custom_send.c
queue_new_entry (optional)
Called after adding a new test case to the queue. Return True if file contents were changed.introspection (optional)
Called after discovering a new queue entry, crash, or timeout (if compiled with INTROSPECTION). Return a string reporting exact mutations used.deinit (optional in Python)
Last method called, for cleanup.Trimming Support
Generic AFL++ trimming can destroy complex format structures. Implement custom trimming to avoid broken test cases.init_trim
Receives initial buffer, returns number of iteration steps possible.
- Remove elements one-by-one: return
n - Binary search: return
log(n) - Unknown steps: return
1, then return0inpost_trimuntil done
trim
Called for each trimming operation. No arguments (state from
init_trim is in data variables). Returns trimmed input buffer.Environment Variables
Disable all other mutation stages. Use only the custom mutator. Best combined with custom trimming to prevent broken test cases.
Path to C/C++ shared library (
.so). Supports multiple mutators separated by semicolons.Python module name (not path). Set
PYTHONPATH to the directory containing the module.With
AFL_NO_UI, emits additional messages about custom trimmer performance and actions.Helper Environment Variables
For mutators in Python, Rust, GO, etc., AFL++ sets these variables:The target program name. Contains the actual target even in QEMU mode (
-Q).The input file path if
-f parameter is used with afl-fuzz.Parameters given to the target program, still contains
@@ identifier.Output directory for this fuzzer instance. E.g., if called with
-o out -S foobar, this is out/foobar.If
AFL_CUSTOM_INFO_PROGRAM_INPUT is empty and AFL_CUSTOM_INFO_PROGRAM_ARGV doesn’t contain @@, the target gets input via stdin.Compilation & Usage
C/C++ Custom Mutator
Python Custom Mutator
Compile AFL++ with Python support
The Makefile auto-detects Python3 via
python-config/python3-config.For non-standard setups:Examples
C Example
Complete C/C++ custom mutator example
Python Example
Complete Python custom mutator example
Custom Send
Example using fuzz_send for IPC
Rust Support
Experimental Rust custom mutators

