diff --git a/libafl/benches/hash_speeds.rs b/libafl/benches/hash_speeds.rs index 20d22f5748..1e2b016c9f 100644 --- a/libafl/benches/hash_speeds.rs +++ b/libafl/benches/hash_speeds.rs @@ -6,8 +6,8 @@ use std::hash::Hasher; use xxhash_rust::const_xxh3; use xxhash_rust::xxh3; -use libafl::utils::{Rand, StdRand}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use libafl::utils::{Rand, StdRand}; fn criterion_benchmark(c: &mut Criterion) { let mut rand = StdRand::new(0); diff --git a/libafl/src/corpus/mod.rs b/libafl/src/corpus/mod.rs index 126c2b2898..02493aa84b 100644 --- a/libafl/src/corpus/mod.rs +++ b/libafl/src/corpus/mod.rs @@ -3,9 +3,9 @@ pub mod testcase; pub use testcase::Testcase; -use alloc::{vec::Vec}; -use core::{cell::RefCell}; -use serde::{Serialize, Deserialize}; +use alloc::vec::Vec; +use core::cell::RefCell; +use serde::{Deserialize, Serialize}; use crate::{ inputs::Input, @@ -36,36 +36,50 @@ where } pub trait CorpusScheduler { - /// Add an entry to the corpus and return its index - fn on_add(&self, state: &mut S, idx: usize, testcase: &Testcase) -> Result<(), Error> + fn on_add( + &self, + state: &mut S, + idx: usize, + testcase: &Testcase, + ) -> Result<(), Error> where S: HasCorpus + HasRand, C: Corpus, I: Input, - R: Rand + R: Rand, { Ok(()) } /// Replaces the testcase at the given idx - fn on_replace(&self, state: &mut S, idx: usize, testcase: &Testcase) -> Result<(), Error> + fn on_replace( + &self, + state: &mut S, + idx: usize, + testcase: &Testcase, + ) -> Result<(), Error> where S: HasCorpus + HasRand, C: Corpus, I: Input, - R: Rand + R: Rand, { Ok(()) } /// Removes an entry from the corpus, returning it if it was present. - fn on_remove(&self, state: &mut S, idx: usize, testcase: &Option>) -> Result<(), Error> + fn on_remove( + &self, + state: &mut S, + idx: usize, + testcase: &Option>, + ) -> Result<(), Error> where S: HasCorpus + HasRand, C: Corpus, I: Input, - R: Rand + R: Rand, { Ok(()) } @@ -78,9 +92,9 @@ pub trait CorpusScheduler { C: Corpus, I: Input, R: Rand; - } +/* pub struct RandCorpusScheduler {} impl CorpusScheduler for RandCorpusScheduler { @@ -90,7 +104,7 @@ impl CorpusScheduler for RandCorpusScheduler { S: HasCorpus + HasRand, C: Corpus, I: Input, - R: Rand + R: Rand, { if state.corpus().count() == 0 { Err(Error::Empty("No entries in corpus".to_owned())) @@ -101,6 +115,7 @@ impl CorpusScheduler for RandCorpusScheduler { } } } +*/ #[derive(Default, Serialize, Deserialize, Clone, Debug)] #[serde(bound = "I: serde::de::DeserializeOwned")] @@ -115,7 +130,6 @@ impl Corpus for InMemoryCorpus where I: Input, { - /// Returns the number of elements #[inline] fn count(&self) -> usize { diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index fe46d05054..27f6078ab3 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -1,7 +1,7 @@ use crate::bolts::llmp::LlmpSender; use alloc::{string::ToString, vec::Vec}; use core::{marker::PhantomData, time::Duration}; -use serde::{Serialize, de::DeserializeOwned}; +use serde::{de::DeserializeOwned, Serialize}; #[cfg(feature = "std")] use crate::bolts::llmp::LlmpReceiver; @@ -22,7 +22,7 @@ use crate::{ executors::{Executor, HasObservers}, inputs::Input, observers::ObserversTuple, - state::{IfInteresting}, + state::IfInteresting, stats::Stats, Error, }; @@ -258,7 +258,7 @@ where where E: Executor + HasObservers, OT: ObserversTuple, - S: IfInteresting + S: IfInteresting, { match event { Event::NewTestcase { @@ -293,7 +293,7 @@ where } } -impl EventManager for LlmpEventManager +impl EventManager for LlmpEventManager where I: Input, SH: ShMem, @@ -311,15 +311,11 @@ where } } - fn process( - &mut self, - state: &mut S, - executor: &mut E, - ) -> Result + fn process(&mut self, state: &mut S, executor: &mut E) -> Result where E: Executor + HasObservers, OT: ObserversTuple, - S: IfInteresting + S: IfInteresting, { // TODO: Get around local event copy by moving handle_in_client let mut events = vec![]; @@ -348,11 +344,7 @@ where Ok(count) } - fn fire( - &mut self, - _state: &mut S, - event: Event, - ) -> Result<(), Error> { + fn fire(&mut self, _state: &mut S, event: Event) -> Result<(), Error> { let serialized = postcard::to_allocvec(&event)?; self.llmp.send_buf(LLMP_TAG_EVENT_TO_BOTH, &serialized)?; Ok(()) @@ -407,7 +399,7 @@ where sender: LlmpSender, } -impl EventManager for LlmpRestartingEventManager +impl EventManager for LlmpRestartingEventManager where I: Input, SH: ShMem, @@ -421,10 +413,7 @@ where } /// Reset the single page (we reuse it over and over from pos 0), then send the current state to the next runner. - fn on_restart( - &mut self, - state: &mut S, - ) -> Result<(), Error> + fn on_restart(&mut self, state: &mut S) -> Result<(), Error> where S: Serialize, { @@ -435,24 +424,16 @@ where .send_buf(_LLMP_TAG_RESTART, &state_corpus_serialized) } - fn process( - &mut self, - state: &mut S, - executor: &mut E, - ) -> Result + fn process(&mut self, state: &mut S, executor: &mut E) -> Result where E: Executor + HasObservers, OT: ObserversTuple, - S: IfInteresting + S: IfInteresting, { self.llmp_mgr.process(state, executor) } - fn fire( - &mut self, - state: &mut S, - event: Event, - ) -> Result<(), Error> { + fn fire(&mut self, state: &mut S, event: Event) -> Result<(), Error> { // Check if we are going to crash in the event, in which case we store our current state for the next runner self.llmp_mgr.fire(state, event) } @@ -493,13 +474,7 @@ pub fn setup_restarting_mgr( //mgr: &mut LlmpEventManager, stats: ST, broker_port: u16, -) -> Result< - ( - Option, - LlmpRestartingEventManager, - ), - Error, -> +) -> Result<(Option, LlmpRestartingEventManager), Error> where I: Input, S: DeserializeOwned, @@ -562,8 +537,7 @@ where // Restoring from a previous run, deserialize state and corpus. Some((_sender, _tag, msg)) => { println!("Subsequent run. Let's load all data from shmem (received {} bytes from previous instance)", msg.len()); - let (state, mgr): (S, LlmpEventManager) = - deserialize_state_mgr(&msg)?; + let (state, mgr): (S, LlmpEventManager) = deserialize_state_mgr(&msg)?; (Some(state), LlmpRestartingEventManager::new(mgr, sender)) } diff --git a/libafl/src/events/logger.rs b/libafl/src/events/logger.rs index e96f5d3ac0..0a37f9b8f2 100644 --- a/libafl/src/events/logger.rs +++ b/libafl/src/events/logger.rs @@ -1,10 +1,10 @@ use alloc::{string::ToString, vec::Vec}; +use core::marker::PhantomData; #[cfg(feature = "std")] #[cfg(unix)] use crate::{ events::{BrokerEventResult, Event, EventManager}, - executors::{Executor}, inputs::Input, stats::Stats, Error, @@ -12,7 +12,7 @@ use crate::{ /// A simple, single-threaded event manager that just logs #[derive(Clone, Debug)] -pub struct LoggerEventManager +pub struct LoggerEventManager where I: Input, ST: Stats, //CE: CustomEvent, @@ -21,21 +21,15 @@ where stats: ST, /// The events that happened since the last handle_in_broker events: Vec>, + phantom: PhantomData<(E, S)>, } -impl EventManager for LoggerEventManager +impl EventManager for LoggerEventManager where I: Input, ST: Stats, //CE: CustomEvent, { - fn process( - &mut self, - state: &mut S, - _executor: &mut E, - ) -> Result - where - E: Executor - { + fn process(&mut self, state: &mut S, _executor: &mut E) -> Result { let count = self.events.len(); while self.events.len() > 0 { let event = self.events.pop().unwrap(); @@ -44,12 +38,7 @@ where Ok(count) } - fn fire( - &mut self, - _state: &mut S, - event: Event, - ) -> Result<(), Error> - { + fn fire(&mut self, _state: &mut S, event: Event) -> Result<(), Error> { match Self::handle_in_broker(&mut self.stats, &event)? { BrokerEventResult::Forward => self.events.push(event), BrokerEventResult::Handled => (), @@ -58,7 +47,7 @@ where } } -impl LoggerEventManager +impl LoggerEventManager where I: Input, ST: Stats, //TODO CE: CustomEvent, @@ -67,6 +56,7 @@ where Self { stats: stats, events: vec![], + phantom: PhantomData, } } @@ -115,11 +105,7 @@ where } // Handle arriving events in the client - fn handle_in_client( - &mut self, - _state: &mut S, - event: Event, - ) -> Result<(), Error> { + fn handle_in_client(&mut self, _state: &mut S, event: Event) -> Result<(), Error> { match event { _ => Err(Error::Unknown(format!( "Received illegal message that message should not have arrived: {:?}.", diff --git a/libafl/src/events/mod.rs b/libafl/src/events/mod.rs index 1aa4f00440..a1c03ff11f 100644 --- a/libafl/src/events/mod.rs +++ b/libafl/src/events/mod.rs @@ -9,10 +9,7 @@ use core::{fmt, marker::PhantomData, time::Duration}; use serde::{Deserialize, Serialize}; use crate::{ - executors::{Executor}, - inputs::Input, - observers::ObserversTuple, - Error, + executors::Executor, inputs::Input, observers::ObserversTuple, state::IfInteresting, Error, }; /// The log event severity @@ -149,7 +146,7 @@ where /// EventManager is the main communications hub. /// For the "normal" multi-processed mode, you may want to look into `RestartingEventManager` -pub trait EventManager +pub trait EventManager where I: Input, { @@ -158,13 +155,7 @@ where /// Lookup for incoming events and process them. /// Return the number of processes events or an error - fn process( - &mut self, - state: &mut S, - executor: &mut E, - ) -> Result - where - E: Executor; + fn process(&mut self, state: &mut S, executor: &mut E) -> Result; /// Serialize all observers for this type and manager fn serialize_observers(&mut self, observers: &OT) -> Result, Error> @@ -184,10 +175,7 @@ where /// For restarting event managers, implement a way to forward state to their next peers. #[inline] - fn on_restart( - &mut self, - _state: &mut S, - ) -> Result<(), Error> { + fn on_restart(&mut self, _state: &mut S) -> Result<(), Error> { Ok(()) } @@ -196,38 +184,26 @@ where fn await_restart_safe(&mut self) {} /// Send off an event to the broker - fn fire( - &mut self, - state: &mut S, - event: Event, - ) -> Result<(), Error>; + fn fire(&mut self, state: &mut S, event: Event) -> Result<(), Error>; } /// An eventmgr for tests, and as placeholder if you really don't need an event manager. #[derive(Copy, Clone, Debug)] -pub struct NopEventManager { - phantom: PhantomData, +pub struct NopEventManager { + phantom: PhantomData<(E, I, S)>, } -impl EventManager for NopEventManager +impl EventManager for NopEventManager where I: Input, { - fn process( - &mut self, - _state: &mut S, - _executor: &mut E, - ) -> Result + fn process(&mut self, _state: &mut S, _executor: &mut E) -> Result where E: Executor, { Ok(0) } - fn fire( - &mut self, - _state: &mut S, - _event: Event, - ) -> Result<(), Error> { + fn fire(&mut self, _state: &mut S, _event: Event) -> Result<(), Error> { Ok(()) } } diff --git a/libafl/src/fuzzer.rs b/libafl/src/fuzzer.rs index e4d924749d..88f5960c94 100644 --- a/libafl/src/fuzzer.rs +++ b/libafl/src/fuzzer.rs @@ -1,21 +1,20 @@ -use core::{marker::PhantomData}; - use crate::{ - corpus::{CorpusScheduler, Corpus}, + corpus::{Corpus, CorpusScheduler}, events::{Event, EventManager}, - executors::{Executor}, + executors::Executor, inputs::Input, stages::StagesTuple, - state::{HasRand, HasCorpus, HasExecutions}, - utils::{Rand, current_milliseconds, current_time}, - Error + state::{HasCorpus, HasExecutions, HasRand}, + utils::{current_milliseconds, current_time, Rand}, + Error, }; +use core::marker::PhantomData; /// Holds a set of stages pub trait HasStages where ST: StagesTuple, - I: Input + I: Input, { fn stages(&self) -> &ST; @@ -37,12 +36,12 @@ pub trait Fuzzer: HasCorpusScheduler + HasStages where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { fn fuzz_one( - &mut self, - executor: &mut E, + &self, state: &mut S, + executor: &mut E, manager: &mut EM, ) -> Result where @@ -50,9 +49,9 @@ where E: Executor; fn fuzz_loop( - &mut self, - executor: &mut E, + &self, state: &mut S, + executor: &mut E, manager: &mut EM, ) -> Result where @@ -66,18 +65,18 @@ pub struct StdFuzzer where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { scheduler: CS, stages: ST, - phantom: PhantomData + phantom: PhantomData, } impl HasStages for StdFuzzer where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { fn stages(&self) -> &ST { &self.stages @@ -92,7 +91,7 @@ impl HasCorpusScheduler for StdFuzzer where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { fn scheduler(&self) -> &CS { &self.scheduler @@ -107,12 +106,12 @@ impl Fuzzer for StdFuzzer where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { fn fuzz_one( - &mut self, - executor: &mut E, + &self, state: &mut S, + executor: &mut E, manager: &mut EM, ) -> Result where @@ -120,21 +119,21 @@ where E: Executor, S: HasCorpus + HasRand, C: Corpus, - R: Rand + R: Rand, { let idx = self.scheduler().next(state)?; self.stages() - .perform_all(executor, state, manager, idx)?; + .perform_all(self, state, executor, manager, idx)?; manager.process(state, executor)?; Ok(idx) } fn fuzz_loop( - &mut self, - executor: &mut E, + &self, state: &mut S, + executor: &mut E, manager: &mut EM, ) -> Result where @@ -142,11 +141,11 @@ where E: Executor, S: HasCorpus + HasRand + HasExecutions, C: Corpus, - R: Rand + R: Rand, { let mut last = current_milliseconds(); loop { - self.fuzz_one(executor, state, manager)?; + self.fuzz_one(state, executor, manager)?; let cur = current_milliseconds(); if cur - last > 60 * 100 { last = cur; @@ -163,18 +162,17 @@ where } } - impl StdFuzzer where CS: CorpusScheduler, ST: StagesTuple, - I: Input + I: Input, { pub fn new(scheduler: CS, stages: ST) -> Self { Self { scheduler: scheduler, stages: stages, - phantom: PhantomData + phantom: PhantomData, } } } diff --git a/libafl/src/mutators/mutations.rs b/libafl/src/mutators/mutations.rs index 8cd1b52bc0..2813a1ebc8 100644 --- a/libafl/src/mutators/mutations.rs +++ b/libafl/src/mutators/mutations.rs @@ -1,8 +1,8 @@ use crate::{ - inputs::{HasBytesVec, Input}, corpus::Corpus, + inputs::{HasBytesVec, Input}, mutators::*, - state::{HasRand, HasCorpus}, + state::{HasCorpus, HasRand}, utils::Rand, Error, }; @@ -27,21 +27,21 @@ pub enum MutationResult { // TODO maybe the mutator arg is not needed /// The generic function type that identifies mutations -pub type MutationFunction = +pub type MutationFunction = fn(&mut M, &F, &mut S, &mut I) -> Result; -pub trait ComposedByMutations +pub trait ComposedByMutations where I: Input, { /// Get a mutation by index - fn mutation_by_idx(&self, index: usize) -> MutationFunction; + fn mutation_by_idx(&self, index: usize) -> MutationFunction; /// Get the number of mutations fn mutations_count(&self) -> usize; /// Add a mutation - fn add_mutation(&mut self, mutation: MutationFunction); + fn add_mutation(&mut self, mutation: MutationFunction); } /// Mem move in the own vec @@ -87,7 +87,6 @@ fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) { } } - const ARITH_MAX: u64 = 35; const INTERESTING_8: [i8; 9] = [-128, -1, 0, 1, 16, 32, 64, 100, 127]; @@ -125,15 +124,16 @@ const INTERESTING_32: [i32; 27] = [ ]; /// Bitflip mutation for inputs with a bytes vector -pub fn mutation_bitflip( +pub fn mutation_bitflip( _: &mut M, + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result where I: Input + HasBytesVec, S: HasRand, - R: Rand + R: Rand, { if input.bytes().len() == 0 { Ok(MutationResult::Skipped) @@ -147,9 +147,9 @@ where } } -pub fn mutation_byteflip( +pub fn mutation_byteflip( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -170,9 +170,9 @@ where } } -pub fn mutation_byteinc( +pub fn mutation_byteinc( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -194,9 +194,9 @@ where } } -pub fn mutation_bytedec( +pub fn mutation_bytedec( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -218,9 +218,9 @@ where } } -pub fn mutation_byteneg( +pub fn mutation_byteneg( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -241,9 +241,9 @@ where } } -pub fn mutation_byterand( +pub fn mutation_byterand( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -264,9 +264,9 @@ where } } -pub fn mutation_byteadd( +pub fn mutation_byteadd( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -292,9 +292,9 @@ where } } -pub fn mutation_wordadd( +pub fn mutation_wordadd( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -322,9 +322,9 @@ where } } -pub fn mutation_dwordadd( +pub fn mutation_dwordadd( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -352,9 +352,9 @@ where } } -pub fn mutation_qwordadd( +pub fn mutation_qwordadd( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -382,9 +382,9 @@ where } } -pub fn mutation_byteinteresting( +pub fn mutation_byteinteresting( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -406,9 +406,9 @@ where } } -pub fn mutation_wordinteresting( +pub fn mutation_wordinteresting( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -421,7 +421,8 @@ where Ok(MutationResult::Skipped) } else { let idx = state.rand_mut().below(input.bytes().len() as u64 - 1) as usize; - let val = INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16; + let val = + INTERESTING_16[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u16; unsafe { // Moar speed, no bound check let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u16; @@ -435,9 +436,9 @@ where } } -pub fn mutation_dwordinteresting( +pub fn mutation_dwordinteresting( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -450,7 +451,8 @@ where Ok(MutationResult::Skipped) } else { let idx = state.rand_mut().below(input.bytes().len() as u64 - 3) as usize; - let val = INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32; + let val = + INTERESTING_32[state.rand_mut().below(INTERESTING_8.len() as u64) as usize] as u32; unsafe { // Moar speed, no bound check let ptr = input.bytes_mut().get_unchecked_mut(idx) as *mut _ as *mut u32; @@ -464,9 +466,9 @@ where } } -pub fn mutation_bytesdelete( +pub fn mutation_bytesdelete( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -487,9 +489,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesexpand( - // TODO: max_size instead of mutator? +pub fn mutation_bytesexpand( mutator: &mut M, + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -517,8 +519,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesinsert( +pub fn mutation_bytesinsert( mutator: &mut M, + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -549,9 +552,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesrandinsert( +pub fn mutation_bytesrandinsert( mutator: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -582,9 +585,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesset( +pub fn mutation_bytesset( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -607,9 +610,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesrandset( +pub fn mutation_bytesrandset( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -632,9 +635,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytescopy( +pub fn mutation_bytescopy( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -657,9 +660,9 @@ where Ok(MutationResult::Mutated) } -pub fn mutation_bytesswap( +pub fn mutation_bytesswap( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -685,8 +688,9 @@ where } /// Crossover insert mutation -pub fn mutation_crossover_insert( +pub fn mutation_crossover_insert( mutator: &mut M, + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -733,9 +737,9 @@ where } /// Crossover replace mutation -pub fn mutation_crossover_replace( +pub fn mutation_crossover_replace( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -787,9 +791,9 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) { } /// Splicing mutation from AFL -pub fn mutation_splice( +pub fn mutation_splice( _: &mut M, - + fuzzer: &F, state: &mut S, input: &mut I, ) -> Result @@ -821,7 +825,9 @@ where counter += 1; }; - let split_at = state.rand_mut().between(first_diff as u64, last_diff as u64) as usize; + let split_at = state + .rand_mut() + .between(first_diff as u64, last_diff as u64) as usize; input .bytes_mut() .splice(split_at.., other.bytes()[split_at..].iter().cloned()); @@ -1056,4 +1062,4 @@ token2="B" */ } } -*/ \ No newline at end of file +*/ diff --git a/libafl/src/mutators/scheduled.rs b/libafl/src/mutators/scheduled.rs index b962da9f98..a40e84329e 100644 --- a/libafl/src/mutators/scheduled.rs +++ b/libafl/src/mutators/scheduled.rs @@ -1,13 +1,13 @@ use crate::inputs::HasBytesVec; use alloc::vec::Vec; -use core::{fmt, default::Default, marker::PhantomData}; +use core::{default::Default, fmt, marker::PhantomData}; use fmt::Debug; use crate::{ - inputs::{Input}, - mutators::{Mutator, HasMaxSize, DEFAULT_MAX_SIZE}, - state::{HasRand, HasCorpus, HasMetadata}, corpus::Corpus, + inputs::Input, + mutators::{HasMaxSize, Mutator, DEFAULT_MAX_SIZE}, + state::{HasCorpus, HasMetadata, HasRand}, utils::Rand, Error, }; @@ -15,7 +15,7 @@ use crate::{ pub use crate::mutators::mutations::*; pub use crate::mutators::token_mutations::*; -pub trait ScheduledMutator: Mutator + ComposedByMutations +pub trait ScheduledMutator: Mutator + ComposedByMutations where I: Input, { @@ -34,7 +34,7 @@ where /// New default implementation for mutate /// Implementations must forward mutate() to this method - fn scheduled_mutate( + fn scheduled_mutate( &mut self, fuzzer: &F, state: &mut S, @@ -44,27 +44,24 @@ where let num = self.iterations(state, input); for _ in 0..num { let idx = self.schedule(self.mutations_count(), state, input); - self.mutation_by_idx(idx)(self, state, input)?; + self.mutation_by_idx(idx)(self, fuzzer, state, input)?; } Ok(()) } } #[derive(Clone)] -pub struct StdScheduledMutator +pub struct StdScheduledMutator where -I: Input, -R: Rand, -S: HasRand,{ - mutations: Vec>, + I: Input, +{ + mutations: Vec>, max_size: usize, } -impl Debug for StdScheduledMutator +impl Debug for StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( @@ -77,31 +74,27 @@ where } } -impl Mutator for StdScheduledMutator +impl Mutator for StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { fn mutate( &mut self, - rand: &mut R, + fuzzer: &F, state: &mut S, input: &mut I, _stage_idx: i32, ) -> Result<(), Error> { - self.scheduled_mutate(state, input, _stage_idx) + self.scheduled_mutate(fuzzer, state, input, _stage_idx) } } -impl ComposedByMutations for StdScheduledMutator +impl ComposedByMutations for StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { #[inline] - fn mutation_by_idx(&self, index: usize) -> MutationFunction { + fn mutation_by_idx(&self, index: usize) -> MutationFunction { self.mutations[index] } @@ -111,25 +104,21 @@ where } #[inline] - fn add_mutation(&mut self, mutation: MutationFunction) { + fn add_mutation(&mut self, mutation: MutationFunction) { self.mutations.push(mutation) } } -impl ScheduledMutator for StdScheduledMutator +impl ScheduledMutator for StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { // Just use the default methods } -impl HasMaxSize for StdScheduledMutator +impl HasMaxSize for StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { #[inline] fn max_size(&self) -> usize { @@ -142,11 +131,9 @@ where } } -impl StdScheduledMutator +impl StdScheduledMutator where I: Input, - R: Rand, - S: HasRand, { /// Create a new StdScheduledMutator instance without mutations and corpus pub fn new() -> Self { @@ -157,7 +144,7 @@ where } /// Create a new StdScheduledMutator instance specifying mutations - pub fn with_mutations(mutations: Vec>) -> Self { + pub fn with_mutations(mutations: Vec>) -> Self { StdScheduledMutator { mutations: mutations, max_size: DEFAULT_MAX_SIZE, @@ -167,21 +154,21 @@ where /// Schedule some selected byte level mutations given a ScheduledMutator type #[derive(Clone, Debug)] -pub struct HavocBytesMutator +pub struct HavocBytesMutator where - SM: ScheduledMutator + HasMaxSize, + SM: ScheduledMutator + HasMaxSize, I: Input + HasBytesVec, S: HasRand + HasCorpus + HasMetadata, C: Corpus, R: Rand, { scheduled: SM, - phantom: PhantomData<(C, I, R, S)>, + phantom: PhantomData<(C, F, I, R, S)>, } -impl Mutator for HavocBytesMutator +impl Mutator for HavocBytesMutator where - SM: ScheduledMutator + HasMaxSize, + SM: ScheduledMutator + HasMaxSize, I: Input + HasBytesVec, S: HasRand + HasCorpus + HasMetadata, C: Corpus, @@ -190,12 +177,12 @@ where /// Mutate bytes fn mutate( &mut self, - rand: &mut R, + fuzzer: &mut F, state: &mut S, input: &mut I, stage_idx: i32, ) -> Result<(), Error> { - self.scheduled.mutate(state, input, stage_idx)?; + self.scheduled.mutate(fuzzer, state, input, stage_idx)?; /*let num = self.scheduled.iterations(state, input); for _ in 0..num { let idx = self.scheduled.schedule(14, state, input); @@ -221,9 +208,9 @@ where } } -impl HasMaxSize for HavocBytesMutator +impl HasMaxSize for HavocBytesMutator where - SM: ScheduledMutator + HasMaxSize, + SM: ScheduledMutator + HasMaxSize, I: Input + HasBytesVec, S: HasRand + HasCorpus + HasMetadata, C: Corpus, @@ -240,9 +227,9 @@ where } } -impl HavocBytesMutator +impl HavocBytesMutator where - SM: ScheduledMutator + HasMaxSize, + SM: ScheduledMutator + HasMaxSize, I: Input + HasBytesVec, S: HasRand + HasCorpus + HasMetadata, C: Corpus, @@ -259,7 +246,7 @@ where } } -impl Default for HavocBytesMutator> +impl Default for HavocBytesMutator> where I: Input + HasBytesVec, S: HasRand + HasCorpus + HasMetadata, @@ -268,7 +255,7 @@ where { /// Create a new HavocBytesMutator instance wrapping StdScheduledMutator fn default() -> Self { - let mut scheduled = StdScheduledMutator::::new(); + let mut scheduled = StdScheduledMutator::::new(); scheduled.add_mutation(mutation_bitflip); scheduled.add_mutation(mutation_byteflip); scheduled.add_mutation(mutation_byteinc); @@ -384,4 +371,4 @@ mod tests { } } } -*/ \ No newline at end of file +*/ diff --git a/libafl/src/stages/mod.rs b/libafl/src/stages/mod.rs index 940b7d7c71..35db374be4 100644 --- a/libafl/src/stages/mod.rs +++ b/libafl/src/stages/mod.rs @@ -2,90 +2,64 @@ pub mod mutational; pub use mutational::StdMutationalStage; use crate::{ - bolts::tuples::TupleList, - corpus::Corpus, - events::EventManager, - executors::{Executor}, - inputs::Input, - Error, + bolts::tuples::TupleList, corpus::Corpus, events::EventManager, executors::Executor, + inputs::Input, Error, }; /// A stage is one step in the fuzzing process. /// Multiple stages will be scheduled one by one for each input. -pub trait Stage -where - I: Input -{ +pub trait Stage { /// Run the stage - fn perform( + fn perform( &self, fuzzer: &F, state: &mut S, executor: &mut E, manager: &mut EM, corpus_idx: usize, - ) -> Result<(), Error> - where - EM: EventManager, - E: Executor; + ) -> Result<(), Error>; } -pub trait StagesTuple -where - I: Input -{ - fn perform_all( +pub trait StagesTuple { + fn perform_all( &self, fuzzer: &F, state: &mut S, executor: &mut E, manager: &mut EM, corpus_idx: usize, - ) -> Result<(), Error> - where - EM: EventManager, - E: Executor; + ) -> Result<(), Error>; } -impl StagesTuple for () -where - I: Input -{ - fn perform_all( +impl StagesTuple for () { + fn perform_all( &self, fuzzer: &F, state: &mut S, executor: &mut E, manager: &mut EM, corpus_idx: usize, - ) -> Result<(), Error> - where - EM: EventManager, - E: Executor - { + ) -> Result<(), Error> { Ok(()) } } -impl StagesTuple for (Head, Tail) +impl StagesTuple for (Head, Tail) where - Head: Stage, - Tail: StagesTuple + TupleList, - I: Input + Head: Stage, + Tail: StagesTuple + TupleList, { - fn perform_all( + fn perform_all( &self, fuzzer: &F, state: &mut S, executor: &mut E, manager: &mut EM, corpus_idx: usize, - ) -> Result<(), Error> - where - EM: EventManager, - E: Executor - { - self.0.perform(fuzzer, state, executor, manager, corpus_idx)?; - self.1 .perform_all(fuzzer, state, executor, manager, corpus_idx) + ) -> Result<(), Error> { + self.0 + .perform(fuzzer, state, executor, manager, corpus_idx)?; + self.1 + .perform_all(fuzzer, state, executor, manager, corpus_idx) } } diff --git a/libafl/src/stages/mutational.rs b/libafl/src/stages/mutational.rs index c45574446d..89e08e8a9d 100644 --- a/libafl/src/stages/mutational.rs +++ b/libafl/src/stages/mutational.rs @@ -2,14 +2,14 @@ use core::marker::PhantomData; use crate::{ events::EventManager, - executors::{Executor}, + executors::Executor, inputs::Input, mutators::Mutator, stages::Corpus, stages::Stage, - state::{HasRand}, + state::HasRand, + state::{Evaluator, HasCorpus}, utils::Rand, - state::{HasCorpus, Evaluator}, Error, }; @@ -45,7 +45,7 @@ where EM: EventManager, E: Executor, S: HasCorpus + Evaluator, - C: Corpus + C: Corpus, { let num = self.iterations(state); for i in 0..num { @@ -56,11 +56,12 @@ where .load_input()? .clone(); self.mutator_mut() - .mutate(state, &mut input_mut, i as i32)?; + .mutate(fuzzer, state, &mut input_mut, i as i32)?; let fitness = state.evaluate_input(input_mut, executor, manager)?; - self.mutator_mut().post_exec(state, fitness, i as i32)?; + self.mutator_mut() + .post_exec(fuzzer, state, fitness, i as i32)?; } Ok(()) } @@ -100,7 +101,7 @@ where fn iterations(&mut self, state: &mut S) -> usize where S: HasRand, - R: Rand + R: Rand, { 1 + state.rand_mut().below(DEFAULT_MUTATIONAL_MAX_ITERATIONS) as usize } @@ -124,7 +125,7 @@ where EM: EventManager, E: Executor, S: HasCorpus + Evaluator, - C: Corpus + C: Corpus, { self.perform_mutational(fuzzer, state, executor, manager, corpus_idx) } diff --git a/libafl/src/state/mod.rs b/libafl/src/state/mod.rs index bcfe3d11e7..0b11d67ade 100644 --- a/libafl/src/state/mod.rs +++ b/libafl/src/state/mod.rs @@ -17,7 +17,7 @@ use crate::{ generators::Generator, inputs::Input, observers::ObserversTuple, - utils::{current_milliseconds, Rand}, + utils::Rand, Error, }; @@ -80,7 +80,7 @@ pub trait HasMetadata { pub trait HasFeedbacks where FT: FeedbacksTuple, - I: Input + I: Input, { /// The feedbacks tuple fn feedbacks(&self) -> &FT; @@ -97,7 +97,11 @@ where /// Creates a new testcase, appending the metadata from each feedback #[inline] - fn testcase_with_feedbacks_metadata(&mut self, input: I, fitness: u32) -> Result, Error> { + fn testcase_with_feedbacks_metadata( + &mut self, + input: I, + fitness: u32, + ) -> Result, Error> { let mut testcase = Testcase::with_fitness(input, fitness); self.feedbacks_mut().append_metadata_all(&mut testcase)?; Ok(testcase) @@ -108,7 +112,7 @@ where pub trait HasObjectives where FT: FeedbacksTuple, - I: Input + I: Input, { /// The objective feedbacks tuple fn objectives(&self) -> &FT; @@ -118,8 +122,7 @@ where } /// Trait for the execution counter -pub trait HasExecutions -{ +pub trait HasExecutions { /// The executions counter fn executions(&self) -> &usize; @@ -128,8 +131,7 @@ pub trait HasExecutions } /// Trait for the starting time -pub trait HasStartTime -{ +pub trait HasStartTime { /// The starting time fn start_time(&self) -> &Duration; @@ -140,7 +142,7 @@ pub trait HasStartTime /// Add to the state if interesting pub trait IfInteresting where - I: Input + I: Input, { /// Evaluate if a set of observation channels has an interesting state fn is_interesting( @@ -205,7 +207,6 @@ where phantom: PhantomData, } - impl HasRand for State where C: Corpus, @@ -228,7 +229,6 @@ where } } - impl HasCorpus for State where C: Corpus, @@ -471,7 +471,6 @@ where } } - #[cfg(feature = "std")] impl State where @@ -551,7 +550,6 @@ where } } - impl State where C: Corpus, @@ -584,13 +582,14 @@ where executor.post_exec_observers()?; let observers = executor.observers(); - let fitness = self .feedbacks_mut() .is_interesting_all(&input, observers, exit_kind)?; - - let is_solution = self.objectives_mut().is_interesting_all(&input, observers, exit_kind.clone())? > 0; + let is_solution = + self.objectives_mut() + .is_interesting_all(&input, observers, exit_kind.clone())? + > 0; Ok((fitness, is_solution)) } @@ -629,7 +628,7 @@ where Ok(()) } - pub fn new(rand: R, corpus: C, feedbacks: FT, solutions: SC, objectives: OFT) -> Self { + pub fn new(rand: R, corpus: C, feedbacks: FT, solutions: SC, objectives: OFT) -> Self { Self { rand, executions: 0,