Skills Plugins MCP Prompt Model 博客 我的中心
Lifestyle & Tools #writing #research

libafl

Builds custom fuzzers with LibAFL, the modular Rust fuzzing library. Covers composing observers, feedbacks, mutators, schedulers, and executors into a fuzzer for targets the standard tools do not fit. Use when writing a bespoke fuzzer or mutator, fuzzing a non-standard target or architecture, implementing a fuzzing research idea, or when libFuzzer and AFL++ lack the control you need.

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=trailofbits-skills-plugins-testing-handbook-skills-skills-libafl-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name libafl type fuzzer description Builds custom fuzzers with LibAFL, the modular Rust fuzzing library. Covers composing observers, feedbacks, mutators, schedulers, and executors into a fuzzer for targets the standard tools do not fit. Use when writing a bespoke fuzzer or mutator, fuzzing a non-standard target or architecture, implementing a fuzzing research idea, or when libFuzzer and AFL++ lack the control you need. 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.sh Compile 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 clang Or install a specific version via apt.llvm.org: wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh sudo ./llvm.sh 15 Configure 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 | sh Install additional dependencies: apt install libssl-dev pkg-config For libFuzzer compatibility mode, install nightly Rust: rustup toolchain install nightly --component llvm-tools Verification Build LibAFL to verify installation: cd LibAFL/libafl_libfuzzer_runtime ./build.sh # Should produce libFuzzer.a Writing 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 fuzz Running: ./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: Observers - Collect execution feedback (coverage, timing) Feedback - Determine if inputs are interesting Objective - Define fuzzing goals (crashes, timeouts) State - Maintain corpus and metadata Mutators - Generate new inputs Scheduler - Select which inputs to mutate 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 fuzz Compiler 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 fuzz See 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 1000 Text 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 (), ]));
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。