add a basic demo
This commit is contained in:
parent
edff095401
commit
de4481e70d
20
fuzzers/wcet_qemu_sys/Cargo.toml
Normal file
20
fuzzers/wcet_qemu_sys/Cargo.toml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[package]
|
||||||
|
name = "wcet_qemu_sys"
|
||||||
|
version = "0.1.2"
|
||||||
|
authors = [ "Alwin Berger <alwin.berger@tu-dortmund.de>" ]
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["std"]
|
||||||
|
std = []
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libafl = { path = "../../libafl/" }
|
||||||
|
libafl_qemu = { path = "../../libafl_qemu/", features = ["systemmode", "arm"] }
|
||||||
|
clap = { version = "3.0.0-beta.2", features = ["default"] }
|
||||||
|
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
|
||||||
|
hashbrown = { version = "0.11", features = ["serde", "ahash-compile-time-rng"], default-features=false } # A faster hashmap, nostd compatible
|
||||||
|
nix = "0.23.0"
|
10
fuzzers/wcet_qemu_sys/README.md
Normal file
10
fuzzers/wcet_qemu_sys/README.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Systemmode Fuzzing
|
||||||
|
|
||||||
|
This folder contains an example fuzzer tailored for system-images.
|
||||||
|
For the moment it is mostly hardcoded.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
To build this example, run `cargo build --release` or `cargo build --release`.
|
||||||
|
Also build the FreeRTOS demo named CORTEX_M3_MPS2_QEMU_GCC.
|
||||||
|
Then run `./starter.sh RTOSDemo.axf` and observe.
|
33
fuzzers/wcet_qemu_sys/src/main.rs
Normal file
33
fuzzers/wcet_qemu_sys/src/main.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
// pub mod fuzzer;
|
||||||
|
pub mod showmap;
|
||||||
|
pub mod worst;
|
||||||
|
use libafl_qemu::{
|
||||||
|
edges,
|
||||||
|
edges::QemuEdgeCoverageHelper,
|
||||||
|
emu, filter_qemu_args,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// let mut args2: Vec<String> = vec![
|
||||||
|
// "qemu-system-arm",
|
||||||
|
// "-machine","mps2-an385",
|
||||||
|
// "-monitor", "null",
|
||||||
|
// "-semihosting",
|
||||||
|
// "--semihosting-config", "enable=on,target=native",
|
||||||
|
// "-kernel", "RTOSDemo.axf",
|
||||||
|
// "-serial", "stdio", "-nographic",
|
||||||
|
// "-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
||||||
|
// "-S"
|
||||||
|
// ].iter().map(|x| x.to_string()).collect();
|
||||||
|
// init(&mut args2, &Vec::new());
|
||||||
|
// let succ = emu::snapshot_save("Start");
|
||||||
|
// println!("Snaphsot: {}",succ);
|
||||||
|
// emu::set_breakpoint(0x00004f5c);
|
||||||
|
// emu::run();
|
||||||
|
// let succ = emu::snapshot_load("Start");
|
||||||
|
// emu::run();
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
// fuzzer::main()
|
||||||
|
showmap::main()
|
||||||
|
}
|
316
fuzzers/wcet_qemu_sys/src/showmap.rs
Normal file
316
fuzzers/wcet_qemu_sys/src/showmap.rs
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
//! A singlethreaded QEMU fuzzer that can auto-restart.
|
||||||
|
|
||||||
|
use libafl::corpus::Corpus;
|
||||||
|
use libafl::state::HasCorpus;
|
||||||
|
use libafl::Fuzzer;
|
||||||
|
use libafl::bolts::tuples::Merge;
|
||||||
|
use libafl::mutators::tokens_mutations;
|
||||||
|
use libafl::mutators::havoc_mutations;
|
||||||
|
use libafl::mutators::StdScheduledMutator;
|
||||||
|
use libafl::stages::StdMutationalStage;
|
||||||
|
use libafl_qemu::QemuExecutor;
|
||||||
|
use libafl::bolts::tuples::Named;
|
||||||
|
use libafl::observers::ObserversTuple;
|
||||||
|
use libafl::events::EventFirer;
|
||||||
|
use libafl::state::HasClientPerfMonitor;
|
||||||
|
use libafl::feedbacks::Feedback;
|
||||||
|
use libafl::Evaluator;
|
||||||
|
use libafl::inputs::Input;
|
||||||
|
use libafl::corpus::InMemoryCorpus;
|
||||||
|
use libafl::events::SimpleEventManager;
|
||||||
|
use libafl::stats::SimpleStats;
|
||||||
|
use crate::worst::HitcountsMapObserver;
|
||||||
|
use crate::worst::HitFeedback;
|
||||||
|
use clap::{App, Arg};
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
fs::{self},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use libafl::{
|
||||||
|
bolts::{
|
||||||
|
current_nanos,
|
||||||
|
rands::StdRand,
|
||||||
|
tuples::{tuple_list},
|
||||||
|
},
|
||||||
|
corpus::{QueueCorpusScheduler},
|
||||||
|
executors::{ExitKind},
|
||||||
|
fuzzer::{StdFuzzer},
|
||||||
|
inputs::{BytesInput, HasTargetBytes},
|
||||||
|
observers::{VariableMapObserver},
|
||||||
|
state::{StdState},
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
use libafl_qemu::{
|
||||||
|
edges,
|
||||||
|
edges::QemuEdgeCoverageHelper,
|
||||||
|
emu::Emulator, filter_qemu_args,
|
||||||
|
snapshot_sys,
|
||||||
|
snapshot_sys::QemuSysSnapshotHelper,
|
||||||
|
elf::EasyElf,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// The fuzzer main
|
||||||
|
pub fn main() {
|
||||||
|
// Registry the metadata types used in this fuzzer
|
||||||
|
// Needed only on no_std
|
||||||
|
//RegistryBuilder::register::<Tokens>();
|
||||||
|
|
||||||
|
let mut args: Vec<String> = env::args().collect();
|
||||||
|
|
||||||
|
let res = match App::new("libafl_qemu_fuzzbench")
|
||||||
|
.version("0.4.0")
|
||||||
|
.author("AFLplusplus team")
|
||||||
|
.about("LibAFL-based fuzzer with QEMU for Fuzzbench")
|
||||||
|
.arg(
|
||||||
|
Arg::new("out")
|
||||||
|
.long("libafl-out")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("in")
|
||||||
|
.long("libafl-in")
|
||||||
|
.required(true)
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("tokens")
|
||||||
|
.long("libafl-tokens")
|
||||||
|
.takes_value(true),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("logfile")
|
||||||
|
.long("libafl-logfile")
|
||||||
|
.default_value("libafl.log"),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
Arg::new("timeout")
|
||||||
|
.long("libafl-timeout")
|
||||||
|
.default_value("1000"),
|
||||||
|
)
|
||||||
|
.try_get_matches_from(filter_qemu_args())
|
||||||
|
{
|
||||||
|
Ok(res) => res,
|
||||||
|
Err(err) => {
|
||||||
|
println!(
|
||||||
|
"Syntax: {}, --libafl-in <input>\n{:?}",
|
||||||
|
env::current_exe()
|
||||||
|
.unwrap_or_else(|_| "fuzzer".into())
|
||||||
|
.to_string_lossy(),
|
||||||
|
err.info,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Workdir: {:?}",
|
||||||
|
env::current_dir().unwrap().to_string_lossy().to_string()
|
||||||
|
);
|
||||||
|
|
||||||
|
// For fuzzbench, crashes and finds are inside the same `corpus` directory, in the "queue" and "crashes" subdir.
|
||||||
|
let mut out_dir = PathBuf::from(res.value_of("out").unwrap().to_string());
|
||||||
|
if fs::create_dir(&out_dir).is_err() {
|
||||||
|
println!("Out dir at {:?} already exists.", &out_dir);
|
||||||
|
if !out_dir.is_dir() {
|
||||||
|
println!("Out dir at {:?} is not a valid directory!", &out_dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut worstcases = out_dir.clone();
|
||||||
|
worstcases.push("worstcase");
|
||||||
|
out_dir.push("queue");
|
||||||
|
|
||||||
|
let in_dir = PathBuf::from(res.value_of("in").unwrap().to_string());
|
||||||
|
if !in_dir.is_dir() {
|
||||||
|
println!("In dir at {:?} is not a valid directory!", &in_dir);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fuzz(in_dir)
|
||||||
|
.expect("An error occurred while fuzzing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The actual fuzzer
|
||||||
|
fn fuzz(
|
||||||
|
seed_dir: PathBuf,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
//=========== Setup emulator
|
||||||
|
let mut env: Vec<(String, String)> = env::vars().collect();
|
||||||
|
let mut args2: Vec<String> = vec![
|
||||||
|
"qemu-system-arm",
|
||||||
|
"-machine","mps2-an385",
|
||||||
|
"-monitor", "null",
|
||||||
|
"-semihosting",
|
||||||
|
"--semihosting-config", "enable=on,target=native",
|
||||||
|
"-kernel", "RTOSDemo.axf",
|
||||||
|
"-serial", "stdio", "-nographic",
|
||||||
|
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
||||||
|
"-S"
|
||||||
|
].iter().map(|x| x.to_string()).collect();
|
||||||
|
let emu = Emulator::new(&mut args2, &mut env);
|
||||||
|
//=========== Analyze the binary to find the target function address
|
||||||
|
// let mut elf_buffer = Vec::new();
|
||||||
|
// let elf = EasyElf::from_file(emu::binary_path(), &mut elf_buffer)?;
|
||||||
|
|
||||||
|
// let test_one_input_ptr = elf
|
||||||
|
// .resolve_symbol("LLVMFuzzerTestOneInput", 0)
|
||||||
|
// .expect("Symbol LLVMFuzzerTestOneInput not found");
|
||||||
|
// println!("LLVMFuzzerTestOneInput @ {:#x}", test_one_input_ptr);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//====== Create the input field
|
||||||
|
let input_addr = 0x00006de4+0xc;
|
||||||
|
println!("Placing input at {:#x}", input_addr);
|
||||||
|
emu.set_breakpoint(0x00004f5c);
|
||||||
|
|
||||||
|
//====== Create the most simple status display and managers.
|
||||||
|
|
||||||
|
let stats = SimpleStats::new(|s| println!("{}", s));
|
||||||
|
|
||||||
|
let mut mgr = SimpleEventManager::new(stats);
|
||||||
|
|
||||||
|
|
||||||
|
//========== EDGES_MAP is static field which somehow(?) gets handed over to the Qemu instrumentation
|
||||||
|
//========== Otherwise setup generic observers
|
||||||
|
// Create an observation channel using the coverage map
|
||||||
|
let edges = unsafe { &mut edges::EDGES_MAP };
|
||||||
|
let edges_counter = unsafe { &mut edges::MAX_EDGES_NUM };
|
||||||
|
let edges_observer =
|
||||||
|
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||||
|
|
||||||
|
//========= Feedback-Function evaluate the Maps. Need to dump it for debugging and check if it reaches targets.
|
||||||
|
let feedback = DumpMapFeedback::new();
|
||||||
|
|
||||||
|
// A feedback to choose if an input is a solution or not
|
||||||
|
let objective = HitFeedback::new();
|
||||||
|
|
||||||
|
// create a State from scratch
|
||||||
|
let mut state = StdState::new(
|
||||||
|
// RNG
|
||||||
|
StdRand::with_seed(current_nanos()),
|
||||||
|
// Corpus that will be evolved, we keep it in memory for performance
|
||||||
|
InMemoryCorpus::new(),
|
||||||
|
// Corpus in which we store solutions (crashes in this example),
|
||||||
|
// on disk so the user can get them after stopping the fuzzer
|
||||||
|
InMemoryCorpus::new(),
|
||||||
|
// States of the feedbacks.
|
||||||
|
// They are the data related to the feedbacks that you want to persist in the State.
|
||||||
|
(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// A minimization+queue policy to get testcasess from the corpus
|
||||||
|
let scheduler = QueueCorpusScheduler::new();
|
||||||
|
|
||||||
|
// A fuzzer with feedbacks and a corpus scheduler
|
||||||
|
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
|
||||||
|
|
||||||
|
//======== The harness has to start the execution of the emulator
|
||||||
|
// The wrapped harness function, calling out to the LLVM-style harness
|
||||||
|
let mut harness = |input: &BytesInput| {
|
||||||
|
let target = input.target_bytes();
|
||||||
|
let mut buf = target.as_slice();
|
||||||
|
let mut len = buf.len();
|
||||||
|
if len > 4096 {
|
||||||
|
buf = &buf[0..4096];
|
||||||
|
len = 4096;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
emu.write_mem(0x00006de4+0xc,buf);
|
||||||
|
// println!("{:#?}",edges_copy);
|
||||||
|
|
||||||
|
emu.run();
|
||||||
|
// println!("{:#?}",edges_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitKind::Ok
|
||||||
|
};
|
||||||
|
|
||||||
|
//======= Construct the executor, including the Helpers. The edges_observer still contains the ref to EDGES_MAP
|
||||||
|
let mut executor = QemuExecutor::new(
|
||||||
|
&mut harness,
|
||||||
|
&emu,
|
||||||
|
tuple_list!(
|
||||||
|
QemuEdgeCoverageHelper::new(),
|
||||||
|
// QemuCmpLogHelper::new(),
|
||||||
|
// QemuAsanHelper::new(),
|
||||||
|
QemuSysSnapshotHelper::new()
|
||||||
|
),
|
||||||
|
tuple_list!(edges_observer),
|
||||||
|
&mut fuzzer,
|
||||||
|
&mut state,
|
||||||
|
&mut mgr,
|
||||||
|
)?;
|
||||||
|
let firstinput = match seed_dir.clone().is_dir() {
|
||||||
|
true => seed_dir.clone().read_dir().expect("Directory not a directory?").next().expect("Directory empty?").expect("File not in directory?").path(),
|
||||||
|
false => seed_dir.clone()
|
||||||
|
};
|
||||||
|
fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
||||||
|
// fuzzer.evaluate_input(&mut state, &mut executor, &mut mgr, Input::from_file(&firstinput).expect("Could not load file")).expect("Evaluation failed");
|
||||||
|
// let mutator = StdScheduledMutator::new(havoc_mutations().merge(tokens_mutations()));
|
||||||
|
// let mut stages = tuple_list!(StdMutationalStage::new(mutator));
|
||||||
|
// if state.corpus().count() < 1 {
|
||||||
|
// state
|
||||||
|
// .load_initial_inputs(&mut fuzzer, &mut executor, &mut mgr, &[seed_dir.clone()])
|
||||||
|
// .expect("Failed to load initial corpus");
|
||||||
|
// println!("We imported {} inputs from disk.", state.corpus().count());
|
||||||
|
// }
|
||||||
|
// fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)
|
||||||
|
// .expect("Error in the fuzzing loop");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================== Debugging Feedback
|
||||||
|
/// A [`Feedback`] meant to dump the edgemap for debugging.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct DumpMapFeedback {}
|
||||||
|
|
||||||
|
impl<I, S> Feedback<I, S> for DumpMapFeedback
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
S: HasClientPerfMonitor,
|
||||||
|
{
|
||||||
|
fn is_interesting<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_input: &I,
|
||||||
|
_observers: &OT,
|
||||||
|
_exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<I>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||||
|
.expect("HitcountsMapObserver not found");
|
||||||
|
println!("{:#?}",observer.edgemap);
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Named for DumpMapFeedback {
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"HitFeedback"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DumpMapFeedback {
|
||||||
|
/// Creates a new [`HitFeedback`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DumpMapFeedback {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
218
fuzzers/wcet_qemu_sys/src/worst.rs
Normal file
218
fuzzers/wcet_qemu_sys/src/worst.rs
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
use libafl::observers::VariableMapObserver;
|
||||||
|
use hashbrown::{HashMap};
|
||||||
|
use libafl::observers::ObserversTuple;
|
||||||
|
use libafl::executors::ExitKind;
|
||||||
|
use libafl::events::EventFirer;
|
||||||
|
use libafl::state::HasClientPerfMonitor;
|
||||||
|
use libafl::inputs::Input;
|
||||||
|
use libafl::feedbacks::Feedback;
|
||||||
|
use libafl::state::HasMetadata;
|
||||||
|
use libafl_qemu::edges::QemuEdgesMapMetadata;
|
||||||
|
use libafl::observers::MapObserver;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use libafl::{
|
||||||
|
bolts::{
|
||||||
|
tuples::Named,
|
||||||
|
HasLen,
|
||||||
|
},
|
||||||
|
observers::Observer,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Map observer with hitcounts postprocessing
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
#[serde(bound = "M: serde::de::DeserializeOwned")]
|
||||||
|
pub struct HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
base: M,
|
||||||
|
pub edgemap: HashMap<(u64,u64),u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
static COUNT_CLASS_LOOKUP: [u8; 256] = [
|
||||||
|
0, 1, 2, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||||
|
32, 32, 32, 32, 32, 32, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||||
|
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||||
|
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||||
|
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
|
||||||
|
64, 64, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||||
|
];
|
||||||
|
|
||||||
|
impl<I, S, M> Observer<I, S> for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: MapObserver<u8> + Observer<I, S>,
|
||||||
|
S: HasMetadata, // Need to grab the HashMap from a Helper
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn pre_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
|
||||||
|
self.edgemap = HashMap::new();
|
||||||
|
self.base.pre_exec(state, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn post_exec(&mut self, state: &mut S, input: &I) -> Result<(), Error> {
|
||||||
|
//new stuff
|
||||||
|
let original_hashmap=&state.metadata().get::<QemuEdgesMapMetadata>().unwrap().map;
|
||||||
|
for (key, val) in original_hashmap.iter() {
|
||||||
|
self.edgemap.insert(*key,*self.base.get(*val as usize));
|
||||||
|
}
|
||||||
|
// println!("Post-Exec Len: {} Cap: {}",self.edgemap.len(),self.edgemap.capacity());
|
||||||
|
// println!("{:#?}",self.edgemap);
|
||||||
|
//end new stuff
|
||||||
|
let cnt = self.usable_count();
|
||||||
|
for i in 0..cnt {
|
||||||
|
*self.get_mut(i) = COUNT_CLASS_LOOKUP[*self.get(i) as usize];
|
||||||
|
}
|
||||||
|
self.base.post_exec(state, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> Named for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: Named + serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
self.base.name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> HasLen for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: MapObserver<u8>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
self.base.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> MapObserver<u8> for HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: MapObserver<u8>,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn map(&self) -> Option<&[u8]> {
|
||||||
|
self.base.map()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn map_mut(&mut self) -> Option<&mut [u8]> {
|
||||||
|
self.base.map_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn usable_count(&self) -> usize {
|
||||||
|
self.base.usable_count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn initial(&self) -> u8 {
|
||||||
|
self.base.initial()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn initial_mut(&mut self) -> &mut u8 {
|
||||||
|
self.base.initial_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn set_initial(&mut self, initial: u8) {
|
||||||
|
self.base.set_initial(initial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> HitcountsMapObserver<M>
|
||||||
|
where
|
||||||
|
M: serde::Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`MapObserver`]
|
||||||
|
pub fn new(base: M) -> Self {
|
||||||
|
Self { edgemap:HashMap::new(), base }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
|
||||||
|
|
||||||
|
/// A [`HitFeedback`] reports as interesting when all predicted worst case edges have been matched.
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
|
pub struct HitFeedback {}
|
||||||
|
|
||||||
|
impl<I, S> Feedback<I, S> for HitFeedback
|
||||||
|
where
|
||||||
|
I: Input,
|
||||||
|
S: HasClientPerfMonitor,
|
||||||
|
{
|
||||||
|
fn is_interesting<EM, OT>(
|
||||||
|
&mut self,
|
||||||
|
_state: &mut S,
|
||||||
|
_manager: &mut EM,
|
||||||
|
_input: &I,
|
||||||
|
_observers: &OT,
|
||||||
|
_exit_kind: &ExitKind,
|
||||||
|
) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
EM: EventFirer<I>,
|
||||||
|
OT: ObserversTuple<I, S>,
|
||||||
|
{
|
||||||
|
// TODO Replace with match_name_type when stable
|
||||||
|
// let observer = _observers.match_name::<HitcountsMapObserver<O>>("edges").expect("SelectedEdgeObserver not found");
|
||||||
|
let observer = _observers.match_name::<HitcountsMapObserver<VariableMapObserver<u8>>>("edges")
|
||||||
|
.expect("HitcountsMapObserver not found");
|
||||||
|
let mut hit_target: bool = true;
|
||||||
|
//check if we've hit any targets.
|
||||||
|
// let inc : u64 = (0x401180);
|
||||||
|
// let call1 : u64 = (0x40119f);
|
||||||
|
// let call2 : u64 = (0x4011b0);
|
||||||
|
// let call3 : u64 = (0x4011c8);
|
||||||
|
let to_check : Vec<(u64,u64)> = vec![
|
||||||
|
(0x401190,0x4011c8), // start -> call
|
||||||
|
(0x40119b,0x4011b0), // cmp -> call
|
||||||
|
(0x4011b5,0x40119f), // cmp -> call
|
||||||
|
];
|
||||||
|
let expected : Vec<u8> = vec![ 1, 1, 1];
|
||||||
|
let combo = to_check.iter().zip(expected.iter());
|
||||||
|
for (edg, val) in combo {
|
||||||
|
// println!("Feedback Len: {} Cap: {}",observer.edgemap.len(),observer.edgemap.capacity());
|
||||||
|
match observer.edgemap.get(edg) {
|
||||||
|
Some(x) => hit_target &= val == x,
|
||||||
|
None =>hit_target = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if hit_target {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Named for HitFeedback {
|
||||||
|
#[inline]
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"HitFeedback"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HitFeedback {
|
||||||
|
/// Creates a new [`HitFeedback`]
|
||||||
|
#[must_use]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for HitFeedback {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
3
fuzzers/wcet_qemu_sys/starter.sh
Executable file
3
fuzzers/wcet_qemu_sys/starter.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
mkdir -p target/test_in target/test_out
|
||||||
|
[ ! -f target/test_in/test ] && echo " !test" > target/test_in/test
|
||||||
|
LD_LIBRARY_PATH=target/debug target/debug/wcet_qemu_sys $1 --libafl-out target/test_out --libafl-in target/test_in
|
Loading…
x
Reference in New Issue
Block a user