add graph feedback

This commit is contained in:
Alwin Berger 2023-02-10 13:46:07 +01:00
parent 9cadc5d61c
commit 8c8ab7c44e
4 changed files with 50 additions and 12 deletions

View File

@ -5,12 +5,14 @@ authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenuk
edition = "2021" edition = "2021"
[features] [features]
default = ["std", "snapshot_restore", "singlecore", "systemstate"] default = ["std", "snapshot_restore", "singlecore"]
std = [] std = []
snapshot_restore = [] snapshot_restore = []
snapshot_fast = [ "snapshot_restore" ] snapshot_fast = [ "snapshot_restore" ]
singlecore = [] singlecore = []
systemstate = [] systemstate = []
systemgraph = [ "systemstate" ]
systemtrace = [ "systemstate" ]
[profile.release] [profile.release]
lto = true lto = true

View File

@ -2,7 +2,7 @@ library("mosaic")
args = commandArgs(trailingOnly=TRUE) args = commandArgs(trailingOnly=TRUE)
#myolors=c("#339933","#0066ff","#993300") # grün, balu, rot #myolors=c("#339933","#0066ff","#993300") # grün, balu, rot
myolors=c("dark green","dark blue","dark red") # grün, balu, rot myolors=c("dark green","dark blue","dark red", "yellow") # grün, balu, rot
if (length(args)==0) { if (length(args)==0) {
runtype="timedump" runtype="timedump"
@ -22,24 +22,30 @@ if (length(args)==0) {
file_1=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_state",runtype,target) file_1=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_state",runtype,target)
file_2=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_afl",runtype,target) file_2=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_afl",runtype,target)
file_3=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_random",runtype,target) file_3=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_random",runtype,target)
file_4=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_graph",runtype,target)
timetrace <- read.table(file_1, quote="\"", comment.char="") timetrace <- read.table(file_1, quote="\"", comment.char="")
timetrace_afl <- read.table(file_2, quote="\"", comment.char="") timetrace_afl <- read.table(file_2, quote="\"", comment.char="")
timetrace_rand <- read.table(file_3, quote="\"", comment.char="") timetrace_rand <- read.table(file_3, quote="\"", comment.char="")
timetrace_graph <- read.table(file_4, quote="\"", comment.char="")
timetrace[[2]]=seq_len(length(timetrace[[1]])) timetrace[[2]]=seq_len(length(timetrace[[1]]))
timetrace_afl[[2]]=seq_len(length(timetrace_afl[[1]])) timetrace_afl[[2]]=seq_len(length(timetrace_afl[[1]]))
timetrace_rand[[2]]=seq_len(length(timetrace_rand[[1]])) timetrace_rand[[2]]=seq_len(length(timetrace_rand[[1]]))
timetrace_graph[[2]]=seq_len(length(timetrace_graph[[1]]))
names(timetrace)[1] <- "timetrace" names(timetrace)[1] <- "timetrace"
names(timetrace)[2] <- "iter" names(timetrace)[2] <- "iter"
names(timetrace_afl)[1] <- "timetrace" names(timetrace_afl)[1] <- "timetrace"
names(timetrace_afl)[2] <- "iter" names(timetrace_afl)[2] <- "iter"
names(timetrace_rand)[1] <- "timetrace" names(timetrace_rand)[1] <- "timetrace"
names(timetrace_rand)[2] <- "iter" names(timetrace_rand)[2] <- "iter"
names(timetrace_graph)[1] <- "timetrace"
names(timetrace_graph)[2] <- "iter"
png(file=filename_1) png(file=filename_1)
# pdf(file=filename_1,width=8, height=8) # pdf(file=filename_1,width=8, height=8)
plot(timetrace[[2]],timetrace[[1]], col=myolors[1], xlab="iters", ylab="wcet", pch='.') 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_afl[[2]],timetrace_afl[[1]], col=myolors[2], pch='.')
points(timetrace_rand[[2]],timetrace_rand[[1]], col=myolors[3], 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),col=myolors[1])
abline(lm(timetrace ~ iter, data=timetrace_afl),col=myolors[2]) abline(lm(timetrace ~ iter, data=timetrace_afl),col=myolors[2])
abline(lm(timetrace ~ iter, data=timetrace_rand),col=myolors[3]) abline(lm(timetrace ~ iter, data=timetrace_rand),col=myolors[3])
@ -48,7 +54,8 @@ dev.off()
png(file=filename_3) png(file=filename_3)
gf_histogram(~ timetrace,data=timetrace, fill=myolors[1]) %>% gf_histogram(~ timetrace,data=timetrace, fill=myolors[1]) %>%
gf_histogram(~ timetrace,data=timetrace_afl, fill=myolors[2]) %>% 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() dev.off()
# Takes a flat list # Takes a flat list
@ -63,11 +70,13 @@ trace2maxline <- function(tr) {
timetrace[[1]] <- trace2maxline(timetrace[[1]]) timetrace[[1]] <- trace2maxline(timetrace[[1]])
timetrace_afl[[1]] <- trace2maxline(timetrace_afl[[1]]) timetrace_afl[[1]] <- trace2maxline(timetrace_afl[[1]])
timetrace_rand[[1]] <- trace2maxline(timetrace_rand[[1]]) timetrace_rand[[1]] <- trace2maxline(timetrace_rand[[1]])
timetrace_graph[[1]] <- trace2maxline(timetrace_graph[[1]])
png(file=filename_2) png(file=filename_2)
plot(timetrace[[2]],timetrace[[1]], col=myolors[1], xlab="iters", ylab="wcet", pch='.') 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_afl[[2]],timetrace_afl[[1]], col=myolors[2], pch='.')
points(timetrace_rand[[2]],timetrace_rand[[1]], col=myolors[3], 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),col=myolors[1])
#abline(lm(timetrace ~ iter, data=timetrace_afl),col=myolors[2]) #abline(lm(timetrace ~ iter, data=timetrace_afl),col=myolors[2])
#abline(lm(timetrace ~ iter, data=timetrace_rand),col=myolors[3]) #abline(lm(timetrace ~ iter, data=timetrace_rand),col=myolors[3])

