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