Skip to content

Commit

Permalink
Merge pull request #72 from srlabs/docs
Browse files Browse the repository at this point in the history
Make docs better
  • Loading branch information
louismerlin authored Oct 12, 2023
2 parents 414a59b + d198b53 commit 6c93260
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 30 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ Features will also include:

First, install `ziggy` and its dependencies by running:

```
```bash
cargo install --force ziggy cargo-afl honggfuzz grcov
```

Here is the output of the tool's help:

```
```text
$ cargo ziggy
A multi-fuzzer management utility for all of your Rust fuzzing needs 🧑‍🎤
Expand All @@ -53,13 +53,24 @@ Options:

For an example fuzz project, see [the url example](./examples/url/).

## The `output` directory

After you've launched your fuzzer, you'll find a couple of items in the `output` directory:

- the `corpus` directory containing the full corpus
- the `crashes` directory containing any crashes detected by the fuzzers
- the `logs` directory containing a fuzzer log files
- the `afl` directory containing AFL++'s output
- the `honggfuzz` directory containing Honggfuzz's output
- the `queue` directory that is used by ziggy to pass items from AFL++ to Honggfuzz

## Note about coverage

The `cargo cover` command will not generate coverage for the dependencies of your fuzzed project
by default.

If this is something you would like to change, you can use the following trick:
```
```bash
CARGO_HOME=.cargo cargo ziggy cover
```

Expand Down
7 changes: 3 additions & 4 deletions examples/url/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Ziggy example - URL

In the root project directory, run:
First, install the tooling:

```
cargo install cargo-afl honggfuzz
cargo install --force --path .
cargo install cargo-afl honggfuzz ziggy
```

Then, in the `examples/url` directory, run:
Then, in this directory, run:

