add graph nodes
This commit is contained in:
parent
89cf096b9d
commit
1d0c43081a
@ -1,3 +1,5 @@
|
|||||||
|
use libafl::bolts::ownedref::OwnedSlice;
|
||||||
|
use libafl::inputs::BytesInput;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use libafl_qemu::QemuClockObserver;
|
use libafl_qemu::QemuClockObserver;
|
||||||
use libafl::feedbacks::FeedbackState;
|
use libafl::feedbacks::FeedbackState;
|
||||||
@ -25,48 +27,84 @@ use petgraph::Direction;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
//============================= Graph Feedback
|
//============================= 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
|
/// Improved System State Graph
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
||||||
pub struct SysMapFeedbackState
|
pub struct SysMapFeedbackState
|
||||||
{
|
{
|
||||||
graph: DiGraph<MiniFreeRTOSSystemState, ()>,
|
graph: DiGraph<SysGraphNode, ()>,
|
||||||
entrypoint: NodeIndex,
|
entrypoint: NodeIndex,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
impl SysMapFeedbackState
|
impl SysMapFeedbackState
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut graph = DiGraph::<MiniFreeRTOSSystemState, ()>::new();
|
let mut graph = DiGraph::<SysGraphNode, ()>::new();
|
||||||
let ind = graph.add_node(MiniFreeRTOSSystemState::default());
|
let ind = graph.add_node(SysGraphNode::default());
|
||||||
Self {graph: graph, entrypoint: ind, name: String::from("SysMap")}
|
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;
|
let mut current_index = self.entrypoint;
|
||||||
for n in list {
|
for n in list {
|
||||||
let mut done = false;
|
let mut done = false;
|
||||||
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
|
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
|
||||||
if n == self.graph[i] {
|
if n == self.graph[i].base {
|
||||||
done = true;
|
done = true;
|
||||||
current_index = i;
|
current_index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !done {
|
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, ());
|
self.graph.add_edge(current_index, j, ());
|
||||||
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 current_index = self.entrypoint;
|
||||||
let mut novel = false;
|
let mut novel = false;
|
||||||
for n in list {
|
for n in list {
|
||||||
let mut matching : Option<NodeIndex> = None;
|
let mut matching : Option<NodeIndex> = None;
|
||||||
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
|
for i in self.graph.neighbors_directed(current_index, Direction::Outgoing) {
|
||||||
let tmp = &self.graph[i];
|
let tmp = &self.graph[i];
|
||||||
if n == tmp {
|
if n == &tmp.base {
|
||||||
matching = Some(i);
|
matching = Some(i);
|
||||||
current_index = i;
|
current_index = i;
|
||||||
break;
|
break;
|
||||||
@ -75,14 +113,14 @@ impl SysMapFeedbackState
|
|||||||
match matching {
|
match matching {
|
||||||
None => {
|
None => {
|
||||||
novel = true;
|
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, ());
|
self.graph.add_edge(current_index, j, ());
|
||||||
current_index = j;
|
current_index = j;
|
||||||
},
|
},
|
||||||
Some(i) => {
|
Some(i) => {
|
||||||
if n.get_time() > self.graph[i].get_time() {
|
if n.get_time() > self.graph[i].base.get_time() {
|
||||||
novel = true;
|
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> {
|
fn reset(&mut self) -> Result<(), Error> {
|
||||||
self.graph.clear();
|
self.graph.clear();
|
||||||
self.entrypoint = self.graph.add_node(MiniFreeRTOSSystemState::default());
|
self.entrypoint = self.graph.add_node(SysGraphNode::default());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,7 +179,7 @@ where
|
|||||||
.feedback_states_mut()
|
.feedback_states_mut()
|
||||||
.match_name_mut::<SysMapFeedbackState>("SysMap")
|
.match_name_mut::<SysMapFeedbackState>("SysMap")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(feedbackstate.update(&observer.last_run))
|
Ok(feedbackstate.update(&observer.last_run, &observer.last_input))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Named for SysMapFeedback
|
impl Named for SysMapFeedback
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use libafl::inputs::HasTargetBytes;
|
||||||
use libafl::bolts::HasLen;
|
use libafl::bolts::HasLen;
|
||||||
use libafl::bolts::tuples::Named;
|
use libafl::bolts::tuples::Named;
|
||||||
use libafl::Error;
|
use libafl::Error;
|
||||||
@ -22,10 +23,13 @@ use super::{
|
|||||||
pub struct QemuSysStateObserver
|
pub struct QemuSysStateObserver
|
||||||
{
|
{
|
||||||
pub last_run: Vec<MiniFreeRTOSSystemState>,
|
pub last_run: Vec<MiniFreeRTOSSystemState>,
|
||||||
|
pub last_input: Vec<u8>,
|
||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I, S> Observer<I, S> for QemuSysStateObserver
|
impl<I, S> Observer<I, S> for QemuSysStateObserver
|
||||||
|
where
|
||||||
|
I: HasTargetBytes
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
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]
|
#[inline]
|
||||||
fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
unsafe {self.last_run = refine_system_states(&mut CURRENT_SYSSTATE_VEC);}
|
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 hasher = DefaultHasher::new();
|
||||||
// let mut a = self.parse_last();
|
// let mut a = self.parse_last();
|
||||||
// a[0].start_tick=21355;
|
// a[0].start_tick=21355;
|
||||||
@ -66,7 +71,7 @@ impl HasLen for QemuSysStateObserver
|
|||||||
|
|
||||||
impl QemuSysStateObserver {
|
impl QemuSysStateObserver {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self{last_run: vec![], name: "sysstate".to_string()}
|
Self{last_run: vec![], last_input: vec![], name: "sysstate".to_string()}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user