add simple iteration counter

This commit is contained in:
Alwin Berger 2023-09-18 13:43:31 +02:00
parent 086a575f44
commit 82908badfd
5 changed files with 55 additions and 36 deletions

View File

@ -36,7 +36,7 @@ libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["arm", "systemmode"] }
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
hashbrown = { version = "0.12", features = ["serde", "ahash-compile-time-rng"] } # A faster hashmap, nostd compatible
hashbrown = { version = "0.14.0", features = ["serde"] } # A faster hashmap, nostd compatible
petgraph = { version="0.6.0", features = ["serde-1"] }
ron = "0.7" # write serialized data - including hashmaps
rand = "0.5"

View File

@ -154,7 +154,7 @@ pub fn match_traces(target: &Vec<RefinedFreeRTOSSystemState>, last: &Vec<Refined
let mut ret = true;
if target.len() > last.len() {return false;}
for i in 0..target.len() {
ret &= target[i].current_task.task_name==last[i].current_task.task_name;
ret &= target[i].current_task.0.task_name==last[i].current_task.0.task_name;
}
ret
}
@ -162,7 +162,7 @@ pub fn match_traces_name(target: &Vec<String>, last: &Vec<RefinedFreeRTOSSystemS
let mut ret = true;
if target.len() > last.len() {return false;}
for i in 0..target.len() {
ret &= target[i]==last[i].current_task.task_name;
ret &= target[i]==last[i].current_task.0.task_name;
}
ret
}
@ -213,7 +213,7 @@ impl Named for HitSystemStateFeedback
impl HitSystemStateFeedback {
pub fn new(target: Option<Vec<RefinedFreeRTOSSystemState>>) -> Self {
Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.task_name).collect())}
Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.0.task_name).collect())}
}
}
//=========================== Debugging Feedback
@ -244,7 +244,7 @@ where
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemuSystemStateObserver not found");
let names : Vec<String> = observer.last_run.iter().map(|x| x.current_task.task_name.clone()).collect();
let names : Vec<String> = observer.last_run.iter().map(|x| x.current_task.0.task_name.clone()).collect();
match &self.dumpfile {
Some(s) => {
std::fs::write(s,ron::to_string(&observer.last_run).expect("Error serializing hashmap")).expect("Can not dump to file");

View File

@ -105,7 +105,7 @@ impl SysGraphNode {
return interesting;
}
pub fn get_taskname(&self) -> &str {
&self.base.current_task.task_name
&self.base.current_task.0.task_name
}
pub fn get_input_counts(&self) -> Vec<u32> {
self.variants.iter().map(|x| x.input_counter).collect()
@ -169,9 +169,9 @@ 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();
entry.base.current_task.0.task_name="Start".to_string();
let mut exit = SysGraphNode::default();
exit.base.current_task.task_name="End".to_string();
exit.base.current_task.0.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: String::from("SysMap")}
@ -238,9 +238,9 @@ 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();
entry.base.current_task.0.task_name="Start".to_string();
let mut exit = SysGraphNode::default();
exit.base.current_task.task_name="End".to_string();
exit.base.current_task.0.task_name="End".to_string();
self.entrypoint = self.graph.add_node(entry);
self.exit = self.graph.add_node(exit);
Ok(())

View File

@ -100,9 +100,9 @@ pub struct RefinedFreeRTOSSystemState {
pub end_tick: u64,
last_pc: Option<u64>,
input_counter: u32,
pub current_task: RefinedTCB,
ready_list_after: Vec<RefinedTCB>,
delay_list_after: Vec<RefinedTCB>,
pub current_task: (RefinedTCB, u32),
ready_list_after: Vec<(RefinedTCB, u32)>,
delay_list_after: Vec<(RefinedTCB, u32)>,
}
impl PartialEq for RefinedFreeRTOSSystemState {
fn eq(&self, other: &Self) -> bool {

View File

@ -6,8 +6,8 @@ use libafl_bolts::Named;
use libafl_bolts::AsSlice;
use libafl::Error;
use libafl::observers::Observer;
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
use hashbrown::HashMap;
use super::{
CURRENT_SYSTEMSTATE_VEC,
@ -112,19 +112,38 @@ fn tcb_list_to_vec_cached(list: List_t, dump: &mut HashMap<u32,rtos_struct>) ->
}
/// Drains a List of raw SystemStates to produce a refined trace
fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> Vec<RefinedFreeRTOSSystemState> {
let mut ret = Vec::<RefinedFreeRTOSSystemState>::new();
let mut start_tick : u64 = 0;
for mut i in input.drain(..) {
let mut iteration_counts : HashMap<String, u32>= HashMap::new();
let mut ret = Vec::<RefinedFreeRTOSSystemState>::new();
let mut start_tick : u64 = 0;
for mut i in input.drain(..) {
let cur = RefinedTCB::from_tcb_owned(i.current_tcb);
// collect ready list
let mut collector = Vec::<RefinedTCB>::new();
for j in i.prio_ready_lists.into_iter().rev() {
let mut tmp = tcb_list_to_vec_cached(j,&mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect();
collector.append(&mut tmp);
}
// collect delay list
let mut delay_list : Vec::<RefinedTCB> = tcb_list_to_vec_cached(i.delay_list, &mut i.dumping_ground).iter().map(|x| RefinedTCB::from_tcb(x)).collect();
// We don't care about the order
delay_list.sort_by(|a,b| a.task_name.cmp(&b.task_name));
// keep counts for all tasks
let _ = iteration_counts.try_insert(cur.task_name.clone(), 1);
for j in collector.iter() {let _ = iteration_counts.try_insert(j.task_name.clone(), 1);}
for j in delay_list.iter() {let _ = iteration_counts.try_insert(j.task_name.clone(), 0);}
// increase when:
// current and delayed afterwards
if let Some(_) = delay_list.iter().find(|x| (*x).task_name==cur.task_name) {
*iteration_counts.get_mut(&cur.task_name).unwrap()+=1;
}
let collector = collector.into_iter().map(|x| {let t = *iteration_counts.get(&x.task_name).unwrap_or(&1); (x, t)}).collect();
let delay_list : Vec<(RefinedTCB, u32)> = delay_list.into_iter().map(|x| {let t = *iteration_counts.get(&x.task_name).unwrap_or(&0); (x, t)}).collect();
let t = *iteration_counts.get(&cur.task_name).unwrap_or(&1);
// We don't care about the order
ret.push(RefinedFreeRTOSSystemState {
current_task: RefinedTCB::from_tcb_owned(i.current_tcb),
current_task: (cur, t),
start_tick: start_tick,
end_tick: i.qemu_tick,
ready_list_after: collector,
@ -133,6 +152,6 @@ for mut i in input.drain(..) {
last_pc: i.last_pc,
});
start_tick=i.qemu_tick;
}
return ret;
}
return ret;
}