faster prng and some fixes

This commit is contained in:
Andrea Fioraldi 2020-11-23 14:42:32 +01:00
parent 21de5efc98
commit 42257f3ffb
6 changed files with 81 additions and 9 deletions

View File

@ -321,8 +321,14 @@ where
} }
fn fuzz_loop(&mut self, rand: &mut R, state: &mut S, events: &mut EM) -> Result<(), AflError> { fn fuzz_loop(&mut self, rand: &mut R, state: &mut S, events: &mut EM) -> Result<(), AflError> {
let mut last = current_milliseconds();
loop { loop {
self.fuzz_one(rand, state, events)?; self.fuzz_one(rand, state, events)?;
let cur = current_milliseconds();
if cur - last > 60 * 100 {
last = cur;
fire_event!(events, LoadInitialEvent)?;
}
} }
} }
} }

View File

@ -34,7 +34,10 @@ where
R: Rand, R: Rand,
{ {
fn generate(&mut self, rand: &mut R) -> Result<BytesInput, AflError> { fn generate(&mut self, rand: &mut R) -> Result<BytesInput, AflError> {
let size = rand.below(self.max_size as u64); let mut size = rand.below(self.max_size as u64);
if size == 0 {
size = 1;
}
let random_bytes: Vec<u8> = (0..size).map(|_| rand.below(256) as u8).collect(); let random_bytes: Vec<u8> = (0..size).map(|_| rand.below(256) as u8).collect();
Ok(BytesInput::new(random_bytes)) Ok(BytesInput::new(random_bytes))
} }
@ -67,7 +70,10 @@ where
R: Rand, R: Rand,
{ {
fn generate(&mut self, rand: &mut R) -> Result<BytesInput, AflError> { fn generate(&mut self, rand: &mut R) -> Result<BytesInput, AflError> {
let size = rand.below(self.max_size as u64); let mut size = rand.below(self.max_size as u64);
if size == 0 {
size = 1;
}
let printables = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \t\n!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".as_bytes(); let printables = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \t\n!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~".as_bytes();
let random_bytes: Vec<u8> = (0..size) let random_bytes: Vec<u8> = (0..size)
.map(|_| printables[rand.below(printables.len() as u64) as usize]) .map(|_| printables[rand.below(printables.len() as u64) as usize])

View File

@ -167,9 +167,13 @@ where
I: Input + HasBytesVec, I: Input + HasBytesVec,
R: Rand, R: Rand,
{ {
if input.bytes().len() == 0 {
Ok(MutationResult::Skipped)
} else {
let bit = rand.below((input.bytes().len() * 8) as u64) as usize; let bit = rand.below((input.bytes().len() * 8) as u64) as usize;
input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8; input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8;
Ok(MutationResult::Mutated) Ok(MutationResult::Mutated)
}
} }
/// Returns the first and last diff position between the given vectors, stopping at the min len /// Returns the first and last diff position between the given vectors, stopping at the min len
@ -292,7 +296,7 @@ where
/// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap /// Create a new HavocBytesMutator instance given a ScheduledMutator to wrap
pub fn new(mut scheduled: SM) -> Self { pub fn new(mut scheduled: SM) -> Self {
scheduled.add_mutation(mutation_bitflip); scheduled.add_mutation(mutation_bitflip);
scheduled.add_mutation(mutation_splice); //scheduled.add_mutation(mutation_splice);
HavocBytesMutator { HavocBytesMutator {
scheduled: scheduled, scheduled: scheduled,
phantom: PhantomData, phantom: PhantomData,
@ -310,7 +314,7 @@ where
pub fn new_default() -> Self { pub fn new_default() -> Self {
let mut scheduled = StdScheduledMutator::<C, I, R>::new(); let mut scheduled = StdScheduledMutator::<C, I, R>::new();
scheduled.add_mutation(mutation_bitflip); scheduled.add_mutation(mutation_bitflip);
scheduled.add_mutation(mutation_splice); //scheduled.add_mutation(mutation_splice);
HavocBytesMutator { HavocBytesMutator {
scheduled: scheduled, scheduled: scheduled,
phantom: PhantomData, phantom: PhantomData,

View File

@ -9,7 +9,7 @@ use xxhash_rust::xxh3::xxh3_64_with_seed;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
pub type StdRand = Xoshiro256StarRand; pub type StdRand = XorShift64Rand;
/// Ways to get random around here /// Ways to get random around here
pub trait Rand: Debug { pub trait Rand: Debug {
@ -165,6 +165,60 @@ impl Xoshiro256StarRand {
} }
} }
/// XXH3 Based, hopefully speedy, rnd implementation
///
#[derive(Copy, Clone, Debug, Default)]
pub struct XorShift64Rand {
rand_seed: u64,
seeded: bool,
}
impl Rand for XorShift64Rand {
fn set_seed(&mut self, seed: u64) {
self.rand_seed = seed;
self.seeded = true;
}
fn next(&mut self) -> u64 {
let mut x = self.rand_seed;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
self.rand_seed = x;
return x;
}
}
impl Into<Rc<RefCell<Self>>> for XorShift64Rand {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
}
impl XorShift64Rand {
/// Creates a new Xoshiro rand with the given seed
pub fn new(seed: u64) -> Self {
let mut ret: Self = Default::default();
ret.set_seed(seed); // TODO: Proper random seed?
ret
}
pub fn to_rc_refcell(self) -> Rc<RefCell<Self>> {
self.into()
}
/// Creates a rand instance, pre-seeded with the current time in nanoseconds.
/// Needs stdlib timer
#[cfg(feature = "std")]
pub fn preseeded() -> Self {
let seed = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos() as u64;
Self::new(seed)
}
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub fn current_milliseconds() -> u64 { pub fn current_milliseconds() -> u64 {
SystemTime::now() SystemTime::now()

View File

@ -39,7 +39,7 @@ pub extern "C" fn afl_libfuzzer_main() {
let mut rand = StdRand::new(0); let mut rand = StdRand::new(0);
let corpus = InMemoryCorpus::new(); let corpus = InMemoryCorpus::new();
let mut generator = RandPrintablesGenerator::new(4096); let mut generator = RandPrintablesGenerator::new(1);
let mut events = LoggerEventManager::new(stderr()); let mut events = LoggerEventManager::new(stderr());
let edges_observer = Rc::new(RefCell::new(StdMapObserver::new_from_ptr( let edges_observer = Rc::new(RefCell::new(StdMapObserver::new_from_ptr(

View File

@ -9,6 +9,8 @@ int target_func(const uint8_t *buf, size_t size) {
} }
printf("\n");*/ printf("\n");*/
if (size == 0) return 0;
switch (buf[0]) { switch (buf[0]) {
case 1: case 1: