Skip to content

Commit

Permalink
Merge pull request #16 from epi052/add-pre-post-loop-hooks
Browse files Browse the repository at this point in the history
random necessities driven by concrete implementations
  • Loading branch information
epi052 authored Dec 1, 2022
2 parents 3eeac81 + 4aa6558 commit d8876bc
Show file tree
Hide file tree
Showing 31 changed files with 5,326 additions and 397 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "feroxfuzz"
version = "1.0.0-rc.4"
version = "1.0.0-rc.5"
edition = "2021"
authors = ["Ben 'epi' Risher (@epi052)"]
license = "Apache-2.0"
Expand Down
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,23 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// the `Fuzzer` is the main component of the feroxfuzz library. It wraps most of the other components
// and takes care of the actual fuzzing process.
let mut fuzzer = AsyncFuzzer::new(
threads, client, request, scheduler, mutators, observers, processors, deciders,
);
let mut fuzzer = AsyncFuzzer::new(threads)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.deciders(deciders)
.post_loop_hook(|state| {
// this closure is called after each fuzzing loop iteration completes.
// it's a good place to do things like print out stats
// or do other things that you want to happen after each
// full iteration over the corpus
println!("\n•*´¨`*•.¸¸.•* Finished fuzzing loop •*´¨`*•.¸¸.•*\n");
println!("{state:#}");
})
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state).await?;
Expand Down
21 changes: 16 additions & 5 deletions examples/async-simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,22 +106,33 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// the `Fuzzer` is the main component of the feroxfuzz library. It wraps most of the other components
// and takes care of the actual fuzzing process.
let mut fuzzer = AsyncFuzzer::new(
threads, client, request, scheduler, mutators, observers, processors, deciders,
);
let mut fuzzer = AsyncFuzzer::new(threads)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.deciders(deciders)
.post_loop_hook(|state| {
println!("\n•*´¨`*•.¸¸.•* Finished fuzzing loop •*´¨`*•.¸¸.•*\n");
println!("{state:#}");
})
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state).await?;

println!("{state:#}");

// example output:
//
// [200] 913 - http://localhost:8000/?admin=AMD - 1.934845ms
// [200] 358 - http://localhost:8000/?admin=Abernathy - 1.009332ms
// ----8<----
// [200] 971 - http://localhost:8000/?admin=zoological - 1.595993ms
// [200] 664 - http://localhost:8000/?admin=zoology%27s - 1.700941ms
//
// •*´¨`*•.¸¸.•* Finished fuzzing loop •*´¨`*•.¸¸.•*
//
// SharedState::{
// Seed=24301
// Rng=RomuDuoJrRand { x_state: 97704, y_state: 403063 }
Expand Down
17 changes: 8 additions & 9 deletions examples/battering-ram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator);
let processors = build_processors!(request_printer);

let mut fuzzer = BlockingFuzzer::new(
client,
request,
scheduler,
mutators,
observers,
processors,
(), // since we didn't use any Deciders, we just pass in ()
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state)?;
Expand Down
12 changes: 9 additions & 3 deletions examples/blocking-regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,15 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator1, mutator2, mutator3);
let processors = build_processors!(response_printer);

let mut fuzzer = BlockingFuzzer::new(
client, request, scheduler, mutators, observers, processors, deciders,
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.deciders(deciders)
.build();

// fuzz_n_iterations means that the fuzzer will iterate over whatever is provided by the scheduler
// n times. In this case, we're going to iterate over the corpus entries twice.
Expand Down
17 changes: 8 additions & 9 deletions examples/cartesian-product.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(user_mutator, id_mutator);
let processors = build_processors!(request_printer);

let mut fuzzer = BlockingFuzzer::new(
client,
request,
scheduler,
mutators,
observers,
processors,
(), // since we didn't use any Deciders, we just pass in ()
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state)?;
Expand Down
17 changes: 8 additions & 9 deletions examples/cluster-bomb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator1, mutator2, mutator3);
let processors = build_processors!(request_printer);

let mut fuzzer = BlockingFuzzer::new(
client,
request,
scheduler,
mutators,
observers,
processors,
(), // since we didn't use any Deciders, we just pass in ()
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state)?;
Expand Down
24 changes: 12 additions & 12 deletions examples/dynamic-dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,22 +170,22 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// the `Fuzzer` is the main component of the feroxfuzz library. It wraps most of the other components
// and takes care of the actual fuzzing process.
let mut fuzzer = AsyncFuzzer::new(
threads,
client,
request,
scheduler,
dynamic_mutators, // <-- our dynamic mutators
observers,
processors,
deciders,
);
let mut fuzzer = AsyncFuzzer::new(threads)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(dynamic_mutators) // <-- our dynamic mutators
.observers(observers)
.processors(processors)
.deciders(deciders)
.post_loop_hook(|state| {
println!("{state:#}");
})
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state).await?;

