remove unused code
This commit is contained in:
parent
6cb2be4408
commit
acf9b04e70
@ -1,41 +1,22 @@
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use libafl_bolts::{
|
||||
current_nanos,
|
||||
rands::StdRand,
|
||||
tuples::{tuple_list,MatchName},
|
||||
impl_serdeany,
|
||||
Named,
|
||||
};
|
||||
use libafl_bolts::Named;
|
||||
use libafl::{
|
||||
executors::{ExitKind},
|
||||
fuzzer::{StdFuzzer},
|
||||
inputs::{BytesInput, HasTargetBytes},
|
||||
observers::{Observer,VariableMapObserver},
|
||||
state::{StdState},
|
||||
executors::ExitKind,
|
||||
observers::Observer,
|
||||
Error,
|
||||
common::HasNamedMetadata,
|
||||
observers::ObserversTuple, prelude::UsesInput,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{cell::UnsafeCell, cmp::max, env, fs::OpenOptions, io::Write, time::Instant};
|
||||
use std::{fs::OpenOptions, io::Write};
|
||||
|
||||
use libafl_qemu::{
|
||||
emu,
|
||||
emu::Emulator,
|
||||
executor::QemuExecutor,
|
||||
helpers::{QemuHelper, QemuHelperTuple, HasInstrumentationFilter},
|
||||
};
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::MaybeHasClientPerfMonitor;
|
||||
use libafl::prelude::State;
|
||||
use libafl::inputs::Input;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl::SerdeAny;
|
||||
use libafl::common::HasMetadata;
|
||||
use libafl::corpus::testcase::Testcase;
|
||||
use core::{fmt::Debug, time::Duration};
|
||||
// use libafl::feedbacks::FeedbackState;
|
||||
// use libafl::state::HasFeedbackStates;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use std::path::PathBuf;
|
||||
use std::borrow::Cow;
|
||||
@ -45,12 +26,12 @@ pub static mut FUZZ_START_TIMESTAMP : SystemTime = UNIX_EPOCH;
|
||||
pub const QEMU_ICOUNT_SHIFT : u32 = 5;
|
||||
pub const QEMU_ISNS_PER_SEC : u32 = u32::pow(10, 9) / u32::pow(2, QEMU_ICOUNT_SHIFT);
|
||||
pub const QEMU_ISNS_PER_USEC : u32 = QEMU_ISNS_PER_SEC / 1000000;
|
||||
pub const QEMU_NS_PER_ISN : u32 = 1 << QEMU_ICOUNT_SHIFT;
|
||||
pub const TARGET_SYSCLK_FREQ : u32 = 25 * 1000 * 1000;
|
||||
pub const TARGET_MHZ_PER_MIPS : f32 = TARGET_SYSCLK_FREQ as f32 / QEMU_ISNS_PER_SEC as f32;
|
||||
pub const TARGET_MIPS_PER_MHZ : f32 = QEMU_ISNS_PER_SEC as f32 / TARGET_SYSCLK_FREQ as f32;
|
||||
pub const TARGET_SYSCLK_PER_QEMU_SEC : u32 = (TARGET_SYSCLK_FREQ as f32 * TARGET_MIPS_PER_MHZ) as u32;
|
||||
pub const QEMU_SYSCLK_PER_TARGET_SEC : u32 = (TARGET_SYSCLK_FREQ as f32 * TARGET_MHZ_PER_MIPS) as u32;
|
||||
pub const _QEMU_NS_PER_ISN : u32 = 1 << QEMU_ICOUNT_SHIFT;
|
||||
pub const _TARGET_SYSCLK_FREQ : u32 = 25 * 1000 * 1000;
|
||||
pub const _TARGET_MHZ_PER_MIPS : f32 = _TARGET_SYSCLK_FREQ as f32 / QEMU_ISNS_PER_SEC as f32;
|
||||
pub const _TARGET_MIPS_PER_MHZ : f32 = QEMU_ISNS_PER_SEC as f32 / _TARGET_SYSCLK_FREQ as f32;
|
||||
pub const _TARGET_SYSCLK_PER_QEMU_SEC : u32 = (_TARGET_SYSCLK_FREQ as f32 * _TARGET_MIPS_PER_MHZ) as u32;
|
||||
pub const _QEMU_SYSCLK_PER_TARGET_SEC : u32 = (_TARGET_SYSCLK_FREQ as f32 * _TARGET_MHZ_PER_MIPS) as u32;
|
||||
|
||||
//========== Metadata
|
||||
#[derive(Debug, SerdeAny, Serialize, Deserialize)]
|
||||
@ -244,7 +225,7 @@ where
|
||||
&mut self,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
observers: &OT,
|
||||
_observers: &OT,
|
||||
testcase: &mut Testcase<S::Input>,
|
||||
) -> Result<(), Error> {
|
||||
*testcase.exec_time_mut() = self.exec_time;
|
||||
@ -325,7 +306,7 @@ where
|
||||
|
||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||
#[inline]
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
// testcase.metadata_mut().insert(QemuIcountMetadata{runtime: self.last_runtime});
|
||||
Ok(())
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use libafl_bolts::{
|
||||
core_affinity::Cores, current_nanos, rands::StdRand, shmem::{ShMemProvider, StdShMemProvider}, tuples::tuple_list, AsSlice
|
||||
};
|
||||
use libafl::{
|
||||
common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator
|
||||
common::{HasMetadata, HasNamedMetadata}, corpus::{Corpus, InMemoryCorpus, OnDiskCorpus}, events::{launcher::Launcher, EventConfig}, executors::ExitKind, feedback_or, feedback_or_fast, feedbacks::{CrashFeedback, MaxMapFeedback, TimeoutFeedback}, fuzzer::{Fuzzer, StdFuzzer}, inputs::{BytesInput, HasTargetBytes}, monitors::MultiMonitor, observers::{CanTrack, VariableMapObserver}, prelude::{havoc_mutations, minimizer::TopRatedsMetadata, CorpusId, Generator, HitcountsMapObserver, RandBytesGenerator, SimpleEventManager, SimpleMonitor, SimpleRestartingEventManager, StdScheduledMutator}, schedulers::QueueScheduler, stages::StdMutationalStage, state::{HasCorpus, StdState}, Error, Evaluator
|
||||
};
|
||||
use libafl_qemu::{
|
||||
edges::{self, edges_map_mut_ptr, QemuEdgeCoverageHelper, MAX_EDGES_FOUND}, elf::EasyElf, emu::Emulator, GuestAddr, GuestPhysAddr, QemuExecutor, QemuFilterList, QemuHooks, Regs, StdInstrumentationFilter
|
||||
@ -780,7 +780,7 @@ let mut run_client = |state: Option<_>, mut mgr, _core_id| {
|
||||
#[cfg(feature = "restarting")]
|
||||
{
|
||||
let mut shmem_provider = StdShMemProvider::new().unwrap();
|
||||
let (state, mut mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)
|
||||
let (state, mgr) = match SimpleRestartingEventManager::launch(monitor, &mut shmem_provider)
|
||||
{
|
||||
// The restarting state will spawn the same process again as child, then restarted it each time it crashes.
|
||||
Ok(res) => res,
|
||||
|
@ -1,12 +1,9 @@
|
||||
use libafl::SerdeAny;
|
||||
use libafl_bolts::ownedref::OwnedSlice;
|
||||
use libafl::inputs::BytesInput;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl::common::HasNamedMetadata;
|
||||
use std::path::PathBuf;
|
||||
use crate::clock::QemuClockObserver;
|
||||
use libafl::corpus::Testcase;
|
||||
use libafl_bolts::tuples::MatchName;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
@ -17,17 +14,13 @@ use libafl::feedbacks::Feedback;
|
||||
use libafl_bolts::Named;
|
||||
use libafl::Error;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, common::HasMetadata};
|
||||
use libafl::{executors::ExitKind, observers::ObserversTuple, common::HasMetadata};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::ExecInterval;
|
||||
use super::ReducedFreeRTOSSystemState;
|
||||
use super::FreeRTOSSystemStateMetadata;
|
||||
use super::observers::QemuSystemStateObserver;
|
||||
use petgraph::prelude::DiGraph;
|
||||
use petgraph::graph::NodeIndex;
|
||||
use petgraph::Direction;
|
||||
use std::cmp::Ordering;
|
||||
use std::borrow::Cow;
|
||||
|
||||
//============================= Feedback
|
||||
@ -71,10 +64,10 @@ where
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
manager: &mut EM,
|
||||
input: &S::Input,
|
||||
_manager: &mut EM,
|
||||
_input: &S::Input,
|
||||
observers: &OT,
|
||||
exit_kind: &ExitKind,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<State = S>,
|
||||
@ -127,7 +120,7 @@ where
|
||||
|
||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||
#[inline]
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
let a = self.last_trace.take();
|
||||
match a {
|
||||
Some(s) => testcase.metadata_map_mut().insert(FreeRTOSSystemStateMetadata::new(s)),
|
||||
@ -177,11 +170,11 @@ where
|
||||
{
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
manager: &mut EM,
|
||||
input: &S::Input,
|
||||
_state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &S::Input,
|
||||
observers: &OT,
|
||||
exit_kind: &ExitKind,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<State = S>,
|
||||
@ -203,7 +196,7 @@ where
|
||||
}
|
||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||
#[inline]
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, _testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
if !self.dump_metadata {return Ok(());}
|
||||
// let a = self.last_trace.take();
|
||||
// match a {
|
||||
@ -232,13 +225,15 @@ impl Named for DumpSystraceFeedback
|
||||
impl DumpSystraceFeedback
|
||||
{
|
||||
/// Creates a new [`DumpSystraceFeedback`]
|
||||
#[must_use]
|
||||
#[allow(unused)]
|
||||
pub fn new() -> Self {
|
||||
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: false, last_trace: None, last_states: None }
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub fn with_dump(dumpfile: Option<PathBuf>) -> Self {
|
||||
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: dumpfile, dump_metadata: false, last_trace: None, last_states: None}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub fn metadata_only() -> Self {
|
||||
Self {name: Cow::from("Dumpsystemstate".to_string()), dumpfile: None, dump_metadata: true, last_trace: None, last_states: None}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr)]
|
||||
#![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr,unused)]
|
||||
use serde::{Deserialize, Serialize};
|
||||
// Manual Types
|
||||
use libafl_qemu::{Emulator, Qemu};
|
||||
use libafl_qemu::Qemu;
|
||||
|
||||
/*========== Start of generated Code =============*/
|
||||
pub type char_ptr = ::std::os::raw::c_uint;
|
||||
|
@ -1,632 +0,0 @@
|
||||
|
||||
use libafl::SerdeAny;
|
||||
/// Feedbacks organizing SystemStates as a graph
|
||||
// use libafl::inputs::HasBytesVec;
|
||||
use libafl_bolts::rands::random_seed;
|
||||
use libafl_bolts::rands::StdRand;
|
||||
use libafl::mutators::Mutator;
|
||||
use libafl::mutators::MutationResult;
|
||||
use libafl::prelude::HasTargetBytes;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl::common::HasNamedMetadata;
|
||||
use libafl::state::UsesState;
|
||||
use libafl::prelude::State;
|
||||
use core::marker::PhantomData;
|
||||
use libafl::state::HasCorpus;
|
||||
use libafl::state::HasSolutions;
|
||||
use libafl::state::HasRand;
|
||||
use crate::worst::MaxExecsLenFavFactor;
|
||||
use crate::worst::MaxTimeFavFactor;
|
||||
use libafl::schedulers::MinimizerScheduler;
|
||||
use libafl_bolts::HasRefCnt;
|
||||
use libafl_bolts::AsSlice;
|
||||
use libafl_bolts::ownedref::OwnedSlice;
|
||||
use libafl::inputs::BytesInput;
|
||||
use std::path::PathBuf;
|
||||
use crate::clock::QemuClockObserver;
|
||||
use libafl::corpus::Testcase;
|
||||
use libafl_bolts::tuples::MatchName;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::MaybeHasClientPerfMonitor;
|
||||
use libafl::feedbacks::Feedback;
|
||||
use libafl_bolts::Named;
|
||||
use libafl::Error;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, common::HasMetadata};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::ExecInterval;
|
||||
use super::ReducedFreeRTOSSystemState;
|
||||
use super::FreeRTOSSystemStateMetadata;
|
||||
use super::observers::QemuSystemStateObserver;
|
||||
use petgraph::prelude::DiGraph;
|
||||
use petgraph::graph::NodeIndex;
|
||||
use petgraph::Direction;
|
||||
use std::cmp::Ordering;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use libafl_bolts::rands::Rand;
|
||||
|
||||
//============================= Data Structures
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
|
||||
pub struct VariantTuple
|
||||
{
|
||||
pub start_tick: u64,
|
||||
pub end_tick: u64,
|
||||
input_counter: u32,
|
||||
pub input: Vec<u8>, // in the end any kind of input are bytes, regardless of type and lifetime
|
||||
}
|
||||
impl VariantTuple {
|
||||
fn from(other: &ReducedFreeRTOSSystemState,input: Vec<u8>) -> Self {
|
||||
// VariantTuple{
|
||||
// start_tick: other.tick,
|
||||
// end_tick: other.end_tick,
|
||||
// input_counter: other.input_counter,
|
||||
// input: input,
|
||||
// }
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
pub struct SysGraphNode
|
||||
{
|
||||
base: ReducedFreeRTOSSystemState,
|
||||
pub variants: Vec<VariantTuple>,
|
||||
}
|
||||
impl SysGraphNode {
|
||||
fn from(base: ReducedFreeRTOSSystemState, input: Vec<u8>) -> Self {
|
||||
SysGraphNode{variants: vec![VariantTuple::from(&base, input)], base:base }
|
||||
}
|
||||
/// unites the variants of this value with another, draining the other if the bases are equal
|
||||
fn unite(&mut self, other: &mut SysGraphNode) -> bool {
|
||||
if self!=other {return false;}
|
||||
self.variants.append(&mut other.variants);
|
||||
self.variants.dedup();
|
||||
return true;
|
||||
}
|
||||
/// add a Varint from a [`RefinedFreeRTOSSystemState`]
|
||||
fn unite_raw(&mut self, other: &ReducedFreeRTOSSystemState, input: &Vec<u8>) -> bool {
|
||||
if &self.base!=other {return false;}
|
||||
self.variants.push(VariantTuple::from(other, input.clone()));
|
||||
self.variants.dedup();
|
||||
return true;
|
||||
}
|
||||
/// add a Varint from a [`RefinedFreeRTOSSystemState`], if it's interesting
|
||||
fn unite_interesting(&mut self, other: &ReducedFreeRTOSSystemState, input: &Vec<u8>) -> bool {
|
||||
// if &self.base!=other {return false;}
|
||||
// let interesting =
|
||||
// self.variants.iter().all(|x| x.end_tick-x.start_tick<other.end_tick-other.tick) || // longest variant
|
||||
// self.variants.iter().all(|x| x.end_tick-x.start_tick>other.end_tick-other.tick) || // shortest variant
|
||||
// self.variants.iter().all(|x| x.input_counter>other.input_counter) || // longest input
|
||||
// self.variants.iter().all(|x| x.input_counter<other.input_counter); // shortest input
|
||||
// if interesting {
|
||||
// let var = VariantTuple::from(other, input.clone());
|
||||
// self.variants.push(var);
|
||||
// }
|
||||
// return interesting;
|
||||
todo!()
|
||||
}
|
||||
pub fn get_taskname(&self) -> &str {
|
||||
&self.base.current_task.task_name
|
||||
}
|
||||
pub fn get_input_counts(&self) -> Vec<u32> {
|
||||
self.variants.iter().map(|x| x.input_counter).collect()
|
||||
}
|
||||
pub fn pretty_print(&self) -> String {
|
||||
let mut ret = String::new();
|
||||
ret.push_str(&format!("{}",&self.base.current_task.task_name));
|
||||
ret.push_str(";Rl:");
|
||||
for i in &self.base.ready_list_after {
|
||||
ret.push_str(&format!(";{}",i.task_name));
|
||||
}
|
||||
ret.push_str(";Dl:");
|
||||
for i in &self.base.delay_list_after {
|
||||
ret.push_str(&format!(";{}",i.task_name));
|
||||
}
|
||||
// println!("{}",ret);
|
||||
ret
|
||||
}
|
||||
}
|
||||
impl PartialEq for SysGraphNode {
|
||||
fn eq(&self, other: &SysGraphNode) -> bool {
|
||||
self.base==other.base
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper around Vec<RefinedFreeRTOSSystemState> to attach as Metadata
|
||||
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
|
||||
pub struct SysGraphMetadata {
|
||||
pub inner: Vec<NodeIndex>,
|
||||
indices: Vec<usize>,
|
||||
tcref: isize,
|
||||
}
|
||||
impl SysGraphMetadata {
|
||||
pub fn new(inner: Vec<NodeIndex>) -> Self{
|
||||
Self {indices: inner.iter().map(|x| x.index()).collect(), inner: inner, tcref: 0}
|
||||
}
|
||||
}
|
||||
// impl AsSlice for SysGraphMetadata {
|
||||
// /// Convert the slice of system-states to a slice of hashes over enumerated states
|
||||
// fn as_slice(&self) -> &[usize] {
|
||||
// self.indices.as_slice()
|
||||
// }
|
||||
|
||||
// type Entry = usize;
|
||||
// }
|
||||
|
||||
impl HasRefCnt for SysGraphMetadata {
|
||||
fn refcnt(&self) -> isize {
|
||||
self.tcref
|
||||
}
|
||||
|
||||
fn refcnt_mut(&mut self) -> &mut isize {
|
||||
&mut self.tcref
|
||||
}
|
||||
}
|
||||
|
||||
libafl_bolts::impl_serdeany!(SysGraphMetadata);
|
||||
|
||||
pub type GraphMaximizerCorpusScheduler<CS, O> =
|
||||
MinimizerScheduler<CS, MaxTimeFavFactor<<CS as UsesState>::State>,SysGraphMetadata,O>;
|
||||
|
||||
//============================= Graph Feedback
|
||||
|
||||
/// Improved System State Graph
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, SerdeAny)]
|
||||
pub struct SysGraphFeedbackState
|
||||
{
|
||||
pub graph: DiGraph<SysGraphNode, ()>,
|
||||
entrypoint: NodeIndex,
|
||||
exit: NodeIndex,
|
||||
name: Cow<'static, str>
|
||||
}
|
||||
impl SysGraphFeedbackState
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
let mut graph = DiGraph::<SysGraphNode, ()>::new();
|
||||
let mut entry = SysGraphNode::default();
|
||||
entry.base.current_task.task_name="Start".to_string();
|
||||
let mut exit = SysGraphNode::default();
|
||||
exit.base.current_task.task_name="End".to_string();
|
||||
let entry = graph.add_node(entry);
|
||||
let exit = graph.add_node(exit);
|
||||
Self {graph: graph, entrypoint: entry, exit: exit, name: Cow::from(String::from("SysMap"))}
|
||||
}
|
||||
fn insert(&mut self, list: Vec<ReducedFreeRTOSSystemState>, input: &Vec<u8>) {
|
||||
let mut current_index = self.entrypoint;
|
||||
for n in list {
|
||||
let mut done = false;
|
||||
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
|
||||
if n == self.graph[i].base {
|
||||
done = true;
|
||||
current_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !done {
|
||||
let j = self.graph.add_node(SysGraphNode::from(n,input.clone()));
|
||||
self.graph.add_edge(current_index, j, ());
|
||||
current_index = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Try adding a system state path from a [Vec<RefinedFreeRTOSSystemState>], return true if the path was interesting
|
||||
fn update(&mut self, list: &Vec<ReducedFreeRTOSSystemState>, input: &Vec<u8>) -> (bool, Vec<NodeIndex>) {
|
||||
let mut current_index = self.entrypoint;
|
||||
let mut novel = false;
|
||||
let mut trace : Vec<NodeIndex> = vec![current_index];
|
||||
for n in list {
|
||||
let mut matching : Option<NodeIndex> = None;
|
||||
for i in self.graph.node_indices() {
|
||||
let tmp = &self.graph[i];
|
||||
if n == &tmp.base {
|
||||
matching = Some(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
match matching {
|
||||
None => {
|
||||
novel = true;
|
||||
let j = self.graph.add_node(SysGraphNode::from(n.clone(),input.clone()));
|
||||
self.graph.update_edge(current_index, j, ());
|
||||
current_index = j;
|
||||
},
|
||||
Some(i) => {
|
||||
novel |= self.graph[i].unite_interesting(&n, input);
|
||||
self.graph.update_edge(current_index, i, ());
|
||||
current_index = i;
|
||||
}
|
||||
}
|
||||
trace.push(current_index);
|
||||
}
|
||||
if current_index != self.entrypoint {
|
||||
self.graph.update_edge(current_index, self.exit, ()); // every path ends in the exit noded
|
||||
}
|
||||
return (novel, trace);
|
||||
}
|
||||
}
|
||||
impl Named for SysGraphFeedbackState
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &Cow<'static, str> {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
impl Default for SysGraphFeedbackState {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
impl SysGraphFeedbackState
|
||||
{
|
||||
fn reset(&mut self) -> Result<(), Error> {
|
||||
self.graph.clear();
|
||||
let mut entry = SysGraphNode::default();
|
||||
entry.base.current_task.task_name="Start".to_string();
|
||||
let mut exit = SysGraphNode::default();
|
||||
exit.base.current_task.task_name="End".to_string();
|
||||
self.entrypoint = self.graph.add_node(entry);
|
||||
self.exit = self.graph.add_node(exit);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||
pub struct SysMapFeedback
|
||||
{
|
||||
name: Cow<'static, str>,
|
||||
last_trace: Option<Vec<NodeIndex>>,
|
||||
}
|
||||
impl SysMapFeedback {
|
||||
pub fn new() -> Self {
|
||||
Self {name: Cow::from(String::from("SysMapFeedback")), last_trace: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Feedback<S> for SysMapFeedback
|
||||
where
|
||||
S: State + UsesInput + MaybeHasClientPerfMonitor + HasNamedMetadata,
|
||||
S::Input: HasTargetBytes,
|
||||
{
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
fn is_interesting<EM, OT>(
|
||||
&mut self,
|
||||
state: &mut S,
|
||||
_manager: &mut EM,
|
||||
_input: &S::Input,
|
||||
observers: &OT,
|
||||
_exit_kind: &ExitKind,
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
EM: EventFirer<State = S>,
|
||||
OT: ObserversTuple<S>,
|
||||
{
|
||||
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
|
||||
.expect("QemuSystemStateObserver not found");
|
||||
let feedbackstate = match state
|
||||
.named_metadata_map_mut()
|
||||
.get_mut::<SysGraphFeedbackState>("SysMap") {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
let n=SysGraphFeedbackState::default();
|
||||
state.named_metadata_map_mut().insert("SysMap",n);
|
||||
state.named_metadata_map_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
|
||||
}
|
||||
};
|
||||
let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
|
||||
self.last_trace = Some(ret.1);
|
||||
Ok(ret.0)
|
||||
}
|
||||
|
||||
/// Append to the testcase the generated metadata in case of a new corpus item
|
||||
#[inline]
|
||||
fn append_metadata<EM, OT>(&mut self, _state: &mut S, _manager: &mut EM, _observers: &OT, testcase: &mut Testcase<S::Input>) -> Result<(), Error> {
|
||||
let a = self.last_trace.take();
|
||||
match a {
|
||||
Some(s) => testcase.metadata_map_mut().insert(SysGraphMetadata::new(s)),
|
||||
None => (),
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Discard the stored metadata in case that the testcase is not added to the corpus
|
||||
#[inline]
|
||||
fn discard_metadata(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
||||
self.last_trace = None;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
impl Named for SysMapFeedback
|
||||
{
|
||||
#[inline]
|
||||
fn name(&self) -> &Cow<'static, str> {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
//============================= Mutators
|
||||
//=============================== Snippets
|
||||
// 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>,
|
||||
// {
|
||||
// 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.extend_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>,
|
||||
// {
|
||||
// fn name(&self) -> &str {
|
||||
// "RandGraphSnippetMutator"
|
||||
// }
|
||||
// }
|
||||
// //=============================== Snippets
|
||||
// pub struct RandInputSnippetMutator<I, S>
|
||||
// where
|
||||
// I: Input + HasBytesVec,
|
||||
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
// {
|
||||
// phantom: PhantomData<(I, S)>,
|
||||
// }
|
||||
// impl<I, S> RandInputSnippetMutator<I, S>
|
||||
// where
|
||||
// I: Input + HasBytesVec,
|
||||
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
// {
|
||||
// pub fn new() -> Self {
|
||||
// RandInputSnippetMutator{phantom: PhantomData}
|
||||
// }
|
||||
// }
|
||||
// impl<I, S> Mutator<I, S> for RandInputSnippetMutator<I, S>
|
||||
// where
|
||||
// I: Input + HasBytesVec,
|
||||
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
// {
|
||||
// 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");
|
||||
|
||||
// let mut collection : Vec<Vec<u8>> = Vec::new();
|
||||
// let mut current_pointer : usize = 0;
|
||||
// for t in &trace.inner {
|
||||
// let node = &g[*t];
|
||||
// for v in &node.variants {
|
||||
// if v.input == input.bytes() {
|
||||
// if v.input_counter > current_pointer.try_into().unwrap() {
|
||||
// collection.push(v.input[current_pointer..v.input_counter as usize].to_owned());
|
||||
// current_pointer = v.input_counter as usize;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// let index_to_mutate = myrand.below(collection.len() as u64) as usize;
|
||||
// for i in 0..collection[index_to_mutate].len() {
|
||||
// collection[index_to_mutate][i] = myrand.below(0xFF) as u8;
|
||||
// }
|
||||
// for i in collection.concat().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 RandInputSnippetMutator<I, S>
|
||||
// where
|
||||
// I: Input + HasBytesVec,
|
||||
// S: HasRand + HasMetadata + HasCorpus<I> + HasSolutions<I>,
|
||||
// {
|
||||
// fn name(&self) -> &str {
|
||||
// "RandInputSnippetMutator"
|
||||
// }
|
||||
// }
|
||||
// //=============================== 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>,
|
||||
// {
|
||||
// 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 = myrand.below(trace.inner.len().try_into().unwrap());
|
||||
// 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>,
|
||||
// {
|
||||
// fn name(&self) -> &str {
|
||||
// "RandGraphSuffixMutator"
|
||||
// }
|
||||
// }
|
@ -1,21 +1,13 @@
|
||||
use std::cell::UnsafeCell;
|
||||
use std::io::Write;
|
||||
use std::ops::Range;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::prelude::ExitKind;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl_qemu::read_user_reg_unchecked;
|
||||
use libafl_qemu::Emulator;
|
||||
use libafl_qemu::GuestAddr;
|
||||
use libafl_qemu::GuestPhysAddr;
|
||||
use libafl_qemu::GuestReg;
|
||||
use libafl_qemu::Qemu;
|
||||
use libafl_qemu::QemuHooks;
|
||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||
use libafl_qemu::emu;
|
||||
use libafl_qemu::hooks;
|
||||
use libafl_qemu::Hook;
|
||||
// use crate::systemstate::extract_abbs_from_trace;
|
||||
use libafl_qemu::helpers::{QemuHelper, QemuHelperTuple};
|
||||
|
||||
use crate::systemstate::RawFreeRTOSSystemState;
|
||||
use crate::systemstate::CURRENT_SYSTEMSTATE_VEC;
|
||||
use crate::systemstate::NUM_PRIOS;
|
||||
@ -26,18 +18,7 @@ use super::freertos::rtos_struct::*;
|
||||
use super::freertos;
|
||||
use super::CaptureEvent;
|
||||
|
||||
use libafl_qemu::{
|
||||
helpers::{QemuHelper, QemuHelperTuple},
|
||||
// edges::SAVED_JUMP,
|
||||
};
|
||||
|
||||
//============================= Struct definitions
|
||||
|
||||
pub static mut INTR_OFFSET : Option<u64> = None;
|
||||
pub static mut INTR_DONE : bool = true;
|
||||
|
||||
// only used when inputs are injected
|
||||
pub static mut NEXT_INPUT : Vec<u8> = Vec::new();
|
||||
|
||||
//============================= API symbols
|
||||
|
||||
@ -235,7 +216,7 @@ fn trigger_collection(emulator: &libafl_qemu::Qemu, edge: (GuestAddr, GuestAddr)
|
||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||
let critical : void_ptr = freertos::emu_lookup::lookup(emulator, h.critical_addr);
|
||||
let suspended : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_lock_addr);
|
||||
let running : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_running_addr);
|
||||
let _running : void_ptr = freertos::emu_lookup::lookup(emulator, h.scheduler_running_addr);
|
||||
|
||||
systemstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
||||
// During ISRs it is only safe to extract structs if they are not currently being modified
|
||||
|
@ -3,13 +3,11 @@ use std::collections::hash_map::DefaultHasher;
|
||||
use std::fmt;
|
||||
use hashbrown::HashSet;
|
||||
use libafl_bolts::HasRefCnt;
|
||||
use libafl_bolts::AsSlice;
|
||||
use libafl_qemu::GuestAddr;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::rc::Rc;
|
||||
|
||||
use freertos::TCB_t;
|
||||
|
||||
@ -17,7 +15,6 @@ pub mod freertos;
|
||||
pub mod helpers;
|
||||
pub mod observers;
|
||||
pub mod feedbacks;
|
||||
pub mod graph;
|
||||
pub mod schedulers;
|
||||
pub mod stg;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// use crate::systemstate::IRQ_INPUT_BYTES_NUMBER;
|
||||
use libafl::prelude::ExitKind;
|
||||
use libafl::{inputs::HasTargetBytes, prelude::UsesInput};
|
||||
use libafl_bolts::HasLen;
|
||||
@ -54,11 +53,11 @@ where
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &S::Input, _exit_kind: &ExitKind) -> Result<(), Error> {
|
||||
// unsafe {self.last_run = invalidate_ineffective_isr(refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC));}
|
||||
unsafe {
|
||||
let mut temp = refine_system_states(&mut CURRENT_SYSTEMSTATE_VEC);
|
||||
let temp = refine_system_states(CURRENT_SYSTEMSTATE_VEC.drain(..).collect());
|
||||
// fix_broken_trace(&mut temp.1);
|
||||
self.last_run = temp.0.clone();
|
||||
// println!("{:?}",temp);
|
||||
let mut temp = states2intervals(temp.0, temp.1);
|
||||
let temp = states2intervals(temp.0, temp.1);
|
||||
self.last_trace = temp.0;
|
||||
self.last_states = temp.1;
|
||||
self.success = temp.2;
|
||||
@ -138,7 +137,7 @@ fn tcb_list_to_vec_cached(list: List_t, dump: &mut HashMap<u32,rtos_struct>) ->
|
||||
ret
|
||||
}
|
||||
/// Drains a List of raw SystemStates to produce a refined trace
|
||||
fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, Vec<(u64, CaptureEvent, String, (u32, u32))>) {
|
||||
fn refine_system_states(mut input: Vec<RawFreeRTOSSystemState>) -> (Vec<ReducedFreeRTOSSystemState>, Vec<(u64, CaptureEvent, String, (u32, u32))>) {
|
||||
let mut ret = (Vec::<_>::new(), Vec::<_>::new());
|
||||
for mut i in input.drain(..) {
|
||||
let cur = RefinedTCB::from_tcb_owned(i.current_tcb);
|
||||
@ -354,39 +353,39 @@ fn add_abb_info(trace: &mut Vec<ExecInterval>, table: &HashMap<u64, ReducedFreeR
|
||||
}
|
||||
|
||||
|
||||
/// restore the isr/api begin/end invariant
|
||||
fn fix_broken_trace(meta: &mut Vec<(u64, CaptureEvent, String, (Option<u32>, Option<u32>))>) {
|
||||
for i in meta.iter_mut() {
|
||||
if i.1 == CaptureEvent::APIStart && i.2.ends_with("FromISR") {
|
||||
i.1 = CaptureEvent::ISREnd;
|
||||
i.2 = "isr_starter".to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// restore the isr/api begin/end invariant
|
||||
// fn fix_broken_trace(meta: &mut Vec<(u64, CaptureEvent, String, (Option<u32>, Option<u32>))>) {
|
||||
// for i in meta.iter_mut() {
|
||||
// if i.1 == CaptureEvent::APIStart && i.2.ends_with("FromISR") {
|
||||
// i.1 = CaptureEvent::ISREnd;
|
||||
// i.2 = "isr_starter".to_string();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// invalidate subsequent intervals of equal states where an ISREnd follows an ISRStart. If the interrupt had no effect on the system we, are not interested.
|
||||
fn invalidate_ineffective_isr(trace: &mut Vec<ExecInterval>) {
|
||||
let mut i = 0;
|
||||
while i < trace.len() - 1 {
|
||||
if trace[i].is_valid() &&
|
||||
matches!(trace[i].start_capture.0, CaptureEvent::ISRStart) && matches!(trace[i].end_capture.0, CaptureEvent::ISREnd) &&
|
||||
trace[i].start_capture.1 == trace[i].end_capture.1 && trace[i].start_state == trace[i].end_state
|
||||
{
|
||||
trace[i].invaildate();
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// invalidate subsequent intervals of equal states where an ISREnd follows an ISRStart. If the interrupt had no effect on the system we, are not interested.
|
||||
// fn invalidate_ineffective_isr(trace: &mut Vec<ExecInterval>) {
|
||||
// let mut i = 0;
|
||||
// while i < trace.len() - 1 {
|
||||
// if trace[i].is_valid() &&
|
||||
// matches!(trace[i].start_capture.0, CaptureEvent::ISRStart) && matches!(trace[i].end_capture.0, CaptureEvent::ISREnd) &&
|
||||
// trace[i].start_capture.1 == trace[i].end_capture.1 && trace[i].start_state == trace[i].end_state
|
||||
// {
|
||||
// trace[i].invaildate();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/// merge a sequence of intervals of the same state+abb. jump over all invalid blocks.
|
||||
fn merge_subsequent_abbs(trace: &mut Vec<ExecInterval>) {
|
||||
let mut i = 1;
|
||||
let mut lst_valid=0;
|
||||
while i < trace.len() - 1 {
|
||||
if trace[i].is_valid() {
|
||||
let mut temp = trace[i].clone();
|
||||
trace[lst_valid].try_unite_with_later_interval(&mut temp);
|
||||
trace[i] = temp;
|
||||
lst_valid = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// merge a sequence of intervals of the same state+abb. jump over all invalid blocks.
|
||||
// fn merge_subsequent_abbs(trace: &mut Vec<ExecInterval>) {
|
||||
// let mut i = 1;
|
||||
// let mut lst_valid=0;
|
||||
// while i < trace.len() - 1 {
|
||||
// if trace[i].is_valid() {
|
||||
// let mut temp = trace[i].clone();
|
||||
// trace[lst_valid].try_unite_with_later_interval(&mut temp);
|
||||
// trace[i] = temp;
|
||||
// lst_valid = i;
|
||||
// }
|
||||
// }
|
||||
// }
|
@ -1,14 +1,14 @@
|
||||
//! The Minimizer schedulers are a family of corpus schedulers that feed the fuzzer
|
||||
//! with testcases only from a subset of the total corpus.
|
||||
|
||||
use core::{marker::PhantomData};
|
||||
use std::{cmp::{max, min}, mem::swap, borrow::BorrowMut};
|
||||
use core::marker::PhantomData;
|
||||
use std::{cmp::{max, min}, mem::swap};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use libafl_bolts::{rands::Rand, serdeany::SerdeAny, AsSlice, HasRefCnt, HasLen};
|
||||
use libafl_bolts::{rands::Rand, HasLen};
|
||||
use libafl::{
|
||||
corpus::{Corpus, Testcase},
|
||||
corpus::Corpus,
|
||||
inputs::UsesInput,
|
||||
schedulers::{Scheduler, TestcaseScore, minimizer::DEFAULT_SKIP_NON_FAVORED_PROB },
|
||||
state::{HasCorpus, HasRand, UsesState, State},
|
||||
@ -40,7 +40,7 @@ impl LongestTracesMetadata {
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LongestTraceScheduler<CS> {
|
||||
base: CS,
|
||||
skip_non_favored_prob: usize,
|
||||
skip_non_favored_prob: f64,
|
||||
}
|
||||
|
||||
impl<CS> UsesState for LongestTraceScheduler<CS>
|
||||
@ -104,7 +104,7 @@ where
|
||||
.get::<STGNodeMetadata>().map_or(0, |x| x.nodes.len());
|
||||
let m = self.get_update_trace_length(state,l);
|
||||
state.rand_mut().below(m as usize) > l
|
||||
} && state.rand_mut().below(100) < self.skip_non_favored_prob
|
||||
} && state.rand_mut().coinflip(self.skip_non_favored_prob)
|
||||
{
|
||||
idx = self.base.next(state)?;
|
||||
}
|
||||
@ -128,10 +128,11 @@ where
|
||||
par as u64
|
||||
}
|
||||
}
|
||||
#[allow(unused)]
|
||||
pub fn new(base: CS) -> Self {
|
||||
Self {
|
||||
base,
|
||||
skip_non_favored_prob: (DEFAULT_SKIP_NON_FAVORED_PROB * 100.0) as usize,
|
||||
skip_non_favored_prob: DEFAULT_SKIP_NON_FAVORED_PROB,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,15 +176,15 @@ where
|
||||
/// if current_gen is empty, swap lists, sort by FavFactor, take top k and return first
|
||||
fn next(&mut self, state: &mut Self::State) -> Result<CorpusId, Error> {
|
||||
let mut to_remove : Vec<(usize, f64)> = vec![];
|
||||
let mut to_return : usize = 0;
|
||||
let mut _to_return : usize = 0;
|
||||
let corpus_len = state.corpus().count();
|
||||
let mut current_len = 0;
|
||||
let mut _current_len = 0;
|
||||
let gm = state.metadata_map_mut().get_mut::<GeneticMetadata>().expect("Corpus Scheduler empty");
|
||||
// println!("index: {} curr: {:?} next: {:?} gen: {} corp: {}", gm.current_cursor, gm.current_gen.len(), gm.next_gen.len(), gm.gen,
|
||||
// c);
|
||||
match gm.current_gen.get(gm.current_cursor) {
|
||||
Some(c) => {
|
||||
current_len = gm.current_gen.len();
|
||||
_current_len = gm.current_gen.len();
|
||||
gm.current_cursor+=1;
|
||||
// println!("normal next: {}", (*c).0);
|
||||
return Ok((*c).0.into())
|
||||
@ -201,25 +202,25 @@ where
|
||||
// for i in 0..gm.current_gen.len() {
|
||||
// gm.current_gen[i] = (i, gm.current_gen[i].1);
|
||||
// }
|
||||
to_return = gm.current_gen.get(0).unwrap().0;
|
||||
_to_return = gm.current_gen.get(0).unwrap().0;
|
||||
// assert_eq!(to_return, 0);
|
||||
gm.current_cursor=1;
|
||||
gm.gen+=1;
|
||||
current_len = gm.current_gen.len();
|
||||
_current_len = gm.current_gen.len();
|
||||
}
|
||||
};
|
||||
// removing these elements will move all indices left by to_remove.len()
|
||||
// to_remove.sort_by(|x,y| x.0.cmp(&(*y).0));
|
||||
// to_remove.reverse();
|
||||
let cm = state.corpus_mut();
|
||||
assert_eq!(corpus_len-to_remove.len(), current_len);
|
||||
assert_ne!(current_len,0);
|
||||
assert_eq!(corpus_len-to_remove.len(), _current_len);
|
||||
assert_ne!(_current_len,0);
|
||||
for i in to_remove {
|
||||
cm.remove(i.0.into()).unwrap();
|
||||
}
|
||||
assert_eq!(cm.get(to_return.into()).is_ok(),true);
|
||||
assert_eq!(cm.get(_to_return.into()).is_ok(),true);
|
||||
// println!("switch next: {to_return}");
|
||||
return Ok(to_return.into());
|
||||
return Ok(_to_return.into());
|
||||
}
|
||||
|
||||
/// Add the new input to the next generation
|
||||
@ -267,6 +268,7 @@ where
|
||||
|
||||
impl<S> GenerationScheduler<S>
|
||||
{
|
||||
#[allow(unused)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
phantom: PhantomData,
|
||||
|
Loading…
x
Reference in New Issue
Block a user