From 6e0b49bf9b4b18568e1ae2865755108d6e815676 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Fri, 8 Dec 2023 11:15:25 +0100 Subject: [PATCH] switch address data type, simplify synbol resolution --- fuzzers/FRET/src/fuzzer.rs | 64 +++++++++++-------------- fuzzers/FRET/src/systemstate/helpers.rs | 47 +++++++++--------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 02b150a17d..986474e8fc 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -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 { + 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}; diff --git a/fuzzers/FRET/src/systemstate/helpers.rs b/fuzzers/FRET/src/systemstate/helpers.rs index 3766ff320c..b4bac0ec23 100644 --- a/fuzzers/FRET/src/systemstate/helpers.rs +++ b/fuzzers/FRET/src/systemstate/helpers.rs @@ -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 = 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, - app_range: Range, + kerneladdr: GuestAddr, + tcb_addr: GuestAddr, + ready_queues: GuestAddr, + delay_queue: GuestAddr, + delay_queue_overflow: GuestAddr, + input_counter: Option, + app_range: Range, } 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, - app_range: Range, + kerneladdr: GuestAddr, + tcb_addr: GuestAddr, + ready_queues: GuestAddr, + delay_queue: GuestAddr, + delay_queue_overflow: GuestAddr, + input_counter: Option, + app_range: Range, ) -> 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::()).unwrap(); + let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::()).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::()).unwrap(); + let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::()).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( hooks: &mut QemuHooks<'_, QT, S>, _state: Option<&mut S>, - _pc: u32, + _pc: GuestAddr, ) where S: UsesInput,