re-add system state fuzzing

This commit is contained in:
Alwin Berger 2023-01-24 09:11:45 +01:00
parent 2cb479581d
commit ba01f600ee
7 changed files with 68 additions and 39 deletions

View File

@ -5,7 +5,7 @@ authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenuk
edition = "2021"
[features]
default = ["std", "snapshot_restore", "singlecore"]
default = ["std", "snapshot_restore", "singlecore", "systemstate"]
std = []
snapshot_restore = []
snapshot_fast = [ "snapshot_restore" ]

View File

@ -33,6 +33,8 @@ all_sequential: timedump/sequential/mpeg2$(FUZZ_RANDOM) timedump/sequential/dijk
all_kernel: timedump/kernel/bsort$(FUZZ_RANDOM) timedump/kernel/insertsort$(FUZZ_RANDOM) #timedump/kernel/fft$(FUZZ_RANDOM)
tacle_rtos: timedump/tacle_rtos$(FUZZ_RANDOM)
graphics:
Rscript --vanilla plot_comparison.r sequential audiobeam
Rscript --vanilla plot_comparison.r sequential dijkstra

View File

@ -13,3 +13,4 @@ huff_dec,huff_dec_main,huff_dec_encoded,419,huff_dec_return
huff_enc,huff_enc_main,huff_enc_plaintext,600,huff_enc_return
gsm_enc,gsm_enc_main,gsm_enc_pcmdata,6400,gsm_enc_return
tmr,main,FUZZ_INPUT,32,trigger_Qemu_break
tacle_rtos,main,FUZZ_INPUT,4096,trigger_Qemu_break
1 kernel main_function input_symbol input_size return_function
13 huff_enc huff_enc_main huff_enc_plaintext 600 huff_enc_return
14 gsm_enc gsm_enc_main gsm_enc_pcmdata 6400 gsm_enc_return
15 tmr main FUZZ_INPUT 32 trigger_Qemu_break
16 tacle_rtos main FUZZ_INPUT 4096 trigger_Qemu_break

View File

