generate initial inputs
This commit is contained in:
parent
a3501cfb43
commit
0a22db2db9
@ -24,119 +24,6 @@ pub trait TestcaseMetadata {
|
|||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TestcaseTraitTODO<I, T>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
T: TestcaseMetadata,
|
|
||||||
{
|
|
||||||
/// The input associated with this testcase
|
|
||||||
fn input(&self) -> &Option<I>;
|
|
||||||
|
|
||||||
/// The input associated with this testcase (mutable)
|
|
||||||
fn input_mut(&mut self) -> &mut Option<I>;
|
|
||||||
|
|
||||||
/// Filename, if this testcase is backed by a file in the filesystem
|
|
||||||
fn filename(&self) -> &Option<String>;
|
|
||||||
|
|
||||||
/// Map of metadatas associated with this testcase
|
|
||||||
fn metadatas(&self) -> &HashMap<&'static str, Box<dyn TestcaseMetadata>>;
|
|
||||||
|
|
||||||
/// Map of metadatas associated with this testcase
|
|
||||||
fn metadatas_mut(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub enum FileBackedTestcase<I, P> {
|
|
||||||
/// A testcase on disk, not yet loaded
|
|
||||||
Stored { filename: P },
|
|
||||||
|
|
||||||
/// A testcase that has been loaded, and not yet dirtied.
|
|
||||||
/// The input should be equal to the on-disk state.
|
|
||||||
Loaded {
|
|
||||||
input: I,
|
|
||||||
filename: P,
|
|
||||||
//metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// A testcase that has been mutated, but not yet written to disk
|
|
||||||
Dirty {
|
|
||||||
input: I,
|
|
||||||
filename: P,
|
|
||||||
//metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<I, P> FileBackedTestcase<I, P>
|
|
||||||
where
|
|
||||||
I: Input,
|
|
||||||
P: AsRef<Path>,
|
|
||||||
{
|
|
||||||
/// Load a testcase from disk if it is not already loaded.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
/// Errors if the testcase is [Dirty](FileBackedTestcase::Dirty)
|
|
||||||
pub fn load(self) -> Result<Self, AflError> {
|
|
||||||
match self {
|
|
||||||
Self::Stored { filename } => {
|
|
||||||
let input = I::from_file(&filename)?;
|
|
||||||
Ok(Self::Loaded { filename, input })
|
|
||||||
}
|
|
||||||
Self::Loaded {
|
|
||||||
input: _,
|
|
||||||
filename: _,
|
|
||||||
} => Ok(self),
|
|
||||||
_ => Err(AflError::IllegalState(
|
|
||||||
"Attempted load on dirty testcase".into(),
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Make sure that the in-memory state is syncd to disk, and load it from disk if
|
|
||||||
/// Nece
|
|
||||||
pub fn refresh(self) -> Result<Self, AflError> {
|
|
||||||
match self {
|
|
||||||
Self::Dirty {
|
|
||||||
input: _,
|
|
||||||
filename: _,
|
|
||||||
} => self.save(),
|
|
||||||
other => other.load(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes changes to disk
|
|
||||||
pub fn save(self) -> Result<Self, AflError> {
|
|
||||||
match self {
|
|
||||||
Self::Loaded {
|
|
||||||
input: _,
|
|
||||||
filename: _,
|
|
||||||
} => Ok(self),
|
|
||||||
Self::Dirty { input, filename } => {
|
|
||||||
let mut file = File::create(&filename)?;
|
|
||||||
file.write_all(input.serialize()?)?;
|
|
||||||
|
|
||||||
Ok(Self::Loaded { input, filename })
|
|
||||||
}
|
|
||||||
Self::Stored { filename } => Err(AflError::IllegalState(format!(
|
|
||||||
"Tried to store to {:?} without input (in stored state)",
|
|
||||||
filename.as_ref()
|
|
||||||
))),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes contents of this testcase from memory
|
|
||||||
pub fn unload(self) -> Result<Self, AflError> {
|
|
||||||
match self {
|
|
||||||
Self::Loaded { input: _, filename } => Ok(Self::Stored { filename }),
|
|
||||||
Self::Stored { filename: _ } => Ok(self),
|
|
||||||
Self::Dirty {
|
|
||||||
filename: _,
|
|
||||||
input: _,
|
|
||||||
} => self.save(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An entry in the Testcase Corpus
|
/// An entry in the Testcase Corpus
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Testcase<I>
|
pub struct Testcase<I>
|
||||||
@ -147,6 +34,8 @@ where
|
|||||||
input: Option<I>,
|
input: Option<I>,
|
||||||
/// Filename, if this testcase is backed by a file in the filesystem
|
/// Filename, if this testcase is backed by a file in the filesystem
|
||||||
filename: Option<String>,
|
filename: Option<String>,
|
||||||
|
/// Accumulated fitness from all the feedbacks
|
||||||
|
fitness: u32,
|
||||||
/// Map of metadatas associated with this testcase
|
/// Map of metadatas associated with this testcase
|
||||||
metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
metadatas: HashMap<&'static str, Box<dyn TestcaseMetadata>>,
|
||||||
}
|
}
|
||||||
@ -186,22 +75,41 @@ where
|
|||||||
pub fn input_mut(&mut self) -> &mut Option<I> {
|
pub fn input_mut(&mut self) -> &mut Option<I> {
|
||||||
&mut self.input
|
&mut self.input
|
||||||
}
|
}
|
||||||
|
/// Set the input
|
||||||
|
pub fn set_input(&mut self, input: I) {
|
||||||
|
self.input = Some(input);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the filename, if any
|
/// Get the filename, if any
|
||||||
pub fn filename(&self) -> &Option<String> {
|
pub fn filename(&self) -> &Option<String> {
|
||||||
&self.filename
|
&self.filename
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the filename, if any (mutable)
|
/// Get the filename, if any (mutable)
|
||||||
pub fn filename_mut(&mut self) -> &mut Option<String> {
|
pub fn filename_mut(&mut self) -> &mut Option<String> {
|
||||||
&mut self.filename
|
&mut self.filename
|
||||||
}
|
}
|
||||||
|
/// Set the filename
|
||||||
|
pub fn set_filename(&mut self, filename: String) {
|
||||||
|
self.filename = Some(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the fitness
|
||||||
|
pub fn fitness(&self) -> u32 {
|
||||||
|
self.fitness
|
||||||
|
}
|
||||||
|
/// Get the fitness (mutable)
|
||||||
|
pub fn fitness_mut(&mut self) -> &mut u32 {
|
||||||
|
&mut self.fitness
|
||||||
|
}
|
||||||
|
/// Set the fitness
|
||||||
|
pub fn set_fitness(&mut self, fitness: u32) {
|
||||||
|
self.fitness = fitness;
|
||||||
|
}
|
||||||
|
|
||||||
/// Get all the metadatas into an HashMap (mutable)
|
/// Get all the metadatas into an HashMap (mutable)
|
||||||
pub fn metadatas(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>> {
|
pub fn metadatas(&mut self) -> &mut HashMap<&'static str, Box<dyn TestcaseMetadata>> {
|
||||||
&mut self.metadatas
|
&mut self.metadatas
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a metadata
|
/// Add a metadata
|
||||||
pub fn add_metadata(&mut self, meta: Box<dyn TestcaseMetadata>) {
|
pub fn add_metadata(&mut self, meta: Box<dyn TestcaseMetadata>) {
|
||||||
self.metadatas.insert(meta.name(), meta);
|
self.metadatas.insert(meta.name(), meta);
|
||||||
@ -215,6 +123,7 @@ where
|
|||||||
Testcase {
|
Testcase {
|
||||||
input: Some(input.into()),
|
input: Some(input.into()),
|
||||||
filename: None,
|
filename: None,
|
||||||
|
fitness: 0,
|
||||||
metadatas: HashMap::default(),
|
metadatas: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,6 +133,7 @@ where
|
|||||||
Testcase {
|
Testcase {
|
||||||
input: Some(input),
|
input: Some(input),
|
||||||
filename: Some(filename),
|
filename: Some(filename),
|
||||||
|
fitness: 0,
|
||||||
metadatas: HashMap::default(),
|
metadatas: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,6 +142,7 @@ where
|
|||||||
Testcase {
|
Testcase {
|
||||||
input: None,
|
input: None,
|
||||||
filename: None,
|
filename: None,
|
||||||
|
fitness: 0,
|
||||||
metadatas: HashMap::default(),
|
metadatas: HashMap::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ use crate::corpus::{Corpus, HasCorpus, Testcase};
|
|||||||
use crate::events::EventManager;
|
use crate::events::EventManager;
|
||||||
use crate::executors::Executor;
|
use crate::executors::Executor;
|
||||||
use crate::feedbacks::Feedback;
|
use crate::feedbacks::Feedback;
|
||||||
|
use crate::generators::Generator;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::observers::Observer;
|
use crate::observers::Observer;
|
||||||
use crate::stages::Stage;
|
use crate::stages::Stage;
|
||||||
@ -95,30 +96,68 @@ where
|
|||||||
fn executor_mut(&mut self) -> &mut E;
|
fn executor_mut(&mut self) -> &mut E;
|
||||||
|
|
||||||
/// Runs the input and triggers observers and feedback
|
/// Runs the input and triggers observers and feedback
|
||||||
fn evaluate_input(&mut self, input: &I) -> Result<bool, AflError> {
|
fn evaluate_input(
|
||||||
|
&mut self,
|
||||||
|
input: I,
|
||||||
|
) -> Result<(bool, Option<Rc<RefCell<Testcase<I>>>>), AflError> {
|
||||||
self.reset_observers()?;
|
self.reset_observers()?;
|
||||||
self.executor_mut().run_target(input)?;
|
self.executor_mut().run_target(&input)?;
|
||||||
self.set_executions(self.executions() + 1);
|
self.set_executions(self.executions() + 1);
|
||||||
self.post_exec_observers()?;
|
self.post_exec_observers()?;
|
||||||
|
|
||||||
let mut rate_acc = 0;
|
let mut fitness = 0;
|
||||||
for feedback in self.feedbacks_mut() {
|
for feedback in self.feedbacks_mut() {
|
||||||
rate_acc += feedback.is_interesting(input)?;
|
fitness += feedback.is_interesting(&input)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if rate_acc >= 25 {
|
if fitness >= 25 {
|
||||||
let testcase = Rc::new(RefCell::new(Testcase::new(input.clone())));
|
let testcase: Rc<RefCell<_>> = Testcase::new(input).into();
|
||||||
for feedback in self.feedbacks_mut() {
|
for feedback in self.feedbacks_mut() {
|
||||||
feedback.append_metadata(testcase.clone())?;
|
feedback.append_metadata(testcase.clone())?;
|
||||||
}
|
}
|
||||||
Ok(true)
|
testcase.borrow_mut().set_fitness(fitness);
|
||||||
|
self.corpus_mut().add(testcase.clone());
|
||||||
|
Ok((true, Some(testcase)))
|
||||||
} else {
|
} else {
|
||||||
for feedback in self.feedbacks_mut() {
|
for feedback in self.feedbacks_mut() {
|
||||||
feedback.discard_metadata()?;
|
feedback.discard_metadata()?;
|
||||||
}
|
}
|
||||||
Ok(false)
|
Ok((false, None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_initial_input(&mut self, input: I) -> Result<(), AflError> {
|
||||||
|
// Inefficent clone, but who cares this is done once at init
|
||||||
|
let (_, testcase) = self.evaluate_input(input.clone())?;
|
||||||
|
if testcase.is_none() {
|
||||||
|
let testcase = Testcase::new(input).into();
|
||||||
|
self.corpus_mut().add(testcase);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_initial_inputs<S, G, C, E, I, R, EM>(
|
||||||
|
rand: &mut R,
|
||||||
|
state: &mut S,
|
||||||
|
generator: &mut G,
|
||||||
|
_events: &mut EM,
|
||||||
|
num: usize,
|
||||||
|
) -> Result<(), AflError>
|
||||||
|
where
|
||||||
|
S: State<C, E, I, R>,
|
||||||
|
G: Generator<I, R>,
|
||||||
|
C: Corpus<I, R>,
|
||||||
|
E: Executor<I>,
|
||||||
|
I: Input,
|
||||||
|
R: Rand,
|
||||||
|
EM: EventManager,
|
||||||
|
{
|
||||||
|
for _ in 0..num {
|
||||||
|
let input = generator.generate(rand)?;
|
||||||
|
state.load_initial_input(input)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdState<C, E, I, R>
|
pub struct StdState<C, E, I, R>
|
||||||
@ -247,12 +286,17 @@ where
|
|||||||
events: &mut EM,
|
events: &mut EM,
|
||||||
) -> Result<usize, AflError> {
|
) -> Result<usize, AflError> {
|
||||||
let (testcase, idx) = state.corpus_mut().next(rand)?;
|
let (testcase, idx) = state.corpus_mut().next(rand)?;
|
||||||
println!("Cur entry: {}\tExecutions: {}", idx, state.executions());
|
|
||||||
for stage in self.stages_mut() {
|
for stage in self.stages_mut() {
|
||||||
stage.perform(rand, state, events, testcase.clone())?;
|
stage.perform(rand, state, events, testcase.clone())?;
|
||||||
}
|
}
|
||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fuzz_loop(&mut self, rand: &mut R, state: &mut S, events: &mut EM) -> Result<(), AflError> {
|
||||||
|
loop {
|
||||||
|
self.fuzz_one(rand, state, events)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StdEngine<S, EM, E, C, I, R>
|
pub struct StdEngine<S, EM, E, C, I, R>
|
||||||
|
@ -5,10 +5,14 @@ pub use scheduled::ScheduledMutator;
|
|||||||
pub use scheduled::StdScheduledMutator;
|
pub use scheduled::StdScheduledMutator;
|
||||||
|
|
||||||
use crate::corpus::Corpus;
|
use crate::corpus::Corpus;
|
||||||
|
use crate::corpus::Testcase;
|
||||||
use crate::inputs::Input;
|
use crate::inputs::Input;
|
||||||
use crate::utils::Rand;
|
use crate::utils::Rand;
|
||||||
use crate::AflError;
|
use crate::AflError;
|
||||||
|
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
pub trait Mutator<C, I, R>
|
pub trait Mutator<C, I, R>
|
||||||
where
|
where
|
||||||
C: Corpus<I, R>,
|
C: Corpus<I, R>,
|
||||||
@ -25,7 +29,12 @@ where
|
|||||||
) -> Result<(), AflError>;
|
) -> Result<(), AflError>;
|
||||||
|
|
||||||
/// Post-process given the outcome of the execution
|
/// Post-process given the outcome of the execution
|
||||||
fn post_exec(&mut self, _is_interesting: bool, _stage_idx: i32) -> Result<(), AflError> {
|
fn post_exec(
|
||||||
|
&mut self,
|
||||||
|
_is_interesting: bool,
|
||||||
|
_new_testcase: Option<Rc<RefCell<Testcase<I>>>>,
|
||||||
|
_stage_idx: i32,
|
||||||
|
) -> Result<(), AflError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ where
|
|||||||
|
|
||||||
/// Bitflip mutation for inputs with a bytes vector
|
/// Bitflip mutation for inputs with a bytes vector
|
||||||
pub fn mutation_bitflip<M, C, I, R>(
|
pub fn mutation_bitflip<M, C, I, R>(
|
||||||
mutator: &mut M,
|
_mutator: &mut M,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
_corpus: &mut C,
|
_corpus: &mut C,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
@ -190,7 +190,7 @@ fn locate_diffs(this: &[u8], other: &[u8]) -> (i64, i64) {
|
|||||||
|
|
||||||
/// Splicing mutator
|
/// Splicing mutator
|
||||||
pub fn mutation_splice<M, C, I, R>(
|
pub fn mutation_splice<M, C, I, R>(
|
||||||
mutator: &mut M,
|
_mutator: &mut M,
|
||||||
rand: &mut R,
|
rand: &mut R,
|
||||||
corpus: &mut C,
|
corpus: &mut C,
|
||||||
input: &mut I,
|
input: &mut I,
|
||||||
|
@ -46,20 +46,15 @@ where
|
|||||||
testcase: Rc<RefCell<Testcase<I>>>,
|
testcase: Rc<RefCell<Testcase<I>>>,
|
||||||
) -> Result<(), AflError> {
|
) -> Result<(), AflError> {
|
||||||
let num = self.iterations(rand);
|
let num = self.iterations(rand);
|
||||||
let input = testcase.borrow_mut().load_input()?.clone();
|
|
||||||
|
|
||||||
for i in 0..num {
|
for i in 0..num {
|
||||||
let mut input_tmp = input.clone();
|
let mut input = testcase.borrow_mut().load_input()?.clone();
|
||||||
self.mutator_mut()
|
self.mutator_mut()
|
||||||
.mutate(rand, state.corpus_mut(), &mut input_tmp, i as i32)?;
|
.mutate(rand, state.corpus_mut(), &mut input, i as i32)?;
|
||||||
|
|
||||||
let interesting = state.evaluate_input(&input_tmp)?;
|
let (interesting, new_testcase) = state.evaluate_input(input)?;
|
||||||
|
|
||||||
self.mutator_mut().post_exec(interesting, i as i32)?;
|
self.mutator_mut()
|
||||||
|
.post_exec(interesting, new_testcase, i as i32)?;
|
||||||
if interesting {
|
|
||||||
state.corpus_mut().add(Testcase::new(input_tmp).into());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,12 @@ use alloc::rc::Rc;
|
|||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use afl::corpus::{Corpus, InMemoryCorpus, Testcase};
|
use afl::corpus::{Corpus, InMemoryCorpus, Testcase};
|
||||||
use afl::engines::{Engine, State, StdEngine, StdState};
|
use afl::engines::{generate_initial_inputs, Engine, State, StdEngine, StdState};
|
||||||
use afl::events::LoggerEventManager;
|
use afl::events::LoggerEventManager;
|
||||||
use afl::executors::inmemory::InMemoryExecutor;
|
use afl::executors::inmemory::InMemoryExecutor;
|
||||||
use afl::executors::{Executor, ExitKind};
|
use afl::executors::{Executor, ExitKind};
|
||||||
use afl::feedbacks::{create_history_map, MaxMapFeedback};
|
use afl::feedbacks::{create_history_map, MaxMapFeedback};
|
||||||
|
use afl::generators::{Generator, RandPrintablesGenerator};
|
||||||
use afl::inputs::bytes::BytesInput;
|
use afl::inputs::bytes::BytesInput;
|
||||||
use afl::mutators::scheduled::HavocBytesMutator;
|
use afl::mutators::scheduled::HavocBytesMutator;
|
||||||
use afl::observers::StdMapObserver;
|
use afl::observers::StdMapObserver;
|
||||||
@ -42,9 +43,9 @@ fn harness<I>(_executor: &dyn Executor<I>, buf: &[u8]) -> ExitKind {
|
|||||||
pub extern "C" fn afl_libfuzzer_main() {
|
pub extern "C" fn afl_libfuzzer_main() {
|
||||||
let mut rand = StdRand::new(0);
|
let mut rand = StdRand::new(0);
|
||||||
|
|
||||||
let mut corpus = InMemoryCorpus::new();
|
let corpus = InMemoryCorpus::new();
|
||||||
let testcase = Testcase::new(vec![0; 4]).into();
|
let mut generator = RandPrintablesGenerator::new(4096);
|
||||||
corpus.add(testcase);
|
let mut events = LoggerEventManager::new();
|
||||||
|
|
||||||
let edges_observer = Rc::new(RefCell::new(StdMapObserver::new_from_ptr(
|
let edges_observer = Rc::new(RefCell::new(StdMapObserver::new_from_ptr(
|
||||||
unsafe { __lafl_edges_map },
|
unsafe { __lafl_edges_map },
|
||||||
@ -53,23 +54,22 @@ pub extern "C" fn afl_libfuzzer_main() {
|
|||||||
let edges_history_map = create_history_map::<u8>(MAP_SIZE);
|
let edges_history_map = create_history_map::<u8>(MAP_SIZE);
|
||||||
let edges_feedback = MaxMapFeedback::new(edges_observer.clone(), edges_history_map);
|
let edges_feedback = MaxMapFeedback::new(edges_observer.clone(), edges_history_map);
|
||||||
|
|
||||||
let executor = InMemoryExecutor::<BytesInput>::new(harness);
|
let executor = InMemoryExecutor::new(harness);
|
||||||
let mut state = StdState::new(corpus, executor);
|
let mut state = StdState::new(corpus, executor);
|
||||||
state.add_observer(edges_observer);
|
state.add_observer(edges_observer);
|
||||||
state.add_feedback(Box::new(edges_feedback));
|
state.add_feedback(Box::new(edges_feedback));
|
||||||
|
|
||||||
|
generate_initial_inputs(&mut rand, &mut state, &mut generator, &mut events, 4)
|
||||||
|
.expect("Failed to load initial inputs");
|
||||||
|
|
||||||
let mut engine = StdEngine::new();
|
let mut engine = StdEngine::new();
|
||||||
let mutator = HavocBytesMutator::new_default();
|
let mutator = HavocBytesMutator::new_default();
|
||||||
let stage = StdMutationalStage::new(mutator);
|
let stage = StdMutationalStage::new(mutator);
|
||||||
engine.add_stage(Box::new(stage));
|
engine.add_stage(Box::new(stage));
|
||||||
|
|
||||||
let mut events = LoggerEventManager::new();
|
|
||||||
|
|
||||||
for i in 0..1000 {
|
|
||||||
engine
|
engine
|
||||||
.fuzz_one(&mut rand, &mut state, &mut events)
|
.fuzz_loop(&mut rand, &mut state, &mut events)
|
||||||
.expect(&format!("Error in iter {}", i));
|
.expect("Fuzzer fatal error");
|
||||||
}
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
println!("OK");
|
println!("OK");
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
int target_func(const uint8_t *buf, size_t size) {
|
int target_func(const uint8_t *buf, size_t size) {
|
||||||
|
|
||||||
printf("BUF (%ld): ", size);
|
/*printf("BUF (%ld): ", size);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
printf("%02X", buf[i]);
|
printf("%02X", buf[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");*/
|
||||||
|
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user