proof of concept syscall-hook tcb tracer
This commit is contained in:
parent
29f89b4b29
commit
44a32398d9
5
fuzzers/wcet_qemu_sys/.gitignore
vendored
Normal file
5
fuzzers/wcet_qemu_sys/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.axf
|
||||||
|
*.qcow2
|
||||||
|
demo
|
||||||
|
*.ron
|
||||||
|
*.bsp
|
@ -1,3 +1,4 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
// Manual Types
|
// Manual Types
|
||||||
use libafl_qemu::Emulator;
|
use libafl_qemu::Emulator;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ pub type StackType_t = u32;
|
|||||||
pub type UBaseType_t = ::std::os::raw::c_uint;
|
pub type UBaseType_t = ::std::os::raw::c_uint;
|
||||||
pub type TickType_t = u32;
|
pub type TickType_t = u32;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct xLIST_ITEM {
|
pub struct xLIST_ITEM {
|
||||||
pub xItemValue: TickType_t,
|
pub xItemValue: TickType_t,
|
||||||
pub pxNext: xLIST_ITEM_ptr,
|
pub pxNext: xLIST_ITEM_ptr,
|
||||||
@ -93,7 +94,7 @@ fn bindgen_test_layout_xLIST_ITEM() {
|
|||||||
}
|
}
|
||||||
pub type ListItem_t = xLIST_ITEM;
|
pub type ListItem_t = xLIST_ITEM;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct xMINI_LIST_ITEM {
|
pub struct xMINI_LIST_ITEM {
|
||||||
pub xItemValue: TickType_t,
|
pub xItemValue: TickType_t,
|
||||||
pub pxNext: xLIST_ITEM_ptr,
|
pub pxNext: xLIST_ITEM_ptr,
|
||||||
@ -144,7 +145,7 @@ fn bindgen_test_layout_xMINI_LIST_ITEM() {
|
|||||||
}
|
}
|
||||||
pub type MiniListItem_t = xMINI_LIST_ITEM;
|
pub type MiniListItem_t = xMINI_LIST_ITEM;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Default)]
|
||||||
pub struct xLIST {
|
pub struct xLIST {
|
||||||
pub uxNumberOfItems: UBaseType_t,
|
pub uxNumberOfItems: UBaseType_t,
|
||||||
pub pxIndex: ListItem_t_ptr,
|
pub pxIndex: ListItem_t_ptr,
|
||||||
@ -194,7 +195,7 @@ fn bindgen_test_layout_xLIST() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub type List_t = xLIST;
|
pub type List_t = xLIST;
|
||||||
pub type TaskHandle_t = *mut tskTaskControlBlock;
|
pub type TaskHandle_t = ::std::os::raw::c_uint;
|
||||||
pub const eTaskState_eRunning: eTaskState = 0;
|
pub const eTaskState_eRunning: eTaskState = 0;
|
||||||
pub const eTaskState_eReady: eTaskState = 1;
|
pub const eTaskState_eReady: eTaskState = 1;
|
||||||
pub const eTaskState_eBlocked: eTaskState = 2;
|
pub const eTaskState_eBlocked: eTaskState = 2;
|
||||||
@ -203,7 +204,7 @@ pub const eTaskState_eDeleted: eTaskState = 4;
|
|||||||
pub const eTaskState_eInvalid: eTaskState = 5;
|
pub const eTaskState_eInvalid: eTaskState = 5;
|
||||||
pub type eTaskState = ::std::os::raw::c_uint;
|
pub type eTaskState = ::std::os::raw::c_uint;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub struct xTASK_STATUS {
|
pub struct xTASK_STATUS {
|
||||||
pub xHandle: TaskHandle_t,
|
pub xHandle: TaskHandle_t,
|
||||||
pub pcTaskName: char_ptr,
|
pub pcTaskName: char_ptr,
|
||||||
@ -322,14 +323,14 @@ fn bindgen_test_layout_xTASK_STATUS() {
|
|||||||
}
|
}
|
||||||
pub type TaskStatus_t = xTASK_STATUS;
|
pub type TaskStatus_t = xTASK_STATUS;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
|
||||||
pub struct tskTaskControlBlock {
|
pub struct tskTaskControlBlock {
|
||||||
pub pxTopOfStack: StackType_t_ptr,
|
pub pxTopOfStack: StackType_t_ptr,
|
||||||
pub xStateListItem: ListItem_t,
|
pub xStateListItem: ListItem_t,
|
||||||
pub xEventListItem: ListItem_t,
|
pub xEventListItem: ListItem_t,
|
||||||
pub uxPriority: UBaseType_t,
|
pub uxPriority: UBaseType_t,
|
||||||
pub pxStack: StackType_t_ptr,
|
pub pxStack: StackType_t_ptr,
|
||||||
pub pcTaskName: [::std::os::raw::c_char; 10usize],
|
pub pcTaskName: [::std::os::raw::c_uchar; 10usize],
|
||||||
pub uxBasePriority: UBaseType_t,
|
pub uxBasePriority: UBaseType_t,
|
||||||
pub uxMutexesHeld: UBaseType_t,
|
pub uxMutexesHeld: UBaseType_t,
|
||||||
pub ulNotifiedValue: [u32; 1usize],
|
pub ulNotifiedValue: [u32; 1usize],
|
||||||
|
@ -3,6 +3,7 @@ pub mod fuzzer;
|
|||||||
pub mod showmap;
|
pub mod showmap;
|
||||||
pub mod worst;
|
pub mod worst;
|
||||||
pub mod freertos;
|
pub mod freertos;
|
||||||
|
pub mod system_trace;
|
||||||
use libafl_qemu::{
|
use libafl_qemu::{
|
||||||
edges,
|
edges,
|
||||||
edges::QemuEdgeCoverageHelper,
|
edges::QemuEdgeCoverageHelper,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||||
|
|
||||||
|
use crate::system_trace::QemuSystemStateHelper;
|
||||||
use libafl::feedbacks::CrashFeedback;
|
use libafl::feedbacks::CrashFeedback;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use libafl_qemu::QemuExecutor;
|
use libafl_qemu::QemuExecutor;
|
||||||
@ -208,6 +209,21 @@ fn fuzz(
|
|||||||
.expect("Symbol pxReadyTasksLists not found");
|
.expect("Symbol pxReadyTasksLists not found");
|
||||||
// let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
|
// let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
|
||||||
println!("Task Queue at {:#x}", task_queue_addr);
|
println!("Task Queue at {:#x}", task_queue_addr);
|
||||||
|
let shv = elf
|
||||||
|
.resolve_symbol("xPortSysTickHandler", 0)
|
||||||
|
.expect("Symbol xPortSysTickHandler not found");
|
||||||
|
let shv = virt2phys(shv,&elf.goblin());
|
||||||
|
println!("SysTick at {:#x}", shv);
|
||||||
|
let shv = elf
|
||||||
|
.resolve_symbol("vPortSVCHandler", 0)
|
||||||
|
.expect("Symbol vPortSVCHandler not found");
|
||||||
|
let shv = virt2phys(shv,&elf.goblin());
|
||||||
|
println!("SVChandle at {:#x}", shv);
|
||||||
|
let shv = elf
|
||||||
|
.resolve_symbol("xPortPendSVHandler", 0)
|
||||||
|
.expect("Symbol xPortPendSVHandler not found");
|
||||||
|
let shv = virt2phys(shv,&elf.goblin());
|
||||||
|
println!("PendHandle at {:#x}", shv);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -274,12 +290,12 @@ fn fuzz(
|
|||||||
|
|
||||||
emu.run();
|
emu.run();
|
||||||
//====== experiment inspecting the current tcb
|
//====== experiment inspecting the current tcb
|
||||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(&emu, curr_tcb_pointer.try_into().unwrap());
|
// let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(&emu, curr_tcb_pointer.try_into().unwrap());
|
||||||
println!("Current TCB addr: {:x}",curr_tcb_addr);
|
// println!("Current TCB addr: {:x}",curr_tcb_addr);
|
||||||
let current_tcb : freertos::TCB_t = freertos::emu_lookup::lookup(&emu,curr_tcb_addr);
|
// let current_tcb : freertos::TCB_t = freertos::emu_lookup::lookup(&emu,curr_tcb_addr);
|
||||||
println!("Current TCB: {:?}",current_tcb);
|
// println!("Current TCB: {:?}",current_tcb);
|
||||||
let ready_queue : freertos::List_t = freertos::emu_lookup::lookup(&emu,task_queue_addr.try_into().unwrap());
|
// let ready_queue : freertos::List_t = freertos::emu_lookup::lookup(&emu,task_queue_addr.try_into().unwrap());
|
||||||
println!("Ready Queue: {:?}",ready_queue);
|
// println!("Ready Queue: {:?}",ready_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitKind::Ok
|
ExitKind::Ok
|
||||||
@ -293,7 +309,8 @@ fn fuzz(
|
|||||||
QemuEdgeCoverageHelper::new(),
|
QemuEdgeCoverageHelper::new(),
|
||||||
// QemuCmpLogHelper::new(),
|
// QemuCmpLogHelper::new(),
|
||||||
// QemuAsanHelper::new(),
|
// QemuAsanHelper::new(),
|
||||||
QemuSysSnapshotHelper::new()
|
QemuSysSnapshotHelper::new(),
|
||||||
|
QemuSystemStateHelper::new()
|
||||||
),
|
),
|
||||||
tuple_list!(edges_observer),
|
tuple_list!(edges_observer),
|
||||||
&mut fuzzer,
|
&mut fuzzer,
|
||||||
@ -305,17 +322,6 @@ fn fuzz(
|
|||||||
false => seed_dir.clone()
|
false => seed_dir.clone()
|
||||||
};
|
};
|
||||||
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
||||||
// fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
|
||||||
// let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
|
|
||||||
// let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
|
||||||
// if state.corpus().count() < 1 {
|
|
||||||
// state
|
|
||||||
// .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
|
|
||||||
// .expect("Failed to load initial corpus");
|
|
||||||
// println!("We imported {} inputs from disk.", state.corpus().count());
|
|
||||||
// }
|
|
||||||
// fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)
|
|
||||||
// .expect("Error in the fuzzing loop");
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
110
fuzzers/wcet_qemu_sys/src/system_trace.rs
Normal file
110
fuzzers/wcet_qemu_sys/src/system_trace.rs
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
use crate::freertos;
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use libafl_qemu::{
|
||||||
|
emu::Emulator,
|
||||||
|
executor::QemuExecutor,
|
||||||
|
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Deserialize)]
|
||||||
|
pub struct QemuSystemStateMetadata {
|
||||||
|
pub tcbs: Vec<freertos::TCB_t>,
|
||||||
|
// pub map: HashMap<u64, u64>,
|
||||||
|
// pub current_id: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QemuSystemStateMetadata {
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
tcbs: Vec::new(),
|
||||||
|
// map: HashMap::new(),
|
||||||
|
// current_id: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libafl::impl_serdeany!(QemuSystemStateMetadata);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct QemuSystemStateHelper {
|
||||||
|
filter: QemuInstrumentationFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl QemuSystemStateHelper {
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
filter: QemuInstrumentationFilter::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_instrumentation_filter(filter: QemuInstrumentationFilter) -> Self {
|
||||||
|
Self { filter }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn must_instrument(&self, addr: u64) -> bool {
|
||||||
|
self.filter.allowed(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for QemuSystemStateHelper {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I, S> QemuHelper<I, S> for QemuSystemStateHelper
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
S: HasMetadata,
|
||||||
|
{
|
||||||
|
fn init<'a, H, OT, QT>(&self, executor: &QemuExecutor<'a, H, I, OT, QT, S>)
|
||||||
|
where
|
||||||
|
H: FnMut(&I) -> ExitKind,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
QT: QemuHelperTuple<I, S>,
|
||||||
|
{
|
||||||
|
executor.hook_block_execution(exec_syscall_hook::<I, QT, S>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exec_syscall_hook<I, QT, S>(
|
||||||
|
emulator: &Emulator,
|
||||||
|
helpers: &mut QT,
|
||||||
|
state: &mut S,
|
||||||
|
pc: u64,
|
||||||
|
)
|
||||||
|
where
|
||||||
|
S: HasMetadata,
|
||||||
|
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(¤t_tcb.pcTaskName).unwrap());
|
||||||
|
meta.tcbs.push(current_tcb);
|
||||||
|
let id = meta.tcbs.len();
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user