struct parsing experiment

This commit is contained in:
Alwin Berger 2022-01-21 00:17:17 +01:00
parent d4d86927b7
commit 45bdab5000
3 changed files with 566 additions and 11 deletions

View File

@ -0,0 +1,524 @@
/* automatically generated by rust-bindgen 0.59.2 */
use std::ops::Deref;
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct __uint8_t(pub ::std::os::raw::c_uchar);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct __uint16_t(pub ::std::os::raw::c_ushort);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct __uint32_t(pub ::std::os::raw::c_uint);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct StackType_t(pub u32);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct StackType_t_ptr(pub u32);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct UBaseType_t(pub ::std::os::raw::c_uint);
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Default)]
pub struct TickType_t(pub u32);
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Default)]
pub struct void_ptr(pub ::std::os::raw::c_uint);
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Default)]
pub struct xLIST_ptr(pub ::std::os::raw::c_uint);
#[repr(transparent)]
#[derive(Debug, Copy, Clone, Default)]
pub struct xLIST_ITEM_ptr(pub ::std::os::raw::c_uint);
#[repr(C)]
#[derive(Debug, Copy, Clone, Default)]
pub struct xLIST_ITEM {
pub xItemValue: TickType_t,
pub pxNext: xLIST_ITEM_ptr,
pub pxPrevious: xLIST_ITEM_ptr,
pub pvOwner: void_ptr,
pub pvContainer: xLIST_ptr,
}
#[test]
fn bindgen_test_layout_xLIST_ITEM() {
assert_eq!(
::std::mem::size_of::<xLIST_ITEM>(),
20usize,
concat!("Size of: ", stringify!(xLIST_ITEM))
);
assert_eq!(
::std::mem::align_of::<xLIST_ITEM>(),
4usize,
concat!("Alignment of ", stringify!(xLIST_ITEM))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST_ITEM>())).xItemValue as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(xLIST_ITEM),
"::",
stringify!(xItemValue)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST_ITEM>())).pxNext as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(xLIST_ITEM),
"::",
stringify!(pxNext)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST_ITEM>())).pxPrevious as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(xLIST_ITEM),
"::",
stringify!(pxPrevious)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST_ITEM>())).pvOwner as *const _ as usize },
12usize,
concat!(
"Offset of field: ",
stringify!(xLIST_ITEM),
"::",
stringify!(pvOwner)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST_ITEM>())).pvContainer as *const _ as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(xLIST_ITEM),
"::",
stringify!(pvContainer)
)
);
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct ListItem_t(pub xLIST_ITEM);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct xMINI_LIST_ITEM {
pub xItemValue: TickType_t,
pub pxNext: xLIST_ITEM_ptr,
pub pxPrevious: xLIST_ITEM_ptr,
}
#[test]
fn bindgen_test_layout_xMINI_LIST_ITEM() {
assert_eq!(
::std::mem::size_of::<xMINI_LIST_ITEM>(),
12usize,
concat!("Size of: ", stringify!(xMINI_LIST_ITEM))
);
assert_eq!(
::std::mem::align_of::<xMINI_LIST_ITEM>(),
4usize,
concat!("Alignment of ", stringify!(xMINI_LIST_ITEM))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xMINI_LIST_ITEM>())).xItemValue as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(xMINI_LIST_ITEM),
"::",
stringify!(xItemValue)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xMINI_LIST_ITEM>())).pxNext as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(xMINI_LIST_ITEM),
"::",
stringify!(pxNext)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xMINI_LIST_ITEM>())).pxPrevious as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(xMINI_LIST_ITEM),
"::",
stringify!(pxPrevious)
)
);
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct MiniListItem_t(pub xMINI_LIST_ITEM);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct xLIST {
pub uxNumberOfItems: UBaseType_t,
pub pxIndex: xLIST_ITEM_ptr,
pub xListEnd: MiniListItem_t,
}
#[test]
fn bindgen_test_layout_xLIST() {
assert_eq!(
::std::mem::size_of::<xLIST>(),
20usize,
concat!("Size of: ", stringify!(xLIST))
);
assert_eq!(
::std::mem::align_of::<xLIST>(),
4usize,
concat!("Alignment of ", stringify!(xLIST))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST>())).uxNumberOfItems as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(xLIST),
"::",
stringify!(uxNumberOfItems)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST>())).pxIndex as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(xLIST),
"::",
stringify!(pxIndex)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xLIST>())).xListEnd as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(xLIST),
"::",
stringify!(xListEnd)
)
);
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct List_t(pub xLIST);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct TaskHandle_t(pub *mut tskTaskControlBlock);
pub const eTaskState_eRunning: eTaskState = 0;
pub const eTaskState_eReady: eTaskState = 1;
pub const eTaskState_eBlocked: eTaskState = 2;
pub const eTaskState_eSuspended: eTaskState = 3;
pub const eTaskState_eDeleted: eTaskState = 4;
pub const eTaskState_eInvalid: eTaskState = 5;
pub type eTaskState = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct xTASK_STATUS {
pub xHandle: TaskHandle_t,
pub pcTaskName: u32,
pub xTaskNumber: UBaseType_t,
pub eCurrentState: eTaskState,
pub uxCurrentPriority: UBaseType_t,
pub uxBasePriority: UBaseType_t,
pub ulRunTimeCounter: u32,
pub pxStackBase: StackType_t_ptr,
pub usStackHighWaterMark: u16,
}
#[test]
fn bindgen_test_layout_xTASK_STATUS() {
assert_eq!(
::std::mem::size_of::<xTASK_STATUS>(),
36usize,
concat!("Size of: ", stringify!(xTASK_STATUS))
);
assert_eq!(
::std::mem::align_of::<xTASK_STATUS>(),
4usize,
concat!("Alignment of ", stringify!(xTASK_STATUS))
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).xHandle as *const _ as usize },
0usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(xHandle)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).pcTaskName as *const _ as usize },
4usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(pcTaskName)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).xTaskNumber as *const _ as usize },
8usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(xTaskNumber)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).eCurrentState as *const _ as usize },
12usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(eCurrentState)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).uxCurrentPriority as *const _ as usize },
16usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(uxCurrentPriority)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).uxBasePriority as *const _ as usize },
20usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(uxBasePriority)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).ulRunTimeCounter as *const _ as usize },
24usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(ulRunTimeCounter)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<xTASK_STATUS>())).pxStackBase as *const _ as usize },
28usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(pxStackBase)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<xTASK_STATUS>())).usStackHighWaterMark as *const _ as usize
},
32usize,
concat!(
"Offset of field: ",
stringify!(xTASK_STATUS),
"::",
stringify!(usStackHighWaterMark)
)
);
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct TaskStatus_t(pub xTASK_STATUS);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct tskTaskControlBlock {
pub pxTopOfStack: StackType_t_ptr,
pub xStateListItem: ListItem_t,
pub xEventListItem: ListItem_t,
pub uxPriority: UBaseType_t,
pub pxStack: StackType_t_ptr,
pub pcTaskName: [::std::os::raw::c_char; 10usize],
pub uxBasePriority: UBaseType_t,
pub uxMutexesHeld: UBaseType_t,
pub ulNotifiedValue: [u32; 1usize],
pub ucNotifyState: [u8; 1usize],
pub ucStaticallyAllocated: u8,
pub ucDelayAborted: u8,
}
#[test]
fn bindgen_test_layout_tskTaskControlBlock() {
assert_eq!(
::std::mem::size_of::<tskTaskControlBlock>(),
80usize,
concat!("Size of: ", stringify!(tskTaskControlBlock))
);
assert_eq!(
::std::mem::align_of::<tskTaskControlBlock>(),
4usize,
concat!("Alignment of ", stringify!(tskTaskControlBlock))
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).pxTopOfStack as *const _ as usize
},
0usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(pxTopOfStack)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).xStateListItem as *const _ as usize
},
4usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(xStateListItem)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).xEventListItem as *const _ as usize
},
24usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(xEventListItem)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<tskTaskControlBlock>())).uxPriority as *const _ as usize },
44usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(uxPriority)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<tskTaskControlBlock>())).pxStack as *const _ as usize },
48usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(pxStack)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<tskTaskControlBlock>())).pcTaskName as *const _ as usize },
52usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(pcTaskName)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).uxBasePriority as *const _ as usize
},
64usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(uxBasePriority)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).uxMutexesHeld as *const _ as usize
},
68usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(uxMutexesHeld)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).ulNotifiedValue as *const _ as usize
},
72usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(ulNotifiedValue)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).ucNotifyState as *const _ as usize
},
76usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(ucNotifyState)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).ucStaticallyAllocated as *const _
as usize
},
77usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(ucStaticallyAllocated)
)
);
assert_eq!(
unsafe {
&(*(::std::ptr::null::<tskTaskControlBlock>())).ucDelayAborted as *const _ as usize
},
78usize,
concat!(
"Offset of field: ",
stringify!(tskTaskControlBlock),
"::",
stringify!(ucDelayAborted)
)
);
}
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct tskTCB(pub tskTaskControlBlock);
#[repr(transparent)]
#[derive(Debug, Copy, Clone)]
pub struct TCB_t(pub tskTCB);

