diff --git a/src/corpus/mod.rs b/src/corpus/mod.rs index ab27c6b63e..0b0b18b3fc 100644 --- a/src/corpus/mod.rs +++ b/src/corpus/mod.rs @@ -331,6 +331,6 @@ mod tests { .unwrap() .to_owned() ); - assert_eq!(filename, PathBuf::from("fancy/path/fancyfile")); + assert_eq!(filename, PathBuf::from("fancyfile")); } } diff --git a/src/engines/mod.rs b/src/engines/mod.rs index 58b3dc483e..50dff41fe5 100644 --- a/src/engines/mod.rs +++ b/src/engines/mod.rs @@ -94,6 +94,19 @@ where } } +/* +pub struct FuzzState +where + I: Input, + C: Corpus, + E: Executor, +{ + +} +*/ + + + pub struct DefaultEngine where I: Input, @@ -188,6 +201,7 @@ mod tests { use crate::executors::{Executor, ExitKind}; use crate::inputs::bytes::BytesInput; use crate::stages::mutational::DefaultMutationalStage; + use crate::mutators::DefaultScheduledMutator; use crate::stages::Stage; use crate::utils::Xoshiro256StarRand; @@ -198,15 +212,17 @@ mod tests { #[test] fn test_engine() { let rand = Xoshiro256StarRand::new_rr(); + let mut 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 mut stage = DefaultMutationalStage::new(&rand, &engine); - //engine.borrow_mut().add_stage(stage); - //engine.borrow_mut().fuzz_one().unwrap(); + //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() }; - stage.perform(&t).unwrap(); + //engine.borrow_mut().stages[0].perform(&t).unwrap(); } } diff --git a/src/mutators/mod.rs b/src/mutators/mod.rs index dc54667ad9..ac1ee8f415 100644 --- a/src/mutators/mod.rs +++ b/src/mutators/mod.rs @@ -1,10 +1,13 @@ +pub mod scheduled; +pub use scheduled::ScheduledMutator; +pub use scheduled::DefaultScheduledMutator; +pub use scheduled::HavocBytesMutator; + use crate::corpus::Corpus; use crate::inputs::Input; use crate::utils::HasRand; use crate::AflError; -pub mod scheduled; - pub trait HasOptionCorpus where I: Input, diff --git a/src/stages/mod.rs b/src/stages/mod.rs index 3ec48bcd23..13ef29e7d0 100644 --- a/src/stages/mod.rs +++ b/src/stages/mod.rs @@ -1,4 +1,5 @@ pub mod mutational; +pub use mutational::DefaultMutationalStage; use crate::corpus::Testcase; use crate::engines::Evaluator; @@ -14,7 +15,7 @@ where { type E: Evaluator; - fn eval(&self) -> &Rc>; + fn evaluator(&self) -> &Rc>; } pub trait Stage: HasEvaluator diff --git a/src/stages/mutational.rs b/src/stages/mutational.rs index 3d33c539dd..1ab6248253 100644 --- a/src/stages/mutational.rs +++ b/src/stages/mutational.rs @@ -8,64 +8,67 @@ use crate::AflError; use std::cell::RefCell; use std::rc::Rc; +use std::marker::PhantomData; // TODO create HasMutatorsVec trait -pub trait MutationalStage: Stage + HasRand +pub trait MutationalStage: Stage + HasRand where I: Input, + M: Mutator, { - fn mutators(&self) -> &Vec>>; + /// The mutator registered for this stage + fn mutator(&self) -> &M; - fn mutators_mut(&mut self) -> &mut Vec>>; - - fn add_mutator(&mut self, mutator: Box>) { - self.mutators_mut().push(mutator); - } + /// The mutator registered for this stage (mutable) + fn mutator_mut(&mut self) -> &mut M; + /// 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 { 1 + self.rand_below(128) as usize } - fn perform_mutational(&mut self, entry: &Rc>>) -> Result<(), AflError> { + /// Runs this (mutational) stage for the given testcase + fn perform_mutational(&mut self, testcase: &Rc>>) -> Result<(), AflError> { let num = self.iterations(); - let mut input = entry.borrow_mut().load_input()?.clone(); + let input = testcase.borrow_mut().load_input()?.clone(); for i in 0..num { - for m in self.mutators_mut() { - m.mutate(&mut input, i as i32)?; - } + let mut input_tmp = input.clone(); + self.mutator_mut().mutate(&mut input_tmp, i as i32)?; let interesting = self - .eval() + .evaluator() .borrow_mut() - .evaluate_input(&mut input, entry.clone())?; + .evaluate_input(&mut input_tmp, testcase.clone())?; - for m in self.mutators_mut() { - m.post_exec(interesting, i as i32)?; - } + self.mutator_mut().post_exec(interesting, i as i32)?; - input = entry.borrow_mut().load_input()?.clone(); } Ok(()) } } -pub struct DefaultMutationalStage +/// The default mutational stage +pub struct DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { rand: Rc>, - eval: Rc>, - mutators: Vec>>, + evaluator: Rc>, + mutator: M, + _phantom_input: PhantomData } -impl HasRand for DefaultMutationalStage +impl HasRand for DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { type R = R; @@ -75,56 +78,66 @@ where } } -impl HasEvaluator for DefaultMutationalStage +/// Indicate that this stage can eval targets +impl HasEvaluator for DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { type E = E; - fn eval(&self) -> &Rc> { - &self.eval + /// Get the evaluator + fn evaluator(&self) -> &Rc> { + &self.evaluator } } -impl MutationalStage for DefaultMutationalStage +impl MutationalStage for DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { - fn mutators(&self) -> &Vec>> { - &self.mutators + /// The mutator, added to this stage + fn mutator(&self) -> &M { + &self.mutator } - fn mutators_mut(&mut self) -> &mut Vec>> { - &mut self.mutators + /// The list of mutators, added to this stage (as mutable ref) + fn mutator_mut(&mut self) -> &mut M { + &mut self.mutator } } -impl Stage for DefaultMutationalStage +impl Stage for DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { - fn perform(&mut self, entry: &Rc>>) -> Result<(), AflError> { - self.perform_mutational(entry) + fn perform(&mut self, testcase: &Rc>>) -> Result<(), AflError> { + self.perform_mutational(testcase) } } -impl DefaultMutationalStage +impl DefaultMutationalStage where I: Input, R: Rand, + M: Mutator, E: Evaluator, { - pub fn new(rand: &Rc>, eval: &Rc>) -> Self { + /// Creates a new default mutational stage + pub fn new(rand: &Rc>, evaluator: &Rc>, mutator: M) -> Self { DefaultMutationalStage { rand: Rc::clone(rand), - eval: Rc::clone(eval), - mutators: vec![], + evaluator: Rc::clone(evaluator), + mutator: mutator, + _phantom_input: PhantomData, } } }