Skip to content
This repository was archived by the owner on Aug 2, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/example_fuzzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ edition = "2018"
[dependencies]
lain = { version = "0.2", path = "../../lain" }
ctrlc = "3.1"
env_logger = "0.6.2"
log = "0.4"
17 changes: 12 additions & 5 deletions examples/example_fuzzer/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![feature(specialization)]

extern crate lain;
extern crate ctrlc;
use env_logger;

use lain::prelude::*;
use lain::rand::Rng;
Expand All @@ -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)]
Expand Down Expand Up @@ -60,6 +59,9 @@ impl Default for PacketType {
}

fn main() {
// env_logger::builder()
// .filter_level(log::LevelFilter::Info)
// .init();
let mut driver = FuzzerDriver::<GlobalContext>::new(THREAD_COUNT);

driver.set_global_context(Default::default());
Expand All @@ -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);

Expand All @@ -78,7 +81,11 @@ fn main() {
println!("Finished in {} iterations", driver.num_iterations());
}

fn fuzzer_routine<R: Rng>(mutator: &mut Mutator<R>, thread_context: &mut FuzzerThreadContext, _global_context: Option<Arc<RwLock<GlobalContext>>>) -> Result<(), ()> {
fn fuzzer_routine<R: Rng>(
mutator: &mut Mutator<R>,
thread_context: &mut FuzzerThreadContext,
_global_context: Option<Arc<RwLock<GlobalContext>>>,
) -> 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?");

Expand Down
2 changes: 1 addition & 1 deletion lain/src/mutatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ fn shrink_vec<T, R: Rng>(vec: &mut Vec<T>, mutator: &mut Mutator<R>) {
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(),
};

Expand Down
8 changes: 7 additions & 1 deletion lain/src/mutator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -118,6 +119,10 @@ impl<R: Rng> Mutator<R> {
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<T: 'static>(&mut self) -> T
where
Expand All @@ -143,7 +148,7 @@ impl<R: Rng> Mutator<R> {
{
// 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
Expand Down Expand Up @@ -224,6 +229,7 @@ impl<R: Rng> Mutator<R> {
}
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);
}
}

Expand Down
2 changes: 2 additions & 0 deletions lain_derive/src/mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down