dump ready lists

This commit is contained in:
Alwin Berger 2022-02-15 23:23:52 +01:00
parent be1ead84f4
commit 44faa80556
2 changed files with 57 additions and 12 deletions

View File

@ -538,8 +538,20 @@ impl emu_lookup for List_t {
} }
} }
impl emu_lookup for MiniListItem_t {
fn lookup(emu: &Emulator, addr: ::std::os::raw::c_uint) -> MiniListItem_t {
let mut tmp : [u8; std::mem::size_of::<MiniListItem_t>()] = [0u8; std::mem::size_of::<MiniListItem_t>()];
unsafe {
emu.read_mem(addr.into(), &mut tmp);
std::mem::transmute::<[u8; std::mem::size_of::<MiniListItem_t>()], MiniListItem_t>(tmp)
}
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)] #[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum rtos_struct { pub enum rtos_struct {
TCB_struct(TCB_t), TCB_struct(TCB_t),
List_struct(List_t), List_struct(List_t),
List_Item_struct(ListItem_t),
List_MiniItem_struct(MiniListItem_t),
} }

View File

@ -1,3 +1,5 @@
use crate::freertos::TCB_t;
use crate::freertos::rtos_struct::List_Item_struct;
use libafl::events::EventFirer; use libafl::events::EventFirer;
use libafl::state::HasClientPerfMonitor; use libafl::state::HasClientPerfMonitor;
use libafl::feedbacks::Feedback; use libafl::feedbacks::Feedback;
@ -18,10 +20,19 @@ use libafl_qemu::{
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter}, helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
}; };
const NUM_PRIOS: usize = 5;
//============================= Datatypes //============================= Datatypes
/// Info Dump from Qemu /// Info Dump from Qemu
pub type SysState = (u64,freertos::TCB_t,HashMap<u32,freertos::rtos_struct>); // pub type SysState = (u64,freertos::TCB_t,HashMap<u32,freertos::rtos_struct>);
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct FreeRTOSSystemStateRaw {
qemu_tick: u64,
current_tcb: TCB_t,
prio_ready_lists: [freertos::List_t; NUM_PRIOS],
dumping_ground: HashMap<u32,freertos::rtos_struct>,
}
/// 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)]
@ -39,7 +50,7 @@ libafl::impl_serdeany!(QemuSystemStateMetadata);
//============================= Qemu Helper //============================= Qemu Helper
static mut CURRENT_SYSSTATE_VEC: Vec<SysState> = vec![]; static mut CURRENT_SYSSTATE_VEC: Vec<FreeRTOSSystemStateRaw> = vec![];
/// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur /// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur
#[derive(Debug)] #[derive(Debug)]
@ -102,18 +113,40 @@ where
if !h.must_instrument(pc) { if !h.must_instrument(pc) {
return; return;
} }
let current_clock = emulator.get_ticks(); let LISTBYTES : u32 = u32::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
let mut sysstate = FreeRTOSSystemStateRaw::default();
sysstate.qemu_tick = emulator.get_ticks();
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr); let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
let current_tcb : freertos::TCB_t = freertos::emu_lookup::lookup(emulator,curr_tcb_addr); sysstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
let mut result_tup : SysState = (current_clock,current_tcb, HashMap::with_capacity(5)); // println!("{:?}",std::str::from_utf8(&current_tcb.pcTaskName));
for i in 0..4 {
let target : u32= (std::mem::size_of::<freertos::List_t>()*i).try_into().unwrap(); for i in 0..NUM_PRIOS {
let ready_list : freertos::List_t = freertos::emu_lookup::lookup(emulator, h.ready_queues+target); let mut target : u32 = LISTBYTES*u32::try_from(i).unwrap()+h.ready_queues;
let a : freertos::rtos_struct = List_struct(ready_list); sysstate.prio_ready_lists[i] = freertos::emu_lookup::lookup(emulator, target);
result_tup.2.insert(target,a); // println!("List at {}: {:?}",target, sysstate.prio_ready_lists[i]);
let mut next_index = sysstate.prio_ready_lists[i].pxIndex;
for _j in 0..sysstate.prio_ready_lists[i].uxNumberOfItems {
// always jump over the xListEnd marker
if (target..target+LISTBYTES).contains(&next_index) {
let next_item : freertos::MiniListItem_t = freertos::emu_lookup::lookup(emulator, next_index);
let new_next_index=next_item.pxNext;
sysstate.dumping_ground.insert(next_index,List_MiniItem_struct(next_item));
next_index = new_next_index;
}
let next_item : freertos::ListItem_t = freertos::emu_lookup::lookup(emulator, next_index);
// println!("Item at {}: {:?}",next_index,next_item);
assert_eq!(next_item.pvContainer,target);
let new_next_index=next_item.pxNext;
let next_tcb : TCB_t= freertos::emu_lookup::lookup(emulator,next_item.pvOwner);
// println!("TCB at {}: {:?}",next_item.pvOwner,next_tcb);
sysstate.dumping_ground.insert(next_item.pvOwner,TCB_struct(next_tcb.clone()));
sysstate.dumping_ground.insert(next_index,List_Item_struct(next_item));
next_index=new_next_index;
}
} }
unsafe { CURRENT_SYSSTATE_VEC.push(result_tup); } unsafe { CURRENT_SYSSTATE_VEC.push(sysstate); }
} }
extern "C" fn test_gen_hook(pc: u64) -> u64 { extern "C" fn test_gen_hook(pc: u64) -> u64 {
@ -145,7 +178,7 @@ pub fn gen_not_exec_block_hook<I, QT, S>(
#[allow(clippy::unsafe_derive_deserialize)] #[allow(clippy::unsafe_derive_deserialize)]
pub struct QemuSysStateObserver pub struct QemuSysStateObserver
{ {
last_run: Vec<SysState>, last_run: Vec<FreeRTOSSystemStateRaw>,
name: String, name: String,
} }