add RandGraphSnippetMutator
This commit is contained in:
parent
66babddb02
commit
4e3acf85ad
@ -1,5 +1,6 @@
|
||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||
|
||||
use wcet_qemu_sys::sysstate::graph::RandGraphSnippetMutator;
|
||||
use wcet_qemu_sys::sysstate::graph::GraphMaximizerCorpusScheduler;
|
||||
use wcet_qemu_sys::sysstate::graph::SysMapFeedback;
|
||||
use wcet_qemu_sys::sysstate::graph::SysGraphFeedbackState;
|
||||
@ -391,7 +392,10 @@ fn fuzz(
|
||||
// let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||
|
||||
// Setup a MOPT mutator
|
||||
let mutator = StdMOptMutator::new(&mut state, havoc_mutations().merge(tokens_mutations()), 5)?;
|
||||
let mutator = StdMOptMutator::new(&mut state, havoc_mutations()
|
||||
.merge(tokens_mutations())
|
||||
.merge(tuple_list!(RandGraphSnippetMutator::new())),
|
||||
5)?;
|
||||
|
||||
// let power = PowerMutationalStage::new(mutator, PowerSchedule::FAST, &edges_observer);
|
||||
let mutation = StdMutationalStage::new(mutator);
|
||||
|
@ -1,5 +1,14 @@
|
||||
|
||||
/// Feedbacks organizing SystemStates as a graph
|
||||
use libafl::inputs::HasBytesVec;
|
||||
use libafl::bolts::rands::RandomSeed;
|
||||
use libafl::bolts::rands::StdRand;
|
||||
use libafl::mutators::Mutator;
|
||||
use libafl::mutators::MutationResult;
|
||||
use core::marker::PhantomData;
|
||||
use libafl::state::HasCorpus;
|
||||
use libafl::state::HasSolutions;
|
||||
use libafl::state::HasRand;
|
||||
use crate::worst::MaxExecsLenFavFactor;
|
||||
use libafl::corpus::MinimizerCorpusScheduler;
|
||||
use libafl::bolts::HasRefCnt;
|
||||
@ -32,6 +41,10 @@ use petgraph::graph::NodeIndex;
|
||||
use petgraph::Direction;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use libafl::bolts::rands::Rand;
|
||||
use rand::SeedableRng;
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
//============================= Data Structures
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||
struct VariantTuple
|
||||
@ -100,12 +113,13 @@ impl PartialEq for SysGraphNode {
|
||||
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct SysGraphMetadata {
|
||||
indices: Vec<usize>, // Hashed enumeration of States
|
||||
inner: Vec<NodeIndex>,
|
||||
indices: Vec<usize>,
|
||||
tcref: isize,
|
||||
}
|
||||
impl SysGraphMetadata {
|
||||
pub fn new(inner: Vec<NodeIndex>) -> Self{
|
||||
Self {indices: inner.into_iter().map(|x| x.index()).collect(), tcref: 0}
|
||||
Self {indices: inner.iter().map(|x| x.index()).collect(), inner: inner, tcref: 0}
|
||||
}
|
||||
}
|
||||
impl AsSlice<usize> for SysGraphMetadata {
|
||||
@ -278,3 +292,106 @@ impl Named for SysMapFeedback
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
//============================= Mutators
|
||||
|
||||
pub struct RandGraphSnippetMutator<I, S>
|
||||
where
|
||||
I: Input + HasBytesVec,
|
||||
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
{
|
||||
phantom: PhantomData<(I, S)>,
|
||||
}
|
||||
impl<I, S> RandGraphSnippetMutator<I, S>
|
||||
where
|
||||
I: Input + HasBytesVec,
|
||||
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
RandGraphSnippetMutator{phantom: PhantomData}
|
||||
}
|
||||
}
|
||||
impl<I, S> Mutator<I, S> for RandGraphSnippetMutator<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 sibling_inputs : Vec<&Vec<u8>>= g[*trace.inner.last().unwrap()].variants.iter().map(|x| &x.input).collect();
|
||||
let mut snippet_collector = vec![];
|
||||
let mut per_input_counters = HashMap::<&Vec<u8>,usize>::new(); // ugly workaround to track multiple inputs
|
||||
for t in &trace.inner {
|
||||
let node = &g[*t];
|
||||
let mut per_node_snippets = HashMap::<&Vec<u8>,&[u8]>::new();
|
||||
for v in &node.variants {
|
||||
match per_input_counters.get_mut(&v.input) {
|
||||
None => {
|
||||
if sibling_inputs.iter().any(|x| *x==&v.input) { // only collect info about siblin inputs from target
|
||||
per_input_counters.insert(&v.input, v.input_counter.try_into().unwrap());
|
||||
}
|
||||
},
|
||||
Some(x) => {
|
||||
let x_u = *x;
|
||||
if x_u<v.input_counter as usize {
|
||||
*x=v.input_counter as usize;
|
||||
per_node_snippets.insert(&v.input,&v.input[x_u..v.input_counter as usize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
snippet_collector.push(per_node_snippets);
|
||||
}
|
||||
let mut new_input : Vec<u8> = vec![];
|
||||
for c in snippet_collector {
|
||||
new_input.clone_from_slice(myrand.choose(c).1);
|
||||
}
|
||||
for i in new_input.iter().enumerate() {
|
||||
input.bytes_mut()[i.0]=*i.1;
|
||||
}
|
||||
|
||||
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 RandGraphSnippetMutator<I, S>
|
||||
where
|
||||
I: Input + HasBytesVec,
|
||||
S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I> + HasFeedbackStates,
|
||||
{
|
||||
fn name(&self) -> &str {
|
||||
"RandGraphSnippetMutator"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user