save last post interrupt edge in app
This commit is contained in:
parent
e8b24b0c7a
commit
47a4bc19d4
@ -269,6 +269,16 @@ fn fuzz(
|
||||
.expect("Symbol xPortPendSVHandler not found");
|
||||
let svh = virt2phys(svh,&elf.goblin());
|
||||
println!("PendHandle at {:#x}", svh);
|
||||
let app_code_start = elf
|
||||
.resolve_symbol("__APP_CODE_START__", 0)
|
||||
.expect("Symbol __APP_CODE_START__ not found");
|
||||
let app_code_start = virt2phys(app_code_start,&elf.goblin());
|
||||
let app_code_end = elf
|
||||
.resolve_symbol("__APP_CODE_END__", 0)
|
||||
.expect("Symbol __APP_CODE_END__ not found");
|
||||
let app_code_end = virt2phys(app_code_end,&elf.goblin());
|
||||
let app_range = app_code_start..app_code_end;
|
||||
println!("App Code {:x}-{:x}",app_code_start,app_code_end);
|
||||
|
||||
|
||||
|
||||
@ -349,7 +359,7 @@ fn fuzz(
|
||||
&mut harness,
|
||||
&emu,
|
||||
tuple_list!(
|
||||
QemuEdgeCoverageHelper::new(),
|
||||
QemuEdgeCoverageHelper::with_app_range(app_range),
|
||||
// QemuCmpLogHelper::new(),
|
||||
// QemuAsanHelper::new(),
|
||||
QemuSysSnapshotHelper::new(),
|
||||
|
@ -1,3 +1,4 @@
|
||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||
use crate::sysstate::RawFreeRTOSSystemState;
|
||||
use crate::sysstate::CURRENT_SYSSTATE_VEC;
|
||||
use crate::sysstate::NUM_PRIOS;
|
||||
@ -11,6 +12,7 @@ use libafl_qemu::{
|
||||
emu::Emulator,
|
||||
executor::QemuExecutor,
|
||||
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
||||
edges::SAVED_JUMP,
|
||||
};
|
||||
|
||||
//============================= Struct definitions
|
||||
@ -78,7 +80,7 @@ where
|
||||
pub fn exec_syscall_hook<I, QT, S>(
|
||||
emulator: &Emulator,
|
||||
helpers: &mut QT,
|
||||
_state: &mut S,
|
||||
state: &mut S,
|
||||
pc: u64,
|
||||
)
|
||||
where
|
||||
@ -99,6 +101,25 @@ where
|
||||
|
||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
|
||||
sysstate.current_tcb = freertos::emu_lookup::lookup(emulator,curr_tcb_addr);
|
||||
|
||||
unsafe {
|
||||
match SAVED_JUMP {
|
||||
Some(s) => {
|
||||
let meta = state
|
||||
.metadata_mut()
|
||||
.get::<QemuEdgesMapMetadata>()
|
||||
.unwrap();
|
||||
for (k,v) in meta.map.iter() {
|
||||
if *v==s {
|
||||
// println!("Jump Saved {:x}",k.1);
|
||||
sysstate.last_pc = Some(k.1); /* Currently save APP entry points */
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||
|
||||
for i in 0..NUM_PRIOS {
|
||||
|
@ -27,6 +27,7 @@ pub struct RawFreeRTOSSystemState {
|
||||
prio_ready_lists: [freertos::List_t; NUM_PRIOS],
|
||||
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
||||
input_counter: u32,
|
||||
last_pc: Option<u64>,
|
||||
}
|
||||
/// List of system state dumps from QemuHelpers
|
||||
static mut CURRENT_SYSSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
||||
@ -88,13 +89,15 @@ impl RefinedTCB {
|
||||
pub struct RefinedFreeRTOSSystemState {
|
||||
start_tick: u64,
|
||||
end_tick: u64,
|
||||
last_pc: Option<u64>,
|
||||
input_counter: u32,
|
||||
current_task: RefinedTCB,
|
||||
ready_list_after: Vec<RefinedTCB>,
|
||||
}
|
||||
impl PartialEq for RefinedFreeRTOSSystemState {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.current_task == other.current_task && self.ready_list_after == other.ready_list_after
|
||||
self.current_task == other.current_task && self.ready_list_after == other.ready_list_after &&
|
||||
self.last_pc == other.last_pc
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +105,7 @@ impl Hash for RefinedFreeRTOSSystemState {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.current_task.hash(state);
|
||||
self.ready_list_after.hash(state);
|
||||
self.last_pc.hash(state);
|
||||
}
|
||||
}
|
||||
impl RefinedFreeRTOSSystemState {
|
||||
|
@ -130,6 +130,7 @@ for mut i in input.drain(..) {
|
||||
end_tick: i.qemu_tick,
|
||||
ready_list_after: collector,
|
||||
input_counter: i.input_counter,
|
||||
last_pc: i.last_pc,
|
||||
});
|
||||
start_tick=i.qemu_tick;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
use std::ops::Range;
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use libafl::{executors::ExitKind, inputs::Input, observers::ObserversTuple, state::HasMetadata};
|
||||
pub use libafl_targets::{EDGES_MAP, EDGES_MAP_SIZE, MAX_EDGES_NUM};
|
||||
@ -31,6 +32,7 @@ libafl::impl_serdeany!(QemuEdgesMapMetadata);
|
||||
#[derive(Debug)]
|
||||
pub struct QemuEdgeCoverageHelper {
|
||||
filter: QemuInstrumentationFilter,
|
||||
app_range: Option<Range<u64>>,
|
||||
}
|
||||
|
||||
impl QemuEdgeCoverageHelper {
|
||||
@ -38,18 +40,37 @@ impl QemuEdgeCoverageHelper {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
filter: QemuInstrumentationFilter::None,
|
||||
app_range: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_instrumentation_filter(filter: QemuInstrumentationFilter) -> Self {
|
||||
Self { filter }
|
||||
pub fn with_instrumentation_filter(filter: QemuInstrumentationFilter, app_range: Option<Range<u64>>) -> Self {
|
||||
Self { filter, app_range }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_app_range(app_range: Range<u64>) -> Self {
|
||||
Self { filter: QemuInstrumentationFilter::None, app_range: Some(app_range) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn must_instrument(&self, addr: u64) -> bool {
|
||||
self.filter.allowed(addr)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn must_save(&self, src: u64, dst: u64) -> bool {
|
||||
match &self.app_range {
|
||||
None => false,
|
||||
Some(s) => {
|
||||
// println!("must_save {} {:x} {:x}",s.contains(&src) != s.contains(&dst),src,dst);
|
||||
// s.contains(&src) && !s.contains(&dst)
|
||||
// println!("must_save {} {:x} {:x}",src==0&&dst!=0x9cc,src,dst);
|
||||
src==0&&dst!=0x9cc
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for QemuEdgeCoverageHelper {
|
||||
@ -70,7 +91,14 @@ where
|
||||
QT: QemuHelperTuple<I, S>,
|
||||
{
|
||||
executor.hook_edge_generation(gen_unique_edge_ids::<I, QT, S>);
|
||||
executor.emulator().set_exec_edge_hook(trace_edge_hitcount);
|
||||
match self.app_range {
|
||||
None => executor.emulator().set_exec_edge_hook(trace_edge_hitcount),
|
||||
Some(_) => executor.emulator().set_exec_edge_hook(trace_edge_hitcount_and_app_range),
|
||||
}
|
||||
}
|
||||
|
||||
fn pre_exec(&mut self, _emulator: &Emulator, _input: &I) {
|
||||
unsafe { SAVED_JUMP=None; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,6 +111,9 @@ fn hash_me(mut x: u64) -> u64 {
|
||||
x
|
||||
}
|
||||
|
||||
pub static mut MUST_SAVE: [bool; EDGES_MAP_SIZE] = [false; EDGES_MAP_SIZE];
|
||||
pub static mut SAVED_JUMP: Option<u64> = None;
|
||||
|
||||
pub fn gen_unique_edge_ids<I, QT, S>(
|
||||
_emulator: &Emulator,
|
||||
helpers: &mut QT,
|
||||
@ -95,10 +126,12 @@ where
|
||||
I: Input,
|
||||
QT: QemuHelperTuple<I, S>,
|
||||
{
|
||||
let mut must_save = false;
|
||||
if let Some(h) = helpers.match_first_type::<QemuEdgeCoverageHelper>() {
|
||||
if !h.must_instrument(src) && !h.must_instrument(dest) {
|
||||
return None;
|
||||
}
|
||||
must_save = h.must_save(src, dest);
|
||||
}
|
||||
if state.metadata().get::<QemuEdgesMapMetadata>().is_none() {
|
||||
state.add_metadata(QemuEdgesMapMetadata::new());
|
||||
@ -114,6 +147,9 @@ where
|
||||
let nxt = (id as usize + 1) & (EDGES_MAP_SIZE - 1);
|
||||
unsafe {
|
||||
MAX_EDGES_NUM = max(MAX_EDGES_NUM, nxt);
|
||||
if must_save {
|
||||
MUST_SAVE[id as usize] = true;
|
||||
}
|
||||
}
|
||||
Some(id)
|
||||
}
|
||||
@ -123,6 +159,9 @@ where
|
||||
meta.current_id = (id + 1) & (EDGES_MAP_SIZE as u64 - 1);
|
||||
unsafe {
|
||||
MAX_EDGES_NUM = meta.current_id as usize;
|
||||
if must_save {
|
||||
MUST_SAVE[id as usize] = true;
|
||||
}
|
||||
}
|
||||
Some(id as u64)
|
||||
}
|
||||
@ -148,6 +187,14 @@ where
|
||||
Some(hash_me(src) ^ hash_me(dest))
|
||||
}
|
||||
|
||||
|
||||
pub extern "C" fn trace_edge_hitcount_and_app_range(id: u64) {
|
||||
unsafe {
|
||||
if MUST_SAVE[id as usize] { SAVED_JUMP=Some(id); }
|
||||
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn trace_edge_hitcount(id: u64) {
|
||||
unsafe {
|
||||
EDGES_MAP[id as usize] = EDGES_MAP[id as usize].wrapping_add(1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user