From d7fce14da1b1898375d3664ba647a59c0a785081 Mon Sep 17 00:00:00 2001 From: Bruno Produit Date: Thu, 22 Jun 2023 13:48:25 +0200 Subject: [PATCH 01/28] first draft for libafl --- Cargo.toml | 5 + src/bin/cargo-ziggy/build.rs | 25 +++++ src/lib.rs | 20 +++- src/libafl_fuzzer.rs | 210 +++++++++++++++++++++++++++++++++++ 4 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 src/libafl_fuzzer.rs diff --git a/Cargo.toml b/Cargo.toml index b3b01e2..91426d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,12 @@ serde_json = { version = "1.0.96", optional = true } log = { version = "0.4.18", optional = true } env_logger = { version = "0.10.0", optional = true } libc = "0.2.145" +libafl = { version = "0.10.1", optional = true } +libafl_targets = { version = "0.10.1", optional = true, features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] } +#libafl = { git = "http://github.com/aflplusplus/libafl", optional = true } +#libafl_targets = { git = "http://github.com/aflplusplus/libafl", optional = true, features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] } [features] default = ["cli"] cli = ["clap", "console", "glob", "toml", "anyhow", "serde_json", "log", "env_logger"] +with_libafl = ["libafl", "libafl_targets"] diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 7c94025..27d93b3 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -61,5 +61,30 @@ pub fn build_fuzzers(no_afl: bool, no_honggfuzz: bool) -> Result<(), anyhow::Err eprintln!(" {} honggfuzz", style("Finished").cyan().bold()); } + + + //if !no_libafl { + eprintln!(" {} libafl", style("Building").red().bold()); + + // Third fuzzer we build: Honggfuzz + let run = process::Command::new(cargo) + .args(["build"]) + .env("CARGO_TARGET_DIR", "./target/honggfuzz") + .env("HFUZZ_BUILD_ARGS", "--features=ziggy/honggfuzz") + .stdout(process::Stdio::piped()) + .spawn()? + .wait() + .context("Error spawning hfuzz build command")?; + + if !run.success() { + return Err(anyhow!( + "Error building honggfuzz fuzzer: Exited with {:?}", + run.code() + )); + } + + eprintln!(" {} honggfuzz", style("Finished").cyan().bold()); + //} + Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 791588e..84d7bf8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,16 @@ pub use afl::fuzz as afl_fuzz; #[cfg(feature = "honggfuzz")] pub use honggfuzz::fuzz as honggfuzz_fuzz; +#[cfg(feature = "with_libafl")] +mod libafl_fuzzer; +#[cfg(feature = "with_libafl")] +pub use libafl; +#[cfg(feature = "with_libafl")] +pub use libafl_targets; // This is our inner harness handler function for the runner and for coverage. // We open the input file and feed the data to the harness closure. -#[cfg(not(any(feature = "afl", feature = "honggfuzz")))] +#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "with_libafl")))] pub fn read_file_and_fuzz(mut closure: F, file: String) where F: FnMut(&[u8]), @@ -21,7 +27,7 @@ where // This is our middle harness handler macro for the runner and for coverage. // We read input files and directories from the command line and run the inner harness `fuzz`. #[macro_export] -#[cfg(not(any(feature = "afl", feature = "honggfuzz")))] +#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "with_libafl")))] macro_rules! read_args_and_fuzz { ( |$buf:ident| $body:block ) => { let args: Vec = std::env::args().collect(); @@ -50,7 +56,7 @@ macro_rules! read_args_and_fuzz { // This is our outer harness handler macro for the runner and for coverage. // It is used to handle different types of arguments for the harness closure, including Arbitrary. #[macro_export] -#[cfg(not(any(feature = "afl", feature = "honggfuzz")))] +#[cfg(not(any(feature = "afl", feature = "honggfuzz", feature = "with_libafl")))] macro_rules! fuzz { (|$buf:ident| $body:block) => { $crate::read_args_and_fuzz!(|$buf| $body); @@ -90,3 +96,11 @@ macro_rules! fuzz { } }; } + +#[macro_export] +#[cfg(feature = "with_libafl")] +macro_rules! fuzz { + ( $($x:tt)* ) => { + $crate::libafl_fuzz!($($x)*); + }; +} \ No newline at end of file diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs new file mode 100644 index 0000000..2a10950 --- /dev/null +++ b/src/libafl_fuzzer.rs @@ -0,0 +1,210 @@ +#[macro_export] +#[cfg(feature = "with_libafl")] +macro_rules! libafl_fuzz { + + ( $($x:tt)* ) => { + + use core::time::Duration; + #[cfg(feature = "crash")] + use std::ptr; + use std::{env, path::PathBuf}; + + use ziggy::libafl::{ + bolts::{ + current_nanos, + rands::StdRand, + tuples::{tuple_list, Merge}, + AsSlice, + }, + corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, + events::{setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager}, + executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor}, + feedback_or, feedback_or_fast, + feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + inputs::{BytesInput, HasTargetBytes}, + monitors::MultiMonitor, + mutators::{ + scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, + token_mutations::Tokens, + }, + observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, + schedulers::{ + powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, + }, + stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage}, + state::{HasCorpus, HasMetadata, StdState}, + Error, + }; + use ziggy::libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; + + // The closure that we want to fuzz + let inner_harness = $($x)*; + + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = |input: &BytesInput| { + let target = input.target_bytes(); + let buf = target.as_slice(); + inner_harness(buf); + ExitKind::Ok + }; + + + + // 'While the stats are state, they are usually used in the broker - which is likely never restarted + let monitor = MultiMonitor::new(|s| println!("{s}")); + let objective_dir = PathBuf::from("./crashes"); + let corpus_dirs = &[PathBuf::from("./corpus")]; + + + let broker_port = 1337; +/* + // The restarting state will spawn the same process again as child, then restarted it each time it crashes. + let (state, mut restarting_mgr) = + match setup_restarting_mgr_std(monitor, broker_port, EventConfig::AlwaysUnique) { + Ok(res) => res, + Err(err) => match err { + Error::ShuttingDown => { + return; + } + _ => { + panic!("Failed to setup the restarter: {err}"); + } + }, + }; + */ + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( + "edges", + EDGES_MAP.as_mut_ptr(), + MAX_EDGES_NUM, + )) + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + + let calibration = CalibrationStage::new(&map_feedback); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + map_feedback, + // Time feedback, this one does not need a feedback state + TimeFeedback::with_observer(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // If not restarting, create a State from scratch + let mut state = //state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved, we keep it in memory for performance + InMemoryCorpus::new(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(objective_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap(); + //}); + + println!("We're a client, let's fuzz :)"); + +/* + // Create a PNG dictionary if not existing + if state.metadata_map().get::().is_none() { + 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(), + ])); + } + */ + + // Setup a basic mutator with a mutational stage + + let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + + let power = StdPowerMutationalStage::new(mutator); + + let mut stages = tuple_list!(calibration, power); + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(PowerSchedule::FAST), + )); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + let mut mgr = SimpleEventManager::new(monitor); + + // Create the executor for an in-process function with one observer for edge coverage and one for the execution time + let mut executor = TimeoutExecutor::new( + InProcessExecutor::new( + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + //&mut restarting_mgr, + &mut mgr, + ).unwrap(), + // 10 seconds timeout + Duration::new(10, 0), + ); + /* + + // The actual target run starts here. + // Call LLVMFUzzerInitialize() if present. + let args: Vec = env::args().collect(); + if libfuzzer_initialize(&args) == -1 { + println!("Warning: LLVMFuzzerInitialize failed with -1"); + } + */ + + // In case the corpus is empty (on first run), reset + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) + //.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) + .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // This fuzzer restarts after 1 mio `fuzz_one` executions. + // Each fuzz_one will internally do many executions of the target. + // If your target is very instable, setting a low count here may help. + // However, you will lose a lot of performance that way. + let iters = 1_000_000; + fuzzer.fuzz_loop_for( + &mut stages, + &mut executor, + &mut state, + //&mut restarting_mgr, + &mut mgr, + iters, + ).unwrap(); + + // It's important, that we store the state before restarting! + // Else, the parent will not respawn a new child and quit. + //restarting_mgr.on_restart(&mut state).unwrap(); + + }; +} \ No newline at end of file From 4b675be72d8a0605321c292e7033412dbabc5825 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 22 Jun 2023 16:34:13 +0200 Subject: [PATCH 02/28] Update LibAFL integration --- Cargo.lock | 810 ++++++++++++++++++++++++++++++++++- src/bin/cargo-ziggy/build.rs | 3 + src/lib.rs | 2 +- src/libafl_fuzzer.rs | 83 +--- 4 files changed, 823 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94b6491..4f5de94 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "afl" version = "0.13.1" @@ -17,6 +32,17 @@ dependencies = [ "xdg", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.0.2" @@ -98,23 +124,91 @@ dependencies = [ "ziggy", ] +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.6.2", + "object", + "rustc-demangle", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "c2rust-bitfields" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec83ed829620a77796c348b3c32bc3013f38dc612e1d8b4f4128dbdff85f9ca4" +dependencies = [ + "c2rust-bitfields-derive", +] + +[[package]] +name = "c2rust-bitfields-derive" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a516c617d800450f0941aaafe55bab206c2e8f6fff55fae1f1dfca505fe80a8d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + [[package]] name = "cc" version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +dependencies = [ + "jobserver", +] [[package]] name = "cfg-if" @@ -156,7 +250,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -165,6 +259,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "colorchoice" version = "1.0.0" @@ -184,6 +284,76 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + +[[package]] +name = "crossterm" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +dependencies = [ + "bitflags", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown 0.12.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "derive_arbitrary" version = "1.3.1" @@ -192,7 +362,7 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.18", ] [[package]] @@ -214,6 +384,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "erased-serde" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +dependencies = [ + "serde", +] + [[package]] name = "errno" version = "0.3.1" @@ -259,18 +438,145 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + [[package]] name = "glob" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", + "serde", +] + +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -304,6 +610,17 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "humantime" version = "2.1.0" @@ -327,7 +644,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -339,6 +656,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "intervaltree" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "270bc34e57047cab801a8c871c124d9dc7132f6473c6401f645524f4e6edd111" +dependencies = [ + "serde", + "smallvec", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -368,30 +695,129 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +[[package]] +name = "jobserver" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +dependencies = [ + "libc", +] + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "libafl" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dcef528afdb9f8fae3b998d50565189b4f9e573ee557d0e43302787e2f187f6" +dependencies = [ + "ahash", + "backtrace", + "bincode", + "byteorder", + "c2rust-bitfields", + "crossterm 0.26.1", + "ctor", + "erased-serde", + "hashbrown 0.13.2", + "hostname", + "intervaltree", + "libafl_derive", + "libc", + "libm", + "lock_api", + "log", + "miniz_oxide 0.7.1", + "nix", + "num-traits", + "num_enum", + "once_cell", + "postcard", + "rand_core", + "regex", + "rustversion", + "serde", + "serde_json", + "serial_test", + "static_assertions", + "tui", + "tuple_list", + "typed-builder", + "uds", + "uuid", + "wait-timeout", + "windows", + "xxhash-rust", +] + +[[package]] +name = "libafl_derive" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f560e150e1686a0bc4ec3af1cff46b916b32b0fc42c15732ed800e0ac8689b4c" +dependencies = [ + "quote", + "syn 2.0.18", +] + +[[package]] +name = "libafl_targets" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "364dd84261ffeb28266c9ba128f1024c27be92fe3d081247b2d9ff13c6f17231" +dependencies = [ + "cc", + "libafl", + "log", + "rangemap", + "serde", +] + [[package]] name = "libc" version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "linux-raw-sys" version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "memchr" version = "2.5.0" @@ -407,18 +833,155 @@ dependencies = [ "libc", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "nix" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", + "static_assertions", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "object" +version = "0.30.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.0", +] + [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postcard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa512cd0d087cc9f99ad30a1bf64795b67871edbead083ffc3a4dfafa59aa00" +dependencies = [ + "cobs", + "heapless", + "serde", +] + [[package]] name = "proc-macro2" version = "1.0.60" @@ -437,6 +1000,18 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rangemap" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9283c6b06096b47afc7109834fdedab891175bb5241ee5d4f7d2546549f263" + [[package]] name = "redox_syscall" version = "0.3.5" @@ -463,6 +1038,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustc_version" version = "0.4.0" @@ -486,12 +1067,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + [[package]] name = "ryu" version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + [[package]] name = "semver" version = "1.0.17" @@ -503,6 +1096,20 @@ name = "serde" version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.164" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] [[package]] name = "serde_json" @@ -524,12 +1131,114 @@ dependencies = [ "serde", ] +[[package]] +name = "serial_test" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "538c30747ae860d6fb88330addbbd3e0ddbe46d662d032855596d8a8ca260611" +dependencies = [ + "dashmap", + "futures", + "lazy_static", + "log", + "parking_lot", + "serial_test_derive", +] + +[[package]] +name = "serial_test_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "079a83df15f85d89a68d64ae1238f142f172b1fa915d0d76b26a7cba1b659a69" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.18" @@ -613,6 +1322,45 @@ dependencies = [ "winnow", ] +[[package]] +name = "tui" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" +dependencies = [ + "bitflags", + "cassowary", + "crossterm 0.25.0", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "tuple_list" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "141fb9f71ee586d956d7d6e4d5a9ef8e946061188520140f7591b668841d502e" + +[[package]] +name = "typed-builder" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cba322cb9b7bc6ca048de49e83918223f35e7a86311267013afff257004870" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "uds" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343758ccc8a17c1663182d780f68b52021d68b9a43d4b912b0a01f48b526e4f0" +dependencies = [ + "libc", +] + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -634,6 +1382,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "unicode-width" version = "0.1.10" @@ -665,6 +1419,37 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "winapi" version = "0.3.9" @@ -696,6 +1481,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -846,9 +1640,15 @@ dependencies = [ "home", ] +[[package]] +name = "xxhash-rust" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" + [[package]] name = "ziggy" -version = "0.6.2" +version = "0.6.3" dependencies = [ "afl", "anyhow", @@ -857,6 +1657,8 @@ dependencies = [ "env_logger", "glob", "honggfuzz", + "libafl", + "libafl_targets", "libc", "log", "serde_json", diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 27d93b3..9274a1e 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -62,6 +62,7 @@ pub fn build_fuzzers(no_afl: bool, no_honggfuzz: bool) -> Result<(), anyhow::Err eprintln!(" {} honggfuzz", style("Finished").cyan().bold()); } + /* //if !no_libafl { eprintln!(" {} libafl", style("Building").red().bold()); @@ -86,5 +87,7 @@ pub fn build_fuzzers(no_afl: bool, no_honggfuzz: bool) -> Result<(), anyhow::Err eprintln!(" {} honggfuzz", style("Finished").cyan().bold()); //} + */ + Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 84d7bf8..cb4ef36 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,4 +103,4 @@ macro_rules! fuzz { ( $($x:tt)* ) => { $crate::libafl_fuzz!($($x)*); }; -} \ No newline at end of file +} diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 2a10950..6d5a6d7 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -1,13 +1,14 @@ +// To run this fuzzer, execute the following command (for example in `examples/url/`): +// LIBAFL_EDGES_MAP_SIZE=1000000 ASAN_OPTION="detect_odr_violation=0:abort_on_error=1:symbolize=0" TSAN_OPTION="report_signal_unsafe=0" RUSTFLAGS="-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard -C llvm-args=-sanitizer-coverage-prune-blocks=0 -C llvm-args=-sanitizer-coverage-trace-compares -C opt-level=3 -C target-cpu=native --cfg fuzzing -Cdebug-assertions -Clink-arg=-fuse-ld=gold" cargo run --features=ziggy/with_libafl --target x86_64-unknown-linux-gnu + #[macro_export] #[cfg(feature = "with_libafl")] macro_rules! libafl_fuzz { - + ( $($x:tt)* ) => { - + use core::time::Duration; - #[cfg(feature = "crash")] - use std::ptr; - use std::{env, path::PathBuf}; + use std::{env, path::PathBuf, ptr::write}; use ziggy::libafl::{ bolts::{ @@ -23,7 +24,7 @@ macro_rules! libafl_fuzz { feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, - monitors::MultiMonitor, + monitors::tui::{ui::TuiUI, TuiMonitor}, mutators::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::Tokens, @@ -40,7 +41,7 @@ macro_rules! libafl_fuzz { // The closure that we want to fuzz let inner_harness = $($x)*; - + // The wrapped harness function, calling out to the LLVM-style harness let mut harness = |input: &BytesInput| { let target = input.target_bytes(); @@ -49,31 +50,12 @@ macro_rules! libafl_fuzz { ExitKind::Ok }; + let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); + let monitor = TuiMonitor::new(ui); - - // 'While the stats are state, they are usually used in the broker - which is likely never restarted - let monitor = MultiMonitor::new(|s| println!("{s}")); let objective_dir = PathBuf::from("./crashes"); let corpus_dirs = &[PathBuf::from("./corpus")]; - - let broker_port = 1337; -/* - // The restarting state will spawn the same process again as child, then restarted it each time it crashes. - let (state, mut restarting_mgr) = - match setup_restarting_mgr_std(monitor, broker_port, EventConfig::AlwaysUnique) { - Ok(res) => res, - Err(err) => match err { - Error::ShuttingDown => { - return; - } - _ => { - panic!("Failed to setup the restarter: {err}"); - } - }, - }; - */ - // Create an observation channel using the coverage map let edges_observer = unsafe { HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( @@ -103,8 +85,7 @@ macro_rules! libafl_fuzz { let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); // If not restarting, create a State from scratch - let mut state = //state.unwrap_or_else(|| { - StdState::new( + let mut state = StdState::new( // RNG StdRand::with_seed(current_nanos()), // Corpus that will be evolved, we keep it in memory for performance @@ -119,25 +100,10 @@ macro_rules! libafl_fuzz { &mut objective, ) .unwrap(); - //}); println!("We're a client, let's fuzz :)"); -/* - // Create a PNG dictionary if not existing - if state.metadata_map().get::().is_none() { - 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(), - ])); - } - */ - // Setup a basic mutator with a mutational stage - let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); let power = StdPowerMutationalStage::new(mutator); @@ -163,48 +129,25 @@ macro_rules! libafl_fuzz { tuple_list!(edges_observer, time_observer), &mut fuzzer, &mut state, - //&mut restarting_mgr, &mut mgr, ).unwrap(), // 10 seconds timeout Duration::new(10, 0), ); - /* - - // The actual target run starts here. - // Call LLVMFUzzerInitialize() if present. - let args: Vec = env::args().collect(); - if libfuzzer_initialize(&args) == -1 { - println!("Warning: LLVMFuzzerInitialize failed with -1"); - } - */ // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { state .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) - //.load_initial_inputs(&mut fuzzer, &mut executor, &mut restarting_mgr, corpus_dirs) .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); println!("We imported {} inputs from disk.", state.corpus().count()); } - // This fuzzer restarts after 1 mio `fuzz_one` executions. - // Each fuzz_one will internally do many executions of the target. - // If your target is very instable, setting a low count here may help. - // However, you will lose a lot of performance that way. - let iters = 1_000_000; - fuzzer.fuzz_loop_for( + fuzzer.fuzz_loop( &mut stages, &mut executor, &mut state, - //&mut restarting_mgr, &mut mgr, - iters, ).unwrap(); - - // It's important, that we store the state before restarting! - // Else, the parent will not respawn a new child and quit. - //restarting_mgr.on_restart(&mut state).unwrap(); - }; -} \ No newline at end of file +} From 9b190edc62c8c6fe71f0d2accba1fe8876a2d5d1 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 22 Jun 2023 18:44:02 +0200 Subject: [PATCH 03/28] Improve LibAFL fuzzer --- Cargo.toml | 6 +++--- examples/url/corpus/init | 1 + examples/url/src/main.rs | 8 ++++++-- src/libafl_fuzzer.rs | 16 +++++++++------- 4 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 examples/url/corpus/init diff --git a/Cargo.toml b/Cargo.toml index 91426d6..e0adaf4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,9 +26,9 @@ log = { version = "0.4.18", optional = true } env_logger = { version = "0.10.0", optional = true } libc = "0.2.145" libafl = { version = "0.10.1", optional = true } -libafl_targets = { version = "0.10.1", optional = true, features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] } -#libafl = { git = "http://github.com/aflplusplus/libafl", optional = true } -#libafl_targets = { git = "http://github.com/aflplusplus/libafl", optional = true, features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] } +libafl_targets = { version = "0.10.1", optional = true, features = ["sancov_pcguard_hitcounts"] } +#libafl = { git = "http://github.com/aflplusplus/libafl", optional = true } +#libafl_targets = { git = "http://github.com/aflplusplus/libafl", optional = true, features = ["sancov_pcguard_hitcounts"] } [features] default = ["cli"] diff --git a/examples/url/corpus/init b/examples/url/corpus/init new file mode 100644 index 0000000..25c15ce --- /dev/null +++ b/examples/url/corpus/init @@ -0,0 +1 @@ +http://hi.com diff --git a/examples/url/src/main.rs b/examples/url/src/main.rs index 47887ec..f17e87b 100644 --- a/examples/url/src/main.rs +++ b/examples/url/src/main.rs @@ -1,9 +1,13 @@ fn main() { ziggy::fuzz!(|data: &[u8]| { if let Ok(s) = std::str::from_utf8(data) { - if let Ok(_parsed) = url::Url::parse(s) { + if let Ok(parsed) = url::Url::parse(s) { #[cfg(not(fuzzing))] - println!("{_parsed}"); + println!("parsed:\t{parsed}"); + let as_str = parsed.as_str(); + #[cfg(not(fuzzing))] + println!("as_str:\t{as_str}"); + assert_eq!(parsed, url::Url::parse(as_str).unwrap()); } } }); diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 6d5a6d7..ae8c192 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -1,5 +1,5 @@ // To run this fuzzer, execute the following command (for example in `examples/url/`): -// LIBAFL_EDGES_MAP_SIZE=1000000 ASAN_OPTION="detect_odr_violation=0:abort_on_error=1:symbolize=0" TSAN_OPTION="report_signal_unsafe=0" RUSTFLAGS="-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard -C llvm-args=-sanitizer-coverage-prune-blocks=0 -C llvm-args=-sanitizer-coverage-trace-compares -C opt-level=3 -C target-cpu=native --cfg fuzzing -Cdebug-assertions -Clink-arg=-fuse-ld=gold" cargo run --features=ziggy/with_libafl --target x86_64-unknown-linux-gnu +// LIBAFL_EDGES_MAP_SIZE=500000 RUSTFLAGS="-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard --cfg fuzzing -Clink-arg=-fuse-ld=gold" cargo run --features=ziggy/with_libafl --target x86_64-unknown-linux-gnu --release #[macro_export] #[cfg(feature = "with_libafl")] @@ -16,15 +16,16 @@ macro_rules! libafl_fuzz { rands::StdRand, tuples::{tuple_list, Merge}, AsSlice, + shmem::{unix_shmem, ShMemProvider}, }, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager}, - executors::{inprocess::InProcessExecutor, ExitKind, TimeoutExecutor}, + executors::{inprocess::InProcessExecutor, InProcessForkExecutor, ExitKind, TimeoutExecutor}, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, - monitors::tui::{ui::TuiUI, TuiMonitor}, + monitors::{tui::{ui::TuiUI, TuiMonitor}, SimpleMonitor}, mutators::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::Tokens, @@ -37,7 +38,7 @@ macro_rules! libafl_fuzz { state::{HasCorpus, HasMetadata, StdState}, Error, }; - use ziggy::libafl_targets::{libfuzzer_initialize, libfuzzer_test_one_input, EDGES_MAP, MAX_EDGES_NUM}; + use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; // The closure that we want to fuzz let inner_harness = $($x)*; @@ -52,6 +53,9 @@ macro_rules! libafl_fuzz { let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); let monitor = TuiMonitor::new(ui); + + //let monitor = SimpleMonitor::new(|_| {}); + //let monitor = SimpleMonitor::new(|s| println!("{s}")); let objective_dir = PathBuf::from("./crashes"); let corpus_dirs = &[PathBuf::from("./corpus")]; @@ -101,8 +105,6 @@ macro_rules! libafl_fuzz { ) .unwrap(); - println!("We're a client, let's fuzz :)"); - // Setup a basic mutator with a mutational stage let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); @@ -134,7 +136,7 @@ macro_rules! libafl_fuzz { // 10 seconds timeout Duration::new(10, 0), ); - + // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { state From c3f71695cc8621d8ab34b586cb4bca3a61194bfe Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 12 Oct 2023 11:24:57 +0200 Subject: [PATCH 04/28] Update LibAFL and example --- Cargo.lock | 901 +++++++++++++++++++-------------------- Cargo.toml | 7 +- examples/url/Cargo.toml | 2 +- examples/url/corpus/init | 1 - src/lib.rs | 2 + src/libafl_fuzzer.rs | 128 +++++- 6 files changed, 582 insertions(+), 459 deletions(-) delete mode 100644 examples/url/corpus/init diff --git a/Cargo.lock b/Cargo.lock index 4f5de94..9b03392 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "afl" -version = "0.13.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34bea480ea82b8f3ad81e0bee1328c41c9c85eddf5a86ae953e66cc621d6e9df" +checksum = "f890b8b9b41264fcff07f3d4036648dd77df46e772793c6bd23a22249d75d7e5" dependencies = [ "clap", "fs_extra", @@ -45,39 +45,38 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] [[package]] name = "anstream" -version = "0.3.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -93,9 +92,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -103,15 +102,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arbitrary" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" +checksum = "a2e1373abdaa212b704512ec2bd8b26bd0b7d5c3f70117411a5d9a451383c859" dependencies = [ "derive_arbitrary", ] @@ -124,15 +123,6 @@ dependencies = [ "ziggy", ] -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -141,15 +131,15 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide 0.6.2", + "miniz_oxide", "object", "rustc-demangle", ] @@ -163,6 +153,28 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.64.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -170,10 +182,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "byteorder" -version = "1.4.3" +name = "bitflags" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "c2rust-bitfields" @@ -203,11 +215,21 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "jobserver", + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", ] [[package]] @@ -216,48 +238,56 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" -version = "4.3.3" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.3.3" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", - "once_cell", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "cobs" @@ -284,35 +314,13 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "critical-section" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" - -[[package]] -name = "crossterm" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" -dependencies = [ - "bitflags", - "crossterm_winapi", - "libc", - "mio", - "parking_lot", - "signal-hook", - "signal-hook-mio", - "winapi", -] - [[package]] name = "crossterm" -version = "0.26.1" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags", + "bitflags 2.4.0", "crossterm_winapi", "libc", "mio", @@ -333,22 +341,22 @@ dependencies = [ [[package]] name = "ctor" -version = "0.1.26" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.12.3", + "hashbrown", "lock_api", "once_cell", "parking_lot_core", @@ -362,9 +370,21 @@ checksum = "53e0efad4403bfc52dc201159c4b842a246a14b98c64b55dfd0f2d89729dfeb8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + [[package]] name = "encode_unicode" version = "0.3.6" @@ -384,44 +404,36 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.3.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "form_urlencoded" @@ -438,83 +450,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - [[package]] name = "getrandom" version = "0.2.10" @@ -528,9 +463,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "glob" @@ -538,45 +473,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" dependencies = [ "ahash", "serde", ] -[[package]] -name = "heapless" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" -dependencies = [ - "atomic-polyfill", - "hash32", - "rustc_version", - "serde", - "spin", - "stable_deref_trait", -] - [[package]] name = "heck" version = "0.4.1" @@ -585,9 +491,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "home" @@ -639,67 +545,51 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "instant" -version = "0.1.12" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ - "cfg-if", + "equivalent", + "hashbrown", ] [[package]] -name = "intervaltree" -version = "0.2.7" +name = "indoc" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "270bc34e57047cab801a8c871c124d9dc7132f6473c6401f645524f4e6edd111" -dependencies = [ - "serde", - "smallvec", -] +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "is-terminal" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "libc", + "rustix", "windows-sys 0.48.0", ] [[package]] -name = "is-terminal" -version = "0.4.7" +name = "itertools" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ - "hermit-abi", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", + "either", ] [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" dependencies = [ "libc", ] @@ -710,69 +600,98 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libafl" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dcef528afdb9f8fae3b998d50565189b4f9e573ee557d0e43302787e2f187f6" +checksum = "59207bf0f8860e98ee649408ddaa0e9962fe5daf6f2de80c8d77a989797d2281" dependencies = [ "ahash", "backtrace", "bincode", - "byteorder", "c2rust-bitfields", - "crossterm 0.26.1", + "crossterm", + "hashbrown", + "libafl_bolts", + "libafl_derive", + "libc", + "libm", + "log", + "meminterval", + "nix", + "num-traits", + "postcard", + "ratatui", + "regex", + "rustversion", + "serde", + "serde_json", + "serial_test", + "tuple_list", + "typed-builder", + "uuid", + "wait-timeout", + "windows", +] + +[[package]] +name = "libafl_bolts" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b356226da330784aa1331e915223880aa7335a19627780a6b3f3849506c749e" +dependencies = [ + "ahash", + "backtrace", "ctor", "erased-serde", - "hashbrown 0.13.2", + "hashbrown", "hostname", - "intervaltree", "libafl_derive", "libc", - "libm", - "lock_api", "log", - "miniz_oxide 0.7.1", + "miniz_oxide", "nix", - "num-traits", "num_enum", - "once_cell", "postcard", "rand_core", - "regex", "rustversion", "serde", "serde_json", "serial_test", - "static_assertions", - "tui", "tuple_list", - "typed-builder", "uds", "uuid", - "wait-timeout", "windows", "xxhash-rust", ] [[package]] name = "libafl_derive" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f560e150e1686a0bc4ec3af1cff46b916b32b0fc42c15732ed800e0ac8689b4c" +checksum = "33990e1b3562e8aaa101bffc1bbe4bb5d0963115ccab7ec00842c95627222331" dependencies = [ "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "libafl_targets" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "364dd84261ffeb28266c9ba128f1024c27be92fe3d081247b2d9ff13c6f17231" +checksum = "b45217016a6dc252be76298431a76d681100ceb561682f7b3484aae954f91698" dependencies = [ + "bindgen", "cc", "libafl", + "libafl_bolts", + "libc", "log", "rangemap", "serde", @@ -780,21 +699,31 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "libloading" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "lock_api" @@ -808,9 +737,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "match_cfg" @@ -820,9 +749,19 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "meminterval" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f8614cf855d251be1c2138d330c04f134923fddec0dcfc8b6f58ac499bf248" +dependencies = [ + "num-traits", + "serde", +] [[package]] name = "memmap2" @@ -843,13 +782,10 @@ dependencies = [ ] [[package]] -name = "miniz_oxide" -version = "0.6.2" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" @@ -874,52 +810,61 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset", "pin-utils", - "static_assertions", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "num_enum" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.11" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "object" -version = "0.30.4" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -950,20 +895,26 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] -name = "percent-encoding" -version = "2.3.0" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] -name = "pin-project-lite" -version = "0.2.9" +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-utils" @@ -973,29 +924,29 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "postcard" -version = "1.0.4" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfa512cd0d087cc9f99ad30a1bf64795b67871edbead083ffc3a4dfafa59aa00" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" dependencies = [ "cobs", - "heapless", + "embedded-io", "serde", ] [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1008,9 +959,26 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "rangemap" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9283c6b06096b47afc7109834fdedab891175bb5241ee5d4f7d2546549f263" +checksum = "977b1e897f9d764566891689e642653e5ed90c6895106acd005eb4c1d0203991" + +[[package]] +name = "ratatui" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e2e4cd95294a85c3b4446e63ef054eea43e0205b1fd60120c16b74ff7ff96ad" +dependencies = [ + "bitflags 2.4.0", + "cassowary", + "crossterm", + "indoc", + "itertools", + "paste", + "strum", + "unicode-segmentation", + "unicode-width", +] [[package]] name = "redox_syscall" @@ -1018,14 +986,26 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", @@ -1034,9 +1014,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "56d84fdd47036b038fc80dd333d10b6aab10d5d31f4a366e20014def75328d33" [[package]] name = "rustc-demangle" @@ -1044,6 +1024,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1055,13 +1041,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "5a74ee2d7c2581cd139b42447d7d9389b889bdaad3a73f1ebb16f2a3237bb19c" dependencies = [ - "bitflags", + "bitflags 2.4.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys 0.48.0", @@ -1069,53 +1054,53 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.17" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.38", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1124,21 +1109,20 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] [[package]] name = "serial_test" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538c30747ae860d6fb88330addbbd3e0ddbe46d662d032855596d8a8ca260611" +checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" dependencies = [ "dashmap", - "futures", "lazy_static", "log", "parking_lot", @@ -1147,20 +1131,26 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079a83df15f85d89a68d64ae1238f142f172b1fa915d0d76b26a7cba1b659a69" +checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -1187,46 +1177,38 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.8" +name = "smallvec" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] -name = "smallvec" -version = "1.10.0" +name = "strsim" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] -name = "spin" -version = "0.9.8" +name = "strum" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "lock_api", + "strum_macros", ] [[package]] -name = "stable_deref_trait" -version = "1.2.0" +name = "strum_macros" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.38", +] [[package]] name = "syn" @@ -1241,9 +1223,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" dependencies = [ "proc-macro2", "quote", @@ -1252,11 +1234,10 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall", @@ -1266,9 +1247,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] @@ -1290,9 +1271,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", @@ -1302,18 +1283,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap", "serde", @@ -1322,19 +1303,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tui" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1" -dependencies = [ - "bitflags", - "cassowary", - "crossterm 0.25.0", - "unicode-segmentation", - "unicode-width", -] - [[package]] name = "tuple_list" version = "0.1.3" @@ -1343,20 +1311,29 @@ checksum = "141fb9f71ee586d956d7d6e4d5a9ef8e946061188520140f7591b668841d502e" [[package]] name = "typed-builder" -version = "0.14.0" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe83c85a85875e8c4cb9ce4a890f05b23d38cd0d47647db7895d3d2a79566d2" +dependencies = [ + "typed-builder-macro", +] + +[[package]] +name = "typed-builder-macro" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cba322cb9b7bc6ca048de49e83918223f35e7a86311267013afff257004870" +checksum = "29a3151c41d0b13e3d011f98adc24434560ef06673a155a6c7f66b9879eecce2" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.38", ] [[package]] name = "uds" -version = "0.2.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343758ccc8a17c1663182d780f68b52021d68b9a43d4b912b0a01f48b526e4f0" +checksum = "3803a8c885a33e84f898c82c3e72dbd5b2e807da66443731065a509fb11c6c9f" dependencies = [ "libc", ] @@ -1369,9 +1346,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -1390,15 +1367,15 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -1421,9 +1398,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.3.4" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ "getrandom", "serde", @@ -1450,6 +1427,18 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1468,9 +1457,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -1483,11 +1472,21 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.44.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-targets 0.42.2", + "windows-core", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -1505,7 +1504,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -1525,17 +1524,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -1546,9 +1545,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -1558,9 +1557,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -1570,9 +1569,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -1582,9 +1581,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -1594,9 +1593,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -1606,9 +1605,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -1618,33 +1617,30 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winnow" -version = "0.4.6" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "037711d82167854aff2018dfd193aa0fef5370f456732f0d5a0c59b0f1b4b907" dependencies = [ "memchr", ] [[package]] name = "xdg" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688597db5a750e9cad4511cb94729a078e274308099a0382b5b8203bbc767fee" -dependencies = [ - "home", -] +checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "xxhash-rust" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" +checksum = "9828b178da53440fa9c766a3d2f73f7cf5d0ac1fe3980c1e5018d899fd19e07b" [[package]] name = "ziggy" @@ -1658,6 +1654,7 @@ dependencies = [ "glob", "honggfuzz", "libafl", + "libafl_bolts", "libafl_targets", "libc", "log", diff --git a/Cargo.toml b/Cargo.toml index e0adaf4..fbc6331 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,12 +25,13 @@ serde_json = { version = "1.0.96", optional = true } log = { version = "0.4.18", optional = true } env_logger = { version = "0.10.0", optional = true } libc = "0.2.145" -libafl = { version = "0.10.1", optional = true } -libafl_targets = { version = "0.10.1", optional = true, features = ["sancov_pcguard_hitcounts"] } +libafl = { version = "0.11.1", optional = true } +libafl_targets = { version = "0.11.1", optional = true, features = ["sancov_pcguard_hitcounts"] } +libafl_bolts = { version = "0.11.1", optional = true } #libafl = { git = "http://github.com/aflplusplus/libafl", optional = true } #libafl_targets = { git = "http://github.com/aflplusplus/libafl", optional = true, features = ["sancov_pcguard_hitcounts"] } [features] default = ["cli"] cli = ["clap", "console", "glob", "toml", "anyhow", "serde_json", "log", "env_logger"] -with_libafl = ["libafl", "libafl_targets"] +with_libafl = ["libafl", "libafl_targets", "libafl_bolts"] diff --git a/examples/url/Cargo.toml b/examples/url/Cargo.toml index 70de68d..528e69e 100644 --- a/examples/url/Cargo.toml +++ b/examples/url/Cargo.toml @@ -6,5 +6,5 @@ edition = "2021" [dependencies] # This git revision has an easy to find crash # url = { git = "https://github.com/servo/rust-url", rev = "bfa167b4e0253642b6766a7aa74a99df60a94048" } -url = "2.3.1" +url = "2.4.1" ziggy = { path = "../../", default-features = false } diff --git a/examples/url/corpus/init b/examples/url/corpus/init deleted file mode 100644 index 25c15ce..0000000 --- a/examples/url/corpus/init +++ /dev/null @@ -1 +0,0 @@ -http://hi.com diff --git a/src/lib.rs b/src/lib.rs index cb4ef36..90c8b1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,8 @@ mod libafl_fuzzer; #[cfg(feature = "with_libafl")] pub use libafl; #[cfg(feature = "with_libafl")] +pub use libafl_bolts; +#[cfg(feature = "with_libafl")] pub use libafl_targets; // This is our inner harness handler function for the runner and for coverage. diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index ae8c192..fa08dc4 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -1,6 +1,129 @@ // To run this fuzzer, execute the following command (for example in `examples/url/`): +// For some reason, using +nightly speeds up the performance quite a lot. // LIBAFL_EDGES_MAP_SIZE=500000 RUSTFLAGS="-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard --cfg fuzzing -Clink-arg=-fuse-ld=gold" cargo run --features=ziggy/with_libafl --target x86_64-unknown-linux-gnu --release +//! In-Memory fuzzing made easy. +//! Use this sugar for scaling `libfuzzer`-style fuzzers. + +#[macro_export] +#[cfg(feature = "with_libafl")] +macro_rules! libafl_fuzz { + + ( $($x:tt)* ) => { + use ziggy::libafl::{ + corpus::{InMemoryCorpus, OnDiskCorpus}, + events::SimpleEventManager, + executors::{inprocess::InProcessExecutor, ExitKind}, + feedbacks::{CrashFeedback, MaxMapFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + generators::RandPrintablesGenerator, + inputs::{BytesInput, HasTargetBytes}, + monitors::SimpleMonitor, + mutators::scheduled::{havoc_mutations, StdScheduledMutator}, + observers::{HitcountsMapObserver, StdMapObserver}, + schedulers::QueueScheduler, + stages::mutational::StdMutationalStage, + state::StdState, + }; + use ziggy::libafl_bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}; + use core::time::Duration; + use std::{env, path::PathBuf, ptr::write}; + use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; + + // The closure that we want to fuzz + let inner_harness = $($x)*; + + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = |input: &BytesInput| { + let target = input.target_bytes(); + let buf = target.as_slice(); + inner_harness(buf); + ExitKind::Ok + }; + + // Create an observation channel using the signals map + // let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) }; + + // Create an observation channel using the coverage map + let observer = unsafe { + HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( + "edges", + EDGES_MAP.as_mut_ptr(), + MAX_EDGES_NUM, + )) + }; + + // Feedback to rate the interestingness of an input + let mut feedback = MaxMapFeedback::new(&observer); + + // A feedback to choose if an input is a solution or not + let mut objective = CrashFeedback::new(); + + // create a State from scratch + let mut state = StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved, we keep it in memory for performance + // InMemoryCorpus::new(), + OnDiskCorpus::new(PathBuf::from("./output/libafl/corpus")).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(PathBuf::from("./output/libafl/crashes")).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap(); + + // The Monitor trait define how the fuzzer stats are displayed to the user + #[cfg(not(feature = "tui"))] + let mon = SimpleMonitor::new(|s| println!("{s}")); + #[cfg(feature = "tui")] + let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); + #[cfg(feature = "tui")] + let mon = TuiMonitor::new(ui); + + // The event manager handle the various events generated during the fuzzing loop + // such as the notification of the addition of a new item to the corpus + let mut mgr = SimpleEventManager::new(mon); + + // A queue policy to get testcasess from the corpus + let scheduler = QueueScheduler::new(); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create the executor for an in-process function with just one observer + let mut executor = InProcessExecutor::new( + &mut harness, + tuple_list!(observer), + &mut fuzzer, + &mut state, + &mut mgr, + ) + .expect("Failed to create the Executor"); + + // Generator of printable bytearrays of max size 32 + let mut generator = RandPrintablesGenerator::new(32); + + // Generate 8 initial inputs + state + .generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8) + .expect("Failed to generate the initial corpus"); + + // Setup a mutational stage with a basic bytes mutator + let mutator = StdScheduledMutator::new(havoc_mutations()); + let mut stages = tuple_list!(StdMutationalStage::new(mutator)); + + fuzzer + .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) + .expect("Error in the fuzzing loop"); + }; +} + +/* #[macro_export] #[cfg(feature = "with_libafl")] macro_rules! libafl_fuzz { @@ -53,7 +176,7 @@ macro_rules! libafl_fuzz { let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); let monitor = TuiMonitor::new(ui); - + //let monitor = SimpleMonitor::new(|_| {}); //let monitor = SimpleMonitor::new(|s| println!("{s}")); @@ -136,7 +259,7 @@ macro_rules! libafl_fuzz { // 10 seconds timeout Duration::new(10, 0), ); - + // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { state @@ -153,3 +276,4 @@ macro_rules! libafl_fuzz { ).unwrap(); }; } +*/ From 16483566d457f2b0644262e8e1cb95cbe14f1e07 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 12 Oct 2023 11:44:19 +0200 Subject: [PATCH 05/28] Add libafl build step --- src/bin/cargo-ziggy/build.rs | 24 ++++++++++++++++++++++++ src/bin/cargo-ziggy/fuzz.rs | 1 + src/bin/cargo-ziggy/main.rs | 8 ++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index 60242a7..e0bcc0b 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -42,6 +42,30 @@ impl Build { eprintln!(" {} afl", style("Finished").cyan().bold()); } + if !self.no_libafl { + eprintln!(" {} libafl", style("Building").red().bold()); + + // Third fuzzer we build: LibAFL + let run = process::Command::new(&cargo) + .args(["build", "--features=ziggy/with_libafl ", "--target=x86_64-unknown-linux-gnu", "--release"]) + .env("CARGO_TARGET_DIR", "./target/libafl") + .env("RUSTFLAGS", "-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard --cfg fuzzing -Clink-arg=-fuse-ld=gold") + .env("LIBAFL_EDGES_MAP_SIZE", "500000") + .stdout(process::Stdio::piped()) + .spawn()? + .wait() + .context("Error spawning hfuzz build command")?; + + if !run.success() { + return Err(anyhow!( + "Error building libafl fuzzer: Exited with {:?}", + run.code() + )); + } + + eprintln!(" {} libafl", style("Finished").cyan().bold()); + } + if !self.no_honggfuzz { eprintln!(" {} honggfuzz", style("Building").red().bold()); diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 1c511cf..8659172 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -58,6 +58,7 @@ impl Fuzz { let build = Build { no_afl: self.no_afl, no_honggfuzz: self.no_honggfuzz, + no_libafl: true, }; build.build().context("Failed to build the fuzzers")?; diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index a1f7c1c..ed14ec2 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -86,11 +86,15 @@ pub enum Ziggy { #[derive(Args)] pub struct Build { - /// No AFL++ (Fuzz only with honggfuzz) + /// No AFL++ #[clap(long = "no-afl", action)] no_afl: bool, - /// No honggfuzz (Fuzz only with AFL++) + /// No LibAFL + #[clap(long = "no-libafl", action)] + no_libafl: bool, + + /// No honggfuzz #[clap(long = "no-honggfuzz", action)] no_honggfuzz: bool, } From 6b05e3c2345ef84acd9340763947928134c2ad5d Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 12 Oct 2023 11:51:28 +0200 Subject: [PATCH 06/28] Run cargo sort --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a8f7c97..cab727e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,9 @@ glob = { version = "0.3.1", optional = true } # We use our own fork of honggfuzz to use the tool's latest release # https://github.com/rust-fuzz/honggfuzz-rs/pull/85 honggfuzz = { package = "ziggy-honggfuzz-2", version = "0.5.55", optional = true } +libafl = { version = "0.11.1", optional = true } +libafl_bolts = { version = "0.11.1", optional = true } +libafl_targets = { version = "0.11.1", optional = true, features = ["sancov_pcguard_hitcounts"] } libc = { version = "0.2.147", optional = true } log = { version = "0.4.20", optional = true } rand = { version = "0.8", optional = true } @@ -31,9 +34,6 @@ serde_json = { version = "1.0.105", optional = true } strip-ansi-escapes = { version = "0.2.0", optional = true } time-humanize = { version = "0.1.3", optional = true } toml = { version = "0.7.6", optional = true } -libafl = { version = "0.11.1", optional = true } -libafl_targets = { version = "0.11.1", optional = true, features = ["sancov_pcguard_hitcounts"] } -libafl_bolts = { version = "0.11.1", optional = true } [features] default = ["cli"] From e6f34055b9b2ee30083279e4a71b0874a2320243 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 12 Oct 2023 12:11:07 +0200 Subject: [PATCH 07/28] Add arbitrary support to libafl, fix tests --- src/lib.rs | 20 ++++++++++++++++++-- src/libafl_fuzzer.rs | 8 ++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 5c52f66..0b48de5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -115,7 +115,23 @@ macro_rules! fuzz { #[macro_export] #[cfg(feature = "with_libafl")] macro_rules! fuzz { - ( $($x:tt)* ) => { - $crate::libafl_fuzz!($($x)*); + (|$buf:ident| $body:block) => { + $crate::libafl_fuzz!(|$buf| $body); + }; + (|$buf:ident: &[u8]| $body:block) => { + $crate::libafl_fuzz!(|$buf| $body); + }; + (|$buf:ident: $dty: ty| $body:block) => { + $crate::libafl_fuzz!(|$buf| { + let $buf: $dty = { + let mut data = ::arbitrary::Unstructured::new($buf); + if let Ok(d) = ::arbitrary::Arbitrary::arbitrary(&mut data).map_err(|_| "") { + d + } else { + return; + } + }; + $body + }); }; } diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index fa08dc4..24c2af8 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -30,20 +30,16 @@ macro_rules! libafl_fuzz { use std::{env, path::PathBuf, ptr::write}; use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; - // The closure that we want to fuzz - let inner_harness = $($x)*; - // The wrapped harness function, calling out to the LLVM-style harness let mut harness = |input: &BytesInput| { let target = input.target_bytes(); let buf = target.as_slice(); + // The closure that we want to fuzz + let inner_harness = $($x)*; inner_harness(buf); ExitKind::Ok }; - // Create an observation channel using the signals map - // let observer = unsafe { StdMapObserver::from_mut_ptr("signals", SIGNALS_PTR, SIGNALS.len()) }; - // Create an observation channel using the coverage map let observer = unsafe { HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( From de23f2f446450df1107bc78724b3bf15b806c881 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 16 Oct 2023 16:09:49 +0200 Subject: [PATCH 08/28] Improve LibAFL fuzzer and add launch command --- examples/arbitrary/src/main.rs | 3 +- src/bin/cargo-ziggy/fuzz.rs | 185 +++++++++++++++++++++--- src/bin/cargo-ziggy/main.rs | 8 +- src/libafl_fuzzer.rs | 253 +++++++++------------------------ 4 files changed, 240 insertions(+), 209 deletions(-) diff --git a/examples/arbitrary/src/main.rs b/examples/arbitrary/src/main.rs index 1377a89..cc5139f 100644 --- a/examples/arbitrary/src/main.rs +++ b/examples/arbitrary/src/main.rs @@ -11,8 +11,7 @@ impl Rgb { #[must_use] pub fn as_hex(&self) -> Hex { let Rgb { r, g, b } = self; - let panic_u8: u8 = 17; - if r == &panic_u8 { + if r == b && *b == 5 + g && g % 128 == 42 { panic!("let the fuzzer find this"); } Hex(format!("{:02X}{:02X}{:02X}", r, g, b)) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 3ef265a..5a70fb2 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -32,6 +32,18 @@ use strip_ansi_escapes::strip_str; /// ``` /// The `all_afl_corpora` directory corresponds to the `output/target_name/afl/**/queue/` directories. +struct FuzzerWeights { + afl: u32, + libafl: u32, + honggfuzz: u32, +} + +const FUZZER_WEIGHTS: FuzzerWeights = FuzzerWeights { + afl: 3, + libafl: 2, + honggfuzz: 1, +}; + impl Fuzz { pub fn corpus(&self) -> String { self.corpus @@ -58,17 +70,25 @@ impl Fuzz { !self.no_afl } + /// Returns true iff LibAFL is enabled + pub fn libafl(&self) -> bool { + !self.no_libafl && (self.no_afl || self.jobs > 1) + } + /// Returns true iff Honggfuzz is enabled pub fn honggfuzz(&self) -> bool { - self.no_afl || (!self.no_honggfuzz && self.jobs > 1) + !self.no_honggfuzz + && ((self.no_afl && self.no_libafl) + || ((self.no_afl || self.no_libafl) && self.jobs > 1) + || (self.jobs > 2)) } // Manages the continuous running of fuzzers pub fn fuzz(&mut self) -> Result<(), anyhow::Error> { let build = Build { no_afl: !self.afl(), + no_libafl: !self.libafl(), no_honggfuzz: !self.honggfuzz(), - no_libafl: true, }; build.build().context("Failed to build the fuzzers")?; @@ -169,7 +189,10 @@ impl Fuzz { self.output_target(), self.target ) - .into()]); + .into()]) + .chain(vec![ + format!("{}/libafl/crashes", self.output_target()).into() + ]); for crash_dir in crash_dirs { if let Ok(crashes) = fs::read_dir(crash_dir) { @@ -222,6 +245,48 @@ impl Fuzz { } } + pub fn compute_job_repartition(&self) -> (u32, u32, u32) { + let afl_weight = if self.afl() { FUZZER_WEIGHTS.afl } else { 0 }; + let libafl_weight = if self.libafl() { + FUZZER_WEIGHTS.libafl + } else { + 0 + }; + let honggfuzz_weight = if self.honggfuzz() { + FUZZER_WEIGHTS.honggfuzz + } else { + 0 + }; + let total_weights = afl_weight + libafl_weight + honggfuzz_weight; + + let mut honggfuzz_jobs = honggfuzz_weight * self.jobs / total_weights; + let mut afl_jobs = afl_weight * self.jobs / total_weights; + let mut libafl_jobs = libafl_weight * self.jobs / total_weights; + + // We adjust the numbers because of potential rounding errors + while honggfuzz_jobs + afl_jobs + libafl_jobs < self.jobs { + if self.honggfuzz() { + honggfuzz_jobs += 1; + } else if self.libafl() { + libafl_jobs += 1; + } else if self.afl() { + afl_jobs += 1; + } + } + + // If Honggfuzz is not the only fuzzer, we will not allow it to get more than 4 parallel jobs. + if honggfuzz_jobs > 4 && (self.afl() || self.libafl()) { + if self.afl() { + afl_jobs += honggfuzz_jobs - 4; + } else if self.libafl() { + libafl_jobs += honggfuzz_jobs - 4; + } + honggfuzz_jobs = 4; + } + + (afl_jobs, libafl_jobs, honggfuzz_jobs) + } + // Spawns new fuzzers pub fn spawn_new_fuzzers(&self) -> Result, anyhow::Error> { // No fuzzers for you @@ -236,21 +301,8 @@ impl Fuzz { // The cargo executable let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); - let (afl_jobs, honggfuzz_jobs) = { - if self.no_afl { - (0, self.jobs) - } else if self.no_honggfuzz { - (self.jobs, 0) - } else { - // we assign roughly 2/3 to AFL++, 1/3 to honggfuzz, however do - // not apply more than 4 jobs to honggfuzz - match self.jobs { - 1 => (1, 0), - 2..=12 => (self.jobs - ((self.jobs + 2) / 3), (self.jobs + 2) / 3), - _ => (self.jobs - 4, 4), - } - } - }; + // We compute the jobs assigned to each fuzzer, according to FUZZER_WEIGHTS + let (afl_jobs, libafl_jobs, honggfuzz_jobs) = self.compute_job_repartition(); if honggfuzz_jobs > 4 { eprintln!("Warning: running more honggfuzz jobs than 4 is not effective"); @@ -387,6 +439,47 @@ impl Fuzz { eprintln!("{} afl ", style(" Launched").green().bold()); } + if libafl_jobs > 0 { + let _ = process::Command::new("mkdir") + .args(["-p", &format!("{}/libafl/logs", self.output_target())]) + .stderr(process::Stdio::piped()) + .spawn()? + .wait()?; + + for identifier in 0..libafl_jobs { + fuzzer_handles.push( + process::Command::new(format!( + "./target/libafl/x86_64-unknown-linux-gnu/release/{}", + self.target + )) + .env("LIBAFL_TARGET_NAME", &self.target) + .env("LIBAFL_IDENTIFIER", &format!("{identifier}")) + .env("LIBAFL_SHARED_CORPUS", self.corpus()) + .env( + "LIBAFL_CORPUS", + &format!("{}/libafl/corpus", self.output_target()), + ) + .env( + "LIBAFL_CRASHES", + &format!("{}/libafl/crashes", self.output_target()), + ) + .stderr(File::create(format!( + "{}/libafl/logs/{identifier}.log", + self.output_target(), + ))?) + .stdout(File::create(format!( + "{}/libafl/logs/{identifier}.log", + self.output_target() + ))?) + .spawn()?, + ); + } + eprintln!( + "{} libafl ", + style(" Launched").green().bold() + ); + } + if honggfuzz_jobs > 0 { let hfuzz_help = process::Command::new(&cargo) .args(["hfuzz", "run", &self.target]) @@ -645,7 +738,13 @@ impl Fuzz { } } - // Second step: Get stats from honggfuzz logs + // Second step: Get stats from libafl + let mut libafl_status = format!("{green}running{reset} ─"); + if !self.libafl() { + libafl_status = format!("{yellow}disabled{reset} "); + } + + // Third step: Get stats from honggfuzz logs let mut hf_status = format!("{green}running{reset} ─"); let mut hf_total_execs = String::new(); let mut hf_threads = String::new(); @@ -722,7 +821,7 @@ impl Fuzz { } } - // Third step: Get global stats + // Fourth step: Get global stats let mut total_run_time = time_humanize::HumanTime::from(self.start_time.elapsed()) .to_text_en( time_humanize::Accuracy::Rough, @@ -732,7 +831,7 @@ impl Fuzz { total_run_time = String::from("..."); } - // Fourth step: Print stats + // Fifth step: Print stats // We start by clearing the screen eprint!("\x1B[1;1H\x1B[2J"); eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}///{reset}───┐"); @@ -753,7 +852,10 @@ impl Fuzz { eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │"); } eprintln!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴────────────────────────────────┬────┘" + "├─ {blue}libafl{reset} {libafl_status:0}────────────────┬──┴────────────────────────────────┬────┘" + ); + eprintln!( + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┼───────────────────────────────────┤" ); if !hf_status.contains("disabled") { eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); @@ -769,6 +871,45 @@ impl Fuzz { } } +#[cfg(test)] +mod tests { + use std::{path::PathBuf, time::Instant}; + #[test] + fn job_repartition_works() { + let mut fuzz = crate::Fuzz { + target: String::new(), + corpus: PathBuf::new(), + initial_corpus: None, + ziggy_output: PathBuf::new(), + jobs: 0, + timeout: None, + minimize: false, + dictionary: None, + max_length: 0, + min_length: 0, + no_afl: false, + no_libafl: false, + no_honggfuzz: false, + start_time: Instant::now(), + }; + for i in 0..1024 { + fuzz.jobs = i; + fuzz.no_afl = i % 7 == 0; + fuzz.no_libafl = i % 11 == 0; + fuzz.no_honggfuzz = i % 5 == 0; + if i % 385 == 0 { + continue; + } + let (afl_jobs, libafl_jobs, honggfuzz_jobs) = fuzz.compute_job_repartition(); + assert_eq!( + afl_jobs + libafl_jobs + honggfuzz_jobs, + fuzz.jobs, + "Jobs total mismatch" + ); + } + } +} + pub fn kill_subprocesses_recursively(pid: &str) -> Result<(), anyhow::Error> { let subprocesses = process::Command::new("pgrep") .arg(&format!("-P{pid}")) diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index ed14ec2..80efa6a 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -141,11 +141,15 @@ pub struct Fuzz { #[clap(short = 'g', long = "minlength", default_value_t = 1)] min_length: u64, - /// No AFL++ (Fuzz only with honggfuzz) + /// No AFL++ #[clap(long = "no-afl", action)] no_afl: bool, - /// No honggfuzz (Fuzz only with AFL++) + /// No LibAFL + #[clap(long = "no-afl", action)] + no_libafl: bool, + + /// No honggfuzz #[clap(long = "no-honggfuzz", action)] no_honggfuzz: bool, diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 24c2af8..cf0c97d 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -11,140 +11,15 @@ macro_rules! libafl_fuzz { ( $($x:tt)* ) => { use ziggy::libafl::{ - corpus::{InMemoryCorpus, OnDiskCorpus}, - events::SimpleEventManager, - executors::{inprocess::InProcessExecutor, ExitKind}, - feedbacks::{CrashFeedback, MaxMapFeedback}, - fuzzer::{Fuzzer, StdFuzzer}, - generators::RandPrintablesGenerator, - inputs::{BytesInput, HasTargetBytes}, - monitors::SimpleMonitor, - mutators::scheduled::{havoc_mutations, StdScheduledMutator}, - observers::{HitcountsMapObserver, StdMapObserver}, - schedulers::QueueScheduler, - stages::mutational::StdMutationalStage, - state::StdState, - }; - use ziggy::libafl_bolts::{current_nanos, rands::StdRand, tuples::tuple_list, AsSlice}; - use core::time::Duration; - use std::{env, path::PathBuf, ptr::write}; - use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; - - // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |input: &BytesInput| { - let target = input.target_bytes(); - let buf = target.as_slice(); - // The closure that we want to fuzz - let inner_harness = $($x)*; - inner_harness(buf); - ExitKind::Ok - }; - - // Create an observation channel using the coverage map - let observer = unsafe { - HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( - "edges", - EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, - )) - }; - - // Feedback to rate the interestingness of an input - let mut feedback = MaxMapFeedback::new(&observer); - - // A feedback to choose if an input is a solution or not - let mut objective = CrashFeedback::new(); - - // create a State from scratch - let mut state = StdState::new( - // RNG - StdRand::with_seed(current_nanos()), - // Corpus that will be evolved, we keep it in memory for performance - // InMemoryCorpus::new(), - OnDiskCorpus::new(PathBuf::from("./output/libafl/corpus")).unwrap(), - // Corpus in which we store solutions (crashes in this example), - // on disk so the user can get them after stopping the fuzzer - OnDiskCorpus::new(PathBuf::from("./output/libafl/crashes")).unwrap(), - // States of the feedbacks. - // The feedbacks can report the data that should persist in the State. - &mut feedback, - // Same for objective feedbacks - &mut objective, - ) - .unwrap(); - - // The Monitor trait define how the fuzzer stats are displayed to the user - #[cfg(not(feature = "tui"))] - let mon = SimpleMonitor::new(|s| println!("{s}")); - #[cfg(feature = "tui")] - let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); - #[cfg(feature = "tui")] - let mon = TuiMonitor::new(ui); - - // The event manager handle the various events generated during the fuzzing loop - // such as the notification of the addition of a new item to the corpus - let mut mgr = SimpleEventManager::new(mon); - - // A queue policy to get testcasess from the corpus - let scheduler = QueueScheduler::new(); - - // A fuzzer with feedbacks and a corpus scheduler - let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); - - // Create the executor for an in-process function with just one observer - let mut executor = InProcessExecutor::new( - &mut harness, - tuple_list!(observer), - &mut fuzzer, - &mut state, - &mut mgr, - ) - .expect("Failed to create the Executor"); - - // Generator of printable bytearrays of max size 32 - let mut generator = RandPrintablesGenerator::new(32); - - // Generate 8 initial inputs - state - .generate_initial_inputs(&mut fuzzer, &mut executor, &mut generator, &mut mgr, 8) - .expect("Failed to generate the initial corpus"); - - // Setup a mutational stage with a basic bytes mutator - let mutator = StdScheduledMutator::new(havoc_mutations()); - let mut stages = tuple_list!(StdMutationalStage::new(mutator)); - - fuzzer - .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) - .expect("Error in the fuzzing loop"); - }; -} - -/* -#[macro_export] -#[cfg(feature = "with_libafl")] -macro_rules! libafl_fuzz { - - ( $($x:tt)* ) => { - - use core::time::Duration; - use std::{env, path::PathBuf, ptr::write}; - - use ziggy::libafl::{ - bolts::{ - current_nanos, - rands::StdRand, - tuples::{tuple_list, Merge}, - AsSlice, - shmem::{unix_shmem, ShMemProvider}, - }, - corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, + corpus::{InMemoryCorpus, OnDiskCorpus, Corpus}, events::{setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager}, executors::{inprocess::InProcessExecutor, InProcessForkExecutor, ExitKind, TimeoutExecutor}, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, + generators::RandPrintablesGenerator, inputs::{BytesInput, HasTargetBytes}, - monitors::{tui::{ui::TuiUI, TuiMonitor}, SimpleMonitor}, + monitors::SimpleMonitor, mutators::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::Tokens, @@ -153,32 +28,31 @@ macro_rules! libafl_fuzz { schedulers::{ powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, }, - stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage}, - state::{HasCorpus, HasMetadata, StdState}, - Error, + stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage}, + state::{HasCorpus, StdState}, }; + use ziggy::libafl_bolts::{current_nanos, rands::StdRand, tuples::{Merge, tuple_list}, AsSlice}; + use core::time::Duration; + use std::{env, path::PathBuf, ptr::write}; use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; - // The closure that we want to fuzz - let inner_harness = $($x)*; + // Environement variables are passed from ziggy to LibAFL + let target_name = env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); + let client_identifier = env::var("LIBAFL_IDENTIFIER").expect("Could not find LIBAFL_IDENTIFIER env variable").parse::().unwrap_or(0); + let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS").expect("Could not find LIBAFL_SHARED_CORPUS env variable").into(); + let libafl_corpus: PathBuf = env::var("LIBAFL_CORPUS").expect("Could not find LIBAFL_CORPUS env variable").into(); + let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES").expect("Could not find LIBAFL_CRASHES env variable").into(); // The wrapped harness function, calling out to the LLVM-style harness let mut harness = |input: &BytesInput| { let target = input.target_bytes(); let buf = target.as_slice(); + // The closure that we want to fuzz + let inner_harness = $($x)*; inner_harness(buf); ExitKind::Ok }; - let ui = TuiUI::with_version(String::from("Baby Fuzzer"), String::from("0.0.1"), false); - let monitor = TuiMonitor::new(ui); - - //let monitor = SimpleMonitor::new(|_| {}); - //let monitor = SimpleMonitor::new(|s| println!("{s}")); - - let objective_dir = PathBuf::from("./crashes"); - let corpus_dirs = &[PathBuf::from("./corpus")]; - // Create an observation channel using the coverage map let edges_observer = unsafe { HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( @@ -191,10 +65,13 @@ macro_rules! libafl_fuzz { // Create an observation channel to keep track of the execution time let time_observer = TimeObserver::new("time"); - let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + // Feedback to rate the interestingness of an input + let mut map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); let calibration = CalibrationStage::new(&map_feedback); + let sync = SyncFromDiskStage::with_from_file(shared_corpus.clone()); + // Feedback to rate the interestingness of an input // This one is composed by two Feedbacks in OR let mut feedback = feedback_or!( @@ -207,54 +84,61 @@ macro_rules! libafl_fuzz { // A feedback to choose if an input is a solution or not let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); - // If not restarting, create a State from scratch + // create a State from scratch let mut state = StdState::new( - // RNG - StdRand::with_seed(current_nanos()), - // Corpus that will be evolved, we keep it in memory for performance - InMemoryCorpus::new(), - // Corpus in which we store solutions (crashes in this example), - // on disk so the user can get them after stopping the fuzzer - OnDiskCorpus::new(objective_dir).unwrap(), - // States of the feedbacks. - // The feedbacks can report the data that should persist in the State. - &mut feedback, - // Same for objective feedbacks - &mut objective, - ) - .unwrap(); + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved + OnDiskCorpus::new(&libafl_corpus).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(&crashes_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap(); - // Setup a basic mutator with a mutational stage - let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + // The Monitor trait define how the fuzzer stats are displayed to the user + let mon = SimpleMonitor::new(|s| println!("{s}")); - let power = StdPowerMutationalStage::new(mutator); + // The event manager handle the various events generated during the fuzzing loop + // such as the notification of the addition of a new item to the corpus + let mut mgr = SimpleEventManager::new(mon); - let mut stages = tuple_list!(calibration, power); + // We derive the strategy from the client identifier (given by ziggy) + let strategy = match client_identifier % 6 { + 0 => PowerSchedule::EXPLORE, + 1 => PowerSchedule::EXPLOIT, + 2 => PowerSchedule::FAST, + 3 => PowerSchedule::COE, + 4 => PowerSchedule::LIN, + _ => PowerSchedule::QUAD, + }; // A minimization+queue policy to get testcasess from the corpus let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule( &mut state, &edges_observer, - Some(PowerSchedule::FAST), + Some(strategy), )); // A fuzzer with feedbacks and a corpus scheduler let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); - let mut mgr = SimpleEventManager::new(monitor); + // Create the executor for an in-process function with just one observer + let mut executor = InProcessExecutor::new( + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + ) + .expect("Failed to create the Executor"); - // Create the executor for an in-process function with one observer for edge coverage and one for the execution time - let mut executor = TimeoutExecutor::new( - InProcessExecutor::new( - &mut harness, - tuple_list!(edges_observer, time_observer), - &mut fuzzer, - &mut state, - &mut mgr, - ).unwrap(), - // 10 seconds timeout - Duration::new(10, 0), - ); + let corpus_dirs = &[libafl_corpus, shared_corpus]; // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { @@ -264,12 +148,15 @@ macro_rules! libafl_fuzz { println!("We imported {} inputs from disk.", state.corpus().count()); } - fuzzer.fuzz_loop( - &mut stages, - &mut executor, - &mut state, - &mut mgr, - ).unwrap(); + // Setup a basic mutator with a mutational stage + let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + + let power = StdPowerMutationalStage::new(mutator); + + let mut stages = tuple_list!(calibration, power, sync); + + fuzzer + .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) + .expect("Error in the fuzzing loop"); }; } -*/ From 4af4de295dec5a81b6cc83e3d9501f4c0cff11fb Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 16 Oct 2023 16:34:49 +0200 Subject: [PATCH 09/28] Fix tests --- src/bin/cargo-ziggy/main.rs | 2 +- tests/arbitrary_fuzz.rs | 4 ++-- tests/url_fuzz.rs | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bin/cargo-ziggy/main.rs b/src/bin/cargo-ziggy/main.rs index 80efa6a..40a9f77 100644 --- a/src/bin/cargo-ziggy/main.rs +++ b/src/bin/cargo-ziggy/main.rs @@ -146,7 +146,7 @@ pub struct Fuzz { no_afl: bool, /// No LibAFL - #[clap(long = "no-afl", action)] + #[clap(long = "no-libafl", action)] no_libafl: bool, /// No honggfuzz diff --git a/tests/arbitrary_fuzz.rs b/tests/arbitrary_fuzz.rs index 5c81286..f642a01 100644 --- a/tests/arbitrary_fuzz.rs +++ b/tests/arbitrary_fuzz.rs @@ -56,11 +56,11 @@ fn integration() { assert!(build_status.success(), "`cargo ziggy build` failed"); - // cargo ziggy fuzz -j 2 -t 5 -o temp_dir + // cargo ziggy fuzz -j 3 -t 5 -o temp_dir let fuzzer = process::Command::new(cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) diff --git a/tests/url_fuzz.rs b/tests/url_fuzz.rs index 2ff51b8..4154fa9 100644 --- a/tests/url_fuzz.rs +++ b/tests/url_fuzz.rs @@ -56,11 +56,11 @@ fn integration() { assert!(build_status.success(), "`cargo ziggy build` failed"); - // cargo ziggy fuzz -j 2 -t 5 + // cargo ziggy fuzz -j 3 -t 5 let fuzzer = process::Command::new(&cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) @@ -86,11 +86,11 @@ fn integration() { .is_dir()); // We resume fuzzing - // cargo ziggy fuzz -j 2 -t 5 + // cargo ziggy fuzz -j 3 -t 5 let fuzzer = process::Command::new(&cargo_ziggy) .arg("ziggy") .arg("fuzz") - .arg("-j2") + .arg("-j3") .arg("-t5") .arg("-G100") .env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display())) From a963ff1226f2d2bfa4327b85baca391f0bcca9a1 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 19 Oct 2023 15:21:44 +0200 Subject: [PATCH 10/28] Improve LibAFL fuzzer --- src/bin/cargo-ziggy/build.rs | 2 +- src/bin/cargo-ziggy/fuzz.rs | 56 ++++--- src/libafl_fuzzer.rs | 274 ++++++++++++++++++++--------------- 3 files changed, 188 insertions(+), 144 deletions(-) diff --git a/src/bin/cargo-ziggy/build.rs b/src/bin/cargo-ziggy/build.rs index e0bcc0b..ced9789 100644 --- a/src/bin/cargo-ziggy/build.rs +++ b/src/bin/cargo-ziggy/build.rs @@ -7,7 +7,7 @@ impl Build { /// Build the fuzzers pub fn build(&self) -> Result<(), anyhow::Error> { // No fuzzers for you - if self.no_afl && self.no_honggfuzz { + if self.no_afl && self.no_honggfuzz && self.no_libafl { return Err(anyhow!("Pick at least one fuzzer")); } diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 5a70fb2..069bc97 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -290,7 +290,7 @@ impl Fuzz { // Spawns new fuzzers pub fn spawn_new_fuzzers(&self) -> Result, anyhow::Error> { // No fuzzers for you - if self.no_afl && self.no_honggfuzz { + if self.no_afl && self.no_honggfuzz && self.no_libafl { return Err(anyhow!("Pick at least one fuzzer")); } @@ -446,34 +446,32 @@ impl Fuzz { .spawn()? .wait()?; - for identifier in 0..libafl_jobs { - fuzzer_handles.push( - process::Command::new(format!( - "./target/libafl/x86_64-unknown-linux-gnu/release/{}", - self.target - )) - .env("LIBAFL_TARGET_NAME", &self.target) - .env("LIBAFL_IDENTIFIER", &format!("{identifier}")) - .env("LIBAFL_SHARED_CORPUS", self.corpus()) - .env( - "LIBAFL_CORPUS", - &format!("{}/libafl/corpus", self.output_target()), - ) - .env( - "LIBAFL_CRASHES", - &format!("{}/libafl/crashes", self.output_target()), - ) - .stderr(File::create(format!( - "{}/libafl/logs/{identifier}.log", - self.output_target(), - ))?) - .stdout(File::create(format!( - "{}/libafl/logs/{identifier}.log", - self.output_target() - ))?) - .spawn()?, - ); - } + fuzzer_handles.push( + process::Command::new(format!( + "./target/libafl/x86_64-unknown-linux-gnu/release/{}", + self.target + )) + .env("LIBAFL_TARGET_NAME", &self.target) + .env("LIBAFL_SHARED_CORPUS", self.corpus()) + .env( + "LIBAFL_CORPUS", + &format!("{}/libafl/corpus", self.output_target()), + ) + .env( + "LIBAFL_CRASHES", + &format!("{}/libafl/crashes", self.output_target()), + ) + .env("LIBAFL_CORES", format!("{libafl_jobs}")) + .stderr(File::create(format!( + "{}/logs/libafl.log", + self.output_target(), + ))?) + .stdout(File::create(format!( + "{}/logs/libafl.log", + self.output_target() + ))?) + .spawn()?, + ); eprintln!( "{} libafl ", style(" Launched").green().bold() diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index cf0c97d..f727052 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -12,7 +12,7 @@ macro_rules! libafl_fuzz { ( $($x:tt)* ) => { use ziggy::libafl::{ corpus::{InMemoryCorpus, OnDiskCorpus, Corpus}, - events::{setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager}, + events::{launcher::Launcher, setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager, LlmpRestartingEventManager}, executors::{inprocess::InProcessExecutor, InProcessForkExecutor, ExitKind, TimeoutExecutor}, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, @@ -30,133 +30,179 @@ macro_rules! libafl_fuzz { }, stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage}, state::{HasCorpus, StdState}, + Error + }; + use ziggy::libafl_bolts::{ + core_affinity::{Cores, CoreId}, current_nanos, rands::StdRand,shmem::{ShMemProvider, StdShMemProvider}, + tuples::{Merge, tuple_list}, AsSlice }; - use ziggy::libafl_bolts::{current_nanos, rands::StdRand, tuples::{Merge, tuple_list}, AsSlice}; use core::time::Duration; - use std::{env, path::PathBuf, ptr::write}; + use std::{env, path::PathBuf, ptr::write, str::FromStr, net::TcpListener}; use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; // Environement variables are passed from ziggy to LibAFL let target_name = env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); - let client_identifier = env::var("LIBAFL_IDENTIFIER").expect("Could not find LIBAFL_IDENTIFIER env variable").parse::().unwrap_or(0); let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS").expect("Could not find LIBAFL_SHARED_CORPUS env variable").into(); let libafl_corpus: PathBuf = env::var("LIBAFL_CORPUS").expect("Could not find LIBAFL_CORPUS env variable").into(); let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES").expect("Could not find LIBAFL_CRASHES env variable").into(); + let num_of_cores = env::var("LIBAFL_CORES").expect("Could not find LIBAFL_CORES env variable").parse::().unwrap_or(1); - // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |input: &BytesInput| { - let target = input.target_bytes(); - let buf = target.as_slice(); - // The closure that we want to fuzz - let inner_harness = $($x)*; - inner_harness(buf); - ExitKind::Ok - }; + let broker_port = TcpListener::bind("127.0.0.1:0").map(|sock| { + let port = sock.local_addr().unwrap().port(); + port + }).expect("Could not bind broker port"); - // Create an observation channel using the coverage map - let edges_observer = unsafe { - HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( - "edges", - EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, - )) - }; - - // Create an observation channel to keep track of the execution time - let time_observer = TimeObserver::new("time"); - - // Feedback to rate the interestingness of an input - let mut map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); - - let calibration = CalibrationStage::new(&map_feedback); - - let sync = SyncFromDiskStage::with_from_file(shared_corpus.clone()); - - // Feedback to rate the interestingness of an input - // This one is composed by two Feedbacks in OR - let mut feedback = feedback_or!( - // New maximization map feedback linked to the edges observer and the feedback state - map_feedback, - // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) - ); - - // A feedback to choose if an input is a solution or not - let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); - - // create a State from scratch - let mut state = StdState::new( - // RNG - StdRand::with_seed(current_nanos()), - // Corpus that will be evolved - OnDiskCorpus::new(&libafl_corpus).unwrap(), - // Corpus in which we store solutions (crashes in this example), - // on disk so the user can get them after stopping the fuzzer - OnDiskCorpus::new(&crashes_dir).unwrap(), - // States of the feedbacks. - // The feedbacks can report the data that should persist in the State. - &mut feedback, - // Same for objective feedbacks - &mut objective, - ) - .unwrap(); + let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); // The Monitor trait define how the fuzzer stats are displayed to the user - let mon = SimpleMonitor::new(|s| println!("{s}")); - - // The event manager handle the various events generated during the fuzzing loop - // such as the notification of the addition of a new item to the corpus - let mut mgr = SimpleEventManager::new(mon); - - // We derive the strategy from the client identifier (given by ziggy) - let strategy = match client_identifier % 6 { - 0 => PowerSchedule::EXPLORE, - 1 => PowerSchedule::EXPLOIT, - 2 => PowerSchedule::FAST, - 3 => PowerSchedule::COE, - 4 => PowerSchedule::LIN, - _ => PowerSchedule::QUAD, + let monitor = SimpleMonitor::new(|s| println!("{s}")); + + /* + // Failed try at affinity + let all_cores: Cores = Cores::all().expect("Could not get all cores"); + let mut num: usize = 0; + let core_ids: Vec = all_cores.ids.iter().filter(|core| { + if num >= num_of_cores { + return false; + } + if core.set_affinity().is_ok() { + num += 1; + return true; + } + return false; + }).cloned().collect(); + */ + + // TODO Change this to not pin on the same cores every time + let cores = Cores::from((0..num_of_cores).collect::>()); + + let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = |input: &BytesInput| { + let target = input.target_bytes(); + let buf = target.as_slice(); + // The closure that we want to fuzz + let inner_harness = $($x)*; + inner_harness(buf); + ExitKind::Ok + }; + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( + "edges", + EDGES_MAP.as_mut_ptr(), + MAX_EDGES_NUM, + )) + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + // Feedback to rate the interestingness of an input + let mut map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + + let calibration = CalibrationStage::new(&map_feedback); + + let sync = SyncFromDiskStage::with_from_file(shared_corpus.clone()); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + map_feedback, + // Time feedback, this one does not need a feedback state + TimeFeedback::with_observer(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // create a State from scratch + let mut state = StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved + OnDiskCorpus::new(&libafl_corpus.clone()).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(&crashes_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .unwrap(); + + // We derive the strategy from the client identifier (given by ziggy) + let strategy = match core_id.0 % 6 { + 0 => PowerSchedule::EXPLORE, + 1 => PowerSchedule::EXPLOIT, + 2 => PowerSchedule::FAST, + 3 => PowerSchedule::COE, + 4 => PowerSchedule::LIN, + _ => PowerSchedule::QUAD, + }; + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule( + &mut state, + &edges_observer, + Some(strategy), + )); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create the executor for an in-process function with just one observer + let mut executor = InProcessExecutor::new( + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + ) + .expect("Failed to create the Executor"); + + let corpus_dirs = &[libafl_corpus.clone(), shared_corpus.clone()]; + + // In case the corpus is empty (on first run), reset + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) + .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // Setup a basic mutator with a mutational stage + let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + + let power = StdPowerMutationalStage::new(mutator); + + let mut stages = tuple_list!(calibration, power, sync); + + fuzzer + .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) + .expect("Error in the fuzzing loop"); + + Ok(()) }; - // A minimization+queue policy to get testcasess from the corpus - let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule( - &mut state, - &edges_observer, - Some(strategy), - )); - - // A fuzzer with feedbacks and a corpus scheduler - let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); - - // Create the executor for an in-process function with just one observer - let mut executor = InProcessExecutor::new( - &mut harness, - tuple_list!(edges_observer, time_observer), - &mut fuzzer, - &mut state, - &mut mgr, - ) - .expect("Failed to create the Executor"); - - let corpus_dirs = &[libafl_corpus, shared_corpus]; - - // In case the corpus is empty (on first run), reset - if state.must_load_initial_inputs() { - state - .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) - .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); - println!("We imported {} inputs from disk.", state.corpus().count()); - } - - // Setup a basic mutator with a mutational stage - let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - - let power = StdPowerMutationalStage::new(mutator); - - let mut stages = tuple_list!(calibration, power, sync); - - fuzzer - .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) - .expect("Error in the fuzzing loop"); + match Launcher::builder() + .shmem_provider(shmem_provider) + .configuration(EventConfig::from_name(&target_name)) + .monitor(monitor) + .run_client(&mut run_client) + .cores(&cores) + .broker_port(broker_port) + .stdout_file(Some("/tmp/libafl.log")) + .build() + .launch() + { + Ok(()) => (), + Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), + Err(e) => panic!("Error in fuzzer: {e}"), + }; }; } From e9673267aef8614903b5bbfb6d03fb50cb327c84 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 23 Oct 2023 15:43:24 +0200 Subject: [PATCH 11/28] Add good core-picking on Linux for LibAFL --- Cargo.lock | 20 ++++++++++++++++++++ Cargo.toml | 3 ++- src/lib.rs | 2 ++ src/libafl_fuzzer.rs | 22 ++++------------------ 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 158ab61..2f93167 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -467,6 +467,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "free-cpus" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64dee16a7db29828f9bce3e5c5b4b441b106bf09260d02a00fdfcaffdf8972a1" +dependencies = [ + "num_cpus", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -845,6 +854,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "num_enum" version = "0.6.1" @@ -1732,6 +1751,7 @@ dependencies = [ "clap", "console", "env_logger", + "free-cpus", "glob", "libafl", "libafl_bolts", diff --git a/Cargo.toml b/Cargo.toml index 07324e2..d0e8397 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ cargo_metadata = { version = "0.18.0", optional = true } clap = { version = "4.4.6", features = ["cargo", "derive", "env"], optional = true } console = { version = "0.15.7", optional = true } env_logger = { version = "0.10.0", optional = true } +free-cpus = { version = "1.0.0", optional = true } glob = { version = "0.3.1", optional = true } # We use our own fork of honggfuzz to use the tool's latest release # https://github.com/rust-fuzz/honggfuzz-rs/pull/85 @@ -52,4 +53,4 @@ cli = [ "time-humanize", "cargo_metadata", ] -with_libafl = ["libafl", "libafl_targets", "libafl_bolts"] +with_libafl = ["libafl", "libafl_targets", "libafl_bolts", "free-cpus"] diff --git a/src/lib.rs b/src/lib.rs index 70f8448..790c4de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,8 @@ pub use honggfuzz::fuzz as honggfuzz_fuzz; #[cfg(feature = "with_libafl")] mod libafl_fuzzer; #[cfg(feature = "with_libafl")] +pub use free_cpus; +#[cfg(feature = "with_libafl")] pub use libafl; #[cfg(feature = "with_libafl")] pub use libafl_bolts; diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index f727052..7dc4a4e 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -36,6 +36,7 @@ macro_rules! libafl_fuzz { core_affinity::{Cores, CoreId}, current_nanos, rands::StdRand,shmem::{ShMemProvider, StdShMemProvider}, tuples::{Merge, tuple_list}, AsSlice }; + use ziggy::free_cpus; use core::time::Duration; use std::{env, path::PathBuf, ptr::write, str::FromStr, net::TcpListener}; use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; @@ -57,24 +58,9 @@ macro_rules! libafl_fuzz { // The Monitor trait define how the fuzzer stats are displayed to the user let monitor = SimpleMonitor::new(|s| println!("{s}")); - /* - // Failed try at affinity - let all_cores: Cores = Cores::all().expect("Could not get all cores"); - let mut num: usize = 0; - let core_ids: Vec = all_cores.ids.iter().filter(|core| { - if num >= num_of_cores { - return false; - } - if core.set_affinity().is_ok() { - num += 1; - return true; - } - return false; - }).cloned().collect(); - */ - - // TODO Change this to not pin on the same cores every time - let cores = Cores::from((0..num_of_cores).collect::>()); + let free_cores: Vec = free_cpus::get().into_iter().collect(); + let mut cores = Cores::from(free_cores); + cores.trim(num_of_cores).expect("Not enough free cores for LibAFL"); let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { // The wrapped harness function, calling out to the LLVM-style harness From df03eb80ae7912636d7d188d698329c3accea71b Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 23 Oct 2023 17:50:20 +0200 Subject: [PATCH 12/28] Upgrade free-cpus --- Cargo.lock | 5 +++-- Cargo.toml | 2 +- src/libafl_fuzzer.rs | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f93167..0a34dad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -469,10 +469,11 @@ dependencies = [ [[package]] name = "free-cpus" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64dee16a7db29828f9bce3e5c5b4b441b106bf09260d02a00fdfcaffdf8972a1" +checksum = "d075faa40bcd39333046862075f62f1493921c47b15a7b13fc283df0192ad239" dependencies = [ + "anyhow", "num_cpus", ] diff --git a/Cargo.toml b/Cargo.toml index d0e8397..e6e652a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ cargo_metadata = { version = "0.18.0", optional = true } clap = { version = "4.4.6", features = ["cargo", "derive", "env"], optional = true } console = { version = "0.15.7", optional = true } env_logger = { version = "0.10.0", optional = true } -free-cpus = { version = "1.0.0", optional = true } +free-cpus = { version = "2.0.0", optional = true } glob = { version = "0.3.1", optional = true } # We use our own fork of honggfuzz to use the tool's latest release # https://github.com/rust-fuzz/honggfuzz-rs/pull/85 diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 7dc4a4e..b4e7345 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -58,7 +58,7 @@ macro_rules! libafl_fuzz { // The Monitor trait define how the fuzzer stats are displayed to the user let monitor = SimpleMonitor::new(|s| println!("{s}")); - let free_cores: Vec = free_cpus::get().into_iter().collect(); + let free_cores: Vec = free_cpus::get().unwrap().into_iter().collect(); let mut cores = Cores::from(free_cores); cores.trim(num_of_cores).expect("Not enough free cores for LibAFL"); @@ -182,6 +182,7 @@ macro_rules! libafl_fuzz { .run_client(&mut run_client) .cores(&cores) .broker_port(broker_port) + // TODO Does this ever output anything? I have not seen it yet. .stdout_file(Some("/tmp/libafl.log")) .build() .launch() From b4c0b741d43aeed54fb7aac61dbe13cfbb328190 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 10:04:17 +0200 Subject: [PATCH 13/28] Add cores fallback for non-linux oses --- src/libafl_fuzzer.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index b4e7345..9793bca 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -58,8 +58,11 @@ macro_rules! libafl_fuzz { // The Monitor trait define how the fuzzer stats are displayed to the user let monitor = SimpleMonitor::new(|s| println!("{s}")); - let free_cores: Vec = free_cpus::get().unwrap().into_iter().collect(); - let mut cores = Cores::from(free_cores); + let maybe_free_cores: Option> = free_cpus::get().map(|cpus| cpus.into_iter().collect()).ok(); + let mut cores = match maybe_free_cores { + Some(free_cores) => Cores::from(free_cores), + None => Cores::all().expect("Could not get all cores"), + }; cores.trim(num_of_cores).expect("Not enough free cores for LibAFL"); let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { From b0513f50bbcf59b43d09da5047f3fc9c4e08fc0c Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 11:07:11 +0200 Subject: [PATCH 14/28] Add shared corpus and stats reporting to LibAFL --- src/bin/cargo-ziggy/fuzz.rs | 54 ++++++++++++++++++++++++++++++------- src/libafl_fuzzer.rs | 5 ++-- 2 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 069bc97..5a2b26a 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -199,9 +199,12 @@ impl Fuzz { for crash_input in crashes.flatten() { let file_name = crash_input.file_name(); let to_path = crash_path.join(&file_name); + let file_name_str = file_name.to_str().unwrap_or_default(); if to_path.exists() || ["", "README.txt", "HONGGFUZZ.REPORT.TXT", "input"] - .contains(&file_name.to_str().unwrap_or_default()) + .contains(&file_name_str) + || file_name_str.contains(".lafl_lock") + || file_name_str.contains(".metadata") { continue; } @@ -453,10 +456,6 @@ impl Fuzz { )) .env("LIBAFL_TARGET_NAME", &self.target) .env("LIBAFL_SHARED_CORPUS", self.corpus()) - .env( - "LIBAFL_CORPUS", - &format!("{}/libafl/corpus", self.output_target()), - ) .env( "LIBAFL_CRASHES", &format!("{}/libafl/crashes", self.output_target()), @@ -738,8 +737,36 @@ impl Fuzz { // Second step: Get stats from libafl let mut libafl_status = format!("{green}running{reset} ─"); + let mut libafl_clients = String::new(); + let mut libafl_speed = String::new(); + let mut libafl_crashes = String::new(); + let mut libafl_total_execs = String::new(); + if !self.libafl() { libafl_status = format!("{yellow}disabled{reset} "); + } else { + let hf_stats_process = process::Command::new("tail") + .args(["-n5", &format!("{}/logs/libafl.log", self.output_target())]) + .output(); + if let Ok(process) = hf_stats_process { + let s = std::str::from_utf8(&process.stdout).unwrap_or_default(); + for raw_line in s.split('\n') { + let stripped_line = strip_str(raw_line); + let line = stripped_line.trim(); + for stat in line.split(", ") { + if let Some(clients) = stat.strip_prefix("clients: ") { + libafl_clients = + format!("{}", clients.parse::().unwrap_or(1) - 1) + } else if let Some(objectives) = stat.strip_prefix("objectives: ") { + libafl_crashes = objectives.to_string(); + } else if let Some(executions) = stat.strip_prefix("executions: ") { + libafl_total_execs = executions.to_string(); + } else if let Some(exec_sec) = stat.strip_prefix("exec/sec: ") { + libafl_speed = exec_sec.to_string(); + } + } + } + } } // Third step: Get stats from honggfuzz logs @@ -850,17 +877,26 @@ impl Fuzz { eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │"); } eprintln!( - "├─ {blue}libafl{reset} {libafl_status:0}────────────────┬──┴────────────────────────────────┬────┘" + "├─ {blue}libafl{reset} {libafl_status:0}───────────────────┼──────────────────────────────────┬──┘" ); + if !libafl_status.contains("disabled") { + eprintln!("│ {gray}clients :{reset} {libafl_clients:17.17} │ │"); + if libafl_crashes == "0" { + eprintln!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {libafl_crashes:17.17} │"); + } else { + eprintln!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {red}{libafl_crashes:17.17}{reset} │"); + } + eprintln!("│ {gray}total execs :{reset} {libafl_total_execs:17.17} │ │"); + } eprintln!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┼───────────────────────────────────┤" + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴────────────────────────────────┬─┘" ); if !hf_status.contains("disabled") { eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); if hf_crashes == "0" { - eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {hf_crashes:17.17} │"); + eprintln!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {hf_crashes:17.17} │"); } else { - eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); + eprintln!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); } eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │{gray}timeouts saved :{reset} {hf_timeouts:17.17} │"); eprintln!("│ │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 9793bca..745a428 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -44,7 +44,6 @@ macro_rules! libafl_fuzz { // Environement variables are passed from ziggy to LibAFL let target_name = env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS").expect("Could not find LIBAFL_SHARED_CORPUS env variable").into(); - let libafl_corpus: PathBuf = env::var("LIBAFL_CORPUS").expect("Could not find LIBAFL_CORPUS env variable").into(); let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES").expect("Could not find LIBAFL_CRASHES env variable").into(); let num_of_cores = env::var("LIBAFL_CORES").expect("Could not find LIBAFL_CORES env variable").parse::().unwrap_or(1); @@ -112,7 +111,7 @@ macro_rules! libafl_fuzz { // RNG StdRand::with_seed(current_nanos()), // Corpus that will be evolved - OnDiskCorpus::new(&libafl_corpus.clone()).unwrap(), + OnDiskCorpus::new(&shared_corpus.clone()).unwrap(), // Corpus in which we store solutions (crashes in this example), // on disk so the user can get them after stopping the fuzzer OnDiskCorpus::new(&crashes_dir).unwrap(), @@ -154,7 +153,7 @@ macro_rules! libafl_fuzz { ) .expect("Failed to create the Executor"); - let corpus_dirs = &[libafl_corpus.clone(), shared_corpus.clone()]; + let corpus_dirs = &[shared_corpus.clone()]; // In case the corpus is empty (on first run), reset if state.must_load_initial_inputs() { From 2295e441719eb1f8a58d32492ec46579cca5aee2 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 14:31:14 +0200 Subject: [PATCH 15/28] Add dictionary to libafl --- src/bin/cargo-ziggy/fuzz.rs | 7 +++++-- src/libafl_fuzzer.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 5a2b26a..e05f71d 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -739,6 +739,7 @@ impl Fuzz { let mut libafl_status = format!("{green}running{reset} ─"); let mut libafl_clients = String::new(); let mut libafl_speed = String::new(); + let mut libafl_coverage = String::new(); let mut libafl_crashes = String::new(); let mut libafl_total_execs = String::new(); @@ -746,7 +747,7 @@ impl Fuzz { libafl_status = format!("{yellow}disabled{reset} "); } else { let hf_stats_process = process::Command::new("tail") - .args(["-n5", &format!("{}/logs/libafl.log", self.output_target())]) + .args(["-n100", &format!("{}/logs/libafl.log", self.output_target())]) .output(); if let Ok(process) = hf_stats_process { let s = std::str::from_utf8(&process.stdout).unwrap_or_default(); @@ -756,13 +757,15 @@ impl Fuzz { for stat in line.split(", ") { if let Some(clients) = stat.strip_prefix("clients: ") { libafl_clients = - format!("{}", clients.parse::().unwrap_or(1) - 1) + format!("{}", clients.parse::().unwrap_or(1).saturating_sub(1).unwrap_or_default()) } else if let Some(objectives) = stat.strip_prefix("objectives: ") { libafl_crashes = objectives.to_string(); } else if let Some(executions) = stat.strip_prefix("executions: ") { libafl_total_execs = executions.to_string(); } else if let Some(exec_sec) = stat.strip_prefix("exec/sec: ") { libafl_speed = exec_sec.to_string(); + } else if let Some(edges) = stat.strip_prefix("edges: ") { + libafl_coverage = edges.to_string(); } } } diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 745a428..c26a7c4 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -19,7 +19,7 @@ macro_rules! libafl_fuzz { fuzzer::{Fuzzer, StdFuzzer}, generators::RandPrintablesGenerator, inputs::{BytesInput, HasTargetBytes}, - monitors::SimpleMonitor, + monitors::MultiMonitor, mutators::{ scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, token_mutations::Tokens, @@ -29,23 +29,25 @@ macro_rules! libafl_fuzz { powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, }, stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage}, - state::{HasCorpus, StdState}, + state::{HasCorpus, StdState, HasMetadata}, Error }; use ziggy::libafl_bolts::{ - core_affinity::{Cores, CoreId}, current_nanos, rands::StdRand,shmem::{ShMemProvider, StdShMemProvider}, - tuples::{Merge, tuple_list}, AsSlice + core_affinity::{Cores, CoreId}, current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider, ShMem}, + tuples::{Merge, tuple_list}, AsSlice, + AsMutSlice }; use ziggy::free_cpus; use core::time::Duration; use std::{env, path::PathBuf, ptr::write, str::FromStr, net::TcpListener}; - use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM}; + use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM, autotokens}; // Environement variables are passed from ziggy to LibAFL let target_name = env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS").expect("Could not find LIBAFL_SHARED_CORPUS env variable").into(); let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES").expect("Could not find LIBAFL_CRASHES env variable").into(); let num_of_cores = env::var("LIBAFL_CORES").expect("Could not find LIBAFL_CORES env variable").parse::().unwrap_or(1); + let dict = env::var("LIBAFL_DICT"); let broker_port = TcpListener::bind("127.0.0.1:0").map(|sock| { let port = sock.local_addr().unwrap().port(); @@ -55,7 +57,7 @@ macro_rules! libafl_fuzz { let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); // The Monitor trait define how the fuzzer stats are displayed to the user - let monitor = SimpleMonitor::new(|s| println!("{s}")); + let monitor = MultiMonitor::new(|s| println!("{s}")); let maybe_free_cores: Option> = free_cpus::get().map(|cpus| cpus.into_iter().collect()).ok(); let mut cores = match maybe_free_cores { @@ -163,6 +165,23 @@ macro_rules! libafl_fuzz { println!("We imported {} inputs from disk.", state.corpus().count()); } + // We load the dictionary + // Attempt to use tokens from libfuzzer dicts + if !state.has_metadata::() { + let mut toks = Tokens::default(); + if let Ok(dictionary) = dict.clone() { + let _ = toks.add_from_file(dictionary); + } + #[cfg(any(target_os = "linux", target_vendor = "apple"))] + { + toks += autotokens()?; + } + + if !toks.is_empty() { + state.add_metadata(toks); + } + } + // Setup a basic mutator with a mutational stage let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); From c073abbed95a8533c190de4393208e73c82813f2 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 14:51:46 +0200 Subject: [PATCH 16/28] Move function, lint code, add LibAFL coverage monitoring --- src/bin/cargo-ziggy/fuzz.rs | 13 ++- src/lib.rs | 2 +- src/libafl_fuzzer.rs | 176 ++++++++++++++++++++---------------- 3 files changed, 108 insertions(+), 83 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index e05f71d..034e290 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -747,7 +747,10 @@ impl Fuzz { libafl_status = format!("{yellow}disabled{reset} "); } else { let hf_stats_process = process::Command::new("tail") - .args(["-n100", &format!("{}/logs/libafl.log", self.output_target())]) + .args([ + "-n100", + &format!("{}/logs/libafl.log", self.output_target()), + ]) .output(); if let Ok(process) = hf_stats_process { let s = std::str::from_utf8(&process.stdout).unwrap_or_default(); @@ -756,8 +759,10 @@ impl Fuzz { let line = stripped_line.trim(); for stat in line.split(", ") { if let Some(clients) = stat.strip_prefix("clients: ") { - libafl_clients = - format!("{}", clients.parse::().unwrap_or(1).saturating_sub(1).unwrap_or_default()) + libafl_clients = format!( + "{}", + clients.parse::().unwrap_or(1).saturating_sub(1) + ) } else if let Some(objectives) = stat.strip_prefix("objectives: ") { libafl_crashes = objectives.to_string(); } else if let Some(executions) = stat.strip_prefix("executions: ") { @@ -883,7 +888,7 @@ impl Fuzz { "├─ {blue}libafl{reset} {libafl_status:0}───────────────────┼──────────────────────────────────┬──┘" ); if !libafl_status.contains("disabled") { - eprintln!("│ {gray}clients :{reset} {libafl_clients:17.17} │ │"); + eprintln!("│ {gray}clients :{reset} {libafl_clients:17.17} │{gray}best coverage :{reset} {libafl_coverage:17.17} │"); if libafl_crashes == "0" { eprintln!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {libafl_crashes:17.17} │"); } else { diff --git a/src/lib.rs b/src/lib.rs index 790c4de..6712d8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ pub use afl::fuzz as afl_fuzz; #[cfg(feature = "honggfuzz")] pub use honggfuzz::fuzz as honggfuzz_fuzz; #[cfg(feature = "with_libafl")] -mod libafl_fuzzer; +pub mod libafl_fuzzer; #[cfg(feature = "with_libafl")] pub use free_cpus; #[cfg(feature = "with_libafl")] diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index c26a7c4..04cff5c 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -8,72 +8,93 @@ #[macro_export] #[cfg(feature = "with_libafl")] macro_rules! libafl_fuzz { - ( $($x:tt)* ) => { - use ziggy::libafl::{ - corpus::{InMemoryCorpus, OnDiskCorpus, Corpus}, - events::{launcher::Launcher, setup_restarting_mgr_std, EventConfig, EventRestarter, SimpleEventManager, LlmpRestartingEventManager}, - executors::{inprocess::InProcessExecutor, InProcessForkExecutor, ExitKind, TimeoutExecutor}, - feedback_or, feedback_or_fast, - feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, - fuzzer::{Fuzzer, StdFuzzer}, - generators::RandPrintablesGenerator, - inputs::{BytesInput, HasTargetBytes}, - monitors::MultiMonitor, - mutators::{ - scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, - token_mutations::Tokens, - }, - observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, - schedulers::{ - powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, - }, - stages::{calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage}, - state::{HasCorpus, StdState, HasMetadata}, - Error - }; - use ziggy::libafl_bolts::{ - core_affinity::{Cores, CoreId}, current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider, ShMem}, - tuples::{Merge, tuple_list}, AsSlice, - AsMutSlice - }; - use ziggy::free_cpus; - use core::time::Duration; - use std::{env, path::PathBuf, ptr::write, str::FromStr, net::TcpListener}; - use ziggy::libafl_targets::{EDGES_MAP, MAX_EDGES_NUM, autotokens}; - - // Environement variables are passed from ziggy to LibAFL - let target_name = env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); - let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS").expect("Could not find LIBAFL_SHARED_CORPUS env variable").into(); - let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES").expect("Could not find LIBAFL_CRASHES env variable").into(); - let num_of_cores = env::var("LIBAFL_CORES").expect("Could not find LIBAFL_CORES env variable").parse::().unwrap_or(1); - let dict = env::var("LIBAFL_DICT"); - - let broker_port = TcpListener::bind("127.0.0.1:0").map(|sock| { + ziggy::libafl_fuzzer::libafl_fuzz($($x)*) + }; +} + +#[cfg(feature = "with_libafl")] +pub fn libafl_fuzz(function: fn(&[u8])) { + use libafl::{ + corpus::{Corpus, OnDiskCorpus}, + events::{launcher::Launcher, EventConfig, LlmpRestartingEventManager}, + executors::{inprocess::InProcessExecutor, ExitKind}, + feedback_or, feedback_or_fast, + feedbacks::{CrashFeedback, MaxMapFeedback, TimeFeedback, TimeoutFeedback}, + fuzzer::{Fuzzer, StdFuzzer}, + inputs::{BytesInput, HasTargetBytes}, + monitors::MultiMonitor, + mutators::{ + scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, + token_mutations::Tokens, + }, + observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, + schedulers::{ + powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, + }, + stages::{ + calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage, + }, + state::{HasCorpus, HasMetadata, StdState}, + Error, + }; + use libafl_bolts::{ + core_affinity::{CoreId, Cores}, + current_nanos, + rands::StdRand, + shmem::{ShMemProvider, StdShMemProvider}, + tuples::{tuple_list, Merge}, + AsSlice, + }; + use libafl_targets::{autotokens, EDGES_MAP, MAX_EDGES_NUM}; + use std::{env, net::TcpListener, path::PathBuf}; + + // Environement variables are passed from ziggy to LibAFL + let target_name = + env::var("LIBAFL_TARGET_NAME").expect("Could not find LIBAFL_TARGET_NAME env variable"); + let shared_corpus: PathBuf = env::var("LIBAFL_SHARED_CORPUS") + .expect("Could not find LIBAFL_SHARED_CORPUS env variable") + .into(); + let crashes_dir: PathBuf = env::var("LIBAFL_CRASHES") + .expect("Could not find LIBAFL_CRASHES env variable") + .into(); + let num_of_cores = env::var("LIBAFL_CORES") + .expect("Could not find LIBAFL_CORES env variable") + .parse::() + .unwrap_or(1); + let dict = env::var("LIBAFL_DICT"); + + let broker_port = TcpListener::bind("127.0.0.1:0") + .map(|sock| { let port = sock.local_addr().unwrap().port(); port - }).expect("Could not bind broker port"); + }) + .expect("Could not bind broker port"); - let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); + let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); - // The Monitor trait define how the fuzzer stats are displayed to the user - let monitor = MultiMonitor::new(|s| println!("{s}")); + // The Monitor trait define how the fuzzer stats are displayed to the user + let monitor = MultiMonitor::new(|s| println!("{s}")); - let maybe_free_cores: Option> = free_cpus::get().map(|cpus| cpus.into_iter().collect()).ok(); - let mut cores = match maybe_free_cores { - Some(free_cores) => Cores::from(free_cores), - None => Cores::all().expect("Could not get all cores"), - }; - cores.trim(num_of_cores).expect("Not enough free cores for LibAFL"); + let maybe_free_cores: Option> = + free_cpus::get().map(|cpus| cpus.into_iter().collect()).ok(); + let mut cores = match maybe_free_cores { + Some(free_cores) => Cores::from(free_cores), + None => Cores::all().expect("Could not get all cores"), + }; + cores + .trim(num_of_cores) + .expect("Not enough free cores for LibAFL"); - let mut run_client = |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { + let mut run_client = + |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |input: &BytesInput| { + let mut harness = |input: &BytesInput| -> ExitKind { let target = input.target_bytes(); let buf = target.as_slice(); // The closure that we want to fuzz - let inner_harness = $($x)*; - inner_harness(buf); + let inner_harness = function; + inner_harness(buf.into()); ExitKind::Ok }; @@ -136,11 +157,9 @@ macro_rules! libafl_fuzz { }; // A minimization+queue policy to get testcasess from the corpus - let scheduler = IndexesLenTimeMinimizerScheduler::new(StdWeightedScheduler::with_schedule( - &mut state, - &edges_observer, - Some(strategy), - )); + let scheduler = IndexesLenTimeMinimizerScheduler::new( + StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(strategy)), + ); // A fuzzer with feedbacks and a corpus scheduler let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); @@ -161,7 +180,9 @@ macro_rules! libafl_fuzz { if state.must_load_initial_inputs() { state .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) - .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); + .unwrap_or_else(|_| { + panic!("Failed to load initial corpus at {:?}", &corpus_dirs) + }); println!("We imported {} inputs from disk.", state.corpus().count()); } @@ -171,7 +192,7 @@ macro_rules! libafl_fuzz { let mut toks = Tokens::default(); if let Ok(dictionary) = dict.clone() { let _ = toks.add_from_file(dictionary); - } + } #[cfg(any(target_os = "linux", target_vendor = "apple"))] { toks += autotokens()?; @@ -196,21 +217,20 @@ macro_rules! libafl_fuzz { Ok(()) }; - match Launcher::builder() - .shmem_provider(shmem_provider) - .configuration(EventConfig::from_name(&target_name)) - .monitor(monitor) - .run_client(&mut run_client) - .cores(&cores) - .broker_port(broker_port) - // TODO Does this ever output anything? I have not seen it yet. - .stdout_file(Some("/tmp/libafl.log")) - .build() - .launch() - { - Ok(()) => (), - Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), - Err(e) => panic!("Error in fuzzer: {e}"), - }; + match Launcher::builder() + .shmem_provider(shmem_provider) + .configuration(EventConfig::from_name(&target_name)) + .monitor(monitor) + .run_client(&mut run_client) + .cores(&cores) + .broker_port(broker_port) + // TODO Does this ever output anything? I have not seen it yet. + .stdout_file(Some("/tmp/libafl.log")) + .build() + .launch() + { + Ok(()) => (), + Err(Error::ShuttingDown) => println!("Fuzzing stopped by user. Good bye."), + Err(e) => panic!("Error in fuzzer: {e}"), }; } From 9dfe715948333ea5cdc616099f7c0fbe188064c5 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 14:52:46 +0200 Subject: [PATCH 17/28] Remove old comments --- src/libafl_fuzzer.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 04cff5c..e433878 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -1,10 +1,3 @@ -// To run this fuzzer, execute the following command (for example in `examples/url/`): -// For some reason, using +nightly speeds up the performance quite a lot. -// LIBAFL_EDGES_MAP_SIZE=500000 RUSTFLAGS="-C passes=sancov-module -C llvm-args=-sanitizer-coverage-level=3 -C llvm-args=-sanitizer-coverage-trace-pc-guard --cfg fuzzing -Clink-arg=-fuse-ld=gold" cargo run --features=ziggy/with_libafl --target x86_64-unknown-linux-gnu --release - -//! In-Memory fuzzing made easy. -//! Use this sugar for scaling `libfuzzer`-style fuzzers. - #[macro_export] #[cfg(feature = "with_libafl")] macro_rules! libafl_fuzz { From 45a6311e026bc9cee9b96095360c572f470f7f9d Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 17:20:27 +0200 Subject: [PATCH 18/28] Misc LibAFL fixes and better clippy checks --- .github/workflows/ci.yml | 1 + src/bin/cargo-ziggy/fuzz.rs | 30 +++++++++++------------ src/lib.rs | 6 ++--- src/libafl_fuzzer.rs | 49 +++++++++++++++---------------------- 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3a5dca..c5aaee7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: run: cargo fmt --check - name: Clippy run: cargo clippy --all-targets -- -D warnings + run: cargo clippy -F with_libafl -- -D warnings build_and_test: name: Rust project - latest runs-on: ubuntu-latest diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 034e290..ede12ac 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -747,28 +747,28 @@ impl Fuzz { libafl_status = format!("{yellow}disabled{reset} "); } else { let hf_stats_process = process::Command::new("tail") - .args([ - "-n100", - &format!("{}/logs/libafl.log", self.output_target()), - ]) + .args(["-n10", &format!("{}/logs/libafl.log", self.output_target())]) .output(); if let Ok(process) = hf_stats_process { let s = std::str::from_utf8(&process.stdout).unwrap_or_default(); for raw_line in s.split('\n') { + let global = raw_line.contains("GLOBAL"); let stripped_line = strip_str(raw_line); let line = stripped_line.trim(); for stat in line.split(", ") { - if let Some(clients) = stat.strip_prefix("clients: ") { - libafl_clients = format!( - "{}", - clients.parse::().unwrap_or(1).saturating_sub(1) - ) - } else if let Some(objectives) = stat.strip_prefix("objectives: ") { - libafl_crashes = objectives.to_string(); - } else if let Some(executions) = stat.strip_prefix("executions: ") { - libafl_total_execs = executions.to_string(); - } else if let Some(exec_sec) = stat.strip_prefix("exec/sec: ") { - libafl_speed = exec_sec.to_string(); + if global { + if let Some(clients) = stat.strip_prefix("clients: ") { + libafl_clients = format!( + "{}", + clients.parse::().unwrap_or(1).saturating_sub(1) + ) + } else if let Some(objectives) = stat.strip_prefix("objectives: ") { + libafl_crashes = objectives.to_string(); + } else if let Some(executions) = stat.strip_prefix("executions: ") { + libafl_total_execs = executions.to_string(); + } else if let Some(exec_sec) = stat.strip_prefix("exec/sec: ") { + libafl_speed = exec_sec.to_string(); + } } else if let Some(edges) = stat.strip_prefix("edges: ") { libafl_coverage = edges.to_string(); } diff --git a/src/lib.rs b/src/lib.rs index 6712d8c..d435b50 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,13 +139,13 @@ macro_rules! fuzz { #[cfg(feature = "with_libafl")] macro_rules! fuzz { (|$buf:ident| $body:block) => { - $crate::libafl_fuzz!(|$buf| $body); + $crate::libafl_fuzzer::libafl_fuzz(|$buf| $body); }; (|$buf:ident: &[u8]| $body:block) => { - $crate::libafl_fuzz!(|$buf| $body); + $crate::libafl_fuzzer::libafl_fuzz(|$buf| $body); }; (|$buf:ident: $dty: ty| $body:block) => { - $crate::libafl_fuzz!(|$buf| { + $crate::libafl_fuzzer::libafl_fuzz(|$buf| { let $buf: $dty = { let mut data = ::arbitrary::Unstructured::new($buf); if let Ok(d) = ::arbitrary::Arbitrary::arbitrary(&mut data).map_err(|_| "") { diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index e433878..59ea4eb 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -1,11 +1,3 @@ -#[macro_export] -#[cfg(feature = "with_libafl")] -macro_rules! libafl_fuzz { - ( $($x:tt)* ) => { - ziggy::libafl_fuzzer::libafl_fuzz($($x)*) - }; -} - #[cfg(feature = "with_libafl")] pub fn libafl_fuzz(function: fn(&[u8])) { use libafl::{ @@ -58,10 +50,7 @@ pub fn libafl_fuzz(function: fn(&[u8])) { let dict = env::var("LIBAFL_DICT"); let broker_port = TcpListener::bind("127.0.0.1:0") - .map(|sock| { - let port = sock.local_addr().unwrap().port(); - port - }) + .map(|sock| sock.local_addr().unwrap().port()) .expect("Could not bind broker port"); let shmem_provider = StdShMemProvider::new().expect("Failed to init shared memory"); @@ -87,7 +76,7 @@ pub fn libafl_fuzz(function: fn(&[u8])) { let buf = target.as_slice(); // The closure that we want to fuzz let inner_harness = function; - inner_harness(buf.into()); + inner_harness(buf); ExitKind::Ok }; @@ -104,7 +93,7 @@ pub fn libafl_fuzz(function: fn(&[u8])) { let time_observer = TimeObserver::new("time"); // Feedback to rate the interestingness of an input - let mut map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); let calibration = CalibrationStage::new(&map_feedback); @@ -123,21 +112,23 @@ pub fn libafl_fuzz(function: fn(&[u8])) { let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); // create a State from scratch - let mut state = StdState::new( - // RNG - StdRand::with_seed(current_nanos()), - // Corpus that will be evolved - OnDiskCorpus::new(&shared_corpus.clone()).unwrap(), - // Corpus in which we store solutions (crashes in this example), - // on disk so the user can get them after stopping the fuzzer - OnDiskCorpus::new(&crashes_dir).unwrap(), - // States of the feedbacks. - // The feedbacks can report the data that should persist in the State. - &mut feedback, - // Same for objective feedbacks - &mut objective, - ) - .unwrap(); + let mut state = state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved + OnDiskCorpus::new(shared_corpus.clone()).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(&crashes_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, + ) + .expect("Failed to create state") + }); // We derive the strategy from the client identifier (given by ziggy) let strategy = match core_id.0 % 6 { From 97f444e414aee5316f7d9892c4dfdfd0adde66c5 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 17:21:29 +0200 Subject: [PATCH 19/28] Fix LibAFL clippy CI --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c5aaee7..05e3add 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,7 @@ jobs: run: cargo fmt --check - name: Clippy run: cargo clippy --all-targets -- -D warnings + - name: Clippy LibAFL fuzzer run: cargo clippy -F with_libafl -- -D warnings build_and_test: name: Rust project - latest From ff49f4d039c8d860789499fab283acd6ebb8f4f7 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 18:12:40 +0200 Subject: [PATCH 20/28] Touch up lightning bolt --- src/bin/cargo-ziggy/fuzz.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index ede12ac..b2861a3 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -867,17 +867,17 @@ impl Fuzz { // Fifth step: Print stats // We start by clearing the screen eprint!("\x1B[1;1H\x1B[2J"); - eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}///{reset}───┐"); + eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}////{reset}──┐"); eprintln!( - "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}//////{reset} │" + "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}///{reset} │" ); - eprintln!("├─ {blue}afl++{reset} {afl_status:0}────────────────────┬────────────────────────────────{blue}/{red}//{reset}──┤"); + eprintln!("├─ {blue}afl++{reset} {afl_status:0}────────────────────┬────────────────────────────────{blue}/{red}///{reset}─┤"); if !afl_status.contains("disabled") { eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │ {gray}best coverage :{reset} {afl_coverage:11.11} {blue}/{red}//{reset} │"); if afl_crashes == "0" { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}//{reset} │"); + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}/{reset} │"); } else { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}//{reset} │"); + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}/{reset} │"); } eprintln!( "│ {gray}total execs :{reset} {afl_total_execs:17.17} │{gray}timeouts saved :{reset} {afl_timeouts:17.17} │" From 9954a79c0f683063bbe0e1a9def8f98c488687c6 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 24 Oct 2023 18:17:10 +0200 Subject: [PATCH 21/28] Change interface symbols --- src/bin/cargo-ziggy/fuzz.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index b2861a3..6e62f22 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -871,7 +871,7 @@ impl Fuzz { eprintln!( "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}///{reset} │" ); - eprintln!("├─ {blue}afl++{reset} {afl_status:0}────────────────────┬────────────────────────────────{blue}/{red}///{reset}─┤"); + eprintln!("├─ {blue}afl++{reset} {afl_status:0}─────────────────────────────────────────────────────{blue}/{red}///{reset}─┤"); if !afl_status.contains("disabled") { eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │ {gray}best coverage :{reset} {afl_coverage:11.11} {blue}/{red}//{reset} │"); if afl_crashes == "0" { @@ -885,7 +885,7 @@ impl Fuzz { eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │"); } eprintln!( - "├─ {blue}libafl{reset} {libafl_status:0}───────────────────┼──────────────────────────────────┬──┘" + "├─ {blue}libafl{reset} {libafl_status:0}──────────────────────────────────────────────────────┬──┘" ); if !libafl_status.contains("disabled") { eprintln!("│ {gray}clients :{reset} {libafl_clients:17.17} │{gray}best coverage :{reset} {libafl_coverage:17.17} │"); @@ -897,7 +897,7 @@ impl Fuzz { eprintln!("│ {gray}total execs :{reset} {libafl_total_execs:17.17} │ │"); } eprintln!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴────────────────────────────────┬─┘" + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────────────────────────────────────────┬─┘" ); if !hf_status.contains("disabled") { eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); @@ -909,7 +909,7 @@ impl Fuzz { eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │{gray}timeouts saved :{reset} {hf_timeouts:17.17} │"); eprintln!("│ │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); } - eprintln!("└──────────────────────────────────┴───────────────────────────────────┘"); + eprintln!("└──────────────────────────────────────────────────────────────────────┘"); } } From 3b47b49ae7a822a0359ffabe3fa597b575cc9c69 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Wed, 25 Oct 2023 12:05:02 +0200 Subject: [PATCH 22/28] Fix screen flickering --- src/bin/cargo-ziggy/fuzz.rs | 52 +++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 6e62f22..ce10f46 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -865,51 +865,53 @@ impl Fuzz { } // Fifth step: Print stats + let mut screen = String::new(); // We start by clearing the screen - eprint!("\x1B[1;1H\x1B[2J"); - eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}////{reset}──┐"); - eprintln!( - "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}///{reset} │" + screen += "\x1B[1;1H\x1B[2J"; + screen += &format!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}////{reset}──┐\n"); + screen += &format!( + "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}///{reset} │\n" ); - eprintln!("├─ {blue}afl++{reset} {afl_status:0}─────────────────────────────────────────────────────{blue}/{red}///{reset}─┤"); + screen += &format!("├─ {blue}afl++{reset} {afl_status:0}─────────────────────────────────────────────────────{blue}/{red}///{reset}─┤\n"); if !afl_status.contains("disabled") { - eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │ {gray}best coverage :{reset} {afl_coverage:11.11} {blue}/{red}//{reset} │"); + screen += &format!("│ {gray}instances :{reset} {afl_instances:17.17} │ {gray}best coverage :{reset} {afl_coverage:11.11} {blue}/{red}//{reset} │\n"); if afl_crashes == "0" { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}/{reset} │"); + screen += &format!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}/{reset} │\n"); } else { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}/{reset} │"); + screen += &format!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}/{reset} │\n"); } - eprintln!( - "│ {gray}total execs :{reset} {afl_total_execs:17.17} │{gray}timeouts saved :{reset} {afl_timeouts:17.17} │" + screen += &format!( + "│ {gray}total execs :{reset} {afl_total_execs:17.17} │{gray}timeouts saved :{reset} {afl_timeouts:17.17} │\n" ); - eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │"); + screen += &format!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │\n"); } - eprintln!( - "├─ {blue}libafl{reset} {libafl_status:0}──────────────────────────────────────────────────────┬──┘" + screen += &format!( + "├─ {blue}libafl{reset} {libafl_status:0}──────────────────────────────────────────────────────┬──┘\n" ); if !libafl_status.contains("disabled") { - eprintln!("│ {gray}clients :{reset} {libafl_clients:17.17} │{gray}best coverage :{reset} {libafl_coverage:17.17} │"); + screen += &format!("│ {gray}clients :{reset} {libafl_clients:17.17} │{gray}best coverage :{reset} {libafl_coverage:17.17} │\n"); if libafl_crashes == "0" { - eprintln!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {libafl_crashes:17.17} │"); + screen += &format!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {libafl_crashes:17.17} │\n"); } else { - eprintln!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {red}{libafl_crashes:17.17}{reset} │"); + screen += &format!("│{gray}cumulative speed :{reset} {libafl_speed:17.17} │{gray}crashes saved :{reset} {red}{libafl_crashes:17.17}{reset} │\n"); } - eprintln!("│ {gray}total execs :{reset} {libafl_total_execs:17.17} │ │"); + screen += &format!("│ {gray}total execs :{reset} {libafl_total_execs:17.17} │ │\n"); } - eprintln!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────────────────────────────────────────┬─┘" + screen += &format!( + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────────────────────────────────────────┬─┘\n" ); if !hf_status.contains("disabled") { - eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); + screen += &format!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │\n"); if hf_crashes == "0" { - eprintln!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {hf_crashes:17.17} │"); + screen += &format!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {hf_crashes:17.17} │\n"); } else { - eprintln!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); + screen += &format!("│{gray}average speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │\n"); } - eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │{gray}timeouts saved :{reset} {hf_timeouts:17.17} │"); - eprintln!("│ │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); + screen += &format!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │{gray}timeouts saved :{reset} {hf_timeouts:17.17} │\n"); + screen += &format!("│ │ {gray}no find for :{reset} {hf_new_finds:17.17} │\n"); } - eprintln!("└──────────────────────────────────────────────────────────────────────┘"); + screen += "└──────────────────────────────────────────────────────────────────────┘"; + eprintln!("{screen}"); } } From fb029c2737c6f4ed3efdd998bcbc8629f7041afc Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 9 Jan 2024 12:25:17 +0100 Subject: [PATCH 23/28] Update libafl --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b98ff76..9888202 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,9 +26,9 @@ glob = { version = "0.3.1", optional = true } # We use our own fork of honggfuzz to use the tool's latest release # https://github.com/rust-fuzz/honggfuzz-rs/pull/85 honggfuzz = { package = "ziggy-honggfuzz-2", version = "0.5.55", optional = true } -libafl = { version = "0.11.1", optional = true } -libafl_bolts = { version = "0.11.1", optional = true } -libafl_targets = { version = "0.11.1", optional = true, features = ["sancov_pcguard_hitcounts"] } +libafl = { version = "0.11.2", optional = true } +libafl_bolts = { version = "0.11.2", optional = true } +libafl_targets = { version = "0.11.2", optional = true, features = ["sancov_pcguard_hitcounts"] } libc = { version = "0.2.147", optional = true } log = { version = "0.4.20", optional = true } rand = { version = "0.8", optional = true } From 2365788bc072d9f8cee9cc26df845e0b98b21565 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 9 Jan 2024 12:38:59 +0100 Subject: [PATCH 24/28] Add core files to gitignore and debug to test --- .gitignore | 4 +++- tests/arbitrary_fuzz.rs | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f315ad9..dd2abc5 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ target/ **/*.rs.bk # MSVC Windows builds of rustc generate these, which store debugging information -*.pdb \ No newline at end of file +*.pdb + +core \ No newline at end of file diff --git a/tests/arbitrary_fuzz.rs b/tests/arbitrary_fuzz.rs index f642a01..7caeff0 100644 --- a/tests/arbitrary_fuzz.rs +++ b/tests/arbitrary_fuzz.rs @@ -72,6 +72,11 @@ fn integration() { thread::sleep(Duration::from_secs(10)); kill_subprocesses_recursively(&format!("{}", fuzzer.id())); + process::Command::new("cat") + .arg(temp_dir_path.join("arbitrary-fuzz").join("logs").join("afl.log")) + .spawn() + .unwrap(); + assert!(temp_dir_path .join("arbitrary-fuzz") .join("afl") From f5183d9961241df8ecd4cac50859d58b166281ae Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 9 Jan 2024 12:40:54 +0100 Subject: [PATCH 25/28] Format file --- tests/arbitrary_fuzz.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/arbitrary_fuzz.rs b/tests/arbitrary_fuzz.rs index 7caeff0..a139a76 100644 --- a/tests/arbitrary_fuzz.rs +++ b/tests/arbitrary_fuzz.rs @@ -73,7 +73,12 @@ fn integration() { kill_subprocesses_recursively(&format!("{}", fuzzer.id())); process::Command::new("cat") - .arg(temp_dir_path.join("arbitrary-fuzz").join("logs").join("afl.log")) + .arg( + temp_dir_path + .join("arbitrary-fuzz") + .join("logs") + .join("afl.log"), + ) .spawn() .unwrap(); From 5387ef94574f3045baffe7ba32326909f1b032ac Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 9 Jan 2024 12:44:46 +0100 Subject: [PATCH 26/28] Fix clippy warning --- src/bin/cargo-ziggy/fuzz.rs | 78 ++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 0e79df6..05282c0 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -919,45 +919,6 @@ impl Fuzz { } } -#[cfg(test)] -mod tests { - use std::{path::PathBuf, time::Instant}; - #[test] - fn job_repartition_works() { - let mut fuzz = crate::Fuzz { - target: String::new(), - corpus: PathBuf::new(), - initial_corpus: None, - ziggy_output: PathBuf::new(), - jobs: 0, - timeout: None, - minimize: false, - dictionary: None, - max_length: 0, - min_length: 0, - no_afl: false, - no_libafl: false, - no_honggfuzz: false, - start_time: Instant::now(), - }; - for i in 0..1024 { - fuzz.jobs = i; - fuzz.no_afl = i % 7 == 0; - fuzz.no_libafl = i % 11 == 0; - fuzz.no_honggfuzz = i % 5 == 0; - if i % 385 == 0 { - continue; - } - let (afl_jobs, libafl_jobs, honggfuzz_jobs) = fuzz.compute_job_repartition(); - assert_eq!( - afl_jobs + libafl_jobs + honggfuzz_jobs, - fuzz.jobs, - "Jobs total mismatch" - ); - } - } -} - pub fn kill_subprocesses_recursively(pid: &str) -> Result<(), anyhow::Error> { let subprocesses = process::Command::new("pgrep") .arg(&format!("-P{pid}")) @@ -1001,3 +962,42 @@ pub fn extract_file_id(file: &Path) -> Option<(u32, String)> { let file_id = str_id.parse::().ok()?; Some((file_id, String::from(file_name))) } + +#[cfg(test)] +mod tests { + use std::{path::PathBuf, time::Instant}; + #[test] + fn job_repartition_works() { + let mut fuzz = crate::Fuzz { + target: String::new(), + corpus: PathBuf::new(), + initial_corpus: None, + ziggy_output: PathBuf::new(), + jobs: 0, + timeout: None, + minimize: false, + dictionary: None, + max_length: 0, + min_length: 0, + no_afl: false, + no_libafl: false, + no_honggfuzz: false, + start_time: Instant::now(), + }; + for i in 0..1024 { + fuzz.jobs = i; + fuzz.no_afl = i % 7 == 0; + fuzz.no_libafl = i % 11 == 0; + fuzz.no_honggfuzz = i % 5 == 0; + if i % 385 == 0 { + continue; + } + let (afl_jobs, libafl_jobs, honggfuzz_jobs) = fuzz.compute_job_repartition(); + assert_eq!( + afl_jobs + libafl_jobs + honggfuzz_jobs, + fuzz.jobs, + "Jobs total mismatch" + ); + } + } +} From e3d65c3df3f3d5df3b86920cedf45fc6dbab750a Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Mon, 18 Nov 2024 16:47:11 +0100 Subject: [PATCH 27/28] Upgrade LibAFL --- Cargo.lock | 633 +++++++++++++----------------------- Cargo.toml | 6 +- src/bin/cargo-ziggy/fuzz.rs | 8 +- src/libafl_fuzzer.rs | 264 +++++++-------- 4 files changed, 375 insertions(+), 536 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee3f6cb..c8862a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,12 +11,6 @@ dependencies = [ "gimli", ] -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - [[package]] name = "adler2" version = "2.0.0" @@ -56,6 +50,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + [[package]] name = "anstream" version = "0.6.18" @@ -128,6 +128,12 @@ dependencies = [ "ziggy", ] +[[package]] +name = "arbitrary-int" +version = "1.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d" + [[package]] name = "asan-fuzz" version = "0.1.0" @@ -150,10 +156,10 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide 0.8.0", + "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -167,32 +173,35 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.68.1" +version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.6.0", + "bitflags", "cexpr", "clang-sys", - "lazy_static", - "lazycell", + "itertools", "log", - "peeking_take_while", "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.87", - "which", + "syn", ] [[package]] -name = "bitflags" +name = "bitbybit" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "fb157f9753a7cddfcf4a4f5fed928fbf4ce1b7b64b6bcc121d7a9f95d698997b" +dependencies = [ + "arbitrary-int", + "proc-macro2", + "quote", + "syn", +] [[package]] name = "bitflags" @@ -200,26 +209,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "c2rust-bitfields" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b43c3f07ab0ef604fa6f595aa46ec2f8a22172c975e186f6f5bf9829a3b72c41" -dependencies = [ - "c2rust-bitfields-derive", -] - -[[package]] -name = "c2rust-bitfields-derive" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3cbc102e2597c9744c8bd8c15915d554300601c91a079430d309816b0912545" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "camino" version = "1.1.9" @@ -252,12 +241,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cassowary" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" - [[package]] name = "cc" version = "1.2.1" @@ -284,6 +267,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "clang-sys" version = "1.8.1" @@ -323,10 +312,10 @@ version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -361,51 +350,42 @@ dependencies = [ ] [[package]] -name = "crossterm" -version = "0.27.0" +name = "const_format" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" dependencies = [ - "bitflags 2.6.0", - "crossterm_winapi", - "libc", - "mio", - "parking_lot", - "signal-hook", - "signal-hook-mio", - "winapi", + "const_format_proc_macros", ] [[package]] -name = "crossterm_winapi" -version = "0.9.1" +name = "const_format_proc_macros" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" dependencies = [ - "winapi", + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] -name = "ctor" -version = "0.2.8" +name = "const_panic" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +checksum = "013b6c2c3a14d678f38cd23994b02da3a1a1b6a5d1eedddfe63a5a5f11b13a81" dependencies = [ - "quote", - "syn 2.0.87", + "typewit", ] [[package]] -name = "dashmap" -version = "5.5.3" +name = "ctor" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ - "cfg-if", - "hashbrown", - "lock_api", - "once_cell", - "parking_lot_core", + "quote", + "syn", ] [[package]] @@ -416,7 +396,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -427,7 +407,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -456,21 +436,12 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", -] - -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys 0.52.0", + "typeid", ] [[package]] @@ -531,15 +502,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash", + "allocator-api2", "serde", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -575,13 +541,13 @@ dependencies = [ [[package]] name = "hostname" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" dependencies = [ + "cfg-if", "libc", - "match_cfg", - "winapi", + "windows 0.52.0", ] [[package]] @@ -699,7 +665,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -723,12 +689,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "indoc" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" - [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -765,23 +725,19 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libafl" -version = "0.11.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a820f5d1bc8e52c719c023bd9b89b93e399cf3164f0a9876391e9d4d2c987c58" +checksum = "f389b9fb070347cb0e62fc7c310f6b4ca134a93975d6bb53653b6bb5a4a3ad5d" dependencies = [ "ahash", + "arbitrary-int", "backtrace", "bincode", - "c2rust-bitfields", - "crossterm", + "bitbybit", + "const_format", + "const_panic", "hashbrown", "libafl_bolts", "libafl_derive", @@ -792,7 +748,6 @@ dependencies = [ "nix", "num-traits", "postcard", - "ratatui", "regex", "rustversion", "serde", @@ -802,14 +757,14 @@ dependencies = [ "typed-builder", "uuid", "wait-timeout", - "windows", + "windows 0.58.0", ] [[package]] name = "libafl_bolts" -version = "0.11.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043cd82830f9df1775d97f53c508cf6b4957c88a973da00e09f1e72219ed07f2" +checksum = "6273d4640897a2e93802e58977803bc7c6ecc76b337457dd134c4f212b060caf" dependencies = [ "ahash", "backtrace", @@ -820,44 +775,49 @@ dependencies = [ "libafl_derive", "libc", "log", - "miniz_oxide 0.7.4", + "mach", + "miniz_oxide", "nix", "num_enum", "postcard", "rand_core", "rustversion", "serde", - "serde_json", "serial_test", + "static_assertions", "tuple_list", "uds", "uuid", - "windows", + "windows 0.58.0", + "windows-result", "xxhash-rust", ] [[package]] name = "libafl_derive" -version = "0.11.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c849878dcc707721a16fd5ec2af449301c1da5e3f31682593d60f5e6ccb7568" +checksum = "d2859c499ffb68ebb4e504ac1cb1199c18b2fb2978dfa85b1f60591115cdbfbc" dependencies = [ + "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] name = "libafl_targets" -version = "0.11.2" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf0ba56577924aa627d7913cfb9de8da62da034ab2d1045aacc142ff422e0bd" +checksum = "769419bf7549eea365ee7a3ef97977ab54e513c1b53fb15969bc97b446cea868" dependencies = [ "bindgen", "cc", + "hashbrown", "libafl", "libafl_bolts", "libc", "log", + "once_cell", "rangemap", "rustversion", "serde", @@ -876,7 +836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -885,12 +845,6 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" -[[package]] -name = "linux-raw-sys" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" - [[package]] name = "litemap" version = "0.7.3" @@ -914,10 +868,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] -name = "match_cfg" -version = "0.1.0" +name = "mach" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] [[package]] name = "memchr" @@ -946,9 +903,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -959,15 +916,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.8.0" @@ -977,29 +925,17 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", -] - [[package]] name = "nix" -version = "0.26.4" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 1.3.2", + "bitflags", "cfg-if", + "cfg_aliases", "libc", "memoffset", - "pin-utils", ] [[package]] @@ -1048,7 +984,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1086,33 +1022,15 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "postcard" version = "1.0.10" @@ -1132,7 +1050,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.87", + "syn", ] [[package]] @@ -1165,30 +1083,13 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" -[[package]] -name = "ratatui" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2e4cd95294a85c3b4446e63ef054eea43e0205b1fd60120c16b74ff7ff96ad" -dependencies = [ - "bitflags 2.6.0", - "cassowary", - "crossterm", - "indoc", - "itertools", - "paste", - "strum", - "unicode-segmentation", - "unicode-width", -] - [[package]] name = "redox_syscall" version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -1241,19 +1142,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - [[package]] name = "rustversion" version = "1.0.18" @@ -1266,12 +1154,27 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "scc" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" +dependencies = [ + "sdd", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sdd" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" + [[package]] name = "semver" version = "1.0.23" @@ -1298,7 +1201,7 @@ checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1315,26 +1218,26 @@ dependencies = [ [[package]] name = "serial_test" -version = "2.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ - "dashmap", - "lazy_static", "log", + "once_cell", "parking_lot", + "scc", "serial_test_derive", ] [[package]] name = "serial_test_derive" -version = "2.0.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1343,36 +1246,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-mio" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" -dependencies = [ - "libc", - "mio", - "signal-hook", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - [[package]] name = "smallvec" version = "1.13.2" @@ -1385,6 +1258,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strip-ansi-escapes" version = "0.2.0" @@ -1400,39 +1279,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.87", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.87" @@ -1452,7 +1298,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1472,7 +1318,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1499,24 +1345,45 @@ checksum = "141fb9f71ee586d956d7d6e4d5a9ef8e946061188520140f7591b668841d502e" [[package]] name = "typed-builder" -version = "0.16.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34085c17941e36627a879208083e25d357243812c30e7d7387c3b954f30ade16" +checksum = "7e14ed59dc8b7b26cacb2a92bad2e8b1f098806063898ab42a3bd121d7d45e75" dependencies = [ "typed-builder-macro", ] [[package]] name = "typed-builder-macro" -version = "0.16.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03ca4cb38206e2bef0700092660bb74d696f808514dae47fa1467cbfe26e96e" +checksum = "560b82d656506509d43abe30e0ba64c56b1953ab3d4fe7ba5902747a7a3cedd5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + +[[package]] +name = "typewit" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + [[package]] name = "uds" version = "0.4.2" @@ -1532,18 +1399,18 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - [[package]] name = "unicode-width" version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "url" version = "2.5.3" @@ -1633,98 +1500,104 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "which" -version = "4.4.2" +name = "windows" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ - "either", - "home", - "once_cell", - "rustix", + "windows-core 0.52.0", + "windows-targets", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows-core 0.58.0", + "windows-targets", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows-core" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets", +] [[package]] -name = "windows" -version = "0.51.1" +name = "windows-implement" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ - "windows-core", - "windows-targets 0.48.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-core" -version = "0.51.1" +name = "windows-interface" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ - "windows-targets 0.48.5", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "windows-sys" -version = "0.48.0" +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-targets 0.48.5", + "windows-targets", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ - "windows-targets 0.52.6", + "windows-result", + "windows-targets", ] [[package]] name = "windows-sys" -version = "0.59.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] -name = "windows-targets" -version = "0.48.5" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-targets", ] [[package]] @@ -1733,46 +1606,28 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -1785,48 +1640,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -1877,7 +1708,7 @@ checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", "synstructure", ] @@ -1898,7 +1729,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -1918,7 +1749,7 @@ checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", "synstructure", ] @@ -1941,7 +1772,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3cfb31f..dc6e7b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,9 +24,9 @@ fork = { version = "0.1.23", optional = true } free-cpus = { version = "2.0.0", optional = true } glob = { version = "0.3.1", optional = true } honggfuzz = { version = "0.5.56", optional = true } -libafl = { version = "0.11.2", optional = true } -libafl_bolts = { version = "0.11.2", optional = true } -libafl_targets = { version = "0.11.2", optional = true, features = ["sancov_pcguard_hitcounts"] } +libafl = { version = "0.14.0", optional = true } +libafl_bolts = { version = "0.14.0", optional = true } +libafl_targets = { version = "0.14.0", optional = true, features = ["sancov_pcguard_hitcounts"] } libc = { version = "0.2.153", optional = true } semver = { version = "1.0.23", optional = true } strip-ansi-escapes = { version = "0.2.0", optional = true } diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 5de749c..15385da 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -88,9 +88,9 @@ impl Fuzz { // If we have "no_afl" and "no_libafl" set then honggfuzz is always enabled true } else if self.no_afl || self.no_libafl { - return !self.no_honggfuzz && self.jobs > 1 + return !self.no_honggfuzz && self.jobs > 1; } else { - return !self.no_honggfuzz && self.jobs > 2 + return !self.no_honggfuzz && self.jobs > 2; } } @@ -100,7 +100,7 @@ impl Fuzz { // Manages the continuous running of fuzzers pub fn fuzz(&mut self) -> Result<(), anyhow::Error> { - if !self.fuzz_binary() { + if !self.fuzz_binary() { let build = Build { no_afl: !self.afl(), no_libafl: !self.libafl(), @@ -586,7 +586,7 @@ impl Fuzz { .env("LIBAFL_SHARED_CORPUS", self.corpus()) .env( "LIBAFL_CRASHES", - &format!("{}/libafl/crashes", self.output_target()), + format!("{}/libafl/crashes", self.output_target()), ) .env("LIBAFL_CORES", format!("{libafl_jobs}")) .stderr(File::create(format!( diff --git a/src/libafl_fuzzer.rs b/src/libafl_fuzzer.rs index 59ea4eb..3adadb0 100644 --- a/src/libafl_fuzzer.rs +++ b/src/libafl_fuzzer.rs @@ -10,18 +10,19 @@ pub fn libafl_fuzz(function: fn(&[u8])) { inputs::{BytesInput, HasTargetBytes}, monitors::MultiMonitor, mutators::{ - scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator}, + havoc_mutations, + scheduled::{tokens_mutations, StdScheduledMutator}, token_mutations::Tokens, }, - observers::{HitcountsMapObserver, StdMapObserver, TimeObserver}, + observers::{CanTrack, HitcountsMapObserver, StdMapObserver, TimeObserver}, schedulers::{ powersched::PowerSchedule, IndexesLenTimeMinimizerScheduler, StdWeightedScheduler, }, stages::{ calibrate::CalibrationStage, power::StdPowerMutationalStage, sync::SyncFromDiskStage, }, - state::{HasCorpus, HasMetadata, StdState}, - Error, + state::{HasCorpus, /*HasMetadata,*/ StdState}, + Error, HasMetadata, }; use libafl_bolts::{ core_affinity::{CoreId, Cores}, @@ -31,7 +32,7 @@ pub fn libafl_fuzz(function: fn(&[u8])) { tuples::{tuple_list, Merge}, AsSlice, }; - use libafl_targets::{autotokens, EDGES_MAP, MAX_EDGES_NUM}; + use libafl_targets::{autotokens, EDGES_MAP, MAX_EDGES_FOUND}; use std::{env, net::TcpListener, path::PathBuf}; // Environement variables are passed from ziggy to LibAFL @@ -68,138 +69,145 @@ pub fn libafl_fuzz(function: fn(&[u8])) { .trim(num_of_cores) .expect("Not enough free cores for LibAFL"); - let mut run_client = - |state: Option<_>, mut mgr: LlmpRestartingEventManager<_, _>, core_id: CoreId| { - // The wrapped harness function, calling out to the LLVM-style harness - let mut harness = |input: &BytesInput| -> ExitKind { - let target = input.target_bytes(); - let buf = target.as_slice(); - // The closure that we want to fuzz - let inner_harness = function; - inner_harness(buf); - ExitKind::Ok - }; - - // Create an observation channel using the coverage map - let edges_observer = unsafe { - HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( - "edges", - EDGES_MAP.as_mut_ptr(), - MAX_EDGES_NUM, - )) - }; - - // Create an observation channel to keep track of the execution time - let time_observer = TimeObserver::new("time"); - - // Feedback to rate the interestingness of an input - let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); - - let calibration = CalibrationStage::new(&map_feedback); - - let sync = SyncFromDiskStage::with_from_file(shared_corpus.clone()); - - // Feedback to rate the interestingness of an input - // This one is composed by two Feedbacks in OR - let mut feedback = feedback_or!( - // New maximization map feedback linked to the edges observer and the feedback state - map_feedback, - // Time feedback, this one does not need a feedback state - TimeFeedback::with_observer(&time_observer) - ); - - // A feedback to choose if an input is a solution or not - let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); - - // create a State from scratch - let mut state = state.unwrap_or_else(|| { - StdState::new( - // RNG - StdRand::with_seed(current_nanos()), - // Corpus that will be evolved - OnDiskCorpus::new(shared_corpus.clone()).unwrap(), - // Corpus in which we store solutions (crashes in this example), - // on disk so the user can get them after stopping the fuzzer - OnDiskCorpus::new(&crashes_dir).unwrap(), - // States of the feedbacks. - // The feedbacks can report the data that should persist in the State. - &mut feedback, - // Same for objective feedbacks - &mut objective, - ) - .expect("Failed to create state") - }); - - // We derive the strategy from the client identifier (given by ziggy) - let strategy = match core_id.0 % 6 { - 0 => PowerSchedule::EXPLORE, - 1 => PowerSchedule::EXPLOIT, - 2 => PowerSchedule::FAST, - 3 => PowerSchedule::COE, - 4 => PowerSchedule::LIN, - _ => PowerSchedule::QUAD, - }; - - // A minimization+queue policy to get testcasess from the corpus - let scheduler = IndexesLenTimeMinimizerScheduler::new( - StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(strategy)), - ); - - // A fuzzer with feedbacks and a corpus scheduler - let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); - - // Create the executor for an in-process function with just one observer - let mut executor = InProcessExecutor::new( - &mut harness, - tuple_list!(edges_observer, time_observer), - &mut fuzzer, - &mut state, - &mut mgr, + let mut run_client = |state: Option<_>, + mut mgr: LlmpRestartingEventManager<_, _, _>, + core_id: CoreId| { + // The wrapped harness function, calling out to the LLVM-style harness + let mut harness = |input: &BytesInput| -> ExitKind { + let target = input.target_bytes(); + let buf = target.as_slice(); + // The closure that we want to fuzz + let inner_harness = function; + inner_harness(buf); + ExitKind::Ok + }; + + // Create an observation channel using the coverage map + let edges_observer = unsafe { + HitcountsMapObserver::new(StdMapObserver::from_mut_ptr( + "edges", + EDGES_MAP.as_mut_ptr(), + MAX_EDGES_FOUND, + )) + .track_indices() + }; + + // Create an observation channel to keep track of the execution time + let time_observer = TimeObserver::new("time"); + + // Feedback to rate the interestingness of an input + // let map_feedback = MaxMapFeedback::tracking(&edges_observer, true, true); + let map_feedback = MaxMapFeedback::new(&edges_observer); + + let calibration = CalibrationStage::new(&map_feedback); + + let sync = SyncFromDiskStage::with_from_file( + vec![shared_corpus.clone()], + std::time::Duration::new(60, 0), + ); + + // Feedback to rate the interestingness of an input + // This one is composed by two Feedbacks in OR + let mut feedback = feedback_or!( + // New maximization map feedback linked to the edges observer and the feedback state + map_feedback, + // Time feedback, this one does not need a feedback state + // TimeFeedback::with_observer(&time_observer) + TimeFeedback::new(&time_observer) + ); + + // A feedback to choose if an input is a solution or not + let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); + + // create a State from scratch + let mut state = state.unwrap_or_else(|| { + StdState::new( + // RNG + StdRand::with_seed(current_nanos()), + // Corpus that will be evolved + OnDiskCorpus::new(shared_corpus.clone()).unwrap(), + // Corpus in which we store solutions (crashes in this example), + // on disk so the user can get them after stopping the fuzzer + OnDiskCorpus::new(&crashes_dir).unwrap(), + // States of the feedbacks. + // The feedbacks can report the data that should persist in the State. + &mut feedback, + // Same for objective feedbacks + &mut objective, ) - .expect("Failed to create the Executor"); - - let corpus_dirs = &[shared_corpus.clone()]; - - // In case the corpus is empty (on first run), reset - if state.must_load_initial_inputs() { - state - .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) - .unwrap_or_else(|_| { - panic!("Failed to load initial corpus at {:?}", &corpus_dirs) - }); - println!("We imported {} inputs from disk.", state.corpus().count()); + .expect("Failed to create state") + }); + + // We derive the strategy from the client identifier (given by ziggy) + let strategy = match core_id.0 % 6 { + 0 => PowerSchedule::explore(), + 1 => PowerSchedule::exploit(), + 2 => PowerSchedule::fast(), + 3 => PowerSchedule::coe(), + 4 => PowerSchedule::lin(), + _ => PowerSchedule::quad(), + }; + + // A minimization+queue policy to get testcasess from the corpus + let scheduler = IndexesLenTimeMinimizerScheduler::new( + &edges_observer, + StdWeightedScheduler::with_schedule(&mut state, &edges_observer, Some(strategy)), + ); + + // A fuzzer with feedbacks and a corpus scheduler + let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); + + // Create the executor for an in-process function with just one observer + let mut executor = InProcessExecutor::new( + &mut harness, + tuple_list!(edges_observer, time_observer), + &mut fuzzer, + &mut state, + &mut mgr, + ) + .expect("Failed to create the Executor"); + + let corpus_dirs = &[shared_corpus.clone()]; + + // In case the corpus is empty (on first run), reset + if state.must_load_initial_inputs() { + state + .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, corpus_dirs) + .unwrap_or_else(|_| panic!("Failed to load initial corpus at {:?}", &corpus_dirs)); + println!("We imported {} inputs from disk.", state.corpus().count()); + } + + // We load the dictionary + // Attempt to use tokens from libfuzzer dicts + if !state.has_metadata::() { + let mut toks = Tokens::default(); + if let Ok(dictionary) = dict.clone() { + let _ = toks.add_from_file(dictionary); + } + #[cfg(any(target_os = "linux", target_vendor = "apple"))] + { + toks += autotokens()?; } - // We load the dictionary - // Attempt to use tokens from libfuzzer dicts - if !state.has_metadata::() { - let mut toks = Tokens::default(); - if let Ok(dictionary) = dict.clone() { - let _ = toks.add_from_file(dictionary); - } - #[cfg(any(target_os = "linux", target_vendor = "apple"))] - { - toks += autotokens()?; - } - - if !toks.is_empty() { - state.add_metadata(toks); - } + if !toks.is_empty() { + state.add_metadata(toks); } + } - // Setup a basic mutator with a mutational stage - let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); + // Setup a basic mutator with a mutational stage + let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations())); - let power = StdPowerMutationalStage::new(mutator); + let power: StdPowerMutationalStage<_, _, BytesInput, _, _> = + StdPowerMutationalStage::new(mutator); - let mut stages = tuple_list!(calibration, power, sync); + let mut stages = tuple_list!(calibration, power, sync); - fuzzer - .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) - .expect("Error in the fuzzing loop"); + fuzzer + .fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr) + .expect("Error in the fuzzing loop"); - Ok(()) - }; + Ok(()) + }; match Launcher::builder() .shmem_provider(shmem_provider) From f065dc002eb645a9e54a84d8c0ec7c507c061b7d Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Tue, 19 Nov 2024 09:33:52 +0100 Subject: [PATCH 28/28] Fix clippy --- src/bin/cargo-ziggy/fuzz.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 15385da..6ad7248 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -1135,6 +1135,14 @@ mod tests { no_libafl: false, no_honggfuzz: false, start_time: Instant::now(), + afl_flags: vec![], + asan: false, + binary: None, + config: crate::FuzzingConfig::Generic, + coverage_interval: 15, + coverage_worker: false, + foreign_sync_dirs: vec![], + release: false, }; for i in 0..1024 { fuzz.jobs = i;