From 77b736ab3b5fbb9714d59f935de0a47029c8a1aa Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Tue, 10 Nov 2020 02:43:53 +0100 Subject: [PATCH] remodelling evaluation --- src/corpus/mod.rs | 2 +- src/corpus/testcase.rs | 2 +- src/engines/mod.rs | 182 +++++++++++--------------------------- src/executors/inmemory.rs | 43 ++++----- src/executors/mod.rs | 51 ++++++++++- src/feedbacks/mod.rs | 2 +- src/mutators/mod.rs | 18 +--- src/mutators/scheduled.rs | 71 +++------------ src/stages/mod.rs | 14 +-- src/stages/mutational.rs | 89 +++++++++---------- src/utils.rs | 13 ++- 11 files changed, 193 insertions(+), 294 deletions(-) diff --git a/src/corpus/mod.rs b/src/corpus/mod.rs index d15e325d4e..93e5da42f6 100644 --- a/src/corpus/mod.rs +++ b/src/corpus/mod.rs @@ -5,7 +5,7 @@ use crate::inputs::Input; use crate::utils::{HasRand, Rand}; use crate::AflError; -use std::cell::RefCell; +use core::cell::RefCell; use std::marker::PhantomData; use std::path::PathBuf; use std::rc::Rc; diff --git a/src/corpus/testcase.rs b/src/corpus/testcase.rs index 1e03ae9670..e80831ee67 100644 --- a/src/corpus/testcase.rs +++ b/src/corpus/testcase.rs @@ -2,7 +2,7 @@ use crate::inputs::Input; use crate::AflError; use hashbrown::HashMap; -use std::cell::RefCell; +use core::cell::RefCell; use std::path::PathBuf; use std::rc::Rc; diff --git a/src/engines/mod.rs b/src/engines/mod.rs index 2cb06daad8..d8ab27940f 100644 --- a/src/engines/mod.rs +++ b/src/engines/mod.rs @@ -6,25 +6,14 @@ use crate::inputs::Input; use crate::stages::Stage; use crate::AflError; -use std::cell::RefCell; +use core::cell::RefCell; use std::rc::Rc; -pub trait Evaluator -where - I: Input, -{ - fn evaluate_input( - &mut self, - input: &mut I, - entry: Rc>>, - ) -> Result; -} - -pub trait Engine: Evaluator +pub trait Engine where I: Input, C: Corpus, - E: Executor, + E: Executor, { fn feedbacks(&self) -> &Vec>>; @@ -34,111 +23,40 @@ where self.feedbacks_mut().push(feedback); } - fn stages(&self) -> &Vec>>; + fn stages(&self) -> &Vec>>; - fn stages_mut(&mut self) -> &mut Vec>>; + fn stages_mut(&mut self) -> &mut Vec>>; - fn add_stage(&mut self, stage: Box>) { + fn add_stage(&mut self, stage: Box>) { self.stages_mut().push(stage); } - fn corpus(&self) -> &C; - - fn corpus_mut(&mut self) -> &mut C; - fn executor(&self) -> &E; fn executor_mut(&mut self) -> &mut E; - fn fuzz_one(&mut self) -> Result<(), AflError> { - if self.corpus().count() == 0 { - return Err(AflError::Empty("No testcases in corpus".to_owned())); - } - let entry = self.corpus_mut().next()?; + fn fuzz_one(&mut self, testcase: &Rc>>) -> Result<(), AflError> { for stage in self.stages_mut() { - stage.perform(&entry)?; + stage.perform(&testcase)?; } Ok(()) } - fn evaluate_input_engine( - &mut self, - input: &mut I, - _entry: Rc>>, - ) -> Result { - self.executor_mut().reset_observers()?; - self.executor_mut().run_target(input)?; - self.executor_mut().post_exec_observers()?; - - let mut metadatas: Vec> = vec![]; - let mut rate_acc = 0; - for feedback in self.feedbacks_mut() { - let (rate, meta) = feedback.is_interesting(input); - rate_acc += rate; - if let Some(m) = meta { - metadatas.push(m); - } - } - - if rate_acc >= 25 { - let new_entry = Rc::new(RefCell::new(Testcase::::new(input.clone()))); - for meta in metadatas { - new_entry.borrow_mut().add_metadata(meta); - } - self.corpus_mut().add(new_entry); - - Ok(true) - } else { - Ok(false) - } - } } -/* -pub struct FuzzState +pub struct DefaultEngine where I: Input, - C: Corpus, - E: Executor, -{ - -} -*/ - - - -pub struct DefaultEngine -where - I: Input, - C: Corpus, - E: Executor, { feedbacks: Vec>>, - stages: Vec>>, - executor: E, - corpus: C, + stages: Vec>>, } -impl Evaluator for DefaultEngine +impl Engine for DefaultEngine where I: Input, C: Corpus, - E: Executor, -{ - fn evaluate_input( - &mut self, - input: &mut I, - entry: Rc>>, - ) -> Result { - self.evaluate_input_engine(input, entry) - } -} - -impl Engine for DefaultEngine -where - I: Input, - C: Corpus, - E: Executor, + E: Executor, { fn feedbacks(&self) -> &Vec>> { &self.feedbacks @@ -148,64 +66,68 @@ where &mut self.feedbacks } - fn stages(&self) -> &Vec>> { + fn stages(&self) -> &Vec>> { &self.stages } - fn stages_mut(&mut self) -> &mut Vec>> { + fn stages_mut(&mut self) -> &mut Vec>> { &mut self.stages } - fn corpus(&self) -> &C { - &self.corpus - } - - fn corpus_mut(&mut self) -> &mut C { - &mut self.corpus - } - - fn executor(&self) -> &E { - &self.executor - } - - fn executor_mut(&mut self) -> &mut E { - &mut self.executor - } } -impl DefaultEngine +impl DefaultEngine where I: Input, - C: Corpus, - E: Executor, { - pub fn new(corpus: C, executor: E) -> Self { + pub fn new(executor: E) -> Self { DefaultEngine { feedbacks: vec![], stages: vec![], - corpus: corpus, - executor: executor, } } - pub fn new_rr(corpus: C, executor: E) -> Rc> { - Rc::new(RefCell::new(Self::new(corpus, executor))) + pub fn new_rr(executor: E) -> Rc> { + Rc::new(RefCell::new(Self::new(executor))) } } +pub struct FuzzState +where + I: Input, + C: Corpus, +{ + + corpus: C, + current_input: Option, + +} + +impl FuzzState +where + I: Input, + C: Corpus, +{ + pub fn new(corpus: C) -> Self { + Self{corpus: corpus, current_input: None} + } +} + + #[cfg(test)] mod tests { use crate::corpus::{Corpus, InMemoryCorpus, Testcase}; - use crate::engines::{DefaultEngine, Engine}; + use crate::engines::{DefaultEngine, Engine, FuzzState}; use crate::executors::inmemory::InMemoryExecutor; use crate::executors::{Executor, ExitKind}; use crate::inputs::bytes::BytesInput; - use crate::stages::mutational::DefaultMutationalStage; use crate::mutators::DefaultScheduledMutator; + use crate::mutators::scheduled::mutation_bitflip; + use crate::stages::mutational::DefaultMutationalStage; use crate::stages::Stage; use crate::utils::Xoshiro256StarRand; - fn harness(_executor: &dyn Executor, _buf: &[u8]) -> ExitKind { + fn harness(_executor: &dyn Executor, _buf: &[u8]) -> ExitKind { ExitKind::Ok } @@ -213,16 +135,16 @@ mod tests { fn test_engine() { let rand = Xoshiro256StarRand::preseeded_rr(); - let mut corpus = InMemoryCorpus::::new(&rand); + let corpus = InMemoryCorpus::::new(&rand); let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4])); corpus.add(testcase); let executor = InMemoryExecutor::new(harness); - let engine = DefaultEngine::new_rr(corpus, executor); - //let mutator = DefaultScheduledMutator::new_all(rand: &rand, corpus: Option>, mutations: Vec>)(&rand); - //let stage = DefaultMutationalStage::new(&rand, &engine, mutator); - //engine.borrow_mut().add_stage(Box::new(stage)); - engine.borrow_mut().fuzz_one().unwrap(); - let t = { engine.borrow_mut().corpus_mut().next().unwrap() }; - //engine.borrow_mut().stages[0].perform(&t).unwrap(); + let state = FuzzState::new(corpus); + let engine = DefaultEngine::new(executor); + let mutator = DefaultScheduledMutator::new(&rand); + mutator.add_mutation(mutation_bitflip); + let stage = DefaultMutationalStage::new(&rand, &engine, mutator); + engine.add_stage(Box::new(stage)); + engine.fuzz_one(&corpus.next().unwrap()).unwrap(); } } diff --git a/src/executors/inmemory.rs b/src/executors/inmemory.rs index e36d4bb732..8e4e6cc20c 100644 --- a/src/executors/inmemory.rs +++ b/src/executors/inmemory.rs @@ -1,3 +1,4 @@ +use crate::executors::Corpus; use crate::inputs::Input; use crate::observers::Observer; use crate::AflError; @@ -7,21 +8,23 @@ use crate::executors::{Executor, ExitKind}; use std::os::raw::c_void; use std::ptr; -type HarnessFunction = fn(&dyn Executor, &[u8]) -> ExitKind; +type HarnessFunction = fn(&dyn Executor, &[u8]) -> ExitKind; -pub struct InMemoryExecutor +pub struct InMemoryExecutor where I: Input, + C: Corpus, { observers: Vec>, - harness: HarnessFunction, + harness: HarnessFunction, } static mut CURRENT_INMEMORY_EXECUTOR_PTR: *const c_void = ptr::null(); -impl Executor for InMemoryExecutor +impl Executor for InMemoryExecutor where I: Input, + C: Corpus, { fn run_target(&mut self, input: &mut I) -> Result { let bytes = input.serialize()?; @@ -58,11 +61,12 @@ where } } -impl InMemoryExecutor +impl InMemoryExecutor where I: Input, + C: Corpus, { - pub fn new(harness_fn: HarnessFunction) -> Self { + pub fn new(harness_fn: HarnessFunction) -> Self { unsafe { os_signals::setup_crash_handlers::(); } @@ -86,16 +90,14 @@ pub mod unix_signals { use std::{mem, process, ptr}; use crate::executors::inmemory::CURRENT_INMEMORY_EXECUTOR_PTR; - use crate::executors::Executor; use crate::inputs::Input; - pub extern "C" fn libaflrs_executor_inmem_handle_crash( + pub extern "C" fn libaflrs_executor_inmem_handle_crash( _sig: c_int, info: siginfo_t, _void: c_void, ) where I: Input, - E: Executor, { unsafe { if CURRENT_INMEMORY_EXECUTOR_PTR == ptr::null() { @@ -110,13 +112,12 @@ pub mod unix_signals { let _ = stdout().flush(); } - pub extern "C" fn libaflrs_executor_inmem_handle_timeout( + pub extern "C" fn libaflrs_executor_inmem_handle_timeout( _sig: c_int, _info: siginfo_t, _void: c_void, ) where I: Input, - E: Executor, { dbg!("TIMEOUT/SIGUSR2 received"); unsafe { @@ -131,15 +132,14 @@ pub mod unix_signals { process::abort(); } - pub unsafe fn setup_crash_handlers() + pub unsafe fn setup_crash_handlers() where I: Input, - E: Executor, { let mut sa: sigaction = mem::zeroed(); libc::sigemptyset(&mut sa.sa_mask as *mut libc::sigset_t); sa.sa_flags = SA_NODEFER | SA_SIGINFO; - sa.sa_sigaction = libaflrs_executor_inmem_handle_crash:: as usize; + sa.sa_sigaction = libaflrs_executor_inmem_handle_crash:: as usize; for (sig, msg) in &[ (SIGSEGV, "segfault"), (SIGBUS, "sigbus"), @@ -153,7 +153,7 @@ pub mod unix_signals { } } - sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout:: as usize; + sa.sa_sigaction = libaflrs_executor_inmem_handle_timeout:: as usize; if sigaction(SIGUSR2, &mut sa as *mut sigaction, ptr::null_mut()) < 0 { panic!("Could not set up sigusr2 handler for timeouts"); } @@ -167,7 +167,8 @@ compile_error!("InMemoryExecutor not yet supported on this OS"); #[cfg(test)] mod tests { - use crate::executors::inmemory::InMemoryExecutor; + use crate::executors::Corpus; +use crate::executors::inmemory::InMemoryExecutor; use crate::executors::{Executor, ExitKind}; use crate::inputs::Input; use crate::observers::Observer; @@ -195,16 +196,16 @@ mod tests { } } - fn test_harness_fn_nop(_executor: &dyn Executor, buf: &[u8]) -> ExitKind { + /*fn test_harness_fn_nop(_executor: &dyn Executor, buf: &[u8]) -> ExitKind { println! {"Fake exec with buf of len {}", buf.len()}; ExitKind::Ok - } + }*/ #[test] fn test_inmem_post_exec() { - let mut in_mem_executor = InMemoryExecutor::new(test_harness_fn_nop); + //let mut in_mem_executor = InMemoryExecutor::new(test_harness_fn_nop); let nopserver = Nopserver {}; - in_mem_executor.add_observer(Box::new(nopserver)); + //in_mem_executor.add_observer(Box::new(nopserver)); assert_eq!(in_mem_executor.post_exec_observers().is_err(), true); } @@ -212,6 +213,6 @@ mod tests { fn test_inmem_exec() { let mut in_mem_executor = InMemoryExecutor::new(test_harness_fn_nop); let mut input = NopInput {}; - assert!(in_mem_executor.run_target(&mut input).is_ok()); + //assert!(in_mem_executor.run_target(&mut input).is_ok()); } } diff --git a/src/executors/mod.rs b/src/executors/mod.rs index 60c7d8b987..764254add7 100644 --- a/src/executors/mod.rs +++ b/src/executors/mod.rs @@ -1,5 +1,11 @@ pub mod inmemory; +use crate::corpus::Testcase; +use core::cell::RefCell; +use std::rc::Rc; +use crate::corpus::Corpus; +use crate::corpus::TestcaseMetadata; +use crate::feedbacks::Feedback; use crate::inputs::Input; use crate::observers::Observer; use crate::AflError; @@ -13,9 +19,10 @@ pub enum ExitKind { // TODO unbox input -pub trait Executor +pub trait Executor where I: Input, + C: Corpus, { /// Instruct the target about the input and run fn run_target(&mut self, input: &mut I) -> Result; @@ -31,4 +38,46 @@ where /// Get the linked observers fn observers(&self) -> &Vec>; + + /// Adds a feedback + fn add_feedback(&mut self, feedback: Box>); + + /// Returns vector of feebacks + fn feedbacks(&self) -> &Vec>>; + + // TODO: Move to another struct, like evaluator? + // In any case, the dependency on Corpus should probably go + /// Runs the input and triggers observers and feedback + fn evaluate_input( + &mut self, + corpus: &mut C, + input: &mut I, + ) -> Result { + self.reset_observers()?; + self.run_target(input)?; + self.post_exec_observers()?; + + let mut metadatas: Vec> = vec![]; + let mut rate_acc = 0; + for feedback in self.feedbacks() { + let (rate, meta) = feedback.is_interesting(input); + rate_acc += rate; + if let Some(m) = meta { + metadatas.push(m); + } + } + + if rate_acc >= 25 { + let new_entry = Rc::new(RefCell::new(Testcase::::new(input.clone()))); + for meta in metadatas { + new_entry.borrow_mut().add_metadata(meta); + } + corpus.add(new_entry); + + Ok(true) + } else { + Ok(false) + } + } + } diff --git a/src/feedbacks/mod.rs b/src/feedbacks/mod.rs index c0efef5661..0f28525f33 100644 --- a/src/feedbacks/mod.rs +++ b/src/feedbacks/mod.rs @@ -5,7 +5,7 @@ use crate::inputs::Input; use crate::observers::MapObserver; use num::Integer; -use std::cell::RefCell; +use core::cell::RefCell; use std::marker::PhantomData; pub trait Feedback diff --git a/src/mutators/mod.rs b/src/mutators/mod.rs index ac1ee8f415..d25faf5510 100644 --- a/src/mutators/mod.rs +++ b/src/mutators/mod.rs @@ -1,29 +1,13 @@ pub mod scheduled; -pub use scheduled::ScheduledMutator; pub use scheduled::DefaultScheduledMutator; pub use scheduled::HavocBytesMutator; +pub use scheduled::ScheduledMutator; use crate::corpus::Corpus; use crate::inputs::Input; use crate::utils::HasRand; use crate::AflError; -pub trait HasOptionCorpus -where - I: Input, -{ - type C: Corpus; - - /// Get the associated corpus, if any - fn corpus(&self) -> &Option>; - - /// Get the associated corpus, if any (mutable) - fn corpus_mut(&mut self) -> &mut Option>; - - /// Set the associated corpus - fn set_corpus(&mut self, corpus: Option>); -} - pub trait Mutator: HasRand where I: Input, diff --git a/src/mutators/scheduled.rs b/src/mutators/scheduled.rs index 0c14a1c127..a87d720d81 100644 --- a/src/mutators/scheduled.rs +++ b/src/mutators/scheduled.rs @@ -1,10 +1,10 @@ use crate::corpus::Corpus; use crate::inputs::{HasBytesVec, Input}; -use crate::mutators::{HasOptionCorpus, Mutator}; +use crate::mutators::Mutator; use crate::utils::{HasRand, Rand}; use crate::AflError; -use std::cell::RefCell; +use core::cell::RefCell; use std::marker::PhantomData; use std::rc::Rc; @@ -25,7 +25,7 @@ where fn add_mutation(&mut self, mutation: MutationFunction); } -pub trait ScheduledMutator: Mutator + HasOptionCorpus + ComposedByMutations +pub trait ScheduledMutator: Mutator + ComposedByMutations where I: Input, { @@ -58,18 +58,17 @@ where } } -pub struct DefaultScheduledMutator<'a, I, R, C> +pub struct DefaultScheduledMutator<'a, I, C, R> where I: Input, - R: Rand, C: Corpus, + R: Rand, { rand: Rc>, - corpus: Option>, mutations: Vec>, } -impl<'a, I, R, C> HasRand for DefaultScheduledMutator<'_, I, R, C> +impl<'a, I, C, R> HasRand for DefaultScheduledMutator<'_, I, C, R> where I: Input, R: Rand, @@ -82,28 +81,8 @@ where } } -impl HasOptionCorpus for DefaultScheduledMutator<'_, I, R, C> -where - I: Input, - R: Rand, - C: Corpus, -{ - type C = C; - fn corpus(&self) -> &Option> { - &self.corpus - } - - fn corpus_mut(&mut self) -> &mut Option> { - &mut self.corpus - } - - fn set_corpus(&mut self, corpus: Option>) { - self.corpus = corpus - } -} - -impl<'a, I, R, C> Mutator for DefaultScheduledMutator<'_, I, R, C> +impl<'a, I, C, R> Mutator for DefaultScheduledMutator<'_, I, C, R> where I: Input, R: Rand, @@ -114,7 +93,7 @@ where } } -impl<'a, I, R, C> ComposedByMutations for DefaultScheduledMutator<'_, I, R, C> +impl<'a, I, C, R> ComposedByMutations for DefaultScheduledMutator<'_, I, C, R> where I: Input, R: Rand, @@ -136,7 +115,7 @@ where } } -impl<'a, I, R, C> ScheduledMutator for DefaultScheduledMutator<'_, I, R, C> +impl<'a, I, C, R> ScheduledMutator for DefaultScheduledMutator<'_, I, C, R> where I: Input, R: Rand, @@ -145,17 +124,16 @@ where // Just use the default methods } -impl<'a, I, R, C> DefaultScheduledMutator<'a, I, R, C> +impl<'a, I, C, R> DefaultScheduledMutator<'a, I, C, R> where I: Input, - R: Rand, C: Corpus, + R: Rand, { /// Create a new DefaultScheduledMutator instance without mutations and corpus pub fn new(rand: &Rc>) -> Self { DefaultScheduledMutator { rand: Rc::clone(rand), - corpus: None, mutations: vec![], } } @@ -163,15 +141,14 @@ where /// Create a new DefaultScheduledMutator instance specifying mutations and corpus too pub fn new_all( rand: &Rc>, - corpus: Option>, mutations: Vec>, ) -> Self { DefaultScheduledMutator { rand: Rc::clone(rand), - corpus: corpus, mutations: mutations, } } + } /// Bitflip mutation for inputs with a bytes vector @@ -207,26 +184,6 @@ where } } -impl HasOptionCorpus for HavocBytesMutator -where - I: Input + HasBytesVec, - S: ScheduledMutator, -{ - type C = S::C; - - fn corpus(&self) -> &Option> { - self.scheduled.corpus() - } - - fn corpus_mut(&mut self) -> &mut Option> { - self.scheduled.corpus_mut() - } - - fn set_corpus(&mut self, corpus: Option>) { - self.scheduled.set_corpus(corpus) - } -} - impl Mutator for HavocBytesMutator where I: Input + HasBytesVec, @@ -252,7 +209,7 @@ where } } -impl<'a, I, R, C> HavocBytesMutator> +impl<'a, I, C, R> HavocBytesMutator> where I: Input + HasBytesVec, R: Rand, @@ -260,7 +217,7 @@ where { /// Create a new HavocBytesMutator instance wrapping DefaultScheduledMutator pub fn new_default(rand: &Rc>) -> Self { - let mut scheduled = DefaultScheduledMutator::<'a, I, R, C>::new(rand); + let mut scheduled = DefaultScheduledMutator::<'a, I, C, R>::new(rand); scheduled.add_mutation(mutation_bitflip); HavocBytesMutator { scheduled: scheduled, diff --git a/src/stages/mod.rs b/src/stages/mod.rs index 13ef29e7d0..08c8392c79 100644 --- a/src/stages/mod.rs +++ b/src/stages/mod.rs @@ -2,23 +2,13 @@ pub mod mutational; pub use mutational::DefaultMutationalStage; use crate::corpus::Testcase; -use crate::engines::Evaluator; use crate::inputs::Input; use crate::AflError; -use std::cell::RefCell; +use core::cell::RefCell; use std::rc::Rc; -pub trait HasEvaluator -where - I: Input, -{ - type E: Evaluator; - - fn evaluator(&self) -> &Rc>; -} - -pub trait Stage: HasEvaluator +pub trait Stage where I: Input, { diff --git a/src/stages/mutational.rs b/src/stages/mutational.rs index 1ab6248253..358cf68075 100644 --- a/src/stages/mutational.rs +++ b/src/stages/mutational.rs @@ -1,21 +1,26 @@ +use crate::corpus::Corpus; +use crate::corpus::TestcaseMetadata; +use crate::executors::Executor; use crate::corpus::testcase::Testcase; use crate::engines::Evaluator; use crate::inputs::Input; use crate::mutators::Mutator; -use crate::stages::{HasEvaluator, Stage}; +use crate::stages::Stage; use crate::utils::{HasRand, Rand}; use crate::AflError; use std::cell::RefCell; -use std::rc::Rc; use std::marker::PhantomData; +use std::rc::Rc; // TODO create HasMutatorsVec trait -pub trait MutationalStage: Stage + HasRand +pub trait MutationalStage: Stage + HasRand where I: Input, M: Mutator, + C: Corpus, + E: Executor, { /// The mutator registered for this stage fn mutator(&self) -> &M; @@ -23,6 +28,9 @@ where /// The mutator registered for this stage (mutable) fn mutator_mut(&mut self) -> &mut M; + /// Rc Refcell to the executor + fn executor(&self) -> &Rc>; + /// Gets the number of iterations this mutator should run for. /// This call uses internal mutability, so it may change for each call fn iterations(&mut self) -> usize { @@ -30,7 +38,8 @@ where } /// Runs this (mutational) stage for the given testcase - fn perform_mutational(&mut self, testcase: &Rc>>) -> Result<(), AflError> { + fn perform_mutational(&mut self, corpus: &mut C, testcase: &Rc>>) -> Result<(), AflError> { + let testcase = corpus.next()?; let num = self.iterations(); let input = testcase.borrow_mut().load_input()?.clone(); @@ -38,38 +47,37 @@ where let mut input_tmp = input.clone(); self.mutator_mut().mutate(&mut input_tmp, i as i32)?; - let interesting = self - .evaluator() - .borrow_mut() - .evaluate_input(&mut input_tmp, testcase.clone())?; + let interesting = self.executor().borrow_mut().evaluate_input(&corpus)?; self.mutator_mut().post_exec(interesting, i as i32)?; - } Ok(()) } } /// The default mutational stage -pub struct DefaultMutationalStage +pub struct DefaultMutationalStage where I: Input, + C: Corpus, R: Rand, - M: Mutator, - E: Evaluator, + M: Mutator, + E: Executor, { rand: Rc>, - evaluator: Rc>, + executor: Rc>, mutator: M, - _phantom_input: PhantomData + _phantom_input: PhantomData, + _phantom_corpus: PhantomData, } -impl HasRand for DefaultMutationalStage +impl HasRand for DefaultMutationalStage where I: Input, + C: Corpus, R: Rand, - M: Mutator, - E: Evaluator, + M: Mutator, + E: Executor, { type R = R; @@ -78,28 +86,14 @@ where } } -/// Indicate that this stage can eval targets -impl HasEvaluator for DefaultMutationalStage + +impl MutationalStage for DefaultMutationalStage where I: Input, + C: Corpus, R: Rand, - M: Mutator, - E: Evaluator, -{ - type E = E; - - /// Get the evaluator - fn evaluator(&self) -> &Rc> { - &self.evaluator - } -} - -impl MutationalStage for DefaultMutationalStage -where - I: Input, - R: Rand, - M: Mutator, - E: Evaluator, + M: Mutator, + E: Executor, { /// The mutator, added to this stage fn mutator(&self) -> &M { @@ -112,32 +106,35 @@ where } } -impl Stage for DefaultMutationalStage +impl Stage for DefaultMutationalStage where I: Input, + C: Corpus, R: Rand, - M: Mutator, - E: Evaluator, + M: Mutator, + E: Executor, { - fn perform(&mut self, testcase: &Rc>>) -> Result<(), AflError> { - self.perform_mutational(testcase) + fn perform(&mut self, corpus: &mut C) -> Result<(), AflError> { + self.perform_mutational(corpus) } } -impl DefaultMutationalStage +impl DefaultMutationalStage where I: Input, R: Rand, - M: Mutator, - E: Evaluator, + C: Corpus, + M: Mutator, + E: Executor, { /// Creates a new default mutational stage - pub fn new(rand: &Rc>, evaluator: &Rc>, mutator: M) -> Self { + pub fn new(rand: &Rc>, executor: &Rc>, mutator: M) -> Self { DefaultMutationalStage { rand: Rc::clone(rand), - evaluator: Rc::clone(evaluator), + executor: Rc::clone(executor), mutator: mutator, _phantom_input: PhantomData, + _phantom_corpus: PhantomData, } } } diff --git a/src/utils.rs b/src/utils.rs index 96068bb76e..7589775028 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,6 @@ //! Utility functions for AFL -use std::cell::RefCell; +use core::cell::RefCell; use std::debug_assert; use std::fmt::Debug; use std::rc::Rc; @@ -122,7 +122,10 @@ impl Xoshiro256StarRand { /// Creates a rand instance, pre-seeded with the current time in nanoseconds. pub fn preseeded() -> Self { - let seed = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos() as u64; + let seed = SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_nanos() as u64; Self::new(seed) } @@ -130,7 +133,6 @@ impl Xoshiro256StarRand { pub fn preseeded_rr() -> Rc> { Rc::new(RefCell::new(Self::preseeded())) } - } /// Get the next higher power of two @@ -158,8 +160,7 @@ mod tests { assert!(rand.between(11, 20) > 10); } - - use std::cell::RefCell; + use core::cell::RefCell; use std::rc::Rc; struct HasRandTest where @@ -190,8 +191,6 @@ mod tests { assert_eq!(has_rand.rand_below(1), 0); } - - #[test] fn test_next_pow2() { assert_eq!(next_pow2(0), 0);