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.
The afl-cmin script minimizes a test corpus by removing redundant test cases that don’t add new coverage. This speeds up fuzzing by reducing the queue size.
Synopsis
afl-cmin -i input_dir -o output_dir [options] -- /path/to/target [target_args]
Description
afl-cmin analyzes a set of test cases and removes those that don’t contribute unique coverage. It uses afl-showmap internally to measure edge coverage for each input.
The result is a smaller corpus that covers the same code paths, which:
- Reduces fuzzing overhead
- Speeds up initial calibration
- Makes corpus management easier
Required Parameters
Input directory containing test cases to minimize.afl-cmin -i corpus/ -o minimized/ -- ./target @@
Output directory for minimized corpus.afl-cmin -i fuzzer_queue/ -o seeds/ -- ./target @@
Execution Control
Timeout for each run in milliseconds (default: 1000ms).afl-cmin -i corpus/ -o min/ -t 5000 -- ./slow_target @@
Memory limit for child process in megabytes.afl-cmin -i corpus/ -o min/ -m 512 -- ./target @@
Use QEMU mode for binary-only targets.afl-cmin -i corpus/ -o min/ -Q -- ./binary_target @@
Use FRIDA mode for binary-only instrumentation.
Additional Options
Solve for edge coverage only (ignore hit counts).afl-cmin -i corpus/ -o min/ -e -- ./target @@
Input file read by the tested program.afl-cmin -i corpus/ -o min/ -f /tmp/input -- ./target /tmp/input
Examples
Basic Corpus Minimization
# Before minimization
ls -1 corpus/ | wc -l
1523
# Minimize
afl-cmin -i corpus/ -o corpus_min/ -- ./target @@
# After minimization
ls -1 corpus_min/ | wc -l
247
# Same coverage with 84% fewer files!
Output Example
corpus minimization tool for afl-fuzz
[*] Testing the target binary...
[+] OK, 1523 test cases found.
[*] Obtaining traces for input files in 'corpus/'.
[*] Processing file 0001/1523...
[*] Processing file 0100/1523...
...
[*] Sorting trace sets (this may take a while)...
[+] Found 247 unique tuples across 1523 files.
[*] Copying files to output directory...
[+] Narrowed down to 247 files, saved in 'corpus_min/'.
Minimize Fuzzer Queue
# After fuzzing, minimize the queue
afl-cmin -i out/queue/ -o seeds_minimized/ -- ./target @@
# Use minimized set for next fuzzing campaign
afl-fuzz -i seeds_minimized/ -o out2/ -- ./target @@
Combine Multiple Fuzzer Queues
# Merge queues from parallel fuzzers
mkdir combined/
cp fuzzer1/queue/* combined/
cp fuzzer2/queue/* combined/
cp fuzzer3/queue/* combined/
# Minimize combined corpus
afl-cmin -i combined/ -o merged_minimal/ -- ./target @@
Binary-Only Target
# Minimize corpus for uninstrumented binary
afl-cmin -Q -i corpus/ -o corpus_min/ -- ./closed_source @@
With Timeout
# Set higher timeout for slow inputs
afl-cmin -i corpus/ -o corpus_min/ -t 10000 -- ./slow_target @@
How It Works
- Extract coverage - Run each input through afl-showmap to get edge coverage
- Build coverage map - Track which inputs cover which edges
- Select minimal set - Choose smallest set of inputs that cover all edges
- Copy results - Copy selected inputs to output directory
The algorithm is greedy:
- Inputs covering more unique edges are preferred
- Smaller files are preferred when coverage is equal
- Process continues until all edges are covered
Use Cases
Seed Corpus Preparation
# Download large corpus from internet
wget https://example.com/corpus.tar.gz
tar xzf corpus.tar.gz
# Minimize before fuzzing
afl-cmin -i corpus/ -o seeds/ -- ./target @@
# Start fuzzing with minimal set
afl-fuzz -i seeds/ -o out/ -- ./target @@
Periodic Maintenance
# Every week, minimize the growing queue
afl-cmin -i out/queue/ -o queue_minimized/ -- ./target @@
# Replace queue with minimized version
rm -rf out/queue
mv queue_minimized out/queue
# Continue fuzzing
afl-fuzz -i - -o out/ -- ./target @@
Corpus Sharing
# Minimize before sharing corpus publicly
afl-cmin -i private_corpus/ -o public_corpus/ -- ./target @@
tar czf corpus.tar.gz public_corpus/
# Smaller, cleaner corpus for others to use
Cross-Project Corpus
# Combine corpora from similar targets
cat project1/corpus/* project2/corpus/* > combined/
# Minimize combined set
afl-cmin -i combined/ -o universal_corpus/ -- ./target @@
Parallel Processing
For very large corpora, use multiple cores:
# afl-cmin automatically uses multiple cores if available
# Ensure cores are not bound (unset AFL_NO_AFFINITY if set)
afl-cmin -i huge_corpus/ -o minimized/ -- ./target @@
Memory Optimization
For memory-intensive targets:
# Set memory limit
afl-cmin -i corpus/ -o min/ -m 1024 -- ./target @@
Skip Timeouts
Crashing and timing out inputs are handled:
# afl-cmin will skip inputs that crash or timeout
# Check for .AFL_CMIN_ERRORS file in output directory
Differences from afl-tmin
| Tool | Purpose | Input | Output |
|---|
| afl-cmin | Minimize corpus | Directory of files | Smaller directory |
| afl-tmin | Minimize single file | One file | Shorter file |
# afl-cmin: reduce number of files
afl-cmin -i 1000_files/ -o 50_files/ -- ./target @@
# afl-tmin: reduce size of one file
afl-tmin -i 10KB_file -o 47B_file -- ./target @@
Environment Variables
Allow running in /tmp directory (security risk on multi-user systems).AFL_ALLOW_TMP=1 afl-cmin -i /tmp/corpus -o /tmp/min -- ./target @@
Keep trace files and metadata after minimization (in <out_dir>/.traces/).AFL_KEEP_TRACES=1 afl-cmin -i corpus/ -o min/ -- ./target @@
ls min/.traces/
Location of afl-showmap binary.AFL_PATH=/custom/afl afl-cmin -i corpus/ -o min/ -- ./target @@
Print each filename as it’s processed.AFL_PRINT_FILENAMES=1 afl-cmin -i corpus/ -o min/ -- ./target @@
Troubleshooting
All Files Kept
# If minimization doesn't reduce corpus:
# 1. Check that target is instrumented
./target < /dev/null # Should show AFL++ banner
# 2. Verify files produce different coverage
afl-showmap -o trace1.txt -- ./target file1
afl-showmap -o trace2.txt -- ./target file2
diff trace1.txt trace2.txt # Should show differences
Crashes During Minimization
# Check .AFL_CMIN_ERRORS file
cat output_dir/.AFL_CMIN_ERRORS
# May contain files that crashed or timed out
# Increase timeout for slow targets
afl-cmin -t 10000 -i corpus/ -o min/ -- ./slow_target @@
# Or skip edge hit counts
afl-cmin -e -i corpus/ -o min/ -- ./target @@
Best Practices
- Minimize regularly - Run after major fuzzing campaigns
- Keep originals - Always preserve original corpus
- Verify coverage - Check that minimized corpus has similar coverage
- Combine with tmin - Optionally minimize individual files after cmin
# Complete minimization workflow
# 1. Minimize corpus
afl-cmin -i queue/ -o queue_min/ -- ./target @@
# 2. Optionally minimize each file
for f in queue_min/*; do
afl-tmin -i "$f" -o "${f}.tmin" -- ./target @@
mv "${f}.tmin" "$f"
done
# 3. Verify coverage is preserved
afl-showmap -C -i queue/ -o cov_before.txt -- ./target @@
afl-showmap -C -i queue_min/ -o cov_after.txt -- ./target @@
diff cov_before.txt cov_after.txt
See Also