switch address data type, simplify synbol resolution
This commit is contained in:
parent
aba83dfb6f
commit
6e0b49bf9b
@ -64,11 +64,24 @@ fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr {
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
pub fn load_symbol(elf : &EasyElf, symbol : &str, do_translation : bool) -> GuestAddr {
|
||||
try_load_symbol(elf, symbol, do_translation).expect(&format!("Symbol {} not found", symbol))
|
||||
}
|
||||
|
||||
pub fn try_load_symbol(elf : &EasyElf, symbol : &str, do_translation : bool) -> Option<GuestAddr> {
|
||||
let ret = elf
|
||||
.resolve_symbol(symbol, 0);
|
||||
if do_translation {
|
||||
Option::map_or(ret, None, |x| Some(virt2phys(x as GuestPhysAddr,&elf) as GuestAddr))
|
||||
} else {ret}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
static mut libafl_interrupt_offsets : [u32; 32];
|
||||
static mut libafl_num_interrupts : usize;
|
||||
}
|
||||
|
||||
|
||||
pub fn fuzz() {
|
||||
unsafe {FUZZ_START_TIMESTAMP = SystemTime::now();}
|
||||
let mut starttime = std::time::Instant::now();
|
||||
@ -98,23 +111,11 @@ pub fn fuzz() {
|
||||
println!("main address = {:#x}", main_addr);
|
||||
}
|
||||
|
||||
let input_addr = elf
|
||||
.resolve_symbol(
|
||||
&env::var("FUZZ_INPUT").unwrap_or_else(|_| "FUZZ_INPUT".to_owned()),
|
||||
0,
|
||||
)
|
||||
.expect("Symbol or env FUZZ_INPUT not found") as GuestPhysAddr;
|
||||
let input_addr = virt2phys(input_addr,&elf) as GuestPhysAddr;
|
||||
let input_addr = load_symbol(&elf, &env::var("FUZZ_INPUT").unwrap_or_else(|_| "FUZZ_INPUT".to_owned()), true);
|
||||
println!("FUZZ_INPUT @ {:#x}", input_addr);
|
||||
|
||||
let test_length_ptr = elf
|
||||
.resolve_symbol("FUZZ_LENGTH", 0).map(|x| x as GuestPhysAddr);
|
||||
let test_length_ptr = Option::map_or(test_length_ptr, None, |x| Some(virt2phys(x,&elf)));
|
||||
|
||||
let input_counter_ptr = elf
|
||||
.resolve_symbol(&env::var("FUZZ_POINTER").unwrap_or_else(|_| "FUZZ_POINTER".to_owned()), 0)
|
||||
.map(|x| x as GuestPhysAddr);
|
||||
let input_counter_ptr = Option::map_or(input_counter_ptr, None, |x| Some(virt2phys(x,&elf)));
|
||||
let input_length_ptr = try_load_symbol(&elf, &env::var("FUZZ_LENGTH").unwrap_or_else(|_| "FUZZ_LENGTH".to_owned()), true);
|
||||
let input_counter_ptr = try_load_symbol(&elf, &env::var("FUZZ_POINTER").unwrap_or_else(|_| "FUZZ_POINTER".to_owned()), true);
|
||||
|
||||
#[cfg(feature = "systemstate")]
|
||||
let curr_tcb_pointer = elf // loads to the address specified in elf, without respecting program headers
|
||||
@ -124,34 +125,22 @@ pub fn fuzz() {
|
||||
#[cfg(feature = "systemstate")]
|
||||
println!("TCB pointer at {:#x}", curr_tcb_pointer);
|
||||
#[cfg(feature = "systemstate")]
|
||||
let task_queue_addr = elf
|
||||
.resolve_symbol("pxReadyTasksLists", 0)
|
||||
.expect("Symbol pxReadyTasksLists not found");
|
||||
let task_delay_addr = elf
|
||||
.resolve_symbol("pxDelayedTaskList", 0)
|
||||
.expect("Symbol pxDelayedTaskList not found");
|
||||
let task_delay_overflow_addr = elf
|
||||
.resolve_symbol("pxOverflowDelayedTaskList", 0)
|
||||
.expect("Symbol pxOverflowDelayedTaskList not found");
|
||||
let task_queue_addr = load_symbol(&elf, "pxReadyTasksLists", false);
|
||||
let task_delay_addr = load_symbol(&elf, "pxDelayedTaskList", false);
|
||||
let task_delay_overflow_addr = load_symbol(&elf, "pxOverflowDelayedTaskList", false);
|
||||
// let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
|
||||
#[cfg(feature = "systemstate")]
|
||||
println!("Task Queue at {:#x}", task_queue_addr);
|
||||
#[cfg(feature = "systemstate")]
|
||||
let svh = elf
|
||||
.resolve_symbol("xPortPendSVHandler", 0)
|
||||
.expect("Symbol xPortPendSVHandler not found");
|
||||
let svh = load_symbol(&elf, "xPortPendSVHandler", false);
|
||||
// let svh=virt2phys(svh, &elf);
|
||||
// let svh = elf
|
||||
// .resolve_symbol("vPortEnterCritical", 0)
|
||||
// .expect("Symbol vPortEnterCritical not found");
|
||||
#[cfg(feature = "systemstate")]
|
||||
let app_start = elf
|
||||
.resolve_symbol("__APP_CODE_START__", 0)
|
||||
.expect("Symbol __APP_CODE_START__ not found");
|
||||
let app_start = load_symbol(&elf, "__APP_CODE_START__", false);
|
||||
#[cfg(feature = "systemstate")]
|
||||
let app_end = elf
|
||||
.resolve_symbol("__APP_CODE_END__", 0)
|
||||
.expect("Symbol __APP_CODE_END__ not found");
|
||||
let app_end = load_symbol(&elf, "__APP_CODE_END__", false);
|
||||
#[cfg(feature = "systemstate")]
|
||||
let app_range = app_start..app_end;
|
||||
#[cfg(feature = "systemstate")]
|
||||
@ -228,9 +217,10 @@ pub fn fuzz() {
|
||||
len = MAX_INPUT_SIZE;
|
||||
}
|
||||
|
||||
emu.write_phys_mem(input_addr, buf);
|
||||
if let Some(s) = test_length_ptr {
|
||||
emu.write_phys_mem(s as u64, &len.to_le_bytes())
|
||||
// Note: I could not find a difference between write_mem and write_phys_mem for my usecase
|
||||
emu.write_mem(input_addr, buf);
|
||||
if let Some(s) = input_length_ptr {
|
||||
emu.write_mem(s, &len.to_le_bytes())
|
||||
}
|
||||
|
||||
emu.run();
|
||||
@ -657,7 +647,7 @@ pub fn fuzz() {
|
||||
emu.run();
|
||||
|
||||
let mut buf = [0u8].repeat(MAX_INPUT_SIZE);
|
||||
emu.read_phys_mem(input_addr, buf.as_mut_slice());
|
||||
emu.read_mem(input_addr, buf.as_mut_slice());
|
||||
|
||||
let dir = env::var("SEED_DIR").map_or("./corpus".to_string(), |x| x);
|
||||
let filename = if input_dump == "" {"input"} else {&input_dump};
|
||||
|
@ -5,6 +5,7 @@ use libafl::prelude::ExitKind;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl_qemu::Emulator;
|
||||
use libafl_qemu::GuestAddr;
|
||||
use libafl_qemu::GuestPhysAddr;
|
||||
use libafl_qemu::QemuHooks;
|
||||
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||
use libafl_qemu::emu;
|
||||
@ -35,25 +36,25 @@ pub static mut NEXT_INPUT : Vec<u8> = Vec::new();
|
||||
/// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur, also inject inputs
|
||||
#[derive(Debug)]
|
||||
pub struct QemuSystemStateHelper {
|
||||
kerneladdr: u32,
|
||||
tcb_addr: u32,
|
||||
ready_queues: u32,
|
||||
delay_queue: u32,
|
||||
delay_queue_overflow: u32,
|
||||
input_counter: Option<u64>,
|
||||
app_range: Range<u32>,
|
||||
kerneladdr: GuestAddr,
|
||||
tcb_addr: GuestAddr,
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
delay_queue_overflow: GuestAddr,
|
||||
input_counter: Option<GuestAddr>,
|
||||
app_range: Range<GuestAddr>,
|
||||
}
|
||||
|
||||
impl QemuSystemStateHelper {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
kerneladdr: u32,
|
||||
tcb_addr: u32,
|
||||
ready_queues: u32,
|
||||
delay_queue: u32,
|
||||
delay_queue_overflow: u32,
|
||||
input_counter: Option<u64>,
|
||||
app_range: Range<u32>,
|
||||
kerneladdr: GuestAddr,
|
||||
tcb_addr: GuestAddr,
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
delay_queue_overflow: GuestAddr,
|
||||
input_counter: Option<GuestAddr>,
|
||||
app_range: Range<GuestAddr>,
|
||||
) -> Self {
|
||||
QemuSystemStateHelper {
|
||||
kerneladdr,
|
||||
@ -94,9 +95,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emulator, target: u32) -> freertos::List_t {
|
||||
fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emulator, target: GuestAddr) -> freertos::List_t {
|
||||
let read : freertos::List_t = freertos::emu_lookup::lookup(emulator, target);
|
||||
let listbytes : u32 = u32::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
|
||||
let mut next_index = read.pxIndex;
|
||||
for _j in 0..read.uxNumberOfItems {
|
||||
@ -127,7 +128,7 @@ fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emul
|
||||
|
||||
#[inline]
|
||||
fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
let listbytes : u32 = u32::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
let mut systemstate = RawFreeRTOSSystemState::default();
|
||||
unsafe {
|
||||
// TODO: investigate why can_do_io is not set sometimes, as this is just a workaround
|
||||
@ -139,10 +140,10 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
}
|
||||
let mut buf : [u8; 4] = [0,0,0,0];
|
||||
match h.input_counter {
|
||||
Some(s) => unsafe { emulator.read_phys_mem(s, &mut buf); },
|
||||
Some(s) => unsafe { emulator.read_mem(s, &mut buf); },
|
||||
None => (),
|
||||
};
|
||||
systemstate.input_counter = u32::from_le_bytes(buf);
|
||||
systemstate.input_counter = GuestAddr::from_le_bytes(buf);
|
||||
|
||||
let curr_tcb_addr : freertos::void_ptr = freertos::emu_lookup::lookup(emulator, h.tcb_addr);
|
||||
if curr_tcb_addr == 0 {
|
||||
@ -163,18 +164,18 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
// println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName));
|
||||
|
||||
// Extract delay list
|
||||
let mut target : u32 = h.delay_queue;
|
||||
let mut target : GuestAddr = h.delay_queue;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract delay list overflow
|
||||
let mut target : u32 = h.delay_queue_overflow;
|
||||
let mut target : GuestAddr = h.delay_queue_overflow;
|
||||
target = freertos::emu_lookup::lookup(emulator, target);
|
||||
systemstate.delay_list_overflow = read_freertos_list(&mut systemstate, emulator, target);
|
||||
|
||||
// Extract priority lists
|
||||
for i in 0..NUM_PRIOS {
|
||||
let target : u32 = listbytes*u32::try_from(i).unwrap()+h.ready_queues;
|
||||
let target : GuestAddr = listbytes*GuestAddr::try_from(i).unwrap()+h.ready_queues;
|
||||
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
||||
}
|
||||
|
||||
@ -184,7 +185,7 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
pub fn exec_syscall_hook<QT, S>(
|
||||
hooks: &mut QemuHooks<'_, QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
_pc: u32,
|
||||
_pc: GuestAddr,
|
||||
)
|
||||
where
|
||||
S: UsesInput,
|
||||
|
Loading…
x
Reference in New Issue
Block a user