mutational stage has one mutator now

This commit is contained in:
Dominik Maier 2020-11-09 17:39:33 +01:00
parent f1565246f5
commit 8454a52856
5 changed files with 78 additions and 45 deletions

View File

@ -331,6 +331,6 @@ mod tests {
.unwrap() .unwrap()
.to_owned() .to_owned()
); );
assert_eq!(filename, PathBuf::from("fancy/path/fancyfile")); assert_eq!(filename, PathBuf::from("fancyfile"));
} }
} }

View File

@ -94,6 +94,19 @@ where
} }
} }
/*
pub struct FuzzState<I, C, E>
where
I: Input,
C: Corpus<I>,
E: Executor<I>,
{
}
*/
pub struct DefaultEngine<I, C, E> pub struct DefaultEngine<I, C, E>
where where
I: Input, I: Input,
@ -188,6 +201,7 @@ mod tests {
use crate::executors::{Executor, ExitKind}; use crate::executors::{Executor, ExitKind};
use crate::inputs::bytes::BytesInput; use crate::inputs::bytes::BytesInput;
use crate::stages::mutational::DefaultMutationalStage; use crate::stages::mutational::DefaultMutationalStage;
use crate::mutators::DefaultScheduledMutator;
use crate::stages::Stage; use crate::stages::Stage;
use crate::utils::Xoshiro256StarRand; use crate::utils::Xoshiro256StarRand;
@ -198,15 +212,17 @@ mod tests {
#[test] #[test]
fn test_engine() { fn test_engine() {
let rand = Xoshiro256StarRand::new_rr(); let rand = Xoshiro256StarRand::new_rr();
let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand); let mut corpus = InMemoryCorpus::<BytesInput, _>::new(&rand);
let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4])); let testcase = Testcase::new_rr(BytesInput::new(vec![0; 4]));
corpus.add(testcase); corpus.add(testcase);
let executor = InMemoryExecutor::new(harness); let executor = InMemoryExecutor::new(harness);
let engine = DefaultEngine::new_rr(corpus, executor); let engine = DefaultEngine::new_rr(corpus, executor);
let mut stage = DefaultMutationalStage::new(&rand, &engine); //let mutator = DefaultScheduledMutator::new_all(rand: &rand, corpus: Option<Box<C>>, mutations: Vec<MutationFunction<Self, I>>)(&rand);
//engine.borrow_mut().add_stage(stage); //let stage = DefaultMutationalStage::new(&rand, &engine, mutator);
//engine.borrow_mut().fuzz_one().unwrap(); //engine.borrow_mut().add_stage(Box::new(stage));
engine.borrow_mut().fuzz_one().unwrap();
let t = { engine.borrow_mut().corpus_mut().next().unwrap() }; let t = { engine.borrow_mut().corpus_mut().next().unwrap() };
stage.perform(&t).unwrap(); //engine.borrow_mut().stages[0].perform(&t).unwrap();
} }
} }

View File

@ -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::corpus::Corpus;
use crate::inputs::Input; use crate::inputs::Input;
use crate::utils::HasRand; use crate::utils::HasRand;
use crate::AflError; use crate::AflError;
pub mod scheduled;
pub trait HasOptionCorpus<I> pub trait HasOptionCorpus<I>
where where
I: Input, I: Input,

View File

@ -1,4 +1,5 @@
pub mod mutational; pub mod mutational;
pub use mutational::DefaultMutationalStage;
use crate::corpus::Testcase; use crate::corpus::Testcase;
use crate::engines::Evaluator; use crate::engines::Evaluator;
@ -14,7 +15,7 @@ where
{ {
type E: Evaluator<I>; type E: Evaluator<I>;
fn eval(&self) -> &Rc<RefCell<Self::E>>; fn evaluator(&self) -> &Rc<RefCell<Self::E>>;
} }
pub trait Stage<I>: HasEvaluator<I> pub trait Stage<I>: HasEvaluator<I>

View File

