From 2216565c634af0d3a8db305af920bbaa94c59209 Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Fri, 30 Aug 2019 14:31:59 -0400 Subject: [PATCH 1/4] fixed shrinking vector --- lain/src/mutatable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lain/src/mutatable.rs b/lain/src/mutatable.rs index 475fc9a..e9b2e2e 100644 --- a/lain/src/mutatable.rs +++ b/lain/src/mutatable.rs @@ -164,7 +164,7 @@ fn shrink_vec(vec: &mut Vec, mutator: &mut Mutator) { VecResizeCount::Quarter => vec.len() / 4, VecResizeCount::Half => vec.len() / 2, VecResizeCount::ThreeQuarters => vec.len() - (vec.len() / 4), - VecResizeCount::FixedBytes => mutator.gen_range(1, 9), + VecResizeCount::FixedBytes => min(mutator.gen_range(1, 9), vec.len()), VecResizeCount::AllBytes => vec.len(), }; From f3bba0d24c1e8d4310360ac8bea3a16cc0da8cdd Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Fri, 6 Sep 2019 14:38:02 -0400 Subject: [PATCH 2/4] Fixed mutation issues in primitive integers --- examples/example_fuzzer/Cargo.toml | 2 ++ examples/example_fuzzer/src/main.rs | 17 ++++++++++++----- lain/src/mutator.rs | 10 ++++++++-- lain_derive/src/mutations.rs | 2 ++ 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/examples/example_fuzzer/Cargo.toml b/examples/example_fuzzer/Cargo.toml index 2fcca83..e1b6e84 100644 --- a/examples/example_fuzzer/Cargo.toml +++ b/examples/example_fuzzer/Cargo.toml @@ -7,3 +7,5 @@ edition = "2018" [dependencies] lain = { version = "0.2", path = "../../lain" } ctrlc = "3.1" +env_logger = "0.6.2" +log = "0.4" \ No newline at end of file diff --git a/examples/example_fuzzer/src/main.rs b/examples/example_fuzzer/src/main.rs index 9e89897..c92a6bf 100644 --- a/examples/example_fuzzer/src/main.rs +++ b/examples/example_fuzzer/src/main.rs @@ -1,7 +1,6 @@ #![feature(specialization)] -extern crate lain; -extern crate ctrlc; +use env_logger; use lain::prelude::*; use lain::rand::Rng; @@ -25,7 +24,7 @@ struct FuzzerThreadContext { #[derive(Default)] struct GlobalContext { // unused, but you could put an iteration - // counter per operation here or whatever you'd like +// counter per operation here or whatever you'd like } #[derive(Debug, Default, Clone, NewFuzzed, Mutatable, VariableSizeObject, BinarySerialize)] @@ -60,6 +59,9 @@ impl Default for PacketType { } fn main() { + // env_logger::builder() + // .filter_level(log::LevelFilter::Info) + // .init(); let mut driver = FuzzerDriver::::new(THREAD_COUNT); driver.set_global_context(Default::default()); @@ -69,7 +71,8 @@ fn main() { ctrlc::set_handler(move || { ctrlc_driver.signal_exit(); - }).expect("couldn't set CTRL-C handler"); + }) + .expect("couldn't set CTRL-C handler"); start_fuzzer(driver.clone(), fuzzer_routine); @@ -78,7 +81,11 @@ fn main() { println!("Finished in {} iterations", driver.num_iterations()); } -fn fuzzer_routine(mutator: &mut Mutator, thread_context: &mut FuzzerThreadContext, _global_context: Option>>) -> Result<(), ()> { +fn fuzzer_routine( + mutator: &mut Mutator, + thread_context: &mut FuzzerThreadContext, + _global_context: Option>>, +) -> Result<(), ()> { // TODO: we have overhead here of re-estabilishing the connection every time let mut stream = TcpStream::connect("127.0.0.1:8080").expect("server isn't running. possible crash?"); diff --git a/lain/src/mutator.rs b/lain/src/mutator.rs index d778188..33e6195 100644 --- a/lain/src/mutator.rs +++ b/lain/src/mutator.rs @@ -2,6 +2,7 @@ use rand::seq::SliceRandom; use rand::Rng; use crate::rand::distributions::uniform::{SampleBorrow, SampleUniform}; +use crate::rand; use crate::traits::*; use crate::types::*; use num::{Bounded, NumCast}; @@ -118,6 +119,10 @@ impl Mutator { self.corpus_state = state; } + pub fn set_total_fields(&mut self, count: usize) { + self.corpus_state.target_total_fields = count; + } + /// Generates a random choice of the given type pub fn gen(&mut self) -> T where @@ -143,7 +148,7 @@ impl Mutator { { // info!("{:?}", self.mode()); // info!("num is: {}", mn); - // info!("{}, {}, {}, {}", self.corpus_state.fields_fuzzed, self.corpus_state.targeted_field_idx, self.corpus_state.target_total_fields, self.corpus_state.target_total_passes); + // info!("Fields Fuzzed: {}, Targeted Field Index: {}, Target Total Fields: {}, Total Passe: {}", self.corpus_state.fields_fuzzed, self.corpus_state.targeted_field_idx, self.corpus_state.target_total_fields, self.corpus_state.target_total_passes); self.corpus_state.fields_fuzzed += 1; if self.mode() != MutatorMode::Havoc && self.corpus_state.finished_iteration @@ -210,11 +215,11 @@ impl Mutator { current_idx: current_idx + 1, }; } else { - self.corpus_state.targeted_field_idx += 1; if self.corpus_state.targeted_field_idx == self.corpus_state.target_total_fields { self.corpus_state.mode = MutatorMode::Havoc; } else { + self.corpus_state.targeted_field_idx += 1; self.corpus_state.mode = MutatorMode::WalkingBitFlip { bits: 1, current_idx: 0, @@ -224,6 +229,7 @@ impl Mutator { } MutatorMode::Havoc => { // stay in havoc mode since we've exhausted all other states + self.corpus_state.targeted_field_idx = rand::thread_rng().gen_range(0, self.corpus_state.target_total_fields + 1); } } diff --git a/lain_derive/src/mutations.rs b/lain_derive/src/mutations.rs index be26908..d6ffe10 100644 --- a/lain_derive/src/mutations.rs +++ b/lain_derive/src/mutations.rs @@ -344,6 +344,8 @@ fn new_fuzzed_struct ( let mut uninit_struct = std::mem::MaybeUninit::<#cont_ident>::uninit(); let uninit_struct_ptr = uninit_struct.as_mut_ptr(); + mutator.set_total_fields(#len - 1); + if Self::is_variable_size() { // this makes for ugly code generation, but better perf for i in sample(&mut mutator.rng, #len, #len).iter() { From 2a6617c0c747ffb95a5ac717228a9987acfdff4c Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Fri, 6 Sep 2019 21:58:12 -0400 Subject: [PATCH 3/4] fixed edge-case infinite loop --- lain/src/mutator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lain/src/mutator.rs b/lain/src/mutator.rs index 33e6195..29d0784 100644 --- a/lain/src/mutator.rs +++ b/lain/src/mutator.rs @@ -215,11 +215,11 @@ impl Mutator { current_idx: current_idx + 1, }; } else { + self.corpus_state.targeted_field_idx += 1; if self.corpus_state.targeted_field_idx == self.corpus_state.target_total_fields { self.corpus_state.mode = MutatorMode::Havoc; } else { - self.corpus_state.targeted_field_idx += 1; self.corpus_state.mode = MutatorMode::WalkingBitFlip { bits: 1, current_idx: 0, From f30deb612f3c7d5c306b0bfbdc39bba25d60d81f Mon Sep 17 00:00:00 2001 From: Carl Hurd Date: Fri, 6 Sep 2019 22:40:41 -0400 Subject: [PATCH 4/4] Fixed nested structure mutation issues --- lain/src/mutator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lain/src/mutator.rs b/lain/src/mutator.rs index 29d0784..3b5ea4c 100644 --- a/lain/src/mutator.rs +++ b/lain/src/mutator.rs @@ -120,7 +120,7 @@ impl Mutator { } pub fn set_total_fields(&mut self, count: usize) { - self.corpus_state.target_total_fields = count; + self.corpus_state.target_total_fields += count; } /// Generates a random choice of the given type