break on all api functions
This commit is contained in:
parent
3817892ff1
commit
5d9bcba0e6
@ -22,3 +22,4 @@ watersv2_int,main_waters,FUZZ_INPUT,4096,trigger_Qemu_break
|
||||
micro_branchless,main_branchless,FUZZ_INPUT,4,trigger_Qemu_break
|
||||
micro_int,main_int,FUZZ_INPUT,16,trigger_Qemu_break
|
||||
micro_longint,main_micro_longint,FUZZ_INPUT,16,trigger_Qemu_break
|
||||
minimal,main_minimal,FUZZ_INPUT,4096,trigger_Qemu_break
|
|
@ -3,6 +3,7 @@
|
||||
use core::time::Duration;
|
||||
use std::{env, path::PathBuf, process::{self, abort}, io::{Read, Write}, fs::{self, OpenOptions}, cmp::{min, max}, mem::transmute_copy, collections::btree_map::Range, ptr::addr_of_mut, ffi::OsStr};
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use libafl_bolts::{
|
||||
core_affinity::Cores,
|
||||
current_nanos,
|
||||
@ -36,11 +37,7 @@ use libafl_qemu::{
|
||||
};
|
||||
use rand::{SeedableRng, StdRng, Rng};
|
||||
use crate::{
|
||||
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, IcHist, FUZZ_START_TIMESTAMP},
|
||||
qemustate::QemuStateRestoreHelper,
|
||||
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}, schedulers::{LongestTraceScheduler, GenerationScheduler}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler, AlwaysTrueFeedback},
|
||||
mutational::MyStateStage,
|
||||
mutational::{MINIMUM_INTER_ARRIVAL_TIME},
|
||||
clock::{ClockTimeFeedback, IcHist, QemuClockIncreaseFeedback, QemuClockObserver, FUZZ_START_TIMESTAMP}, mutational::{MyStateStage, MINIMUM_INTER_ARRIVAL_TIME}, qemustate::QemuStateRestoreHelper, systemstate::{self, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{GraphMaximizerCorpusScheduler, SysGraphFeedbackState, SysMapFeedback}, helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, schedulers::{GenerationScheduler, LongestTraceScheduler}}, worst::{AlwaysTrueFeedback, ExecTimeIncFeedback, TimeMaximizerCorpusScheduler, TimeStateMaximizerCorpusScheduler}
|
||||
};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use clap::{Parser, Subcommand};
|
||||
@ -310,8 +307,8 @@ pub fn fuzz() {
|
||||
// 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 = load_symbol(&elf, "xPortPendSVHandler", false);
|
||||
// #[cfg(feature = "systemstate")]
|
||||
// let svh = load_symbol(&elf, "xPortPendSVHandler", false);
|
||||
// let svh=virt2phys(svh, &elf);
|
||||
// let svh = elf
|
||||
// .resolve_symbol("vPortEnterCritical", 0)
|
||||
@ -345,6 +342,17 @@ pub fn fuzz() {
|
||||
unsafe {RNG_SEED = str::parse::<u64>(&seed).expect("SEED_RANDOM must be an integer.");}
|
||||
}
|
||||
|
||||
#[cfg(feature = "systemstate")]
|
||||
let mut api_addreses : HashMap<GuestAddr,&'static str> = HashMap::new();
|
||||
#[cfg(feature = "systemstate")]
|
||||
for s in systemstate::helpers::API_SYMBOLS {
|
||||
if let Some(sb) = try_load_symbol(&elf, &s, false) {
|
||||
api_addreses.insert(sb,s);
|
||||
}
|
||||
}
|
||||
|
||||
// Client setup ================================================================================
|
||||
|
||||
let mut run_client = |state: Option<_>, mut mgr, _core_id| {
|
||||
// Initialize QEMU
|
||||
let args: Vec<String> = vec![
|
||||
@ -537,7 +545,7 @@ pub fn fuzz() {
|
||||
let qhelpers = tuple_list!(
|
||||
QemuEdgeCoverageHelper::default(),
|
||||
QemuStateRestoreHelper::new(),
|
||||
QemuSystemStateHelper::new(svh,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
||||
QemuSystemStateHelper::new(api_addreses,curr_tcb_pointer,task_queue_addr,task_delay_addr,task_delay_overflow_addr,input_counter_ptr,app_range.clone())
|
||||
);
|
||||
let mut hooks = QemuHooks::new(emu.clone(),qhelpers);
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::cell::UnsafeCell;
|
||||
use std::io::Write;
|
||||
use std::ops::Range;
|
||||
use hashbrown::HashMap;
|
||||
use libafl::prelude::ExitKind;
|
||||
use libafl::prelude::UsesInput;
|
||||
use libafl_qemu::Emulator;
|
||||
@ -32,12 +33,47 @@ pub static mut INTR_DONE : bool = true;
|
||||
// only used when inputs are injected
|
||||
pub static mut NEXT_INPUT : Vec<u8> = Vec::new();
|
||||
|
||||
//============================= API symbols
|
||||
|
||||
pub static API_SYMBOLS : &'static [&str] = &[
|
||||
// Task Creation
|
||||
"xTaskCreate", "xTaskCreateStatic", "vTaskDelete", "xTaskGetStaticBuffers",
|
||||
// Task Control
|
||||
"vTaskDelay","vTaskDelayUntil","xTaskDelayUntil", "uxTaskPriorityGet", "uxTaskPriorityGetFromISR", "uxTaskBasePriorityGet","uxTaskBasePriorityGetFromISR", "vTaskPrioritySet","vTaskSuspend","vTaskResume","xTaskResumeFromISR","xTaskAbortDelay",
|
||||
// Task Utilities
|
||||
"uxTaskGetSystemState","vTaskGetInfo","xTaskGetCurrentTaskHandle","xTaskGetIdleTaskHandle","uxTaskGetStackHighWaterMark","eTaskGetState","pcTaskGetName","xTaskGetHandle","xTaskGetTickCount","xTaskGetTickCountFromISR","xTaskGetSchedulerState","uxTaskGetNumberOfTasks","vTaskList","vTaskListTasks","vTaskStartTrace","ulTaskEndTrace","vTaskGetRunTimeStats","vTaskGetRunTimeStatistics","vTaskGetIdleRunTimeCounter","ulTaskGetRunTimeCounter","ulTaskGetRunTimePercent","ulTaskGetIdleRunTimeCounter","ulTaskGetIdleRunTimePercent","vTaskSetApplicationTaskTag","xTaskGetApplicationTaskTag","xTaskCallApplicationTaskHook","pvTaskGetThreadLocalStoragePointer","vTaskSetThreadLocalStoragePointer","vTaskSetTimeOutState","xTaskCheckForTimeOut",
|
||||
// RTOS Kernel Control
|
||||
"taskYIELD","taskENTER_CRITICAL","taskEXIT_CRITICAL","taskENTER_CRITICAL_FROM_ISR","taskEXIT_CRITICAL_FROM_ISR","taskDISABLE_INTERRUPTS","taskENABLE_INTERRUPTS","vTaskStartScheduler","vTaskEndScheduler","vTaskSuspendAll","xTaskResumeAll","vTaskStepTick",
|
||||
// Direct To Task Notifications
|
||||
"xTaskNotifyGive","xTaskNotifyGiveIndexed","vTaskNotifyGiveFromISR","vTaskNotifyGiveIndexedFromISR","ulTaskNotifyTake","ulTaskNotifyTakeIndexed","xTaskNotify","xTaskNotifyIndexed","xTaskNotifyAndQuery","xTaskNotifyAndQueryIndexed","xTaskNotifyAndQueryFromISR","xTaskNotifyAndQueryFromISRIndexed","xTaskNotifyFromISR","xTaskNotifyFromISRIndexed","xTaskNotifyWait","xTaskNotifyWaitIndexed","xTaskNotifyStateClear","xTaskNotifyStateClearIndexed","ulTasknotifyValueClear","ulTasknotifyValueClearIndexed",
|
||||
// Queues
|
||||
"xQueueCreate","xQueueCreateStatic","vQueueDelete","xQueueSend","xQueueSendFromISR","xQueueSendToBack","xQueueSendToBackFromISR","xQueueSendToFront","xQueueSendToFrontFromISR","xQueueReceive","xQueueReceiveFromISR","uxQueueMessagesWaiting","uxQueueMessagesWaitingFromISR","uxQueueSpacesAvailable","xQueueReset","xQueuePeek","xQueuePeekFromISR","vQueueAddToRegistry","pcQueueGetName","vQueueUnregisterQueue","xQueueIsQueueEmptyFromISR","xQueueIsQueueFullFromISR","xQueueOverwrite","xQueueOverwriteFromISR","xQueueGetStaticBuffers",
|
||||
// Queue Sets
|
||||
"xQueueCreateSet","xQueueAddToSet","xQueueRemoveFromSet","xQueueSelectFromSet","xQueueSelectFromSetFromISR",
|
||||
// Stream Buffers
|
||||
"xStreamBufferCreate","xStreamBufferCreateStatic","xStreamBufferSend","xStreamBufferSendFromISR","xStreamBufferReceive","xStreamBufferReceiveFromISR","vStreamBufferDelete","xStreamBufferBytesAvailable","xStreamBufferSpacesAvailable","xStreamBufferSetTriggerLevel","xStreamBufferReset","xStreamBufferIsEmpty","xStreamBufferIsFull","xStreamBufferGetStaticBuffers",
|
||||
// Message Buffers
|
||||
"xMessageBufferCreate","xMessageBufferCreateStatic","xMessageBufferSend","xMessageBufferSendFromISR","xMessageBufferReceive","xMessageBufferReceiveFromISR","vMessageBufferDelete","xMessageBufferSpacesAvailable","xMessageBufferReset","xMessageBufferIsEmpty","xMessageBufferIsFull","xMessageBufferGetStaticBuffers",
|
||||
// Semaphores
|
||||
"xSemaphoreCreateBinary","xSemaphoreCreateBinaryStatic","vSemaphoreCreateBinary","xSemaphoreCreateCounting","xSemaphoreCreateCountingStatic","xSemaphoreCreateMutex","xSemaphoreCreateMutexStatic","xSemaphoreCreateRecursiveMutex","xSemaphoreCreateRecursiveMutexStatic","vSemaphoreDelete","xSemaphoreGetMutexHolder","xSemaphoreTake","xSemaphoreTakeFromISR","xSemaphoreTakeRecursive","xSemaphoreGive","xSemaphoreGiveRecursive","xSemaphoreGiveFromISR","uxSemaphoreGetCount","xSemaphoreGetStaticBuffer",
|
||||
// Software Timers
|
||||
"xTimerCreate","xTimerCreateStatic","xTimerIsTimerActive","pvTimerGetTimerID","pcTimerGetName","vTimerSetReloadMode","xTimerStart","xTimerStop","xTimerChangePeriod","xTimerDelete","xTimerReset","xTimerStartFromISR","xTimerStopFromISR","xTimerChangePeriodFromISR","xTimerResetFromISR","pvTimerGetTimerID","vTimerSetTimerID","xTimerGetTimerDaemonTaskHandle","xTimerPendFunctionCall","xTimerPendFunctionCallFromISR","pcTimerGetName","xTimerGetPeriod","xTimerGetExpiryTime","xTimerGetReloadMode",
|
||||
// Event Groups
|
||||
"vEventGroupDelete","xEventGroupClearBits","xEventGroupClearBitsFromISR","xEventGroupCreate","xEventGroupCreateStatic","xEventGroupGetBits","xEventGroupGetBitsFromISR","xEventGroupGetStaticBuffer","xEventGroupSetBits","xEventGroupSetBitsFromISR","xEventGroupSync","xEventGroupWaitBits",
|
||||
// MPU Specific functions
|
||||
"xTaskCreateRestricted","xTaskCreateRestrictedStatic","vTaskAllocateMPURegions","portSWITCH_TO_USER_MODE",
|
||||
// Co-routines
|
||||
"xCoRoutineCreate","crDELAY","crQUEUE_SEND","crQUEUE_RECEIVE","crQUEUE_SEND_FROM_ISR","crQUEUE_RECEIVE_FROM_ISR","vCoRoutineSchedule",
|
||||
// Custom resolved macros
|
||||
"vPortEnterCritical","vPortExitCritical","xTaskGenericNotify","xTaskGenericNotifyFromISR","xQueueGenericSend","xQueueGenericReset"
|
||||
];
|
||||
|
||||
//============================= Qemu Helper
|
||||
|
||||
/// A Qemu Helper with reads FreeRTOS specific structs from Qemu whenever certain syscalls occur, also inject inputs
|
||||
#[derive(Debug)]
|
||||
pub struct QemuSystemStateHelper {
|
||||
kerneladdr: GuestAddr,
|
||||
watchaddr: HashMap<GuestAddr, &'static str>,
|
||||
tcb_addr: GuestAddr,
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
@ -49,7 +85,7 @@ pub struct QemuSystemStateHelper {
|
||||
impl QemuSystemStateHelper {
|
||||
#[must_use]
|
||||
pub fn new(
|
||||
kerneladdr: GuestAddr,
|
||||
watchaddr: HashMap<GuestAddr, &'static str>,
|
||||
tcb_addr: GuestAddr,
|
||||
ready_queues: GuestAddr,
|
||||
delay_queue: GuestAddr,
|
||||
@ -58,7 +94,7 @@ impl QemuSystemStateHelper {
|
||||
app_range: Range<GuestAddr>,
|
||||
) -> Self {
|
||||
QemuSystemStateHelper {
|
||||
kerneladdr,
|
||||
watchaddr: watchaddr,
|
||||
tcb_addr: tcb_addr,
|
||||
ready_queues: ready_queues,
|
||||
delay_queue,
|
||||
@ -77,7 +113,9 @@ where
|
||||
where
|
||||
QT: QemuHelperTuple<S>,
|
||||
{
|
||||
_hooks.instruction(self.kerneladdr, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||
for wp in self.watchaddr.keys() {
|
||||
_hooks.instruction(*wp, Hook::Function(exec_syscall_hook::<QT, S>), false);
|
||||
}
|
||||
#[cfg(feature = "trace_abbs")]
|
||||
_hooks.jmps(Hook::Function(gen_jmp_is_syscall::<QT, S>), Hook::Function(trace_api_call::<QT, S>));
|
||||
}
|
||||
@ -92,7 +130,7 @@ where
|
||||
}
|
||||
|
||||
fn post_exec<OT>(&mut self, emulator: &Emulator, _input: &S::Input, _observers: &mut OT, _exit_kind: &mut ExitKind) {
|
||||
trigger_collection(emulator, self)
|
||||
trigger_collection(emulator,0, self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,7 +166,7 @@ fn read_freertos_list(systemstate : &mut RawFreeRTOSSystemState, emulator: &Emul
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
fn trigger_collection(emulator: &Emulator, pc: GuestAddr, h: &QemuSystemStateHelper) {
|
||||
let listbytes : GuestAddr = GuestAddr::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
|
||||
let mut systemstate = RawFreeRTOSSystemState::default();
|
||||
unsafe {
|
||||
@ -180,13 +218,15 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
|
||||
systemstate.prio_ready_lists[i] = read_freertos_list(&mut systemstate, emulator, target);
|
||||
}
|
||||
|
||||
systemstate.capture_point = h.watchaddr.get(&pc).unwrap_or(&"unknown");
|
||||
|
||||
unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); }
|
||||
}
|
||||
|
||||
pub fn exec_syscall_hook<QT, S>(
|
||||
hooks: &mut QemuHooks<QT, S>,
|
||||
_state: Option<&mut S>,
|
||||
_pc: GuestAddr,
|
||||
pc: GuestAddr,
|
||||
)
|
||||
where
|
||||
S: UsesInput,
|
||||
@ -194,7 +234,7 @@ where
|
||||
{
|
||||
let emulator = hooks.emulator();
|
||||
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
|
||||
trigger_collection(emulator, h);
|
||||
trigger_collection(emulator, pc, h);
|
||||
}
|
||||
|
||||
thread_local!(static LAST_API_CALL : UnsafeCell<Option<(GuestAddr,GuestAddr)>> = UnsafeCell::new(None));
|
||||
|
@ -2,6 +2,7 @@
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use libafl_bolts::HasRefCnt;
|
||||
use libafl_bolts::AsSlice;
|
||||
use libafl_qemu::GuestAddr;
|
||||
use std::hash::Hasher;
|
||||
use std::hash::Hash;
|
||||
use hashbrown::HashMap;
|
||||
@ -37,6 +38,7 @@ pub struct RawFreeRTOSSystemState {
|
||||
dumping_ground: HashMap<u32,freertos::rtos_struct>,
|
||||
input_counter: u32,
|
||||
last_pc: Option<u64>,
|
||||
capture_point: &'static str
|
||||
}
|
||||
/// List of system state dumps from QemuHelpers
|
||||
static mut CURRENT_SYSTEMSTATE_VEC: Vec<RawFreeRTOSSystemState> = vec![];
|
||||
@ -113,6 +115,7 @@ pub struct RefinedFreeRTOSSystemState {
|
||||
pub current_task: (RefinedTCB, u32),
|
||||
ready_list_after: Vec<(RefinedTCB, u32)>,
|
||||
delay_list_after: Vec<(RefinedTCB, u32)>,
|
||||
pub capture_point: String
|
||||
}
|
||||
impl PartialEq for RefinedFreeRTOSSystemState {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
|
@ -163,6 +163,7 @@ fn refine_system_states(input: &mut Vec<RawFreeRTOSSystemState>) -> Vec<RefinedF
|
||||
delay_list_after: delay_list,
|
||||
input_counter: i.input_counter,//+IRQ_INPUT_BYTES_NUMBER,
|
||||
last_pc: i.last_pc,
|
||||
capture_point: i.capture_point.to_string()
|
||||
});
|
||||
start_tick=i.qemu_tick;
|
||||
}
|
||||
|
5
fuzzers/FRET/tests/.gitignore
vendored
Normal file
5
fuzzers/FRET/tests/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
dump
|
||||
demo*
|
||||
*.dot
|
||||
*.time
|
||||
*.case
|
22
fuzzers/FRET/tests/run_test.sh
Normal file
22
fuzzers/FRET/tests/run_test.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
# cargo build --no-default-features --features std,snapshot_restore,singlecore,feed_afl,observer_hitcounts
|
||||
|
||||
# Test basic fuzzing loop
|
||||
../target/debug/fret -k ../benchmark/build/waters.elf -c ../benchmark/target_symbols.csv -n ./dump/waters -tar fuzz -t 10 -s 123
|
||||
|
||||
# Test reprodcibility
|
||||
rm -f ./dump/demo.case.time
|
||||
../target/debug/fret -k ../benchmark/build/waters.elf -c ../benchmark/target_symbols.csv -n ./dump/demo -tr showmap -i ./demo.case
|
||||
if [[ $(cut -d, -f1 ./dump/demo.case.time) != $(cut -d, -f1 ./demo.example.time) ]]; then echo "Not reproducible!" && exit 1; else echo "Reproducible"; fi
|
||||
|
||||
# Test state dump
|
||||
# cargo build --no-default-features --features std,snapshot_restore,singlecore,feed_afl,observer_hitcounts,systemstate
|
||||
if [[ -n "$(diff -q demo.example.state.ron dump/demo.trace.ron)" ]]; then echo "State not reproducible!"; else echo "State Reproducible"; fi
|
||||
|
||||
# Test abb traces
|
||||
# cargo build --no-default-features --features std,snapshot_restore,singlecore,feed_afl,observer_hitcounts,systemstate,trace_abbs
|
||||
if [[ -n "$(diff -q demo.example.abb.ron dump/demo.trace.ron)" ]]; then echo "ABB not reproducible!"; else echo "ABB Reproducible"; fi
|
||||
|
||||
# ../target/debug/fret -k ../benchmark/build/minimal.elf -c ../benchmark/target_symbols.csv -n ./dump/minimal -tar fuzz -t 100 -s 123
|
||||
# ../target/debug/fret -k ../benchmark/build/minimal.elf -c ../benchmark/target_symbols.csv -n ./dump/minimal_worst -tr showmap -i ./dump/minimal.case
|
Loading…
x
Reference in New Issue
Block a user