add systemstate feature and dump times

This commit is contained in:
Alwin Berger 2023-01-05 17:34:34 +01:00
parent d936234976
commit f4e1990387
4 changed files with 67 additions and 17 deletions

View File

@ -10,6 +10,7 @@ std = []
snapshot_restore = []
snapshot_fast = [ "snapshot_restore" ]
singlecore = []
systemstate = []
[profile.release]
lto = true

View File

@ -3,6 +3,8 @@
[ -n "$2" -a "$2" != "+" -a -z "$FUZZ_MAIN" ] && export FUZZ_MAIN="$2"
[ -n "$3" -a "$3" != "+" -a -z "$FUZZ_INPUT" ] && export FUZZ_INPUT="$3"
[ -n "$4" -a "$4" != "+" -a -z "$BREAKPOINT" ] && export BREAKPOINT="$4"
[ -n "$5" -a "$5" != "+" -a -z "$DO_SHOWMAP" ] && export DO_SHOWMAP="$5"
[ -n "$6" -a "$6" != "+" -a -z "$SHOWMAP_TEXTINPUT" ] && export SHOWMAP_TEXTINPUT="$6"
[ -n "$5" -a "$5" != "+" -a -z "$FUZZ_ITERS" ] && export FUZZ_ITERS="$5"
[ -n "$6" -a "$6" != "+" -a -z "$TIME_DUMP" ] && export TIME_DUMP="$6"
[ -n "$7" -a "$7" != "+" -a -z "$DO_SHOWMAP" ] && export DO_SHOWMAP="$7"
[ -n "$8" -a "$8" != "+" -a -z "$SHOWMAP_TEXTINPUT" ] && export SHOWMAP_TEXTINPUT="$8"
target/debug/qemu_systemmode -icount shift=3,align=off,sleep=off -machine mps2-an385 -monitor null -kernel $KERNEL -serial null -nographic -S -semihosting --semihosting-config enable=on,target=native # -snapshot -drive if=none,format=qcow2,file=dummy.qcow2

View File

@ -84,6 +84,8 @@ impl Default for MaxIcountMetadata {
//========== Observer
pub static mut ICOUNT_HISTORY : Vec<u64> = vec![];
/// A simple observer, just overlooking the runtime of the target.
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct QemuClockObserver {
@ -130,7 +132,8 @@ where
fn post_exec(&mut self, _state: &mut S, _input: &S::Input, _exit_kind: &ExitKind) -> Result<(), Error> {
unsafe { self.end_tick = emu::icount_get_raw() };
// println!("clock post {}", self.end_tick);
println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick);
// println!("Number of Ticks: {} <- {} {}",self.end_tick - self.start_tick, self.end_tick, self.start_tick);
unsafe { ICOUNT_HISTORY.push(self.end_tick - self.start_tick) };
Ok(())
}
}

View File

@ -35,7 +35,7 @@ use libafl_qemu::{
QemuHooks, Regs, QemuInstrumentationFilter, GuestAddr,
};
use crate::{
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback},
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, ICOUNT_HISTORY},
qemustate::QemuStateRestoreHelper,
systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::DumpSystraceFeedback}, worst::TimeMaximizerCorpusScheduler,
};
@ -98,16 +98,21 @@ pub fn fuzz() {
.expect("Symbol main not found");
println!("main address = {:#x}", main_addr);
#[cfg(feature = "systemstate")]
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);
#[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_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");
@ -115,12 +120,15 @@ pub fn fuzz() {
// 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");
#[cfg(feature = "systemstate")]
let app_end = elf
.resolve_symbol("__APP_CODE_END__", 0)
.expect("Symbol __APP_CODE_END__ not found");
#[cfg(feature = "systemstate")]
let app_range = app_start..app_end;
let breakpoint = elf
@ -140,11 +148,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
@ -192,13 +200,17 @@ pub fn fuzz() {
// Feedback to rate the interestingness of an input
// This one is composed by two Feedbacks in OR
let mut feedback = feedback_or!(
DumpSystraceFeedback::with_dump(None),
// New maximization map feedback linked to the edges observer and the feedback state
MaxMapFeedback::new_tracking(&edges_observer, true, true),
// QemuClockIncreaseFeedback::default(),
// Time feedback, this one does not need a feedback state
ClockTimeFeedback::new_with_observer(&clock_time_observer)
);
#[cfg(feature = "systemstate")]
let mut feedback = feedback_or!(
DumpSystraceFeedback::with_dump(None),
feedback
);
// A feedback to choose if an input is a solution or not
let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new());
@ -227,15 +239,23 @@ pub fn fuzz() {
// A fuzzer with feedbacks and a corpus scheduler
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
let mut hooks = QemuHooks::new(&emu,
tuple_list!(QemuEdgeCoverageHelper::default(),QemuStateRestoreHelper::new(),
QemuSystemStateHelper::new(svh,curr_tcb_pointer,task_queue_addr,input_counter_ptr,app_range.clone())));
let qhelpers = tuple_list!(
QemuEdgeCoverageHelper::default(),
QemuStateRestoreHelper::new());
#[cfg(feature = "systemstate")]
let qhelpers = tuple_list!(qhelpers,
QemuSystemStateHelper::new(svh,curr_tcb_pointer,task_queue_addr,input_counter_ptr,app_range.clone()));
let mut hooks = QemuHooks::new(&emu,qhelpers);
let observer_list = tuple_list!(edges_observer, clock_time_observer);
#[cfg(feature = "systemstate")]
let observer_list = tuple_list!(observer_list ,systemstate_observer);
// Create a QEMU in-process executor
let executor = QemuExecutor::new(
&mut hooks,
&mut harness,
tuple_list!(edges_observer, clock_time_observer, systemstate_observer),
observer_list,
&mut fuzzer,
&mut state,
&mut mgr,
@ -273,9 +293,33 @@ pub fn fuzz() {
println!("We imported {} inputs from disk.", state.corpus().count());
}
match env::var("FUZZ_ITERS") {
Err(_) => {
fuzzer
.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)
.unwrap();
},
Ok(t) => {
println!("Iterations {}",t);
let num = str::parse::<u64>(&t).expect("FUZZ_ITERS was not a number");
fuzzer
.fuzz_loop_for(&mut stages, &mut executor, &mut state, &mut mgr, num)
.unwrap();
let mut strbuf = String::new();
unsafe {
for i in ICOUNT_HISTORY.iter() {
strbuf.push_str(&format!("{}\n",i));
}
}
match env::var("TIME_DUMP") {
Err(_) => (),
Ok(td) => {
fs::write(td, strbuf).expect("could not write time dump");
}
}
},
}
}
#[cfg(not(feature = "singlecore"))]
Ok(())