generalize system state hook

This commit is contained in:
Alwin Berger 2022-01-26 23:14:38 +01:00
parent 44a32398d9
commit 8676342776
3 changed files with 54 additions and 47 deletions

View File

@ -145,7 +145,7 @@ fn bindgen_test_layout_xMINI_LIST_ITEM() {
}
pub type MiniListItem_t = xMINI_LIST_ITEM;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct xLIST {
pub uxNumberOfItems: UBaseType_t,
pub pxIndex: ListItem_t_ptr,
@ -536,3 +536,9 @@ impl emu_lookup for List_t {
}
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum rtos_struct {
TCB_struct(TCB_t),
List_struct(List_t),
}

View File

@ -1,5 +1,6 @@
//! A singlethreaded QEMU fuzzer that can auto-restart.
use libafl_qemu::QemuInstrumentationFilter;
use crate::system_trace::QemuSystemStateHelper;
use libafl::feedbacks::CrashFeedback;
use std::path::Path;
@ -209,21 +210,21 @@ fn fuzz(
.expect("Symbol pxReadyTasksLists not found");
// let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
println!("Task Queue at {:#x}", task_queue_addr);
let shv = elf
let systick_handler = elf
.resolve_symbol("xPortSysTickHandler", 0)
.expect("Symbol xPortSysTickHandler not found");
let shv = virt2phys(shv,&elf.goblin());
println!("SysTick at {:#x}", shv);
let shv = elf
let systick_handler = virt2phys(systick_handler,&elf.goblin());
println!("SysTick at {:#x}", systick_handler);
let svc_handle = elf
.resolve_symbol("vPortSVCHandler", 0)
.expect("Symbol vPortSVCHandler not found");
let shv = virt2phys(shv,&elf.goblin());
println!("SVChandle at {:#x}", shv);
let shv = elf
let svc_handle = virt2phys(svc_handle,&elf.goblin());
println!("SVChandle at {:#x}", svc_handle);
let svh = elf
.resolve_symbol("xPortPendSVHandler", 0)
.expect("Symbol xPortPendSVHandler not found");
let shv = virt2phys(shv,&elf.goblin());
println!("PendHandle at {:#x}", shv);
let svh = virt2phys(svh,&elf.goblin());
println!("PendHandle at {:#x}", svh);
@ -300,6 +301,8 @@ fn fuzz(
ExitKind::Ok
};
//======= Set System-State watchpoints
let system_state_filter = QemuInstrumentationFilter::AllowList(vec![svh..svh+1]);
//======= Construct the executor, including the Helpers. The edges_observer still contains the ref to EDGES_MAP
let mut executor = QemuExecutor::new(
@ -310,7 +313,7 @@ fn fuzz(
// QemuCmpLogHelper::new(),
// QemuAsanHelper::new(),
QemuSysSnapshotHelper::new(),
QemuSystemStateHelper::new()
QemuSystemStateHelper::with_instrumentation_filter(system_state_filter,curr_tcb_pointer.try_into().unwrap(),task_queue_addr.try_into().unwrap())
),
tuple_list!(edges_observer),
&mut fuzzer,

View File

@ -1,3 +1,4 @@
use crate::freertos::rtos_struct::*;
use crate::freertos;
use hashbrown::HashMap;
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata};
@ -11,18 +12,14 @@ use libafl_qemu::{
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct QemuSystemStateMetadata {
pub tcbs: Vec<freertos::TCB_t>,
// pub map: HashMap<u64, u64>,
// pub current_id: u64,
pub rtos_states: Vec<(freertos::TCB_t,HashMap<u32,freertos::rtos_struct>)>,
}
impl QemuSystemStateMetadata {
#[must_use]
pub fn new() -> Self {
Self {
tcbs: Vec::new(),
// map: HashMap::new(),
// current_id: 0,
rtos_states: Vec::new(),
}
}
}
@ -32,19 +29,23 @@ libafl::impl_serdeany!(QemuSystemStateMetadata);
#[derive(Debug)]
pub struct QemuSystemStateHelper {
filter: QemuInstrumentationFilter,
tcb_addr: u32,
ready_queues: u32,
}
impl QemuSystemStateHelper {
#[must_use]
pub fn new() -> Self {
pub fn new(tcb_addr: u32, ready_queues: u32) -> Self {
Self {
filter: QemuInstrumentationFilter::None,
tcb_addr: tcb_addr,
ready_queues: ready_queues,
}
}
#[must_use]
pub fn with_instrumentation_filter(filter: QemuInstrumentationFilter) -> Self {
Self { filter }
pub fn with_instrumentation_filter(filter: QemuInstrumentationFilter, tcb_addr: u32, ready_queues: u32) -> Self {
Self { filter, tcb_addr, ready_queues}
}
#[must_use]
@ -53,12 +54,6 @@ impl QemuSystemStateHelper {
}
}
impl Default for QemuSystemStateHelper {
fn default() -> Self {
Self::new()
}
}
impl<I, S> QemuHelper<I, S> for QemuSystemStateHelper
where
I: Input,
@ -85,26 +80,29 @@ where
I: Input,
QT: QemuHelperTuple<I, S>,
{
// if pc == 0x2e8 { //vPortSVCHandler
// if pc == 0x3c4 { //SystemTick
if pc == 0x37c { //xPortPendSVHandler
if let Some(h) = helpers.match_first_type::<QemuSystemStateHelper>() {
if !h.must_instrument(pc) {
return;
}
}
if state.metadata().get::<QemuSystemStateMetadata>().is_none() {
state.add_metadata(QemuSystemStateMetadata::new());
}
let meta = state
.metadata_mut()
.get_mut::<QemuSystemStateMetadata>()
.unwrap();
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, 0x20006ff0.try_into().unwrap());
// println!("Current TCB addr: {:x}",curr_tcb_addr);
let current_tcb : freertos::TCB_t = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
println!("{}", std::str::from_utf8(&current_tcb.pcTaskName).unwrap());
meta.tcbs.push(current_tcb);
let id = meta.tcbs.len();
let h = helpers.match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
if !h.must_instrument(pc) {
return;
}
if state.metadata().get::<QemuSystemStateMetadata>().is_none() {
state.add_metadata(QemuSystemStateMetadata::new());
}
let meta = state
.metadata_mut()
.get_mut::<QemuSystemStateMetadata>()
.unwrap();
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
// println!("Current TCB addr: {:x}",curr_tcb_addr);
let current_tcb : freertos::TCB_t = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
println!("{:?}",current_tcb);
println!("{}", std::str::from_utf8(&current_tcb.pcTaskName).unwrap());
let mut result_tup : (freertos::TCB_t,HashMap<u32,freertos::rtos_struct>) = (current_tcb, HashMap::with_capacity(5));
for i in 0..4 {
let target : u32= (std::mem::size_of::<freertos::List_t>()*i).try_into().unwrap();
let ready_list : freertos::List_t = freertos::emu_lookup::lookup(emulator, h.ready_queues+target);
let a : freertos::rtos_struct = List_struct(ready_list);
// println!("{:?}",ready_list);
// println!("Prio: {} Number: {} first {:x}",i,ready_list.uxNumberOfItems, ready_list.pxIndex);
}
meta.rtos_states.push(result_tup);
}