parse raw freertos system state
This commit is contained in:
parent
5bf3269c8f
commit
b85e0a6d5b
@ -119,3 +119,4 @@ impl_emu_lookup!(List_t);
|
|||||||
impl_emu_lookup!(ListItem_t);
|
impl_emu_lookup!(ListItem_t);
|
||||||
impl_emu_lookup!(MiniListItem_t);
|
impl_emu_lookup!(MiniListItem_t);
|
||||||
impl_emu_lookup!(void_ptr);
|
impl_emu_lookup!(void_ptr);
|
||||||
|
impl_emu_lookup!(TaskStatus_t);
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use crate::freertos::emu_lookup;
|
||||||
|
use crate::freertos::rtos_struct;
|
||||||
|
use crate::freertos::List_t;
|
||||||
use crate::freertos::TCB_t;
|
use crate::freertos::TCB_t;
|
||||||
use crate::freertos::rtos_struct::List_Item_struct;
|
use crate::freertos::rtos_struct::List_Item_struct;
|
||||||
use libafl::events::EventFirer;
|
use libafl::events::EventFirer;
|
||||||
@ -34,16 +37,40 @@ pub struct FreeRTOSSystemStateRaw {
|
|||||||
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
|
pub struct MiniTCB {
|
||||||
|
task_name: String,
|
||||||
|
priority: u32,
|
||||||
|
base_priority: u32,
|
||||||
|
mutexes_held: u32,
|
||||||
|
notify_value: u32,
|
||||||
|
notify_state: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MiniTCB {
|
||||||
|
pub fn from_tcb(input: &TCB_t) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let tmp = std::mem::transmute::<[i8; 10],[u8; 10]>(input.pcTaskName);
|
||||||
|
let name : String = std::str::from_utf8(&tmp).expect("TCB name was not utf8").chars().filter(|x| *x != '\0').collect::<String>();
|
||||||
|
Self {
|
||||||
|
task_name: name,
|
||||||
|
priority: input.uxPriority,
|
||||||
|
base_priority: input.uxBasePriority,
|
||||||
|
mutexes_held: input.uxMutexesHeld,
|
||||||
|
notify_value: input.ulNotifiedValue[0],
|
||||||
|
notify_state: input.ucNotifyState[0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Refined information about the states an execution transitioned between
|
/// Refined information about the states an execution transitioned between
|
||||||
#[derive(Debug, Default, Serialize, Deserialize)]
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
pub struct QemuSystemStateMetadata {
|
pub struct QemuSystemStateMetadata {
|
||||||
}
|
start_tick: u64,
|
||||||
|
end_tick: u64,
|
||||||
impl QemuSystemStateMetadata {
|
current_task: MiniTCB,
|
||||||
#[must_use]
|
ready_list_after: Vec<MiniTCB>,
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
libafl::impl_serdeany!(QemuSystemStateMetadata);
|
libafl::impl_serdeany!(QemuSystemStateMetadata);
|
||||||
@ -122,7 +149,7 @@ where
|
|||||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||||
|
|
||||||
for i in 0..NUM_PRIOS {
|
for i in 0..NUM_PRIOS {
|
||||||
let mut target : u32 = LISTBYTES*u32::try_from(i).unwrap()+h.ready_queues;
|
let target : u32 = LISTBYTES*u32::try_from(i).unwrap()+h.ready_queues;
|
||||||
sysstate.prio_ready_lists[i] = freertos::emu_lookup::lookup(emulator, target);
|
sysstate.prio_ready_lists[i] = freertos::emu_lookup::lookup(emulator, target);
|
||||||
// println!("List at {}: {:?}",target, sysstate.prio_ready_lists[i]);
|
// println!("List at {}: {:?}",target, sysstate.prio_ready_lists[i]);
|
||||||
let mut next_index = sysstate.prio_ready_lists[i].pxIndex;
|
let mut next_index = sysstate.prio_ready_lists[i].pxIndex;
|
||||||
@ -144,15 +171,16 @@ where
|
|||||||
sysstate.dumping_ground.insert(next_index,List_Item_struct(next_item));
|
sysstate.dumping_ground.insert(next_index,List_Item_struct(next_item));
|
||||||
next_index=new_next_index;
|
next_index=new_next_index;
|
||||||
}
|
}
|
||||||
|
// Handle edge case where the end marker was not included yet
|
||||||
|
if (target..target+LISTBYTES).contains(&next_index) {
|
||||||
|
let next_item : freertos::MiniListItem_t = freertos::emu_lookup::lookup(emulator, next_index);
|
||||||
|
sysstate.dumping_ground.insert(next_index,List_MiniItem_struct(next_item));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { CURRENT_SYSSTATE_VEC.push(sysstate); }
|
unsafe { CURRENT_SYSSTATE_VEC.push(sysstate); }
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn test_gen_hook(pc: u64) -> u64 {
|
|
||||||
u32::MAX as u64
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gen_not_exec_block_hook<I, QT, S>(
|
pub fn gen_not_exec_block_hook<I, QT, S>(
|
||||||
_emulator: &Emulator,
|
_emulator: &Emulator,
|
||||||
helpers: &mut QT,
|
helpers: &mut QT,
|
||||||
@ -193,6 +221,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.append(&mut CURRENT_SYSSTATE_VEC);}
|
unsafe {self.last_run.append(&mut CURRENT_SYSSTATE_VEC);}
|
||||||
|
println!("{:#?}",self.parse_last());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,8 +246,58 @@ impl QemuSysStateObserver {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self{last_run: vec![], name: "sysstate".to_string()}
|
Self{last_run: vec![], name: "sysstate".to_string()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_last(&self) -> Vec<QemuSystemStateMetadata> {
|
||||||
|
let mut ret = Vec::<QemuSystemStateMetadata>::new();
|
||||||
|
let mut start_tick : u64 = 0;
|
||||||
|
for i in 0..self.last_run.len() {
|
||||||
|
let mut collector = Vec::<MiniTCB>::new();
|
||||||
|
for j in self.last_run[i].prio_ready_lists.iter().rev() {
|
||||||
|
let mut tmp = list_to_tcb_vec(j,&self.last_run[i].dumping_ground).iter().map(|x| MiniTCB::from_tcb(x)).collect();
|
||||||
|
collector.append(&mut tmp);
|
||||||
|
}
|
||||||
|
ret.push(QemuSystemStateMetadata {
|
||||||
|
current_task: MiniTCB::from_tcb(&self.last_run[i].current_tcb),
|
||||||
|
start_tick: start_tick,
|
||||||
|
end_tick: self.last_run[i].qemu_tick,
|
||||||
|
ready_list_after: collector,
|
||||||
|
});
|
||||||
|
start_tick=self.last_run[i].qemu_tick;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_to_tcb_vec(list: &List_t, dump: &HashMap<u32,rtos_struct>) -> Vec<TCB_t>
|
||||||
|
{
|
||||||
|
let mut ret : Vec<TCB_t> = Vec::new();
|
||||||
|
if list.uxNumberOfItems == 0 {return ret;}
|
||||||
|
let first_list_index = match dump.get(&list.pxIndex).expect("List_t entry was not in Hashmap") {
|
||||||
|
List_Item_struct(li) => li.pxNext,
|
||||||
|
List_MiniItem_struct(mli) => match dump.get(&mli.pxNext).expect("MiniListItem pointer invaild") {
|
||||||
|
List_Item_struct(li) => li.pxNext,
|
||||||
|
_ => panic!("MiniListItem of a non empty List does not point to ListItem"),
|
||||||
|
},
|
||||||
|
_ => panic!("List_t entry was not a ListItem"),
|
||||||
|
};
|
||||||
|
let mut next_index = first_list_index;
|
||||||
|
for _ in 0..list.uxNumberOfItems {
|
||||||
|
let next_list_item = match dump.get(&next_index).expect("List_t entry was not in Hashmap") {
|
||||||
|
List_Item_struct(li) => li,
|
||||||
|
List_MiniItem_struct(mli) => match dump.get(&mli.pxNext).expect("MiniListItem pointer invaild") {
|
||||||
|
List_Item_struct(li) => li,
|
||||||
|
_ => panic!("MiniListItem of a non empty List does not point to ListItem"),
|
||||||
|
},
|
||||||
|
_ => panic!("List_t entry was not a ListItem"),
|
||||||
|
};
|
||||||
|
match dump.get(&next_list_item.pvOwner).expect("ListItem Owner not in Hashmap") {
|
||||||
|
TCB_struct(t) => {ret.push(*t)},
|
||||||
|
_ => panic!("List content does not equal type"),
|
||||||
|
}
|
||||||
|
next_index=next_list_item.pxNext;
|
||||||
|
}
|
||||||
|
ret
|
||||||
|
}
|
||||||
//============================= Feedback
|
//============================= Feedback
|
||||||
|
|
||||||
/// A Feedback reporting interesting System-State Transitions
|
/// A Feedback reporting interesting System-State Transitions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user