println!("{state:#}");

// example output:
//
// [200] 1771 - http://localhost:8000/?admin=AOL%27s&password=AOL%27s&domain=AOL%27s - 4.052876ms
Expand Down
23 changes: 13 additions & 10 deletions examples/from-url-list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,19 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {

// the `Fuzzer` is the main component of the feroxfuzz library. It wraps most of the other components
// and takes care of the actual fuzzing process.
let mut fuzzer = AsyncFuzzer::new(
threads,
client,
request,
scheduler,
mutators,
observers,
processors,
(), // no deciders
);

// no deciders
let mut fuzzer = AsyncFuzzer::new(threads)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.post_loop_hook(|state| {
println!("{state:#}");
})
.build();

// the fuzzer will run until it iterates over the entire corpus once
fuzzer.fuzz_once(&mut state).await?;
Expand Down
12 changes: 9 additions & 3 deletions examples/havoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator);
let processors = build_processors!(response_printer);

let mut fuzzer = AsyncFuzzer::new(
40, client, request, scheduler, mutators, observers, processors, deciders,
);
let mut fuzzer = AsyncFuzzer::new(40)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.deciders(deciders)
.build();

state
.events()
Expand Down
17 changes: 8 additions & 9 deletions examples/pitchfork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator1, mutator2, mutator3);
let processors = build_processors!(request_printer);

let mut fuzzer = BlockingFuzzer::new(
client,
request,
scheduler,
mutators,
observers,
processors,
(), // since we didn't use any Deciders, we just pass in ()
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();

// fuzz_n_iterations means that the fuzzer will iterate over whatever is provided by the scheduler
// n times. In this case, we're going to iterate over the corpus entries twice.
Expand Down
19 changes: 9 additions & 10 deletions examples/sniper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
// result of the mutation that was performed. In this case, the RequestProcessor doesn't care about
// checking the mutation, we simply want to print the mutated fields to show how a OrderedScheduler
// does its work.
let request_printer = RequestProcessor::new(|request, _action, _state| {
let request_printer = RequestProcessor::new(move |request, _action, _state| {
print!("{}?", request.original_url());

for (i, (key, value)) in request.params().unwrap().iter().enumerate() {
Expand All @@ -112,15 +112,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator1, mutator2, mutator3, mutator4, mutator5);
let processors = build_processors!(request_printer);

let mut fuzzer = BlockingFuzzer::new(
client,
request,
scheduler,
mutators,
observers,
processors,
(), // since we didn't use any Deciders, we just pass in ()
);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();

// our overall strategy is to let the fuzzer run through a full iteration of the corpus/scheduler
// on each iteration of this outer loop. Within each iteration, we'll also only mark a single
Expand Down
12 changes: 9 additions & 3 deletions examples/with-logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mutators = build_mutators!(mutator);
let processors = build_processors!(response_printer);

let mut fuzzer = AsyncFuzzer::new(
40, client, request, scheduler, mutators, observers, processors, deciders,
);
let mut fuzzer = AsyncFuzzer::new(40)
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.deciders(deciders)
.build();

// fuzz_n_iterations means that the fuzzer will iterate over whatever is provided by the scheduler
// n times. In this case, we're going to iterate over the corpus entries twice.
Expand Down
4 changes: 0 additions & 4 deletions src/corpora/wordlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ pub struct Wordlist {
/// let expected = vec!["1", "2", "3"];
/// let wordlist = Wordlist::with_words(expected.clone()).name("words").build();
///
/// # // load bearing; allows Wordlist to derive its two generic types
/// # SharedState::with_corpus(wordlist.clone());
/// let mut gathered = vec![];
///
/// for i in &wordlist {
Expand Down Expand Up @@ -112,8 +110,6 @@ impl<'i> IntoIterator for &'i mut Wordlist {
/// let expected = vec!["1", "2", "3"];
/// let wordlist = Wordlist::with_words(expected.clone()).name("words").build();
///
/// # // load bearing; allows Wordlist to derive its two generic types
/// # SharedState::with_corpus(wordlist.clone());
/// let mut gathered = vec![];
///
/// for i in wordlist {
Expand Down
Loading

0 comments on commit d8876bc

Please sign in to comment.