Once Agentic-AFL detects a math wall bypass — the harness prints the accept marker and a queue entry is confirmed — it can automatically restart AFL++ with a custom Python mutator that has been tailored to the now-unlocked code region. This is called Level 3 deployment. The idea is that standard AFL++ mutation strategies (bit flips, byte substitutions, havoc) are efficient for exploring shallow code, but after a protocol validation wall is bypassed, the post-validation state machine benefits from domain-aware mutation that understands the protocol’s structure — field boundaries, enum values, length fields, and checksum positions.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/AdithyaaSivamal/Agentic-AFL/llms.txt
Use this file to discover all available pages before exploring further.
How Custom Mutator Deployment Works
Level 3 deployment is triggered automatically byCampaignRunner the moment bypass_detected transitions to True:
Bypass confirmed
CampaignRunner re-runs queue entries against the harness. When a queue entry’s combined stdout and stderr contains the accept marker, bypass_detected is set to True and bypass_evidence is set to the queue entry filename.AFL++ terminated gracefully
The running AFL++ process is sent
SIGTERM and given 5 seconds to exit. If it does not exit within that window, it is sent SIGKILL. The AFL++ output directory and sync directory are preserved — the queue and corpus remain intact.AFL++ restarted with the custom mutator
AFL++ is relaunched with
- as the input directory (resume mode, reading from the existing output directory). AFL_PYTHON_MODULE is set to the mutator file’s stem (e.g., dnp3_mutator for ./mutators/dnp3_mutator.py) and PYTHONPATH is set to the mutator’s parent directory (e.g., ./mutators). All other AFL++ environment variables are preserved from the original launch.Specifying a Custom Mutator
Pass the path to your mutator Python file with--custom-mutator:
CampaignRunner will log a warning and skip Level 3 deployment when a bypass occurs. Verify the path before starting a long campaign.
Writing a Custom Mutator
AFL++ custom mutators in Python must export aninit function and a fuzz function. The describe function is optional but recommended — AFL++ uses it to label the mutator in its status output:
dnp3_mutator.py
fuzz with three arguments:
| Argument | Type | Description |
|---|---|---|
buf | bytes | The current test case bytes to mutate. |
add_buf | bytes | An additional splicing input from the corpus (may be empty). |
max_size | int | Maximum allowed output size in bytes. |
bytes. If it returns None or raises an exception, AFL++ discards the mutation for that cycle.
Custom Mutator Environment
Agentic-AFL sets up the Python environment automatically at Level 3 deployment. You do not need to install anything or set environment variables manually:AFL_PYTHON_MODULEis set to the file stem of your mutator (e.g.,dnp3_mutatorfor./mutators/dnp3_mutator.py).PYTHONPATHis set to the directory containing the mutator file (e.g.,./mutators).- All other AFL++ environment variables (
AFL_NO_UI,AFL_SKIP_CPUFREQ, etc.) are preserved from the original AFL++ launch.
PYTHONPATH. A virtualenv in the mutator’s directory works:
PYTHONPATH=./mutators/.venv/lib/python3.x/site-packages:./mutators before starting the campaign, or include the activation in the mutator itself via sys.path.
The custom mutator is only deployed after
bypass_detected becomes True — that is, after the accept marker is observed in an AFL++ queue entry. If no bypass occurs during the campaign, the mutator file is never used and AFL++ runs with its built-in mutation strategies for the entire duration.