diff --git a/src/mutators/mod.rs b/src/mutators/mod.rs index 878e73ace9..d6c8188a83 100644 --- a/src/mutators/mod.rs +++ b/src/mutators/mod.rs @@ -1,5 +1,6 @@ extern crate alloc; pub mod scheduled; +use crate::corpus::Corpus; pub use scheduled::ComposedByMutations; pub use scheduled::DefaultScheduledMutator; pub use scheduled::HavocBytesMutator; @@ -9,12 +10,13 @@ use crate::inputs::Input; use crate::utils::HasRand; use crate::AflError; -pub trait Mutator: HasRand +pub trait Mutator: HasRand where + C: Corpus, I: Input, { /// Mutate a given input - fn mutate(&mut self, input: &mut I, stage_idx: i32) -> Result<(), AflError>; + fn mutate(&mut self, corpus: &mut C, input: &mut I, stage_idx: i32) -> Result<(), AflError>; /// Post-process given the outcome of the execution fn post_exec(&mut self, _is_interesting: bool, _stage_idx: i32) -> Result<(), AflError> { diff --git a/src/mutators/scheduled.rs b/src/mutators/scheduled.rs index 11350a05a4..198b83a7f5 100644 --- a/src/mutators/scheduled.rs +++ b/src/mutators/scheduled.rs @@ -1,4 +1,5 @@ extern crate alloc; +use crate::mutators::Corpus; use crate::inputs::{HasBytesVec, Input}; use crate::mutators::Mutator; use crate::utils::{HasRand, Rand}; @@ -9,24 +10,26 @@ use core::cell::RefCell; use core::marker::PhantomData; /// The generic function type that identifies mutations -type MutationFunction = fn(&mut M, &mut I) -> Result<(), AflError>; +type MutationFunction = fn(&mut M, &mut C, &mut I) -> Result<(), AflError>; -pub trait ComposedByMutations +pub trait ComposedByMutations where + C: Corpus, I: Input, { /// Get a mutation by index - fn mutation_by_idx(&self, index: usize) -> Result, AflError>; + fn mutation_by_idx(&self, index: usize) -> Result, AflError>; /// 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); } -pub trait ScheduledMutator: Mutator + ComposedByMutations +pub trait ScheduledMutator: Mutator + ComposedByMutations where + C: Corpus, I: Input, { /// Compute the number of iterations used to apply stacked mutations @@ -35,7 +38,7 @@ where } /// Get the next mutation to apply - fn schedule(&mut self, _input: &I) -> Result, AflError> { + fn schedule(&mut self, _input: &I) -> Result, AflError> { let count = self.mutations_count() as u64; if count == 0 { return Err(AflError::Empty("no mutations".to_string())); @@ -49,26 +52,28 @@ where /// New default implementation for mutate /// Implementations must forward mutate() to this method - fn scheduled_mutate(&mut self, input: &mut I, _stage_idx: i32) -> Result<(), AflError> { + fn scheduled_mutate(&mut self, corpus: &mut C, input: &mut I, _stage_idx: i32) -> Result<(), AflError> { let num = self.iterations(input); for _ in 0..num { - self.schedule(input)?(self, input)?; + self.schedule(input)?(self, corpus, input)?; } Ok(()) } } -pub struct DefaultScheduledMutator<'a, I, R> +pub struct DefaultScheduledMutator<'a, C, I, R> where + C: Corpus, I: Input, R: Rand, { rand: Rc>, - mutations: Vec>, + mutations: Vec>, } -impl<'a, I, R> HasRand for DefaultScheduledMutator<'_, I, R> +impl<'a, C, I, R> HasRand for DefaultScheduledMutator<'_, C, I, R> where + C: Corpus, I: Input, R: Rand, { @@ -79,22 +84,24 @@ where } } -impl<'a, I, R> Mutator for DefaultScheduledMutator<'_, I, R> +impl<'a, C, I, R> Mutator for DefaultScheduledMutator<'_, C, I, R> where + C: Corpus, I: Input, R: Rand, { - fn mutate(&mut self, input: &mut I, _stage_idx: i32) -> Result<(), AflError> { - self.scheduled_mutate(input, _stage_idx) + fn mutate(&mut self, corpus: &mut C, input: &mut I, _stage_idx: i32) -> Result<(), AflError> { + self.scheduled_mutate(corpus, input, _stage_idx) } } -impl<'a, I, R> ComposedByMutations for DefaultScheduledMutator<'_, I, R> +impl<'a, C, I, R> ComposedByMutations for DefaultScheduledMutator<'_, C, I, R> where + C: Corpus, I: Input, R: Rand, { - fn mutation_by_idx(&self, index: usize) -> Result, AflError> { + fn mutation_by_idx(&self, index: usize) -> Result, AflError> { if index >= self.mutations.len() { return Err(AflError::Unknown("oob".to_string())); } @@ -105,21 +112,23 @@ where self.mutations.len() } - fn add_mutation(&mut self, mutation: MutationFunction) { + fn add_mutation(&mut self, mutation: MutationFunction) { self.mutations.push(mutation) } } -impl<'a, I, R> ScheduledMutator for DefaultScheduledMutator<'_, I, R> +impl<'a, C, I, R> ScheduledMutator for DefaultScheduledMutator<'_, C, I, R> where + C: Corpus, I: Input, R: Rand, { // Just use the default methods } -impl<'a, I, R> DefaultScheduledMutator<'a, I, R> +impl<'a, C, I, R> DefaultScheduledMutator<'a, C, I, R> where + C: Corpus, I: Input, R: Rand, { @@ -132,7 +141,7 @@ where } /// Create a new DefaultScheduledMutator instance specifying mutations and corpus too - pub fn new_all(rand: &Rc>, mutations: Vec>) -> Self { + pub fn new_all(rand: &Rc>, mutations: Vec>) -> Self { DefaultScheduledMutator { rand: Rc::clone(rand), mutations: mutations, @@ -141,9 +150,10 @@ where } /// Bitflip mutation for inputs with a bytes vector -pub fn mutation_bitflip(mutator: &mut M, input: &mut I) -> Result<(), AflError> +pub fn mutation_bitflip(mutator: &mut M, _corpus: &mut C, input: &mut I) -> Result<(), AflError> where - M: Mutator, + C: Corpus, + M: Mutator, I: Input + HasBytesVec, { let bit = mutator.rand_below(input.bytes().len() as u64) as usize; @@ -152,19 +162,22 @@ where } /// Schedule some selected byte level mutations given a ScheduledMutator type -pub struct HavocBytesMutator +pub struct HavocBytesMutator where + C: Corpus, I: Input + HasBytesVec, - S: ScheduledMutator, + S: ScheduledMutator, { scheduled: S, phantom: PhantomData, + _phantom_corpus: PhantomData, } -impl HasRand for HavocBytesMutator +impl HasRand for HavocBytesMutator where + C: Corpus, I: Input + HasBytesVec, - S: ScheduledMutator, + S: ScheduledMutator, { type R = S::R; @@ -173,20 +186,22 @@ where } } -impl Mutator for HavocBytesMutator +impl Mutator for HavocBytesMutator where + C: Corpus, I: Input + HasBytesVec, - S: ScheduledMutator, + S: ScheduledMutator, { - fn mutate(&mut self, input: &mut I, stage_idx: i32) -> Result<(), AflError> { - self.scheduled.mutate(input, stage_idx) + fn mutate(&mut self, corpus: &mut C, input: &mut I, stage_idx: i32) -> Result<(), AflError> { + self.scheduled.mutate(corpus, input, stage_idx) } } -impl HavocBytesMutator +impl HavocBytesMutator where + C: Corpus, I: Input + HasBytesVec, - S: ScheduledMutator, + S: ScheduledMutator, { /// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap pub fn new(mut scheduled: S) -> Self { @@ -194,22 +209,25 @@ where HavocBytesMutator { scheduled: scheduled, phantom: PhantomData, + _phantom_corpus: PhantomData, } } } -impl<'a, I, R> HavocBytesMutator> +impl<'a, C, I, R> HavocBytesMutator> where + C: Corpus, I: Input + HasBytesVec, R: Rand, { /// Create a new HavocBytesMutator instance wrapping DefaultScheduledMutator pub fn new_default(rand: &Rc>) -> Self { - let mut scheduled = DefaultScheduledMutator::<'a, I, R>::new(rand); + let mut scheduled = DefaultScheduledMutator::<'a, C, I, R>::new(rand); scheduled.add_mutation(mutation_bitflip); HavocBytesMutator { scheduled: scheduled, phantom: PhantomData, + _phantom_corpus: PhantomData, } } } diff --git a/src/stages/mutational.rs b/src/stages/mutational.rs index 532b8fba95..3519ce30e4 100644 --- a/src/stages/mutational.rs +++ b/src/stages/mutational.rs @@ -18,7 +18,7 @@ pub trait MutationalStage: Stage + HasRand where C: Corpus, I: Input, - M: Mutator, + M: Mutator, E: Executor, { /// The mutator registered for this stage @@ -44,7 +44,7 @@ where for i in 0..num { let mut input_tmp = input.clone(); - self.mutator_mut().mutate(&mut input_tmp, i as i32)?; + self.mutator_mut().mutate(corpus, &mut input_tmp, i as i32)?; let interesting = self.executor().borrow_mut().evaluate_input(&input_tmp)?; @@ -59,24 +59,27 @@ where } /// The default mutational stage -pub struct DefaultMutationalStage +pub struct DefaultMutationalStage where + C: Corpus, I: Input, R: Rand, - M: Mutator, + M: Mutator, E: Executor, { rand: Rc>, executor: Rc>, mutator: M, + _phantom_corpus: PhantomData, _phantom_input: PhantomData, } -impl HasRand for DefaultMutationalStage +impl HasRand for DefaultMutationalStage where + C: Corpus, I: Input, R: Rand, - M: Mutator, + M: Mutator, E: Executor, { type R = R; @@ -86,12 +89,12 @@ where } } -impl MutationalStage for DefaultMutationalStage +impl MutationalStage for DefaultMutationalStage where C: Corpus, I: Input, R: Rand, - M: Mutator, + M: Mutator, E: Executor, { /// The mutator, added to this stage @@ -109,12 +112,12 @@ where } } -impl Stage for DefaultMutationalStage +impl Stage for DefaultMutationalStage where C: Corpus, I: Input, R: Rand, - M: Mutator, + M: Mutator, E: Executor, { fn perform(&mut self, corpus: &mut C) -> Result<(), AflError> { @@ -122,11 +125,12 @@ where } } -impl DefaultMutationalStage +impl DefaultMutationalStage where + C: Corpus, I: Input, R: Rand, - M: Mutator, + M: Mutator, E: Executor, { /// Creates a new default mutational stage @@ -135,6 +139,7 @@ where rand: Rc::clone(rand), executor: Rc::clone(executor), mutator: mutator, + _phantom_corpus: PhantomData, _phantom_input: PhantomData, } }