add RandGraphSnippetMutator
This commit is contained in:
parent
66babddb02
commit
4e3acf85ad
@ -1,5 +1,6 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! 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::GraphMaximizerCorpusScheduler;
|
||||||
use wcet_qemu_sys::sysstate::graph::SysMapFeedback;
|
use wcet_qemu_sys::sysstate::graph::SysMapFeedback;
|
||||||
use wcet_qemu_sys::sysstate::graph::SysGraphFeedbackState;
|
use wcet_qemu_sys::sysstate::graph::SysGraphFeedbackState;
|
||||||
@ -391,7 +392,10 @@ fn fuzz(
|
|||||||
// let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
// let i2s = StdMutationalStage::new(StdScheduledMutator::new(tuple_list!(I2SRandReplace::new())));
|
||||||
|
|
||||||
// Setup a MOPT mutator
|
// 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 power = PowerMutationalStage::new(mutator, PowerSchedule::FAST, &edges_observer);
|
||||||
let mutation = StdMutationalStage::new(mutator);
|
let mutation = StdMutationalStage::new(mutator);
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
|
|
||||||
/// Feedbacks organizing SystemStates as a graph
|
/// 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 crate::worst::MaxExecsLenFavFactor;
|
||||||
use libafl::corpus::MinimizerCorpusScheduler;
|
use libafl::corpus::MinimizerCorpusScheduler;
|
||||||
use libafl::bolts::HasRefCnt;
|
use libafl::bolts::HasRefCnt;
|
||||||
@ -32,6 +41,10 @@ use petgraph::graph::NodeIndex;
|
|||||||
use petgraph::Direction;
|
use petgraph::Direction;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
use libafl::bolts::rands::Rand;
|
||||||
|
use rand::SeedableRng;
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
|
||||||
//============================= Data Structures
|
//============================= Data Structures
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||||
struct VariantTuple
|
struct VariantTuple
|
||||||
@ -100,12 +113,13 @@ impl PartialEq for SysGraphNode {
|
|||||||
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
||||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||||
pub struct SysGraphMetadata {
|
pub struct SysGraphMetadata {
|
||||||
indices: Vec<usize>, // Hashed enumeration of States
|
inner: Vec<NodeIndex>,
|
||||||
|
indices: Vec<usize>,
|
||||||
tcref: isize,
|
tcref: isize,
|
||||||
}
|
}
|
||||||
impl SysGraphMetadata {
|
impl SysGraphMetadata {
|
||||||
pub fn new(inner: Vec<NodeIndex>) -> Self{
|
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 {
|
impl AsSlice<usize> for SysGraphMetadata {
|
||||||
@ -277,4 +291,107 @@ impl Named for SysMapFeedback
|
|||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
&self.name
|
&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