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"
[features]
default = ["std", "snapshot_restore", "singlecore", "systemstate"]
default = ["std", "snapshot_restore", "singlecore"]
std = []
snapshot_restore = []
snapshot_fast = [ "snapshot_restore" ]
singlecore = []
systemstate = []
systemgraph = [ "systemstate" ]
systemtrace = [ "systemstate" ]
[profile.release]
lto = true

View File

@ -2,7 +2,7 @@ library("mosaic")
args = commandArgs(trailingOnly=TRUE)
#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) {
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_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_4=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_graph",runtype,target)
timetrace <- read.table(file_1, quote="\"", comment.char="")
timetrace_afl <- read.table(file_2, 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_afl[[2]]=seq_len(length(timetrace_afl[[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)[2] <- "iter"
names(timetrace_afl)[1] <- "timetrace"
names(timetrace_afl)[2] <- "iter"
names(timetrace_rand)[1] <- "timetrace"
names(timetrace_rand)[2] <- "iter"
names(timetrace_graph)[1] <- "timetrace"
names(timetrace_graph)[2] <- "iter"
png(file=filename_1)
# pdf(file=filename_1,width=8, height=8)
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])
@ -48,7 +54,8 @@ dev.off()
png(file=filename_3)
gf_histogram(~ timetrace,data=timetrace, fill=myolors[1]) %>%
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])

View File

@ -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::<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")
.expect("QemuSystemStateObserver not found");
let feedbackstate = state
let feedbackstate = match state
.named_metadata_mut()
.get_mut::<SysGraphFeedbackState>("SysMap")
.unwrap();
.get_mut::<SysGraphFeedbackState>("SysMap") {
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);
self.last_trace = Some(ret.1);
Ok(ret.0)