@ -8,64 +8,67 @@ use crate::AflError;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use std::marker::PhantomData;
// TODO create HasMutatorsVec trait // TODO create HasMutatorsVec trait
pub trait MutationalStage<I>: Stage<I> + HasRand pub trait MutationalStage<I, M>: Stage<I> + HasRand
where where
I: Input, I: Input,
M: Mutator<I, R = Self::R>,
{ {
fn mutators(&self) -> &Vec<Box<dyn Mutator<I, R = Self::R>>>; /// The mutator registered for this stage
fn mutator(&self) -> &M;
fn mutators_mut(&mut self) -> &mut Vec<Box<dyn Mutator<I, R = Self::R>>>; /// The mutator registered for this stage (mutable)
fn mutator_mut(&mut self) -> &mut M;
fn add_mutator(&mut self, mutator: Box<dyn Mutator<I, R = Self::R>>) {
self.mutators_mut().push(mutator);
}
/// 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 { fn iterations(&mut self) -> usize {
1 + self.rand_below(128) as usize 1 + self.rand_below(128) as usize
} }
fn perform_mutational(&mut self, entry: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> { /// Runs this (mutational) stage for the given testcase
fn perform_mutational(&mut self, testcase: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
let num = self.iterations(); 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 i in 0..num {
for m in self.mutators_mut() { let mut input_tmp = input.clone();
m.mutate(&mut input, i as i32)?; self.mutator_mut().mutate(&mut input_tmp, i as i32)?;
}
let interesting = self let interesting = self
.eval() .evaluator()
.borrow_mut() .borrow_mut()
.evaluate_input(&mut input, entry.clone())?; .evaluate_input(&mut input_tmp, testcase.clone())?;
for m in self.mutators_mut() { self.mutator_mut().post_exec(interesting, i as i32)?;
m.post_exec(interesting, i as i32)?;
}
input = entry.borrow_mut().load_input()?.clone();
} }
Ok(()) Ok(())
} }
} }
pub struct DefaultMutationalStage<I, R, E> /// The default mutational stage
pub struct DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
rand: Rc<RefCell<R>>, rand: Rc<RefCell<R>>,
eval: Rc<RefCell<E>>, evaluator: Rc<RefCell<E>>,
mutators: Vec<Box<dyn Mutator<I, R = R>>>, mutator: M,
_phantom_input: PhantomData<I>
} }
impl<I, R, E> HasRand for DefaultMutationalStage<I, R, E> impl<I, R, M, E> HasRand for DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
type R = R; type R = R;
@ -75,56 +78,66 @@ where
} }
} }
impl<I, R, E> HasEvaluator<I> for DefaultMutationalStage<I, R, E> /// Indicate that this stage can eval targets
impl<I, R, M, E> HasEvaluator<I> for DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
type E = E; type E = E;
fn eval(&self) -> &Rc<RefCell<Self::E>> { /// Get the evaluator
&self.eval fn evaluator(&self) -> &Rc<RefCell<Self::E>> {
&self.evaluator
} }
} }
impl<I, R, E> MutationalStage<I> for DefaultMutationalStage<I, R, E> impl<I, R, M, E> MutationalStage<I, M> for DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
fn mutators(&self) -> &Vec<Box<dyn Mutator<I, R = Self::R>>> { /// The mutator, added to this stage
&self.mutators fn mutator(&self) -> &M {
&self.mutator
} }
fn mutators_mut(&mut self) -> &mut Vec<Box<dyn Mutator<I, R = Self::R>>> { /// The list of mutators, added to this stage (as mutable ref)
&mut self.mutators fn mutator_mut(&mut self) -> &mut M {
&mut self.mutator
} }
} }
impl<I, R, E> Stage<I> for DefaultMutationalStage<I, R, E> impl<I, R, M, E> Stage<I> for DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
fn perform(&mut self, entry: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> { fn perform(&mut self, testcase: &Rc<RefCell<Testcase<I>>>) -> Result<(), AflError> {
self.perform_mutational(entry) self.perform_mutational(testcase)
} }
} }
impl<I, R, E> DefaultMutationalStage<I, R, E> impl<I, R, M, E> DefaultMutationalStage<I, R, M, E>
where where
I: Input, I: Input,
R: Rand, R: Rand,
M: Mutator<I, R=R>,
E: Evaluator<I>, E: Evaluator<I>,
{ {
pub fn new(rand: &Rc<RefCell<R>>, eval: &Rc<RefCell<E>>) -> Self { /// Creates a new default mutational stage
pub fn new(rand: &Rc<RefCell<R>>, evaluator: &Rc<RefCell<E>>, mutator: M) -> Self {
DefaultMutationalStage { DefaultMutationalStage {
rand: Rc::clone(rand), rand: Rc::clone(rand),
eval: Rc::clone(eval), evaluator: Rc::clone(evaluator),
mutators: vec![], mutator: mutator,
_phantom_input: PhantomData,
} }
} }
} }