From 139a63789874f6f2e25a64070c56dd04289965ae Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Mon, 12 May 2025 10:21:24 +0000 Subject: [PATCH] WIP: start parsing queues --- .../target_os/freertos/bindings.rs | 18 ++++++++++- .../systemstate/target_os/freertos/config.rs | 4 +++ .../src/systemstate/target_os/freertos/mod.rs | 17 +++++++++++ .../target_os/freertos/qemu_module.rs | 3 ++ fuzzers/FRET/src/systemstate/target_os/mod.rs | 30 +++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/fuzzers/FRET/src/systemstate/target_os/freertos/bindings.rs b/fuzzers/FRET/src/systemstate/target_os/freertos/bindings.rs index 41b67f9ccb..9a6546bf72 100644 --- a/fuzzers/FRET/src/systemstate/target_os/freertos/bindings.rs +++ b/fuzzers/FRET/src/systemstate/target_os/freertos/bindings.rs @@ -1,5 +1,8 @@ #![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr,unused)] use serde::{Deserialize, Serialize}; +use std::fmt::Debug; +use std::fmt::Formatter; +use std::fmt; /*========== Start of generated Code =============*/ pub type char_ptr = ::std::os::raw::c_uint; @@ -133,7 +136,7 @@ pub struct SemaphoreData { } pub type SemaphoreData_t = SemaphoreData; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub struct QueueDefinition { pub pcHead: i_ptr8, pub pcWriteTo: i_ptr8, @@ -154,10 +157,23 @@ pub union QueueDefinition__bindgen_ty_1 { pub xQueue: QueuePointers_t, pub xSemaphore: SemaphoreData_t, } +impl fmt::Debug for QueueDefinition__bindgen_ty_1 { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("union").finish() + } +} pub type xQUEUE = QueueDefinition; pub type Queue_t = xQUEUE; #[repr(C)] #[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)] +pub struct QUEUE_REGISTRY_ITEM { + pub pcQueueName: char_ptr, + pub xHandle: QueueHandle_t, +} +pub type xQueueRegistryItem = QUEUE_REGISTRY_ITEM; +pub type QueueRegistryItem_t = xQueueRegistryItem; +#[repr(C)] +#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)] pub struct tskTaskControlBlock { pub pxTopOfStack: StackType_t_ptr, pub xStateListItem: ListItem_t, diff --git a/fuzzers/FRET/src/systemstate/target_os/freertos/config.rs b/fuzzers/FRET/src/systemstate/target_os/freertos/config.rs index ce62ede601..22bbeff122 100644 --- a/fuzzers/FRET/src/systemstate/target_os/freertos/config.rs +++ b/fuzzers/FRET/src/systemstate/target_os/freertos/config.rs @@ -34,6 +34,10 @@ pub fn add_target_symbols(elf: &EasyElf, addrs: &mut HashMap<&'static str, Guest "uxCriticalNesting", load_symbol(&elf, "uxCriticalNesting", false), ); + addrs.insert( + "xQueueRegistry", + load_symbol(&elf, "xQueueRegistry", false), + ); } diff --git a/fuzzers/FRET/src/systemstate/target_os/freertos/mod.rs b/fuzzers/FRET/src/systemstate/target_os/freertos/mod.rs index dbbc22ff42..94a05acb5b 100644 --- a/fuzzers/FRET/src/systemstate/target_os/freertos/mod.rs +++ b/fuzzers/FRET/src/systemstate/target_os/freertos/mod.rs @@ -80,6 +80,8 @@ impl_emu_lookup!(ListItem_t); impl_emu_lookup!(MiniListItem_t); impl_emu_lookup!(void_ptr); impl_emu_lookup!(TaskStatus_t); +impl_emu_lookup!(QueueRegistryItem_t); +impl_emu_lookup!(Queue_t); pub const ISR_SYMBOLS: &'static [&'static str] = &[ // ISRs @@ -224,6 +226,21 @@ fn trigger_collection( return; }; + /* + let mut queue_registry : Vec = QemuLookup::lookup_slice(emulator, h.queue_registry_addrs, configQUEUE_REGISTRY_SIZE as usize); + let queue_registry = queue_registry.into_iter().filter(|x| x.xHandle != 0).map(|x| { + let queue_def: freertos::QueueDefinition = QemuLookup::lookup(emulator, x.xHandle); + let queue_name: String = emu_lookup_string(emulator, x.pcQueueName, None); + if queue_def.cRxLock == 0xFF && queue_def.cTxLock == 0xFF { + let sending = read_freertos_list(&mut systemstate, emulator, queue_def.xTasksWaitingToSend); + let recieving = read_freertos_list(&mut systemstate, emulator, queue_def.xTasksWaitingToSend); + } + (queue_def, queue_name) + } + ).collect::>(); + dbg!(&queue_registry); + */ + // println!("{:?}",std::str::from_utf8(¤t_tcb.pcTaskName)); let critical: void_ptr = QemuLookup::lookup(emulator, h.critical_addr); let suspended: void_ptr = QemuLookup::lookup(emulator, h.scheduler_lock_addr); diff --git a/fuzzers/FRET/src/systemstate/target_os/freertos/qemu_module.rs b/fuzzers/FRET/src/systemstate/target_os/freertos/qemu_module.rs index e194c3db3f..9700b4936f 100644 --- a/fuzzers/FRET/src/systemstate/target_os/freertos/qemu_module.rs +++ b/fuzzers/FRET/src/systemstate/target_os/freertos/qemu_module.rs @@ -49,6 +49,7 @@ pub struct FreeRTOSSystemStateHelper { pub scheduler_running_addr: GuestAddr, pub critical_addr: GuestAddr, pub job_done_addrs: GuestAddr, + pub queue_registry_addrs: GuestAddr, } impl FreeRTOSSystemStateHelper { @@ -75,6 +76,7 @@ impl FreeRTOSSystemStateHelper { let scheduler_running_addr = *target_symbols.get("xSchedulerRunning").unwrap(); let critical_addr = *target_symbols.get("uxCriticalNesting").unwrap(); let job_done_addrs = *target_symbols.get("trigger_job_done").unwrap(); + let queue_registry_addrs = *target_symbols.get("xQueueRegistry").unwrap(); FreeRTOSSystemStateHelper { app_range, @@ -91,6 +93,7 @@ impl FreeRTOSSystemStateHelper { scheduler_running_addr, critical_addr, job_done_addrs, + queue_registry_addrs, } } } diff --git a/fuzzers/FRET/src/systemstate/target_os/mod.rs b/fuzzers/FRET/src/systemstate/target_os/mod.rs index 67b8df6cff..9e3d81844e 100644 --- a/fuzzers/FRET/src/systemstate/target_os/mod.rs +++ b/fuzzers/FRET/src/systemstate/target_os/mod.rs @@ -119,6 +119,14 @@ pub trait TaskControlBlock: Serialize + for<'a> Deserialize<'a> + Default + Debu pub trait QemuLookup { fn lookup(emu: &Qemu, addr: ::std::os::raw::c_uint) -> Self; + fn lookup_slice(emu: &Qemu, addr: ::std::os::raw::c_uint, count: usize) -> Vec where Self: Sized { + let mut res = Vec::with_capacity(count); + for i in 0..count { + let tmp = Self::lookup(emu, addr + (i * std::mem::size_of::()) as u32); + res.push(tmp); + } + res + } } #[macro_export] @@ -136,6 +144,28 @@ macro_rules! impl_emu_lookup { }; } +fn emu_lookup_string(emu: &Qemu, addr: ::std::os::raw::c_uint, length: Option) -> String { + let mut res = String::new(); + let mut tmp = [0u8; 1]; + let mut cur_addr = addr; + loop { + unsafe { + emu.read_mem(cur_addr.into(), &mut tmp).unwrap(); + } + if tmp[0] == 0 { + break; + } + res.push(tmp[0] as char); + cur_addr += 1; + if let Some(length) = length { + if res.len() >= length { + break; + } + } + } + res +} + pub fn compute_hash(obj: &T) -> u64 where T: Hash,