@ -37,7 +37,7 @@ use libafl_qemu::{
use crate::{
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, ICOUNT_HISTORY},
qemustate::QemuStateRestoreHelper,
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::DumpSystraceFeedback}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback},
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback},
};
pub static mut MAX_INPUT_SIZE: usize = 32;
@ -152,11 +152,11 @@ pub fn fuzz() {
let env: Vec<(String, String)> = env::vars().collect();
let emu = Emulator::new(&args, &env);
emu.set_breakpoint(main_addr);
unsafe {
emu.run();
}
emu.remove_breakpoint(main_addr);
// emu.set_breakpoint(main_addr);
// unsafe {
// emu.run();
// }
// emu.remove_breakpoint(main_addr);
emu.set_breakpoint(breakpoint); // BREAKPOINT
@ -214,7 +214,8 @@ pub fn fuzz() {
);
#[cfg(feature = "systemstate")]
let mut feedback = feedback_or!(
DumpSystraceFeedback::with_dump(None),
// DumpSystraceFeedback::with_dump(None),
NovelSystemStateFeedback::default(),
feedback
);

View File

@ -31,12 +31,12 @@ use std::cmp::Ordering;
/// Shared Metadata for a systemstateFeedback
#[derive(Debug, Serialize, Deserialize, SerdeAny, Clone, Default)]
pub struct systemstateFeedbackState
pub struct SystemStateFeedbackState
{
known_traces: HashMap<u64,(u64,u64,usize)>, // encounters,ticks,length
longest: Vec<RefinedFreeRTOSSystemState>,
}
impl Named for systemstateFeedbackState
impl Named for SystemStateFeedbackState
{
#[inline]
fn name(&self) -> &str {
@ -52,7 +52,7 @@ impl Named for systemstateFeedbackState
// }
// }
/// A Feedback reporting novel System-State Transitions. Depends on [`QemusystemstateObserver`]
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`]
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct NovelSystemStateFeedback
{
@ -77,13 +77,19 @@ where
OT: ObserversTuple<S>
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemusystemstateObserver not found");
let clock_observer = observers.match_name::<QemuClockObserver>("clock") //TODO not fixed
.expect("QemusystemstateObserver not found");
let feedbackstate = state
.expect("QemuSystemStateObserver not found");
let clock_observer = observers.match_name::<QemuClockObserver>("clocktime") //TODO not fixed
.expect("QemuClockObserver not found");
let feedbackstate = match state
.named_metadata_mut()
.get_mut::<systemstateFeedbackState>("systemstate")
.unwrap();
.get_mut::<SystemStateFeedbackState>("systemstate") {
Some(s) => s,
None => {
let n=SystemStateFeedbackState::default();
state.named_metadata_mut().insert(n, "systemstate");
state.named_metadata_mut().get_mut::<SystemStateFeedbackState>("systemstate").unwrap()
}
};
// let feedbackstate = state
// .feedback_states_mut()
// .match_name_mut::<systemstateFeedbackState>("systemstate")
@ -161,14 +167,14 @@ pub fn match_traces_name(target: &Vec<String>, last: &Vec<RefinedFreeRTOSSystemS
ret
}
/// A Feedback reporting novel System-State Transitions. Depends on [`QemusystemstateObserver`]
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`]
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct HitsystemstateFeedback
pub struct HitSystemStateFeedback
{
target: Option<Vec<String>>,
}
impl<S> Feedback<S> for HitsystemstateFeedback
impl<S> Feedback<S> for HitSystemStateFeedback
where
S: UsesInput + HasClientPerfMonitor,
{
@ -185,7 +191,7 @@ where
OT: ObserversTuple<S>
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemusystemstateObserver not found");
.expect("QemuSystemStateObserver not found");
// Do Stuff
match &self.target {
Some(s) => {
@ -197,7 +203,7 @@ where
}
}
impl Named for HitsystemstateFeedback
impl Named for HitSystemStateFeedback
{
#[inline]
fn name(&self) -> &str {
@ -205,13 +211,13 @@ impl Named for HitsystemstateFeedback
}
}
impl HitsystemstateFeedback {
impl HitSystemStateFeedback {
pub fn new(target: Option<Vec<RefinedFreeRTOSSystemState>>) -> Self {
Self {target: target.map(|x| x.into_iter().map(|y| y.current_task.task_name).collect())}
}
}
//=========================== Debugging Feedback
/// A [`Feedback`] meant to dump the system-traces for debugging. Depends on [`QemusystemstateObserver`]
/// A [`Feedback`] meant to dump the system-traces for debugging. Depends on [`QemuSystemStateObserver`]
#[derive(Debug)]
pub struct DumpSystraceFeedback
{
@ -237,7 +243,7 @@ where
OT: ObserversTuple<S>
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemusystemstateObserver not found");
.expect("QemuSystemStateObserver not found");
let names : Vec<String> = observer.last_run.iter().map(|x| x.current_task.task_name.clone()).collect();
match &self.dumpfile {
Some(s) => {

View File

@ -247,7 +247,7 @@ impl SysGraphFeedbackState
}
}
/// A Feedback reporting novel System-State Transitions. Depends on [`QemusystemstateObserver`]
/// A Feedback reporting novel System-State Transitions. Depends on [`QemuSystemStateObserver`]
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
pub struct SysMapFeedback
{
@ -279,7 +279,7 @@ where
OT: ObserversTuple<S>,
{
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemusystemstateObserver not found");
.expect("QemuSystemStateObserver not found");
let feedbackstate = state
.named_metadata_mut()
.get_mut::<SysGraphFeedbackState>("SysMap")

View File

@ -2,6 +2,7 @@ use std::cell::UnsafeCell;
use std::io::Write;
use std::ops::Range;
use libafl::prelude::UsesInput;
use libafl_qemu::Emulator;
use libafl_qemu::GuestAddr;
use libafl_qemu::QemuHooks;
use libafl_qemu::edges::QemuEdgesMapMetadata;
@ -70,19 +71,23 @@ where
_hooks.instruction(self.kerneladdr, exec_syscall_hook::<QT, S>, false);
_hooks.jmps(Some(gen_jmp_is_syscall::<QT, S>), Some(trace_api_call::<QT, S>));
}
// TODO: refactor duplicate code
fn pre_exec(&mut self, _emulator: &Emulator, _input: &S::Input) {
unsafe {
CURRENT_SYSTEMSTATE_VEC.clear();
let p = LAST_API_CALL.with(|x| x.get());
*p = None;
}
}
fn post_exec(&mut self, emulator: &Emulator, _input: &S::Input) {
trigger_collection(emulator, self)
}
}
pub fn exec_syscall_hook<QT, S>(
hooks: &mut QemuHooks<'_, QT, S>,
_state: Option<&mut S>,
_pc: u32,
)
where
S: UsesInput,
QT: QemuHelperTuple<S>,
{
let emulator = hooks.emulator();
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
#[inline]
fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) {
let listbytes : u32 = u32::try_from(std::mem::size_of::<freertos::List_t>()).unwrap();
let mut systemstate = RawFreeRTOSSystemState::default();
unsafe {
@ -151,6 +156,20 @@ where
unsafe { CURRENT_SYSTEMSTATE_VEC.push(systemstate); }
}
pub fn exec_syscall_hook<QT, S>(
hooks: &mut QemuHooks<'_, QT, S>,
_state: Option<&mut S>,
_pc: u32,
)
where
S: UsesInput,
QT: QemuHelperTuple<S>,
{
let emulator = hooks.emulator();
let h = hooks.helpers().match_first_type::<QemuSystemStateHelper>().expect("QemuSystemHelper not found in helper tupel");
trigger_collection(emulator, h);
}
thread_local!(static LAST_API_CALL : UnsafeCell<Option<(GuestAddr,GuestAddr)>> = UnsafeCell::new(None));
pub fn gen_jmp_is_syscall<QT, S>(