View File

@ -26,7 +26,7 @@ use libafl::{
observers::{VariableMapObserver}, observers::{VariableMapObserver},
schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler}, schedulers::{IndexesLenTimeMinimizerScheduler, QueueScheduler},
stages::StdMutationalStage, stages::StdMutationalStage,
state::{HasCorpus, StdState, HasMetadata}, state::{HasCorpus, StdState, HasMetadata, HasNamedMetadata},
Error, Error,
prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec}, Evaluator, prelude::{SimpleMonitor, SimpleEventManager, AsMutSlice, RandBytesGenerator, Generator, SimpleRestartingEventManager, HasBytesVec}, Evaluator,
}; };
@ -37,7 +37,7 @@ use libafl_qemu::{
use crate::{ use crate::{
clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, IcHist}, clock::{QemuClockObserver, ClockTimeFeedback, QemuClockIncreaseFeedback, IcHist},
qemustate::QemuStateRestoreHelper, 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; pub static mut MAX_INPUT_SIZE: usize = 32;
@ -136,6 +136,8 @@ pub fn fuzz() {
.expect("Symbol __APP_CODE_END__ not found"); .expect("Symbol __APP_CODE_END__ not found");
#[cfg(feature = "systemstate")] #[cfg(feature = "systemstate")]
let app_range = app_start..app_end; let app_range = app_start..app_end;
#[cfg(feature = "systemstate")]
dbg!(app_range.clone());
let breakpoint = elf let breakpoint = elf
.resolve_symbol( .resolve_symbol(
@ -221,12 +223,21 @@ pub fn fuzz() {
// Feedback to reward any input which increses the execution time // Feedback to reward any input which increses the execution time
ExecTimeIncFeedback::new() 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!( let mut feedback = feedback_or!(
// DumpSystraceFeedback::with_dump(env::var("TRACE_DUMP").ok().map(PathBuf::from)),
NovelSystemStateFeedback::default(), NovelSystemStateFeedback::default(),
feedback feedback
); );
#[cfg(feature = "systemgraph")]
let mut feedback = feedback_or!(
SysMapFeedback::default(),
feedback
);
// A feedback to choose if an input is a solution or not // A feedback to choose if an input is a solution or not
let mut objective = feedback_or_fast!(CrashFeedback::new(), TimeoutFeedback::new()); 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 // 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()); let scheduler = TimeMaximizerCorpusScheduler::new(QueueScheduler::new());
#[cfg(feature = "systemstate")] #[cfg(feature = "systemtrace")]
let scheduler = TimeStateMaximizerCorpusScheduler::new(QueueScheduler::new()); let scheduler = TimeStateMaximizerCorpusScheduler::new(QueueScheduler::new());
#[cfg(feature = "systemgraph")]
let scheduler = GraphMaximizerCorpusScheduler::new(QueueScheduler::new());
// A fuzzer with feedbacks and a corpus scheduler // A fuzzer with feedbacks and a corpus scheduler
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective); 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");}, Some(wi) => {fs::write(&td,wi).expect("Failed to write worst corpus element");},
None => (), None => (),
} }
#[cfg(feature = "systemgraph")]
{
let mut gd = String::from(&td);
gd.push_str(".graph");
if let Some(md) = state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap") {
fs::write(&gd,ron::to_string(&md).expect("Failed to serialize graph")).expect("Failed to write graph");
}
}
} }
}, },
} }

View File

@ -280,10 +280,16 @@ where
{ {
let observer = observers.match_name::<QemuSystemStateObserver>("systemstate") let observer = observers.match_name::<QemuSystemStateObserver>("systemstate")
.expect("QemuSystemStateObserver not found"); .expect("QemuSystemStateObserver not found");
let feedbackstate = state let feedbackstate = match state
.named_metadata_mut() .named_metadata_mut()
.get_mut::<SysGraphFeedbackState>("SysMap") .get_mut::<SysGraphFeedbackState>("SysMap") {
.unwrap(); Some(s) => s,
None => {
let n=SysGraphFeedbackState::default();
state.named_metadata_mut().insert(n, "SysMap");
state.named_metadata_mut().get_mut::<SysGraphFeedbackState>("SysMap").unwrap()
}
};
let ret = feedbackstate.update(&observer.last_run, &observer.last_input); let ret = feedbackstate.update(&observer.last_run, &observer.last_input);
self.last_trace = Some(ret.1); self.last_trace = Some(ret.1);
Ok(ret.0) Ok(ret.0)