add RandGraphSuffixMutator

This commit is contained in:
Alwin Berger 2022-05-08 13:45:10 +02:00
parent 5d28754e1b
commit 86ca7863ca

View File

@ -307,7 +307,7 @@ impl Named for SysMapFeedback
} }
//============================= Mutators //============================= Mutators
//=============================== Snippets
pub struct RandGraphSnippetMutator<I, S> pub struct RandGraphSnippetMutator<I, S>
where where
I: Input + HasBytesVec, I: Input + HasBytesVec,
@ -380,7 +380,7 @@ where
} }
let mut new_input : Vec<u8> = vec![]; let mut new_input : Vec<u8> = vec![];
for c in snippet_collector { for c in snippet_collector {
new_input.clone_from_slice(myrand.choose(c).1); new_input.extend_from_slice(myrand.choose(c).1);
} }
for i in new_input.iter().enumerate() { for i in new_input.iter().enumerate() {
input.bytes_mut()[i.0]=*i.1; input.bytes_mut()[i.0]=*i.1;
@ -408,3 +408,93 @@ where
"RandGraphSnippetMutator" "RandGraphSnippetMutator"
} }
} }
//============================= Mutators
//=============================== Suffix
pub struct RandGraphSuffixMutator<I, S>
where
I: Input + HasBytesVec,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
phantom: PhantomData<(I, S)>,
}
impl<I, S> RandGraphSuffixMutator<I, S>
where
I: Input + HasBytesVec,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
{
pub fn new() -> Self {
RandGraphSuffixMutator{phantom: PhantomData}
}
}
impl<I, S> Mutator<I, S> for RandGraphSuffixMutator<I, S>
where
I: Input + HasBytesVec,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I> + HasFeedbackStates,
{
fn mutate(
&mut self,
state: &mut S,
input: &mut I,
_stage_idx: i32
) -> Result<MutationResult, Error>
{
// need our own random generator, because borrowing rules
let mut myrand = StdRand::new();
let tmp = &mut state.rand_mut();
myrand.set_seed(tmp.next());
drop(tmp);
let feedbackstate = state
.feedback_states()
.match_name::<SysGraphFeedbackState>("SysMap")
.unwrap();
let g = &feedbackstate.graph;
let tmp = state.metadata().get::<SysGraphMetadata>();
if tmp.is_none() { // if there are no metadata it was probably not interesting anyways
return Ok(MutationResult::Skipped);
}
let trace =tmp.expect("SysGraphMetadata not found");
// follow the path, extract snippets from last reads, find common snippets.
// those are likley keys parts. choose random parts from other sibling traces
let inp_c_end = g[*trace.inner.last().unwrap()].base.input_counter;
let mut num_to_reverse = 1;
for t in trace.inner.iter().rev() {
let int_c_prefix = g[*t].base.input_counter;
if int_c_prefix < inp_c_end {
num_to_reverse-=1;
if num_to_reverse<=0 {
let mut new_input=input.bytes()[..(int_c_prefix as usize)].to_vec();
let mut ext : Vec<u8> = (int_c_prefix..inp_c_end).map(|_| myrand.next().to_le_bytes()).flatten().collect();
new_input.append(&mut ext);
for i in new_input.iter().enumerate() {
if input.bytes_mut().len()>i.0 {
input.bytes_mut()[i.0]=*i.1;
}
else { break };
}
break;
}
}
}
Ok(MutationResult::Mutated)
}
fn post_exec(
&mut self,
_state: &mut S,
_stage_idx: i32,
_corpus_idx: Option<usize>
) -> Result<(), Error> {
Ok(())
}
}
impl<I, S> Named for RandGraphSuffixMutator<I, S>
where
I: Input + HasBytesVec,
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I> + HasFeedbackStates,
{
fn name(&self) -> &str {
"RandGraphSuffixMutator"
}
}