From 8c8ab7c44e0943c4407a70271754bde9701c4c8d Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Fri, 10 Feb 2023 13:46:07 +0100 Subject: [PATCH] add graph feedback --- fuzzers/FRET/Cargo.toml | 4 ++- fuzzers/FRET/benchmark/plot_comparison.r | 13 ++++++++-- fuzzers/FRET/src/fuzzer.rs | 33 +++++++++++++++++++----- fuzzers/FRET/src/systemstate/graph.rs | 12 ++++++--- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/fuzzers/FRET/Cargo.toml b/fuzzers/FRET/Cargo.toml index 58b66de041..8927e55c64 100644 --- a/fuzzers/FRET/Cargo.toml +++ b/fuzzers/FRET/Cargo.toml @@ -5,12 +5,14 @@ authors = ["Andrea Fioraldi ", "Dominik Maier % gf_histogram(~ timetrace,data=timetrace_afl, fill=myolors[2]) %>% -gf_histogram(~ timetrace,data=timetrace_rand, fill=myolors[3]) +gf_histogram(~ timetrace,data=timetrace_rand, fill=myolors[3]) %>% +gf_histogram(~ timetrace,data=timetrace_graph, fill=myolors[4]) dev.off() # Takes a flat list @@ -63,11 +70,13 @@ trace2maxline <- function(tr) { timetrace[[1]] <- trace2maxline(timetrace[[1]]) timetrace_afl[[1]] <- trace2maxline(timetrace_afl[[1]]) timetrace_rand[[1]] <- trace2maxline(timetrace_rand[[1]]) +timetrace_graph[[1]] <- trace2maxline(timetrace_graph[[1]]) png(file=filename_2) plot(timetrace[[2]],timetrace[[1]], col=myolors[1], xlab="iters", ylab="wcet", pch='.') points(timetrace_afl[[2]],timetrace_afl[[1]], col=myolors[2], pch='.') points(timetrace_rand[[2]],timetrace_rand[[1]], col=myolors[3], pch='.') +points(timetrace_graph[[2]],timetrace_graph[[1]], col=myolors[4], pch='.') #abline(lm(timetrace ~ iter, data=timetrace),col=myolors[1]) #abline(lm(timetrace ~ iter, data=timetrace_afl),col=myolors[2]) #abline(lm(timetrace ~ iter, data=timetrace_rand),col=myolors[3]) diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 4ffc3eb228..3f594d48df 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -26,7 +26,7 @@ use libafl::{ observers::{VariableMapObserver}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, stages::StdMutationalStage, - state::{HasCorpus, StdState, HasMetadata}, + state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata}, Error, prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec}, Evaluator, }; @@ -37,7 +37,7 @@ use libafl_qemu::{ use crate::{ clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, IcHist}, qemustate::QemuStateRestoreHelper, - systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler}, + systemstate::{helpers::QemuSystemStateHelper, observers::QemuSystemStateObserver, feedbacks::{DumpSystraceFeedback, NovelSystemStateFeedback}, graph::{SysMapFeedback, SysGraphFeedbackState, GraphMaximizerCorpusScheduler}}, worst::{TimeMaximizerCorpusScheduler, ExecTimeIncFeedback, TimeStateMaximizerCorpusScheduler}, }; pub static mut MAX_INPUT_SIZE: usize = 32; @@ -136,6 +136,8 @@ pub fn fuzz() { .expect("Symbol __APP_CODE_END__ not found"); #[cfg(feature = "systemstate")] let app_range = app_start..app_end; + #[cfg(feature = "systemstate")] + dbg!(app_range.clone()); let breakpoint = elf .resolve_symbol( @@ -221,12 +223,21 @@ pub fn fuzz() { // Feedback to reward any input which increses the execution time ExecTimeIncFeedback::new() ); - #[cfg(feature = "systemstate")] + #[cfg(all(feature = "systemstate",not(any(feature = "systemgraph",feature = "systemtrace"))))] + let mut feedback = feedback_or!( + DumpSystraceFeedback::with_dump(env::var("TRACE_DUMP").ok().map(PathBuf::from)), + feedback + ); + #[cfg(feature = "systemtrace")] let mut feedback = feedback_or!( - // DumpSystraceFeedback::with_dump(env::var("TRACE_DUMP").ok().map(PathBuf::from)), NovelSystemStateFeedback::default(), feedback ); + #[cfg(feature = "systemgraph")] + let mut feedback = feedback_or!( + SysMapFeedback::default(), + feedback + ); // A feedback to choose if an input is a solution or not let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); @@ -251,10 +262,12 @@ pub fn fuzz() { }); // A minimization+queue policy to get testcasess from the corpus - #[cfg(not(feature = "systemstate"))] + #[cfg(not(any(feature = "systemgraph",feature = "systemtrace")))] let scheduler = TimeMaximizerCorpusScheduler::new(QueueScheduler::new()); - #[cfg(feature = "systemstate")] + #[cfg(feature = "systemtrace")] let scheduler = TimeStateMaximizerCorpusScheduler::new(QueueScheduler::new()); + #[cfg(feature = "systemgraph")] + let scheduler = GraphMaximizerCorpusScheduler::new(QueueScheduler::new()); // A fuzzer with feedbacks and a corpus scheduler let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); @@ -394,6 +407,14 @@ pub fn fuzz() { Some(wi) => {fs::write(&td,wi).expect("Failed to write worst corpus element");}, None => (), } + #[cfg(feature = "systemgraph")] + { + let mut gd = String::from(&td); + gd.push_str(".graph"); + if let Some(md) = state.named_metadata_mut().get_mut::("SysMap") { + fs::write(&gd,ron::to_string(&md).expect("Failed to serialize graph")).expect("Failed to write graph"); + } + } } }, } diff --git a/fuzzers/FRET/src/systemstate/graph.rs b/fuzzers/FRET/src/systemstate/graph.rs index 7c6da55557..7db7094249 100644 --- a/fuzzers/FRET/src/systemstate/graph.rs +++ b/fuzzers/FRET/src/systemstate/graph.rs @@ -280,10 +280,16 @@ where { let observer = observers.match_name::("systemstate") .expect("QemuSystemStateObserver not found"); - let feedbackstate = state + let feedbackstate = match state .named_metadata_mut() - .get_mut::("SysMap") - .unwrap(); + .get_mut::("SysMap") { + Some(s) => s, + None => { + let n=SysGraphFeedbackState::default(); + state.named_metadata_mut().insert(n, "SysMap"); + state.named_metadata_mut().get_mut::("SysMap").unwrap() + } + }; let ret = feedbackstate.update(&observer.last_run, &observer.last_input); self.last_trace = Some(ret.1); Ok(ret.0)