Make InProcessExecutor use a plain Input instead of bytes (#115)

* Make InProcessExecutor use a plain Input instead of bytes

* Use HasTargetBytes and fix CI
This commit is contained in:
Max Ammann 2021-05-20 17:57:31 +02:00 committed by GitHub
parent 2f54e9dc01
commit bfbaa7ae83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 37 deletions

View File

@ -1,5 +1,6 @@
use std::path::PathBuf;
use libafl::inputs::{BytesInput, HasTargetBytes};
use libafl::{
bolts::{current_nanos, rands::StdRand, tuples::tuple_list},
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
@ -26,7 +27,9 @@ fn signals_set(idx: usize) {
#[allow(clippy::similar_names)]
pub fn main() {
// The closure that we want to fuzz
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
signals_set(0);
if !buf.is_empty() && buf[0] == b'a' {
signals_set(1);

View File

@ -26,7 +26,7 @@ use libafl::{
feedback_or,
feedbacks::{CrashFeedback, MapFeedbackState, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{HasTargetBytes, Input},
inputs::{BytesInput, HasTargetBytes, Input},
mutators::{
scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
token_mutations::Tokens,
@ -61,7 +61,7 @@ use libafl_frida::{
struct FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
@ -78,7 +78,7 @@ impl<'a, 'b, 'c, FH, H, I, OT, S> Executor<I>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
@ -117,7 +117,7 @@ impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
@ -152,7 +152,7 @@ impl<'a, 'b, 'c, FH, H, I, OT, S> HasObservers<OT>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
@ -171,7 +171,7 @@ impl<'a, 'b, 'c, EM, FH, H, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z>
for FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
@ -180,7 +180,7 @@ where
impl<'a, 'b, 'c, FH, H, I, OT, S> FridaInProcessExecutor<'a, 'b, 'c, FH, H, I, OT, S>
where
FH: FridaHelper<'b>,
H: FnMut(&[u8]) -> ExitKind,
H: FnMut(&I) -> ExitKind,
I: Input + HasTargetBytes,
OT: ObserversTuple,
{
@ -336,7 +336,9 @@ unsafe fn fuzz(
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
> = lib.get(symbol_name.as_bytes()).unwrap();
let mut frida_harness = move |buf: &[u8]| {
let mut frida_harness = move |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
(target_func)(buf.as_ptr(), buf.len());
ExitKind::Ok
};

View File

@ -15,6 +15,7 @@ use libafl::{
feedback_or,
feedbacks::{CrashFeedback, MapFeedbackState, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
mutators::token_mutations::Tokens,
observers::StdMapObserver,
@ -128,7 +129,9 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// The wrapped harness function, calling out to the LLVM-style harness
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};

View File

@ -16,6 +16,7 @@ use libafl::{
feedback_or,
feedbacks::{CrashFeedback, MapFeedbackState, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
mutators::token_mutations::Tokens,
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
@ -126,7 +127,9 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// The wrapped harness function, calling out to the LLVM-style harness
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};

View File

@ -24,6 +24,7 @@ use libafl::{
feedback_or,
feedbacks::{CrashFeedback, MapFeedbackState, MaxMapFeedback, TimeFeedback, TimeoutFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, tokens_mutations, StdScheduledMutator},
mutators::token_mutations::Tokens,
observers::{HitcountsMapObserver, StdMapObserver, TimeObserver},
@ -127,7 +128,9 @@ pub fn main() {
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// The wrapped harness function, calling out to the LLVM-style harness
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};

View File

@ -10,6 +10,7 @@ use libafl::{
executors::{inprocess::InProcessExecutor, ExitKind},
feedbacks::{MapFeedbackState, MaxMapFeedback, ReachabilityFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
observers::{HitcountsMapObserver, StdMapObserver},
stages::mutational::StdMutationalStage,
@ -107,7 +108,9 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// The wrapped harness function, calling out to the LLVM-style harness
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};

View File

@ -14,6 +14,7 @@ use libafl::{
feedback_or,
feedbacks::{CrashFeedback, MapFeedbackState, MaxMapFeedback, TimeFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
mutators::token_mutations::I2SRandReplace,
observers::{StdMapObserver, TimeObserver},
@ -114,7 +115,9 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
// The wrapped harness function, calling out to the LLVM-style harness
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};
@ -149,7 +152,9 @@ fn fuzz(corpus_dirs: &[PathBuf], objective_dir: PathBuf, broker_port: u16) -> Re
}
// Secondary harness due to mut ownership
let mut harness = |buf: &[u8]| {
let mut harness = |input: &BytesInput| {
let target = input.target_bytes();
let buf = target.as_slice();
libfuzzer_test_one_input(buf);
ExitKind::Ok
};

View File

@ -23,7 +23,7 @@ use crate::{
},
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::{HasTargetBytes, Input},
inputs::Input,
observers::ObserversTuple,
state::HasSolutions,
Error,
@ -32,8 +32,8 @@ use crate::{
/// The inmem executor simply calls a target function, then returns afterwards.
pub struct InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
/// The harness function, being executed for each fuzzing loop execution
@ -45,22 +45,21 @@ where
impl<'a, H, I, OT, S> Executor<I> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
fn run_target(&mut self, input: &I) -> Result<ExitKind, Error> {
let bytes = input.target_bytes();
let ret = (self.harness_fn)(bytes.as_slice());
let ret = (self.harness_fn)(input);
Ok(ret)
}
}
impl<'a, EM, H, I, OT, S, Z> HasExecHooks<EM, I, S, Z> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
@ -140,8 +139,8 @@ where
impl<'a, H, I, OT, S> HasObservers<OT> for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
#[inline]
@ -158,16 +157,16 @@ where
impl<'a, EM, H, I, OT, S, Z> HasObserversHooks<EM, I, OT, S, Z>
for InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple + HasExecHooksTuple<EM, I, S, Z>,
{
}
impl<'a, H, I, OT, S> InProcessExecutor<'a, H, I, OT, S>
where
H: FnMut(&[u8]) -> ExitKind,
I: Input + HasTargetBytes,
H: FnMut(&I) -> ExitKind,
I: Input,
OT: ObserversTuple,
{
/// Create a new in mem executor.
@ -256,7 +255,7 @@ mod unix_signal_handler {
executors::ExitKind,
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::{HasTargetBytes, Input},
inputs::Input,
observers::ObserversTuple,
state::HasSolutions,
};
@ -343,7 +342,7 @@ mod unix_signal_handler {
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I>,
I: Input + HasTargetBytes,
I: Input,
Z: HasObjective<I, OF, S>,
{
let state = (data.state_ptr as *mut S).as_mut().unwrap();
@ -417,7 +416,7 @@ mod unix_signal_handler {
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I>,
I: Input + HasTargetBytes,
I: Input,
Z: HasObjective<I, OF, S>,
{
#[cfg(all(target_os = "android", target_arch = "aarch64"))]
@ -570,7 +569,7 @@ mod windows_exception_handler {
executors::ExitKind,
feedbacks::Feedback,
fuzzer::HasObjective,
inputs::{HasTargetBytes, Input},
inputs::Input,
observers::ObserversTuple,
state::HasSolutions,
};
@ -636,7 +635,7 @@ mod windows_exception_handler {
OC: Corpus<I>,
OF: Feedback<I, S>,
S: HasSolutions<OC, I>,
I: Input + HasTargetBytes,
I: Input,
Z: HasObjective<I, OF, S>,
{
#[cfg(feature = "std")]
@ -735,7 +734,7 @@ mod tests {
#[test]
fn test_inmem_exec() {
let mut harness = |_buf: &[u8]| ExitKind::Ok;
let mut harness = |_buf: &NopInput| ExitKind::Ok;
let mut in_process_executor = InProcessExecutor::<_, NopInput, (), ()> {
harness_fn: &mut harness,

View File

@ -201,7 +201,7 @@ mod tests {
let scheduler = RandCorpusScheduler::new();
let mut fuzzer = StdFuzzer::new(scheduler, (), ());
let mut harness = |_buf: &[u8]| ExitKind::Ok;
let mut harness = |_buf: &BytesInput| ExitKind::Ok;
let mut executor = InProcessExecutor::new(
&mut harness,
tuple_list!(),