From 2eedb67dafed01189f746b9795d054cd0f2a59e8 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Wed, 11 Nov 2020 05:24:54 +0100 Subject: [PATCH] started corpus --- src/executors/mod.rs | 3 +- src/mutators/scheduled.rs | 67 +++++++++++++++++++++++++++++++++++++-- src/stages/mutational.rs | 3 +- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/executors/mod.rs b/src/executors/mod.rs index 25aaf8e3f1..a13333c81f 100644 --- a/src/executors/mod.rs +++ b/src/executors/mod.rs @@ -47,9 +47,8 @@ where /// Returns vector of feebacks (mutable) fn feedbacks_mut(&mut self) -> &mut 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 + // TODO: Move to another struct, like evaluator? fn evaluate_input(&mut self, input: &I) -> Result { self.reset_observers()?; self.run_target(input)?; diff --git a/src/mutators/scheduled.rs b/src/mutators/scheduled.rs index 198b83a7f5..87092c1901 100644 --- a/src/mutators/scheduled.rs +++ b/src/mutators/scheduled.rs @@ -1,6 +1,6 @@ extern crate alloc; -use crate::mutators::Corpus; use crate::inputs::{HasBytesVec, Input}; +use crate::mutators::Corpus; use crate::mutators::Mutator; use crate::utils::{HasRand, Rand}; use crate::AflError; @@ -52,7 +52,12 @@ where /// New default implementation for mutate /// Implementations must forward mutate() to this method - fn scheduled_mutate(&mut self, corpus: &mut C, 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, corpus, input)?; @@ -150,7 +155,11 @@ where } /// Bitflip mutation for inputs with a bytes vector -pub fn mutation_bitflip(mutator: &mut M, _corpus: &mut C, input: &mut I) -> Result<(), AflError> +pub fn mutation_bitflip( + mutator: &mut M, + _corpus: &mut C, + input: &mut I, +) -> Result<(), AflError> where C: Corpus, M: Mutator, @@ -161,6 +170,58 @@ where Ok(()) } +/// Returns the first and last diff position between the given vectors, stopping at the min len +fn locate_diffs(this: &Vec, other: &Vec) -> (i64, i64) { + let mut first_diff: i64 = -1; + let mut last_diff: i64 = -1; + for (i, (this_el, other_el)) in this.iter().zip(other.iter()).enumerate() { + if this_el != other_el { + if first_diff < 0 { + first_diff = i as i64; + } + last_diff = i as i64; + } + } + + (first_diff, last_diff) +} + +/// Splicing mutator +pub fn mutation_splice( + mutator: &mut M, + corpus: &mut C, + input: &mut I, +) -> Result<(), AflError> +where + C: Corpus, + M: Mutator, + I: Input + HasBytesVec, +{ + let other_rr = corpus.random_entry()?; + let mut other_testcase = other_rr.borrow_mut(); + let other = other_testcase.load_input()?; + + let mut counter = 0; + let (first_diff, last_diff) = loop { + let (f, l) = locate_diffs(input.bytes(), other.bytes()); + if f != l && f >= 0 && l >= 2 { + break (f, l); + } + if counter == 20 { + return Err(AflError::Empty("No valid diff found".to_owned())); + } + counter += 1; + }; + + let split_at = mutator.rand_between(first_diff as u64, last_diff as u64) as usize; + + Err(AflError::NotImplemented(format!("TODO: fix Splice (would split at {})", counter)); + + //input.bytes_mut().splice(split_at.., other.bytes()[split_at..]).collect(); + + //Ok(()) +} + /// Schedule some selected byte level mutations given a ScheduledMutator type pub struct HavocBytesMutator where diff --git a/src/stages/mutational.rs b/src/stages/mutational.rs index 3519ce30e4..ad22f5f078 100644 --- a/src/stages/mutational.rs +++ b/src/stages/mutational.rs @@ -44,7 +44,8 @@ where for i in 0..num { let mut input_tmp = input.clone(); - self.mutator_mut().mutate(corpus, &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)?;