add graph nodes

This commit is contained in:
Alwin Berger 2022-03-17 22:37:14 +01:00
parent 89cf096b9d
commit 1d0c43081a
2 changed files with 57 additions and 14 deletions

View File

@ -1,3 +1,5 @@
use libafl::bolts::ownedref::OwnedSlice;
use libafl::inputs::BytesInput;
use std::path::PathBuf;
use libafl_qemu::QemuClockObserver;
use libafl::feedbacks::FeedbackState;
@ -25,48 +27,84 @@ use petgraph::Direction;
use std::cmp::Ordering;
//============================= Graph Feedback
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
struct VariantTuple
{
start_tick: u64,
end_tick: u64,
input_counter: u32,
input: Vec<u8>, // in the end any kind of input are bytes, regardless of type and lifetime
}
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
struct SysGraphNode
{
base: MiniFreeRTOSSystemState,
variants: Vec<VariantTuple>,
}
impl SysGraphNode {
fn from(base: MiniFreeRTOSSystemState, input: Vec<u8>) -> Self {
SysGraphNode{variants: vec![VariantTuple{
start_tick: base.start_tick,
end_tick: base.end_tick,
input_counter: base.input_counter,
input: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;
}
}
impl PartialEq for SysGraphNode {
fn eq(&self, other: &SysGraphNode) -> bool {
self.base==other.base
}
}
/// Improved System State Graph
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysMapFeedbackState
{
graph: DiGraph<MiniFreeRTOSSystemState, ()>,
graph: DiGraph<SysGraphNode, ()>,
entrypoint: NodeIndex,
name: String,
}
impl SysMapFeedbackState
{
pub fn new() -> Self {
let mut graph = DiGraph::<MiniFreeRTOSSystemState, ()>::new();
let ind = graph.add_node(MiniFreeRTOSSystemState::default());
let mut graph = DiGraph::<SysGraphNode, ()>::new();
let ind = graph.add_node(SysGraphNode::default());
Self {graph: graph, entrypoint: ind, name: String::from("SysMap")}
}
fn insert(&mut self, list: Vec<MiniFreeRTOSSystemState>) {
fn insert(&mut self, list: Vec<MiniFreeRTOSSystemState>, 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] {
if n == self.graph[i].base {
done = true;
current_index = i;
break;
}
}
if !done {
let j = self.graph.add_node(n);
let j = self.graph.add_node(SysGraphNode::from(n,input.clone()));
self.graph.add_edge(current_index, j, ());
current_index = j;
}
}
}
fn update(&mut self, list: &Vec<MiniFreeRTOSSystemState>) -> bool {
fn update(&mut self, list: &Vec<MiniFreeRTOSSystemState>, input: &Vec<u8>) -> bool {
let mut current_index = self.entrypoint;
let mut novel = false;
for n in list {
let mut matching : Option<NodeIndex> = None;
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
let tmp = &self.graph[i];
if n == tmp {
if n == &tmp.base {
matching = Some(i);
current_index = i;
break;
@ -75,14 +113,14 @@ impl SysMapFeedbackState
match matching {
None => {
novel = true;
let j = self.graph.add_node(n.clone());
let j = self.graph.add_node(SysGraphNode::from(n.clone(),input.clone()));
self.graph.add_edge(current_index, j, ());
current_index = j;
},
Some(i) => {
if n.get_time() > self.graph[i].get_time() {
if n.get_time() > self.graph[i].base.get_time() {
novel = true;
self.graph[i]=n.clone();
self.graph[i]=SysGraphNode::from(n.clone(),input.clone());
}
}
}
@ -101,7 +139,7 @@ impl FeedbackState for SysMapFeedbackState
{
fn reset(&mut self) -> Result<(), Error> {
self.graph.clear();
self.entrypoint = self.graph.add_node(MiniFreeRTOSSystemState::default());
self.entrypoint = self.graph.add_node(SysGraphNode::default());
Ok(())
}
}
@ -141,7 +179,7 @@ where
.feedback_states_mut()
.match_name_mut::<SysMapFeedbackState>("SysMap")
.unwrap();
Ok(feedbackstate.update(&observer.last_run))
Ok(feedbackstate.update(&observer.last_run, &observer.last_input))
}
}
impl Named for SysMapFeedback

View File

@ -1,3 +1,4 @@
use libafl::inputs::HasTargetBytes;
use libafl::bolts::HasLen;
use libafl::bolts::tuples::Named;
use libafl::Error;
@ -22,10 +23,13 @@ use super::{
pub struct QemuSysStateObserver
{
pub last_run: Vec<MiniFreeRTOSSystemState>,
pub last_input: Vec<u8>,
name: String,
}
impl<I, S> Observer<I, S> for QemuSysStateObserver
where
I: HasTargetBytes
{
#[inline]
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
@ -36,6 +40,7 @@ impl<I, S> Observer<I, S> for QemuSysStateObserver
#[inline]
fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
unsafe {self.last_run = refine_system_states(&mut CURRENT_SYSSTATE_VEC);}
self.last_input=_input.target_bytes().as_slice().to_owned();
// let mut hasher = DefaultHasher::new();
// let mut a = self.parse_last();
// a[0].start_tick=21355;
@ -66,7 +71,7 @@ impl HasLen for QemuSysStateObserver
impl QemuSysStateObserver {
pub fn new() -> Self {
Self{last_run: vec![], name: "sysstate".to_string()}
Self{last_run: vec![], last_input: vec![], name: "sysstate".to_string()}
}
}