add QemuClockObserver
This commit is contained in:
parent
ba85877ab4
commit
b3b8e81190
@ -219,6 +219,7 @@ fn fuzz(
|
||||
"-kernel", kernel.to_str().unwrap(),
|
||||
"-serial", "stdio", "-nographic",
|
||||
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
||||
"-icount", "shift=auto,align=off,sleep=off",
|
||||
"-S"
|
||||
].iter().map(|x| x.to_string()).collect();
|
||||
let env: Vec<(String, String)> = env::vars().collect();
|
||||
|
@ -43,6 +43,8 @@ use libafl_qemu::{
|
||||
emu::Emulator, filter_qemu_args,
|
||||
snapshot_sys::QemuSysSnapshotHelper,
|
||||
elf::EasyElf,
|
||||
clock,
|
||||
clock::{QemuClockObserver,QemuClockIncreaseFeedback},
|
||||
};
|
||||
use crate::freertos;
|
||||
|
||||
@ -177,6 +179,7 @@ fn fuzz(
|
||||
"-kernel", kernel.to_str().unwrap(),
|
||||
"-serial", "stdio", "-nographic",
|
||||
"-snapshot", "-drive", "if=none,format=qcow2,file=dummy.qcow2",
|
||||
"-icount", "shift=auto,align=off,sleep=off",
|
||||
"-S"
|
||||
].iter().map(|x| x.to_string()).collect();
|
||||
let emu = Emulator::new(&mut args, &mut env);
|
||||
@ -248,11 +251,14 @@ fn fuzz(
|
||||
let edges_observer =
|
||||
HitcountsMapObserver::new(VariableMapObserver::new("edges", edges, edges_counter));
|
||||
|
||||
//========== Observe Execution Cycles
|
||||
let clock_observer = QemuClockObserver::default();
|
||||
|
||||
//========= Feedback-Function evaluate the Maps. Need to dump it for debugging and check if it reaches targets.
|
||||
let feedback = DumpMapFeedback::with_dump(dump_edges);
|
||||
|
||||
// A feedback to choose if an input is a solution or not
|
||||
let objective = CrashFeedback::new();
|
||||
let objective = QemuClockIncreaseFeedback::new();
|
||||
|
||||
// create a State from scratch
|
||||
let mut state = StdState::new(
|
||||
@ -315,7 +321,7 @@ fn fuzz(
|
||||
QemuSysSnapshotHelper::new(),
|
||||
QemuSystemStateHelper::with_instrumentation_filter(system_state_filter,curr_tcb_pointer.try_into().unwrap(),task_queue_addr.try_into().unwrap())
|
||||
),
|
||||
tuple_list!(edges_observer),
|
||||
tuple_list!(edges_observer,clock_observer),
|
||||
&mut fuzzer,
|
||||
&mut state,
|
||||
&mut mgr,
|
||||
|
141
libafl_qemu/src/clock.rs
Normal file
141
libafl_qemu/src/clock.rs
Normal file
@ -0,0 +1,141 @@
|
||||
use hashbrown::{hash_map::Entry, HashMap};
|
||||
use libafl::{
|
||||
bolts::{
|
||||
current_nanos,
|
||||
rands::StdRand,
|
||||
tuples::{tuple_list},
|
||||
},
|
||||
corpus::{QueueCorpusScheduler},
|
||||
executors::{ExitKind},
|
||||
fuzzer::{StdFuzzer},
|
||||
inputs::{BytesInput, HasTargetBytes},
|
||||
observers::{Observer,VariableMapObserver},
|
||||
state::{StdState},
|
||||
Error,
|
||||
observers::ObserversTuple,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{cell::UnsafeCell, cmp::max};
|
||||
use libafl::bolts::tuples::Named;
|
||||
|
||||
use crate::{
|
||||
emu,
|
||||
emu::Emulator,
|
||||
executor::QemuExecutor,
|
||||
helper::{QemuHelper, QemuHelperTuple, QemuInstrumentationFilter},
|
||||
};
|
||||
use libafl::events::EventFirer;
|
||||
use libafl::state::HasClientPerfMonitor;
|
||||
use libafl::inputs::Input;
|
||||
use libafl::feedbacks::Feedback;
|
||||
|
||||
//========== Observer
|
||||
|
||||
/// A simple observer, just overlooking the runtime of the target.
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
pub struct QemuClockObserver {
|
||||
name: String,
|
||||
last_runtime: i64,
|
||||
}
|
||||
|
||||
impl QemuClockObserver {
|
||||
/// Creates a new [`QemuClockObserver`] with the given name.
|
||||
#[must_use]
|
||||
pub fn new(name: &'static str) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
last_runtime: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the runtime for the last execution of this target.
|
||||
#[must_use]
|
||||
pub fn last_runtime(&self) -> i64 {
|
||||
self.last_runtime
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, S> Observer<I, S> for QemuClockObserver {
|
||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||
self.last_runtime=0;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn post_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||
unsafe { self.last_runtime = emu::libafl_get_clock() };
|
||||
println!("Observer Clock: {}",self.last_runtime());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for QemuClockObserver {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for QemuClockObserver {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: String::from("clock"),
|
||||
last_runtime: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//========== Observer
|
||||
|
||||
/// A [`Feedback`] rewarding increasing the execution cycles on Qemu.
|
||||
#[derive(Debug)]
|
||||
pub struct QemuClockIncreaseFeedback {
|
||||
maximum: i64
|
||||
}
|
||||
|
||||
impl<I, S> Feedback<I, S> for QemuClockIncreaseFeedback
|
||||
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::<QemuClockObserver>("clock")
|
||||
.expect("QemuClockObserver not found");
|
||||
if observer.last_runtime() >= self.maximum {
|
||||
self.maximum = observer.last_runtime();
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
impl Named for QemuClockIncreaseFeedback {
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
"QemuClockFeedback"
|
||||
}
|
||||
}
|
||||
|
||||
impl QemuClockIncreaseFeedback {
|
||||
/// Creates a new [`HitFeedback`]
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {maximum: 0}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for QemuClockIncreaseFeedback {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
@ -199,6 +199,8 @@ extern "C" {
|
||||
fn libafl_snapshot_save(name: *const c_char) -> i32;
|
||||
#[cfg(feature = "systemmode")]
|
||||
fn libafl_snapshot_load(name: *const c_char) -> i32;
|
||||
#[cfg(feature = "systemmode")]
|
||||
pub fn libafl_get_clock() -> i64;
|
||||
|
||||
fn strlen(s: *const u8) -> usize;
|
||||
|
||||
@ -678,6 +680,11 @@ impl Emulator {
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "systemmode")]
|
||||
pub fn get_ticks(&self) -> i64{
|
||||
return unsafe { libafl_get_clock() };
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python")]
|
||||
|
@ -43,6 +43,10 @@ pub use snapshot::QemuSnapshotHelper;
|
||||
pub mod snapshot_sys;
|
||||
#[cfg(all(target_os = "linux",feature = "systemmode"))]
|
||||
pub use snapshot_sys::QemuSysSnapshotHelper;
|
||||
#[cfg(all(target_os = "linux",feature = "systemmode"))]
|
||||
pub mod clock;
|
||||
#[cfg(all(target_os = "linux",feature = "systemmode"))]
|
||||
pub use clock::QemuClockObserver;
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod asan;
|
||||
#[cfg(target_os = "linux")]
|
||||
|
Loading…
x
Reference in New Issue
Block a user