View File

@ -2,6 +2,7 @@
pub mod fuzzer; pub mod fuzzer;
pub mod showmap; pub mod showmap;
pub mod worst; pub mod worst;
pub mod freertos;
use libafl_qemu::{ use libafl_qemu::{
edges, edges,
edges::QemuEdgeCoverageHelper, edges::QemuEdgeCoverageHelper,

View File

@ -1,16 +1,7 @@
//! A singlethreaded QEMU fuzzer that can auto-restart. //! A singlethreaded QEMU fuzzer that can auto-restart.
use libafl::feedbacks::CrashFeedback; use libafl::feedbacks::CrashFeedback;
use std::fs::File;
use std::path::Path; use std::path::Path;
use libafl::corpus::Corpus;
use libafl::state::HasCorpus;
use libafl::Fuzzer;
use libafl::bolts::tuples::Merge;
use libafl::mutators::tokens_mutations;
use libafl::mutators::havoc_mutations;
use libafl::mutators::StdScheduledMutator;
use libafl::stages::StdMutationalStage;
use libafl_qemu::QemuExecutor; use libafl_qemu::QemuExecutor;
use libafl::bolts::tuples::Named; use libafl::bolts::tuples::Named;
use libafl::observers::ObserversTuple; use libafl::observers::ObserversTuple;
@ -23,7 +14,6 @@ use libafl::corpus::InMemoryCorpus;
use libafl::events::SimpleEventManager; use libafl::events::SimpleEventManager;
use libafl::stats::SimpleStats; use libafl::stats::SimpleStats;
use crate::worst::HitcountsMapObserver; use crate::worst::HitcountsMapObserver;
use crate::worst::HitFeedback;
use clap::{App, Arg}; use clap::{App, Arg};
use std::{ use std::{
env, env,
@ -49,10 +39,10 @@ use libafl_qemu::{
edges, edges,
edges::QemuEdgeCoverageHelper, edges::QemuEdgeCoverageHelper,
emu::Emulator, filter_qemu_args, emu::Emulator, filter_qemu_args,
snapshot_sys,
snapshot_sys::QemuSysSnapshotHelper, snapshot_sys::QemuSysSnapshotHelper,
elf::EasyElf, elf::EasyElf,
}; };
use crate::freertos;
/// The fuzzer main /// The fuzzer main
@ -208,6 +198,16 @@ fn fuzz(
.expect("Symbol trigger_Qemu_break not found"); .expect("Symbol trigger_Qemu_break not found");
let check_breakpoint = virt2phys(check_breakpoint,&elf.goblin()); let check_breakpoint = virt2phys(check_breakpoint,&elf.goblin());
println!("Breakpoint at {:#x}", check_breakpoint); println!("Breakpoint at {:#x}", check_breakpoint);
let curr_tcb_pointer = elf // loads to the address specified in elf, without respecting program headers
.resolve_symbol("pxCurrentTCB", 0)
.expect("Symbol pxCurrentTCBC not found");
// let curr_tcb_pointer = virt2phys(curr_tcb_pointer,&elf.goblin());
println!("TCB pointer at {:#x}", curr_tcb_pointer);
// let task_queue_addr = elf
// .resolve_symbol("pxReadyTasksLists", 0)
// .expect("Symbol pxReadyTasksLists not found");
// // let task_queue_addr = virt2phys(task_queue_addr,&elf.goblin());
// println!("Task Queue at {:#x}", task_queue_addr);
@ -269,12 +269,42 @@ fn fuzz(
} }
unsafe { unsafe {
// let mut addr_buf : [u8; 4] = [0u8; 4];
// emu.read_mem(test_length_ptr,&mut addr_buf);
// println!("current len: {}",u32::from_le_bytes(addr_buf));
//==end test
emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes()); emu.write_mem(test_length_ptr,&(len as u32).to_le_bytes());
emu.write_mem(input_addr,buf); emu.write_mem(input_addr,buf);
//== next test
// emu.read_mem(test_length_ptr,&mut addr_buf);
// println!("new len: {}, expected: {}",u32::from_le_bytes(addr_buf),len);
// println!("{:#?}",edges_copy); // println!("{:#?}",edges_copy);
emu.run(); emu.run();
// println!("{:#?}",edges_copy); // println!("{:#?}",edges_copy);
// let mut buf_struct : [u8; 5*std::mem::size_of::<freertos::List_t>()] = [1u8; 5*std::mem::size_of::<freertos::List_t>()];
// emu.read_mem(task_queue_addr, &mut buf_struct);
// let mut prio_lists : Vec<freertos::List_t> = Vec::new();
// for i in 0..5 {
// let mut tmp : [u8; std::mem::size_of::<freertos::List_t>()] = [0u8; std::mem::size_of::<freertos::List_t>()];
// emu.read_mem(task_queue_addr+i*40, &mut tmp);
// let list_struct = std::mem::transmute::<[u8; std::mem::size_of::<freertos::List_t>()], freertos::List_t>(tmp);
// prio_lists.push(list_struct);
// }
// println!("Raw Buffer: {:?}",buf_struct);
// println!("Lists: {:?}",prio_lists);
//====== experiment inspecting the current tcb
let mut curr_tcb_addr : [u8; 4] = [1u8; 4];
emu.read_mem(curr_tcb_pointer,&mut curr_tcb_addr);
let curr_tcb_addr = u32::from_le_bytes(curr_tcb_addr);
println!("tcb addr: {:x}",curr_tcb_addr);
let mut tmp : [u8; std::mem::size_of::<freertos::TCB_t>()] = [1u8; std::mem::size_of::<freertos::TCB_t>()];
emu.read_mem(curr_tcb_addr.into(), &mut tmp);
println!("Raw TCB: {:?}",tmp);
let tcb = std::mem::transmute::<[u8; std::mem::size_of::<freertos::TCB_t>()], freertos::TCB_t>(tmp);
println!("TCB: {:?}",tcb);
} }
ExitKind::Ok ExitKind::Ok