
Libafl
- 3.9k installs
- 6.4k repo stars
- Updated August 4, 2026
- trailofbits/skills
libafl is an agent skill for build custom libafl fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation.
About
The libafl skill Build custom libAFL fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation. LibAFL is a modular fuzzing library that implements features from AFL-based fuzzers like AFL++. Unlike traditional fuzzers, LibAFL provides all functionality in a modular and customizable way as a Rust library. It can be used as a drop-in replacement for libFuzzer or as a library to build custom fuzzers from scratch. Fuzzer Best For Complexity -------- ---------- ------------ libFuzzer Quick setup, single-threaded Low AFL++ Multi-core, general purpose Medium LibAFL Custom fuzzers, advanced features, research High Choose LibAFL when: - You need custom mutation strategies or feedback mechanisms - Standard fuzzers don't support your target architecture - You want to implement novel fuzzing techniques - You need fine-grained control over fuzzing components - You're conducting fuzzing research LibAFL can be used as a drop-in replacement for li
- You need custom mutation strategies or feedback mechanisms
- Standard fuzzers don't support your target architecture
- You want to implement novel fuzzing techniques
- You need fine-grained control over fuzzing components
- You're conducting fuzzing research
Libafl by the numbers
- 3,875 all-time installs (skills.sh)
- +112 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #166 of 2,203 Security skills by installs in the Skillselion catalog
- Security screen: HIGH risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
libafl capabilities & compatibility
- Capabilities
- you need custom mutation strategies or feedback · standard fuzzers don't support your target archi · you want to implement novel fuzzing techniques · you need fine grained control over fuzzing compo · you're conducting fuzzing research
- Use cases
- security audit · testing
What libafl says it does
LibAFL can be used as a drop-in replacement for libFuzzer with minimal setup:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Call your code with fuzzer-provided data
npx skills add https://github.com/trailofbits/skills --skill libaflAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3.9k |
|---|---|
| repo stars | ★ 6.4k |
| Security audit | 1 / 3 scanners passed |
| Last updated | August 4, 2026 |
| Repository | trailofbits/skills ↗ |
How do I build custom libafl fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation with documented agent guidance?
Build custom libAFL fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation.
Who is it for?
Developers who need security help during ship work.
Skip if: Skip when the task falls outside Security scope described in SKILL.md.
When should I use this skill?
Build custom libAFL fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation.
What you get
Completed security workflow aligned with SKILL.md steps and validation.
- LibAFL fuzz harness
- Crash reproducers and campaign configs
By the numbers
- You need custom mutation strategies or feedback mechanisms
- Standard fuzzers don't support your target architecture
- You want to implement novel fuzzing techniques
Files
LibAFL
LibAFL is a modular fuzzing library that implements features from AFL-based fuzzers like AFL++. Unlike traditional fuzzers, LibAFL provides all functionality in a modular and customizable way as a Rust library. It can be used as a drop-in replacement for libFuzzer or as a library to build custom fuzzers from scratch.
When to Use
| Fuzzer | Best For | Complexity |
|---|---|---|
| libFuzzer | Quick setup, single-threaded | Low |
| AFL++ | Multi-core, general purpose | Medium |
| LibAFL | Custom fuzzers, advanced features, research | High |
Choose LibAFL when:
- You need custom mutation strategies or feedback mechanisms
- Standard fuzzers don't support your target architecture
- You want to implement novel fuzzing techniques
- You need fine-grained control over fuzzing components
- You're conducting fuzzing research
Quick Start
LibAFL can be used as a drop-in replacement for libFuzzer with minimal setup:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Call your code with fuzzer-provided data
my_function(data, size);
return 0;
}Build LibAFL's libFuzzer compatibility layer:
git clone https://github.com/AFLplusplus/LibAFL
cd LibAFL/libafl_libfuzzer_runtime
./build.shCompile and run:
clang++ -DNO_MAIN -g -O2 -fsanitize=fuzzer-no-link libFuzzer.a harness.cc main.cc -o fuzz
./fuzz corpus/Installation
Prerequisites
- Clang/LLVM 15-18
- Rust (via rustup)
- Additional system dependencies
Linux/macOS
Install Clang:
apt install clangOr install a specific version via apt.llvm.org:
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 15Configure environment for Rust:
export RUSTFLAGS="-C linker=/usr/bin/clang-15"
export CC="clang-15"
export CXX="clang++-15"Install Rust:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInstall additional dependencies:
apt install libssl-dev pkg-configFor libFuzzer compatibility mode, install nightly Rust:
rustup toolchain install nightly --component llvm-toolsVerification
Build LibAFL to verify installation:
cd LibAFL/libafl_libfuzzer_runtime
./build.sh
# Should produce libFuzzer.aWriting a Harness
LibAFL harnesses follow the same pattern as libFuzzer when using drop-in replacement mode:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Your fuzzing target code here
return 0;
}When building custom fuzzers with LibAFL as a Rust library, harness logic is integrated directly into the fuzzer. See the "Writing a Custom Fuzzer" section below for the full pattern.
See Also: For detailed harness writing techniques, see the harness-writing technique skill.
Usage Modes
LibAFL supports two primary usage modes:
1. libFuzzer Drop-in Replacement
Use LibAFL as a replacement for libFuzzer with existing harnesses.
Compilation:
clang++ -DNO_MAIN -g -O2 -fsanitize=fuzzer-no-link libFuzzer.a harness.cc main.cc -o fuzzRunning:
./fuzz corpus/Recommended for long campaigns:
./fuzz -fork=1 -ignore_crashes=1 corpus/2. Custom Fuzzer as Rust Library
Build a fully customized fuzzer using LibAFL components.
Create project:
cargo init --lib my_fuzzer
cd my_fuzzer
cargo add libafl@0.13 libafl_targets@0.13 libafl_bolts@0.13 libafl_cc@0.13 \
--features "libafl_targets@0.13/libfuzzer,libafl_targets@0.13/sancov_pcguard_hitcounts"Configure Cargo.toml:
[lib]
crate-type = ["staticlib"]Writing a Custom Fuzzer
See Also: For detailed harness writing techniques, patterns for handling complex inputs,
and advanced strategies, see the fuzz-harness-writing technique skill.
Fuzzer Components
A LibAFL fuzzer consists of modular components:
1. Observers - Collect execution feedback (coverage, timing) 2. Feedback - Determine if inputs are interesting 3. Objective - Define fuzzing goals (crashes, timeouts) 4. State - Maintain corpus and metadata 5. Mutators - Generate new inputs 6. Scheduler - Select which inputs to mutate 7. Executor - Run the target with inputs
Basic Fuzzer Structure
use libafl::prelude::*;
use libafl_bolts::prelude::*;
use libafl_targets::{libfuzzer_test_one_input, std_edges_map_observer};
#[no_mangle]
pub extern "C" fn libafl_main() {
let mut run_client = |state: Option<_>, mut restarting_mgr, _core_id| {
// 1. Setup observers
let edges_observer = HitcountsMapObserver::new(
unsafe { std_edges_map_observer("edges") }
).track_indices();
let time_observer = TimeObserver::new("time");
// 2. Define feedback
let mut feedback = feedback_or!(
MaxMapFeedback::new(&edges_observer),
TimeFeedback::new(&time_observer)
);
// 3. Define objective
let mut objective = feedback_or_fast!(
CrashFeedback::new(),
TimeoutFeedback::new()
);
// 4. Create or restore state
let mut state = state.unwrap_or_else(|| {
StdState::new(
StdRand::new(),
InMemoryCorpus::new(),
OnDiskCorpus::new(&output_dir).unwrap(),
&mut feedback,
&mut objective,
).unwrap()
});
// 5. Setup mutator
let mutator = StdScheduledMutator::new(havoc_mutations());
let mut stages = tuple_list!(StdMutationalStage::new(mutator));
// 6. Setup scheduler
let scheduler = IndexesLenTimeMinimizerScheduler::new(
&edges_observer,
QueueScheduler::new()
);
// 7. Create fuzzer
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// 8. Define harness
let mut harness = |input: &BytesInput| {
let buf = input.target_bytes().as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};
// 9. Setup executor
let mut executor = InProcessExecutor::with_timeout(
&mut harness,
tuple_list!(edges_observer, time_observer),
&mut fuzzer,
&mut state,
&mut restarting_mgr,
timeout,
)?;
// 10. Load initial inputs
if state.must_load_initial_inputs() {
state.load_initial_inputs(
&mut fuzzer,
&mut executor,
&mut restarting_mgr,
&input_dir
)?;
}
// 11. Start fuzzing
fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut restarting_mgr)?;
Ok(())
};
// Launch fuzzer
Launcher::builder()
.run_client(&mut run_client)
.cores(&cores)
.build()
.launch()
.unwrap();
}Compilation
Verbose Mode
Manually specify all instrumentation flags:
clang++-15 -DNO_MAIN -g -O2 \
-fsanitize-coverage=trace-pc-guard \
-fsanitize=address \
-Wl,--whole-archive target/release/libmy_fuzzer.a -Wl,--no-whole-archive \
main.cc harness.cc -o fuzzCompiler Wrapper (Recommended)
Create a LibAFL compiler wrapper to handle instrumentation automatically.
Create `src/bin/libafl_cc.rs`:
use libafl_cc::{ClangWrapper, CompilerWrapper, Configuration, ToolWrapper};
pub fn main() {
let args: Vec<String> = env::args().collect();
let mut cc = ClangWrapper::new();
cc.cpp(is_cpp)
.parse_args(&args)
.link_staticlib(&dir, "my_fuzzer")
.add_args(&Configuration::GenerateCoverageMap.to_flags().unwrap())
.add_args(&Configuration::AddressSanitizer.to_flags().unwrap())
.run()
.unwrap();
}Compile and use:
cargo build --release
target/release/libafl_cxx -DNO_MAIN -g -O2 main.cc harness.cc -o fuzzSee Also: For detailed sanitizer configuration, common issues, and advanced flags,
see the address-sanitizer and undefined-behavior-sanitizer technique skills.
Running Campaigns
Basic Run
./fuzz --cores 0 --input corpus/Multi-Core Fuzzing
./fuzz --cores 0,8-15 --input corpus/This runs 9 clients: one on core 0, and 8 on cores 8-15.
With Options
./fuzz --cores 0-7 --input corpus/ --output crashes/ --timeout 1000Text User Interface (TUI)
Enable graphical statistics view:
./fuzz -tui=1 corpus/Interpreting Output
| Output | Meaning |
|---|---|
corpus: N | Number of interesting test cases found |
objectives: N | Number of crashes/timeouts found |
executions: N | Total number of target invocations |
exec/sec: N | Current execution throughput |
edges: X% | Code coverage percentage |
clients: N | Number of parallel fuzzing processes |
The fuzzer emits two main event types:
- UserStats - Regular heartbeat with current statistics
- Testcase - New interesting input discovered
Advanced Usage
Tips and Tricks
| Tip | Why It Helps |
|---|---|
Use -fork=1 -ignore_crashes=1 | Continue fuzzing after first crash |
Use InMemoryOnDiskCorpus | Persist corpus across restarts |
Enable TUI with -tui=1 | Better visualization of progress |
| Use specific LLVM version | Avoid compatibility issues |
Set RUSTFLAGS correctly | Prevent linking errors |
Crash Deduplication
Avoid storing duplicate crashes from the same bug:
Add backtrace observer:
let backtrace_observer = BacktraceObserver::owned(
"BacktraceObserver",
libafl::observers::HarnessType::InProcess
);Update executor:
let mut executor = InProcessExecutor::with_timeout(
&mut harness,
tuple_list!(edges_observer, time_observer, backtrace_observer),
&mut fuzzer,
&mut state,
&mut restarting_mgr,
timeout,
)?;Update objective with hash feedback:
let mut objective = feedback_and!(
feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()),
NewHashFeedback::new(&backtrace_observer)
);This ensures only crashes with unique backtraces are saved.
Dictionary Fuzzing
Use dictionaries to guide fuzzing toward specific tokens:
Add tokens from file:
let mut tokens = Tokens::new();
if let Some(tokenfile) = &tokenfile {
tokens.add_from_file(tokenfile)?;
}
state.add_metadata(tokens);Update mutator:
let mutator = StdScheduledMutator::new(
havoc_mutations().merge(tokens_mutations())
);Hard-coded tokens example (PNG):
state.add_metadata(Tokens::from([
vec![137, 80, 78, 71, 13, 10, 26, 10], // PNG header
"IHDR".as_bytes().to_vec(),
"IDAT".as_bytes().to_vec(),
"PLTE".as_bytes().to_vec(),
"IEND".as_bytes().to_vec(),
]));See Also: For detailed dictionary creation strategies and format-specific dictionaries,
see the fuzzing-dictionaries technique skill.
Auto Tokens
Automatically extract magic values and checksums from the program:
Enable in compiler wrapper:
cc.add_pass(LLVMPasses::AutoTokens)Load auto tokens in fuzzer:
tokens += libafl_targets::autotokens()?;Verify tokens section:
echo "p (uint8_t *)__token_start" | gdb fuzzPerformance Tuning
| Setting | Impact |
|---|---|
| Multi-core fuzzing | Linear speedup with cores |
InMemoryCorpus | Faster but non-persistent |
InMemoryOnDiskCorpus | Balanced speed and persistence |
| Sanitizers | 2-5x slowdown, essential for bugs |
Optimization level -O2 | Balance between speed and coverage |
Debugging Fuzzer
Run fuzzer in single-process mode for easier debugging:
// Replace launcher with direct call
run_client(None, SimpleEventManager::new(monitor), 0).unwrap();
// Comment out:
// Launcher::builder()
// .run_client(&mut run_client)
// ...
// .launch()Then debug with GDB:
gdb --args ./fuzz --cores 0 --input corpus/Real-World Examples
Example: libpng
Fuzzing libpng using LibAFL:
1. Get source code:
curl -L -O https://downloads.sourceforge.net/project/libpng/libpng16/1.6.37/libpng-1.6.37.tar.xz
tar xf libpng-1.6.37.tar.xz
cd libpng-1.6.37/
apt install zlib1g-dev2. Set compiler wrapper:
export FUZZER_CARGO_DIR="/path/to/libafl/project"
export CC=$FUZZER_CARGO_DIR/target/release/libafl_cc
export CXX=$FUZZER_CARGO_DIR/target/release/libafl_cxx3. Build static library:
./configure --enable-shared=no
make4. Get harness:
curl -O https://raw.githubusercontent.com/glennrp/libpng/f8e5fa92b0e37ab597616f554bee254157998227/contrib/oss-fuzz/libpng_read_fuzzer.cc5. Link fuzzer:
$CXX libpng_read_fuzzer.cc .libs/libpng16.a -lz -o fuzz6. Prepare seeds:
mkdir seeds/
curl -o seeds/input.png https://raw.githubusercontent.com/glennrp/libpng/acfd50ae0ba3198ad734e5d4dec2b05341e50924/contrib/pngsuite/iftp1n3p08.png7. Get dictionary (optional):
curl -O https://raw.githubusercontent.com/glennrp/libpng/2fff013a6935967960a5ae626fc21432807933dd/contrib/oss-fuzz/png.dict8. Start fuzzing:
./fuzz --input seeds/ --cores 0 -x png.dictExample: CMake Project
Integrate LibAFL with CMake build system:
CMakeLists.txt:
project(BuggyProgram)
cmake_minimum_required(VERSION 3.0)
add_executable(buggy_program main.cc)
add_executable(fuzz main.cc harness.cc)
target_compile_definitions(fuzz PRIVATE NO_MAIN=1)
target_compile_options(fuzz PRIVATE -g -O2)Build non-instrumented binary:
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .
cmake --build . --target buggy_programBuild fuzzer:
export FUZZER_CARGO_DIR="/path/to/libafl/project"
cmake -DCMAKE_C_COMPILER=$FUZZER_CARGO_DIR/target/release/libafl_cc \
-DCMAKE_CXX_COMPILER=$FUZZER_CARGO_DIR/target/release/libafl_cxx .
cmake --build . --target fuzzRun fuzzing:
./fuzz --input seeds/ --cores 0Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
| No coverage increases | Instrumentation failed | Verify compiler wrapper used, check for -fsanitize-coverage |
| Fuzzer won't start | Empty corpus with no interesting inputs | Provide seed inputs that trigger code paths |
Linker errors with libafl_main | Runtime not linked | Use -Wl,--whole-archive or -u libafl_main |
| LLVM version mismatch | LibAFL requires LLVM 15-18 | Install compatible LLVM version, set environment variables |
| Rust compilation fails | Outdated Rust or Cargo | Update Rust with rustup update |
| Slow fuzzing | Sanitizers enabled | Expected 2-5x slowdown, necessary for finding bugs |
| Environment variable interference | CC, CXX, RUSTFLAGS set | Unset after building LibAFL project |
| Cannot attach debugger | Multi-process fuzzing | Run in single-process mode (see Debugging section) |
Related Skills
Technique Skills
| Skill | Use Case |
|---|---|
| fuzz-harness-writing | Detailed guidance on writing effective harnesses |
| address-sanitizer | Memory error detection during fuzzing |
| undefined-behavior-sanitizer | Undefined behavior detection |
| coverage-analysis | Measuring and improving code coverage |
| fuzzing-corpus | Building and managing seed corpora |
| fuzzing-dictionaries | Creating dictionaries for format-aware fuzzing |
Related Fuzzers
| Skill | When to Consider |
|---|---|
| libfuzzer | Simpler setup, don't need LibAFL's advanced features |
| aflpp | Multi-core fuzzing without custom fuzzer development |
| cargo-fuzz | Fuzzing Rust projects with less setup |
Resources
Official Documentation
- LibAFL Book - Official handbook with comprehensive documentation
- LibAFL GitHub - Source code and examples
- LibAFL API Documentation - Rust API reference
Examples and Tutorials
- LibAFL Examples - Collection of example fuzzers
- cargo-fuzz with LibAFL - Using LibAFL as cargo-fuzz backend
- Testing Handbook LibAFL Examples - Complete working examples from this handbook
interface:
icon_small: "assets/trail-of-bits-mark.svg"
icon_large: "assets/trail-of-bits-mark.svg"
brand_color: "#D83A34"
<svg xmlns="http://www.w3.org/2000/svg" width="94" height="56" fill="none" viewBox="0 0 94 56"><path fill="#F0F4F7" d="m34.04 54.662-7.61-4.147L24.593 56l9.433-1.335c-.029 0-.043 0 .014-.003"/><path fill="#F0F4F7" d="m34.039 54.662-.014.003c.035 0 .096-.003.014-.003m26.191-2.67 6.124-1.804 2.301-7.26-5.655.387zM74.805 5.478l-4.68-3.035-2.62 8.332 5.15 1.548zM43.224 3.532s3.172.973 4.423 1.328l4.508 1.335L52.234 0l-7.928 1.576zm-31.473 23.14 5.566.014 1.982-6.216-5.06-1.342c-.538 1.708-1.94 5.837-2.488 7.544M1.394 20.896l4.164 4.338 2.398-7.696-5.11-1.357zm88.205 24.841c-.086-2.18-.692-2.894-1.978-4.232l-6.71.447c1.871 1.175 3.018 2.63 3.255 4.583.261 2.145-2.068 4.623-4.322 4.623-1.258 0-1.885-.987-1.885-2.12.035-.845.333-1.942.777-2.673h-5.691c-.444 1.136-.813 2.418-.813 3.625 0 4.136 3.659 5.197 7.131 5.197 3.62 0 6.616-.696 8.501-4.03.85-1.505 1.806-3.663 1.735-5.42M18.804.56 1.362.576 0 4.86l6.394-.007-3.161 9.962 5.114 1.356 3.551-11.322 5.544-.007z"/><path fill="#F0F4F7" d="M20.707 15.898c.628-.04 1.258-.04 1.886-.04 1.035-.003 2.587.072 2.587 1.499.004.987-.366 2.233-.66 3.184-.551 1.942-1.214 3.88-1.325 5.858l5.727-.007c-.151-3.185 1.842-5.968 1.838-9.117 0-2.123-1.627-2.964-3.512-3.294l.552-.075c4.103-.554 6.39-3.738 6.386-7.729-.004-4.423-3.738-5.666-7.544-5.662l-6.576.007c-1.87 5.751-3.645 11.534-5.462 17.31l5.057 1.339zM24.245 4.58l1.849-.004c1.369 0 2.734.327 2.738 1.939.003 1.977-1.437 5.31-3.803 5.31l-3.031.004zm11.959 21.883 2.949-5.531 7.06-.008-.215 5.564 5.544-.004.441-18.94-4.763-1.43a89 89 0 0 0-.677 10.71h-.036l-5.322.004c1.914-3.586 3.749-7.2 5.4-10.906L42.77 4.775 30.437 26.466zm39.249-.036 1.402-4.214-7.43.01 2.753-8.612-5.15-1.548-4.584 14.375zm-34.411 1.658h-7.28l-6.834 21.18 8.698 4.694c5.208-.196 8.856-4.012 8.856-9.252 0-2.013-1.258-3.586-3.215-4.136 3.846-.877 6.319-3.33 6.319-7.356-.004-3.923-3.072-5.13-6.544-5.13m-2.993 20.318c-1.036 1.537-2.143 1.647-3.881 1.647h-2.254l2.476-7.611c1.81.07 5.024-.366 5.024 2.268 0 1.168-.698 2.744-1.365 3.696m-.444-9.667h-2.072l2.18-6.7c1.626.075 4.694-.436 4.694 2.053.04 2.928-1.846 4.647-4.802 4.647M58.67 9.582l-5.522 18.29-4.878 14.836 5.856-.447 4.23-13.2h.006l5.713-17.878c-.796-.22-3.964-1.228-5.404-1.601m2.738 18.542-1.37 4.278h6.398l-2.993 9.525 5.584-.38 2.913-9.145h5.541l1.37-4.278zm25.351-.259c-5.726 0-9.127 3.951-9.127 9.444.007.798.727 2.765 2.2 3.422l6.888-.462c-1.172-.98-3.243-3.29-3.243-4.519 0-1.686.95-3.891 2.91-3.891 1.33 0 2.143.366 2.143 1.793 0 .916-.444 1.757-.702 2.638h5.322c.333-.77.849-2.528.849-3.334.004-3.994-3.913-5.09-7.24-5.09m-63.15.372c-2.605 0-2.978 1.906-3.623 3.93-.215.728-.623 1.615-.623 2.379 0 1.47 1.315 1.75 2.537 1.75 1.494.01 2.29-.487 2.82-1.878.362-.952 1.305-3.568 1.305-4.488 0-1.303-1.326-1.693-2.416-1.693m.728 1.87c0 .328-.373 1.392-.498 1.765l-.577 1.782c-.226.675-.498 1.449-1.359 1.449-.487 0-.802-.28-.802-.785 0-.653.509-1.864.724-2.538.215-.671.498-2.01 1.247-2.269.168-.056.351-.078.534-.078.34 0 .749.302.749.664zm5.902 2.674.394-1.292H28.37l.613-1.928h2.38l.42-1.292h-4.126l-2.48 7.924h1.735l1.075-3.412z"/></svg>
Related skills
How it compares
libafl is an agent skill for build custom libafl fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation, not a generic alternative.
FAQ
Who is libafl for?
Developers using Security workflows with agent-guided SKILL.md steps.
When should I use libafl?
Build custom libAFL fuzzers with tailored mutation strategies, feedback hooks, and coverage instrumentation.
Is libafl safe to install?
Review the Security Audits panel on this page before installing in production.