```
cargo ziggy fuzz
Expand Down
47 changes: 26 additions & 21 deletions src/bin/cargo-ziggy/fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,21 @@ impl Fuzz {
format!("{}/{}", self.ziggy_output.display(), self.target)
}

/// Returns true iff AFL++ is enabled
pub fn afl(&self) -> bool {
!self.no_afl
}

/// Returns true iff Honggfuzz is enabled
pub fn honggfuzz(&self) -> bool {
self.no_afl || (!self.no_honggfuzz && self.jobs > 1)
}

// Manages the continuous running of fuzzers
pub fn fuzz(&mut self) -> Result<(), anyhow::Error> {
let build = Build {
no_afl: self.no_afl,
no_honggfuzz: self.no_honggfuzz,
no_afl: !self.afl(),
no_honggfuzz: !self.honggfuzz(),
};
build.build().context("Failed to build the fuzzers")?;

Expand Down Expand Up @@ -117,7 +127,7 @@ impl Fuzz {
writeln!(&mut initial_corpus, "00000000")?;
drop(initial_corpus);

let mut processes = self.spawn_new_fuzzers(false)?;
let mut processes = self.spawn_new_fuzzers()?;

self.start_time = Instant::now();

Expand Down Expand Up @@ -176,13 +186,10 @@ impl Fuzz {
}
}

// If both fuzzers are running, we copy over AFL++'s queue for consumption by Honggfuzz
// If both fuzzers are running, we copy over AFL++'s queue for consumption by Honggfuzz.
// Otherwise, if only AFL++ is up we copy AFL++'s queue to the global corpus.
// We do this every 10 seconds
if !self.no_afl
&& !self.no_honggfuzz
&& self.jobs > 1
&& last_sync_time.elapsed().as_secs() > 10
{
if self.afl() && last_sync_time.elapsed().as_secs() > 10 {
let afl_corpus = glob(&format!(
"{}/afl/mainaflfuzzer/queue/*",
self.output_target(),
Expand All @@ -191,10 +198,11 @@ impl Fuzz {
for file in afl_corpus {
if let Some((file_id, file_name)) = extract_file_id(&file) {
if file_id > last_synced_queue_id {
let _ = fs::copy(
&file,
format!("{}/queue/{file_name}", self.output_target()),
);
let copy_destination = match self.honggfuzz() {
true => format!("{}/queue/{file_name}", self.output_target()),
false => format!("{}/corpus/{file_name}", self.output_target()),
};
let _ = fs::copy(&file, copy_destination);
last_synced_queue_id = file_id;
}
}
Expand All @@ -214,10 +222,7 @@ impl Fuzz {
}

// Spawns new fuzzers
pub fn spawn_new_fuzzers(
&self,
only_honggfuzz: bool,
) -> Result<Vec<process::Child>, anyhow::Error> {
pub fn spawn_new_fuzzers(&self) -> Result<Vec<process::Child>, anyhow::Error> {
// No fuzzers for you
if self.no_afl && self.no_honggfuzz {
return Err(anyhow!("Pick at least one fuzzer"));
Expand Down Expand Up @@ -250,7 +255,7 @@ impl Fuzz {
eprintln!("Warning: running more honggfuzz jobs than 4 is not effective");
}

if !self.no_afl && !only_honggfuzz && afl_jobs > 0 {
if afl_jobs > 0 {
let _ = process::Command::new("mkdir")
.args(["-p", &format!("{}/afl", self.output_target())])
.stderr(process::Stdio::piped())
Expand Down Expand Up @@ -381,7 +386,7 @@ impl Fuzz {
eprintln!("{} afl ", style(" Launched").green().bold());
}

if !self.no_honggfuzz && honggfuzz_jobs > 0 {
if honggfuzz_jobs > 0 {
let hfuzz_help = process::Command::new(&cargo)
.args(["hfuzz", "run", &self.target])
.env("HFUZZ_BUILD_ARGS", "--features=ziggy/honggfuzz")
Expand Down Expand Up @@ -585,7 +590,7 @@ impl Fuzz {
let mut afl_new_finds = String::new();
let mut afl_faves = String::new();

if self.no_afl {
if !self.afl() {
afl_status = String::from("disabled ")
} else {
let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo"));
Expand Down Expand Up @@ -640,7 +645,7 @@ impl Fuzz {
let mut hf_crashes = String::new();
let mut hf_new_finds = String::new();

if self.no_honggfuzz || (self.jobs == 1 && !self.no_afl) {
if !self.honggfuzz() {
hf_status = String::from("disabled ");
} else {
let hf_stats_process = process::Command::new("tail")
Expand Down
25 changes: 23 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![doc = include_str!("../README.md")]
#[cfg(feature = "afl")]
pub use afl::fuzz as afl_fuzz;
#[cfg(feature = "honggfuzz")]
pub use honggfuzz::fuzz as honggfuzz_fuzz;

// This is our inner harness handler function for the runner and for coverage.
// We open the input file and feed the data to the harness closure.
#[doc(hidden)]
#[cfg(not(any(feature = "afl", feature = "honggfuzz")))]
pub fn read_file_and_fuzz<F>(mut closure: F, file: String)
where
Expand Down Expand Up @@ -32,6 +34,7 @@ where

// This is our middle harness handler macro for the runner and for coverage.
// We read input files and directories from the command line and run the inner harness `fuzz`.
#[doc(hidden)]
#[macro_export]
#[cfg(not(any(feature = "afl", feature = "honggfuzz")))]
macro_rules! read_args_and_fuzz {
Expand Down Expand Up @@ -60,8 +63,26 @@ macro_rules! read_args_and_fuzz {
};
}

// This is our outer harness handler macro for the runner and for coverage.
// It is used to handle different types of arguments for the harness closure, including Arbitrary.
/// Fuzz a closure-like block of code by passing an object of arbitrary type.
///
/// It can handle different types of arguments for the harness closure, including Arbitrary.
///
/// See [our examples](https://github.com/srlabs/ziggy/tree/main/examples).
///
/// ```no_run
/// # fn main() {
/// ziggy::fuzz!(|data: &[u8]| {
/// if data.len() != 6 {return}
/// if data[0] != b'q' {return}
/// if data[1] != b'w' {return}
/// if data[2] != b'e' {return}
/// if data[3] != b'r' {return}
/// if data[4] != b't' {return}
/// if data[5] != b'y' {return}
/// panic!("BOOM")
/// });
/// # }
/// ```
#[macro_export]
#[cfg(not(any(feature = "afl", feature = "honggfuzz")))]
macro_rules! fuzz {
Expand Down
1 change: 1 addition & 0 deletions tests/arbitrary_fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn integration() {
.arg("fuzz")
.arg("-j2")
.arg("-t5")
.arg("-G100")
.env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display()))
.env("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "1")
.env("AFL_SKIP_CPUFREQ", "1")
Expand Down
2 changes: 2 additions & 0 deletions tests/url_fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn integration() {
.arg("fuzz")
.arg("-j2")
.arg("-t5")
.arg("-G100")
.env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display()))
.env("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "1")
.env("AFL_SKIP_CPUFREQ", "1")
Expand Down Expand Up @@ -91,6 +92,7 @@ fn integration() {
.arg("fuzz")
.arg("-j2")
.arg("-t5")
.arg("-G100")
.env("ZIGGY_OUTPUT", format!("{}", temp_dir_path.display()))
.env("AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "1")
.env("AFL_SKIP_CPUFREQ", "1")
Expand Down

0 comments on commit 6c93260

Please sign in to comment.