diff --git a/afl/src/engines/mod.rs b/afl/src/engines/mod.rs index c4440f42da..bfb3f1ae09 100644 --- a/afl/src/engines/mod.rs +++ b/afl/src/engines/mod.rs @@ -321,8 +321,14 @@ where } fn fuzz_loop(&mut self, rand: &mut R, state: &mut S, events: &mut EM) -> Result<(), AflError> { + let mut last = current_milliseconds(); loop { self.fuzz_one(rand, state, events)?; + let cur = current_milliseconds(); + if cur - last > 60 * 100 { + last = cur; + fire_event!(events, LoadInitialEvent)?; + } } } } diff --git a/afl/src/generators/mod.rs b/afl/src/generators/mod.rs index a5aac2e5a0..1f1fefaa13 100644 --- a/afl/src/generators/mod.rs +++ b/afl/src/generators/mod.rs @@ -34,7 +34,10 @@ where R: Rand, { fn generate(&mut self, rand: &mut R) -> Result { - 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 = (0..size).map(|_| rand.below(256) as u8).collect(); Ok(BytesInput::new(random_bytes)) } @@ -67,7 +70,10 @@ where R: Rand, { fn generate(&mut self, rand: &mut R) -> Result { - 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 random_bytes: Vec = (0..size) .map(|_| printables[rand.below(printables.len() as u64) as usize]) diff --git a/afl/src/mutators/scheduled.rs b/afl/src/mutators/scheduled.rs index 5d15f8fc6e..eb9f2a0cb5 100644 --- a/afl/src/mutators/scheduled.rs +++ b/afl/src/mutators/scheduled.rs @@ -167,9 +167,13 @@ where I: Input + HasBytesVec, R: Rand, { - let bit = rand.below((input.bytes().len() * 8) as u64) as usize; - input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8; - Ok(MutationResult::Mutated) + if input.bytes().len() == 0 { + Ok(MutationResult::Skipped) + } else { + let bit = rand.below((input.bytes().len() * 8) as u64) as usize; + input.bytes_mut()[bit >> 3] ^= (128 >> (bit & 7)) as u8; + Ok(MutationResult::Mutated) + } } /// 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 pub fn new(mut scheduled: SM) -> Self { scheduled.add_mutation(mutation_bitflip); - scheduled.add_mutation(mutation_splice); + //scheduled.add_mutation(mutation_splice); HavocBytesMutator { scheduled: scheduled, phantom: PhantomData, @@ -310,7 +314,7 @@ where pub fn new_default() -> Self { let mut scheduled = StdScheduledMutator::::new(); scheduled.add_mutation(mutation_bitflip); - scheduled.add_mutation(mutation_splice); + //scheduled.add_mutation(mutation_splice); HavocBytesMutator { scheduled: scheduled, phantom: PhantomData, diff --git a/afl/src/utils.rs b/afl/src/utils.rs index e02d23f1a0..1ed8ab73e0 100644 --- a/afl/src/utils.rs +++ b/afl/src/utils.rs @@ -9,7 +9,7 @@ use xxhash_rust::xxh3::xxh3_64_with_seed; #[cfg(feature = "std")] use std::time::{SystemTime, UNIX_EPOCH}; -pub type StdRand = Xoshiro256StarRand; +pub type StdRand = XorShift64Rand; /// Ways to get random around here 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>> for XorShift64Rand { + fn into(self) -> Rc> { + 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> { + 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")] pub fn current_milliseconds() -> u64 { SystemTime::now() diff --git a/fuzzers/libfuzzer/src/lib.rs b/fuzzers/libfuzzer/src/lib.rs index 17fb1e6409..5abeeb1bbd 100644 --- a/fuzzers/libfuzzer/src/lib.rs +++ b/fuzzers/libfuzzer/src/lib.rs @@ -39,7 +39,7 @@ pub extern "C" fn afl_libfuzzer_main() { let mut rand = StdRand::new(0); let corpus = InMemoryCorpus::new(); - let mut generator = RandPrintablesGenerator::new(4096); + let mut generator = RandPrintablesGenerator::new(1); let mut events = LoggerEventManager::new(stderr()); let edges_observer = Rc::new(RefCell::new(StdMapObserver::new_from_ptr( diff --git a/fuzzers/libfuzzer/test/test.c b/fuzzers/libfuzzer/test/test.c index 1e8eb75bbc..04d002b2ae 100755 --- a/fuzzers/libfuzzer/test/test.c +++ b/fuzzers/libfuzzer/test/test.c @@ -9,6 +9,8 @@ int target_func(const uint8_t *buf, size_t size) { } printf("\n");*/ + if (size == 0) return 0; + switch (buf[0]) { case 1: