From 594554eca0aeca997017cfa174597520003286c6 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Thu, 26 Jan 2023 14:03:18 +0100 Subject: [PATCH] remove address translations, extend plots --- fuzzers/FRET/benchmark/plot_comparison.r | 41 ++++++++++++------- fuzzers/FRET/benchmark/target_symbols.csv | 2 +- fuzzers/FRET/src/clock.rs | 5 ++- fuzzers/FRET/src/fuzzer.rs | 49 ++++++++++++++--------- fuzzers/FRET/src/systemstate/helpers.rs | 6 +-- 5 files changed, 63 insertions(+), 40 deletions(-) diff --git a/fuzzers/FRET/benchmark/plot_comparison.r b/fuzzers/FRET/benchmark/plot_comparison.r index 69ffad216d..c3cc84b9f1 100644 --- a/fuzzers/FRET/benchmark/plot_comparison.r +++ b/fuzzers/FRET/benchmark/plot_comparison.r @@ -1,8 +1,11 @@ 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 + if (length(args)==0) { - runtype="timedump" + runtype="timedump_exp02" target="tacle_rtos" filename_1=sprintf("%s.png",target) filename_2=sprintf("%s_maxline.png",target) @@ -17,27 +20,35 @@ if (length(args)==0) { } file_1=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s",runtype,target) -file_2=sprintf("~/code/FRET/LibAFL/fuzzers/FRET/benchmark/%s/%s_random",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) timetrace <- read.table(file_1, quote="\"", comment.char="") -timetrace_rand <- 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[[2]]=seq_len(length(timetrace[[1]])) +timetrace_afl[[2]]=seq_len(length(timetrace_afl[[1]])) timetrace_rand[[2]]=seq_len(length(timetrace_rand[[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" png(file=filename_1) # pdf(file=filename_1,width=8, height=8) -plot(timetrace[[2]],timetrace[[1]], col="#99bbff", xlab="iters", ylab="wcet", pch='.') -points(timetrace_rand[[2]],timetrace_rand[[1]], col="#ffbb99", pch='.') -abline(lm(timetrace ~ iter, data=timetrace),col="green") -abline(lm(timetrace ~ iter, data=timetrace_rand),col="magenta") +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='.') +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]) dev.off() png(file=filename_3) -gf_histogram(~ timetrace,data=timetrace, fill="blue") %>% -gf_histogram(~ timetrace,data=timetrace_rand, fill="orange") +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]) dev.off() # Takes a flat list @@ -50,12 +61,14 @@ trace2maxline <- function(tr) { return(maxline) } timetrace[[1]] <- trace2maxline(timetrace[[1]]) +timetrace_afl[[1]] <- trace2maxline(timetrace_afl[[1]]) timetrace_rand[[1]] <- trace2maxline(timetrace_rand[[1]]) png(file=filename_2) -# pdf(file=filename_1,width=8, height=8) -plot(timetrace[[2]],timetrace[[1]], col="#99bbff", xlab="iters", ylab="wcet", pch='.') -points(timetrace_rand[[2]],timetrace_rand[[1]], col="#ffbb99", pch='.') -#abline(lm(timetrace ~ iter, data=timetrace),col="green") -#abline(lm(timetrace ~ iter, data=timetrace_rand),col="magenta") +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='.') +#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]) dev.off() \ No newline at end of file diff --git a/fuzzers/FRET/benchmark/target_symbols.csv b/fuzzers/FRET/benchmark/target_symbols.csv index 0e31e4f984..503b7e34e1 100644 --- a/fuzzers/FRET/benchmark/target_symbols.csv +++ b/fuzzers/FRET/benchmark/target_symbols.csv @@ -13,4 +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 \ No newline at end of file +tacle_rtos,prvStage0,FUZZ_INPUT,604,trigger_Qemu_break \ No newline at end of file diff --git a/fuzzers/FRET/src/clock.rs b/fuzzers/FRET/src/clock.rs index 131b66b85b..b2ef629d32 100644 --- a/fuzzers/FRET/src/clock.rs +++ b/fuzzers/FRET/src/clock.rs @@ -143,7 +143,7 @@ where } Some(v) => { v.0.push(self.end_tick - self.start_tick); - if v.0.len() >= 1000 { + if v.0.len() >= 100 { if let Ok(td) = env::var("TIME_DUMP") { let mut file = OpenOptions::new() .read(true) @@ -151,7 +151,8 @@ where .create(true) .append(true) .open(td).expect("Could not open timedump"); - for i in std::mem::take(&mut v.0).into_iter() { + let newv : Vec = Vec::with_capacity(100); + for i in std::mem::replace(&mut v.0, newv).into_iter() { writeln!(file, "{}", i).expect("Write to dump failed"); } } else { diff --git a/fuzzers/FRET/src/fuzzer.rs b/fuzzers/FRET/src/fuzzer.rs index 05d47ec0dd..2d8b2ab31a 100644 --- a/fuzzers/FRET/src/fuzzer.rs +++ b/fuzzers/FRET/src/fuzzer.rs @@ -42,12 +42,12 @@ use crate::{ pub static mut MAX_INPUT_SIZE: usize = 32; /// Read ELF program headers to resolve physical load addresses. -fn virt2phys(vaddr: GuestAddr, tab: &EasyElf) -> GuestAddr { +fn virt2phys(vaddr: GuestPhysAddr, tab: &EasyElf) -> GuestPhysAddr { let ret; for i in &tab.goblin().program_headers { if i.vm_range().contains(&vaddr.try_into().unwrap()) { - ret = vaddr - TryInto::::try_into(i.p_vaddr).unwrap() - + TryInto::::try_into(i.p_paddr).unwrap(); + ret = vaddr - TryInto::::try_into(i.p_vaddr).unwrap() + + TryInto::::try_into(i.p_paddr).unwrap(); return ret - (ret % 2); } } @@ -77,27 +77,32 @@ pub fn fuzz() { ) .unwrap(); + // the main address where the fuzzer starts + // if this is set for freeRTOS it has an influence on where the data will have to be written, + // since the startup routine copies the data segemnt to it's virtual address + let main_addr = elf + .resolve_symbol(&env::var("FUZZ_MAIN").unwrap_or_else(|_| "FUZZ_MAIN".to_owned()), 0); + if let Some(main_addr) = main_addr { + println!("main address = {:#x}", main_addr); + } + let input_addr = elf .resolve_symbol( &env::var("FUZZ_INPUT").unwrap_or_else(|_| "FUZZ_INPUT".to_owned()), 0, ) - .expect("Symbol or env FUZZ_INPUT not found"); //as GuestPhysAddr; + .expect("Symbol or env FUZZ_INPUT not found") as GuestPhysAddr; let input_addr = virt2phys(input_addr,&elf) as GuestPhysAddr; println!("FUZZ_INPUT @ {:#x}", input_addr); let test_length_ptr = elf - .resolve_symbol("FUZZ_LENGTH", 0); - let test_length_ptr = Option::map_or(test_length_ptr, None, |x| Some(virt2phys(x,&elf) as u32)); + .resolve_symbol("FUZZ_LENGTH", 0).map(|x| x as GuestPhysAddr); + let test_length_ptr = Option::map_or(test_length_ptr, None, |x| Some(virt2phys(x,&elf))); let input_counter_ptr = elf - .resolve_symbol(&env::var("FUZZ_POINTER").unwrap_or_else(|_| "FUZZ_POINTER".to_owned()), 0); - let input_counter_ptr = Option::map_or(input_counter_ptr, None, |x| Some(virt2phys(x,&elf) as u32)); - - let main_addr = elf - .resolve_symbol(&env::var("FUZZ_MAIN").unwrap_or_else(|_| "FUZZ_INPUT".to_owned()), 0) - .expect("Symbol main not found"); - println!("main address = {:#x}", main_addr); + .resolve_symbol(&env::var("FUZZ_POINTER").unwrap_or_else(|_| "FUZZ_POINTER".to_owned()), 0) + .map(|x| x as GuestPhysAddr); + let input_counter_ptr = Option::map_or(input_counter_ptr, None, |x| Some(virt2phys(x,&elf))); #[cfg(feature = "systemstate")] let curr_tcb_pointer = elf // loads to the address specified in elf, without respecting program headers @@ -153,11 +158,13 @@ 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); + if let Some(main_addr) = main_addr { + emu.set_breakpoint(main_addr); + unsafe { + emu.run(); + } + emu.remove_breakpoint(main_addr); + } emu.set_breakpoint(breakpoint); // BREAKPOINT @@ -374,7 +381,7 @@ pub fn fuzz() { } } #[cfg(not(feature = "singlecore"))] - Ok(()) + return Ok(()); }; // Special case where no fuzzing happens, but standard input is dumped @@ -384,7 +391,9 @@ pub fn fuzz() { let env: Vec<(String, String)> = env::vars().collect(); let emu = Emulator::new(&args, &env); - emu.set_breakpoint(main_addr); + if let Some(main_addr) = main_addr { + emu.set_breakpoint(main_addr); + } unsafe { emu.run(); diff --git a/fuzzers/FRET/src/systemstate/helpers.rs b/fuzzers/FRET/src/systemstate/helpers.rs index 8da48f0950..b8c9c78606 100644 --- a/fuzzers/FRET/src/systemstate/helpers.rs +++ b/fuzzers/FRET/src/systemstate/helpers.rs @@ -37,7 +37,7 @@ pub struct QemuSystemStateHelper { kerneladdr: u32, tcb_addr: u32, ready_queues: u32, - input_counter: Option, + input_counter: Option, app_range: Range, } @@ -47,7 +47,7 @@ impl QemuSystemStateHelper { kerneladdr: u32, tcb_addr: u32, ready_queues: u32, - input_counter: Option, + input_counter: Option, app_range: Range, ) -> Self { QemuSystemStateHelper { @@ -100,7 +100,7 @@ fn trigger_collection(emulator: &Emulator, h: &QemuSystemStateHelper) { } let mut buf : [u8; 4] = [0,0,0,0]; match h.input_counter { - Some(s) => unsafe { emulator.read_mem(s, &mut buf); }, + Some(s) => unsafe { emulator.read_phys_mem(s, &mut buf); }, None => (), }; systemstate.input_counter = u32::from_le_bytes(buf);