From 0872d518fed5d5180af0d9fa1f58fa4155ae9494 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 5 Oct 2023 15:26:07 +0200 Subject: [PATCH 1/3] Add colors and new UI --- Cargo.lock | 2 +- src/bin/cargo-ziggy/fuzz.rs | 76 ++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c73d027..412c11f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -877,7 +877,7 @@ checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" [[package]] name = "ziggy" -version = "0.7.0" +version = "0.7.1" dependencies = [ "afl", "anyhow", diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index 2a14a62..bf34ee8 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -451,7 +451,7 @@ impl Fuzz { ); } - eprintln!("\nSee live information by running:"); + eprintln!("\nSee more live information by running:"); if afl_jobs > 0 { eprintln!( " {}", @@ -474,11 +474,6 @@ impl Fuzz { .bold() ); } - eprintln!("\n\n\n\n\n"); - eprintln!(" Waiting for fuzzers to"); - eprintln!(" finish executing the"); - eprintln!(" existing corpus once"); - eprintln!("\n\n"); Ok(fuzzer_handles) } @@ -568,8 +563,16 @@ impl Fuzz { } pub fn print_stats(&self) { + let reset = "\x1b[0m"; + let gray = "\x1b[1;90m"; + let red = "\x1b[1;91m"; + let green = "\x1b[1;92m"; + let yellow = "\x1b[1;93m"; + let purple = "\x1b[1;95m"; + let blue = "\x1b[1;96m"; + // First step: execute afl-whatsup - let mut afl_status = String::from("running ─"); + let mut afl_status = format!("{green}running{reset} ─"); let mut afl_total_execs = String::new(); let mut afl_instances = String::new(); let mut afl_speed = String::new(); @@ -579,7 +582,7 @@ impl Fuzz { let mut afl_faves = String::new(); if self.no_afl { - afl_status = String::from("disabled ") + afl_status = format!("{yellow}disabled{reset} ") } else { let cargo = env::var("CARGO").unwrap_or_else(|_| String::from("cargo")); let afl_stats_process = process::Command::new(cargo) @@ -625,7 +628,7 @@ impl Fuzz { } // Second step: Get stats from honggfuzz logs - let mut hf_status = String::from("running ─"); + let mut hf_status = format!("{green}running{reset} ─"); let mut hf_total_execs = String::new(); let mut hf_threads = String::new(); let mut hf_speed = String::new(); @@ -634,7 +637,7 @@ impl Fuzz { let mut hf_new_finds = String::new(); if self.no_honggfuzz || (self.jobs == 1 && !self.no_afl) { - hf_status = String::from("disabled "); + hf_status = format!("{yellow}disabled{reset} "); } else { let hf_stats_process = process::Command::new("tail") .args([ @@ -709,35 +712,38 @@ impl Fuzz { } // Fourth step: Print stats - // TODO Colors, of course! - // Move 11 lines up and clear line - eprint!("\x1B[11A\x1B[K"); - eprint!("\x1B[K"); - eprintln!("┌── ziggy rocking ──────────────────────────────────────────────────────────┐"); - eprint!("\x1B[K"); + // We start by clearing the screen + eprint!("\x1B[1;1H\x1B[2J"); + eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ────────────────────────────────────────────────────{blue}/{red}///{reset}───┐"); eprintln!( - "│ run time : {total_run_time:17} │" + "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}//////{reset} │" ); - eprint!("\x1B[K"); - eprintln!("├── afl++ {afl_status:0}───────────────────┬── honggfuzz {hf_status:0}───────────────┤"); - eprint!("\x1B[K"); + eprintln!("├─ {blue}afl++{reset} {afl_status:0}────────────────────┬────────────────────────────────{blue}/{red}//{reset}──┤"); + if !afl_status.contains("disabled") { + eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │{gray}best coverage :{reset} {afl_coverage:8.8} {blue}/{red}//{reset} │"); + if afl_crashes == "0" { + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │{gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}//{reset} │"); + } else { + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │{gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}//{reset} │"); + } + eprintln!( + "│ {gray}total execs :{reset} {afl_total_execs:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │" + ); + eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ │"); + } eprintln!( - "│ total execs : {afl_total_execs:17} │ total execs : {hf_total_execs:17} │" + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴───────────────────────────────┬─────┘" ); - eprint!("\x1B[K"); - eprintln!("│ instances : {afl_instances:17} │ threads : {hf_threads:17} │"); - eprint!("\x1B[K"); - eprintln!("│cumulative speed : {afl_speed:17} │ average Speed : {hf_speed:17} │"); - eprint!("\x1B[K"); - eprintln!("│ best coverage : {afl_coverage:17} │ coverage : {hf_coverage:17} │"); - eprint!("\x1B[K"); - eprintln!("│ crashes saved : {afl_crashes:17} │ crashes saved : {hf_crashes:17} │"); - eprint!("\x1B[K"); - eprintln!("│ no find for : {afl_new_finds:17} │ no find for : {hf_new_finds:17} │"); - eprint!("\x1B[K"); - eprintln!("│ top inputs todo : {afl_faves:17} │ │"); - eprint!("\x1B[K"); - eprintln!("└─────────────────────────────────────┴─────────────────────────────────────┘"); + if !hf_status.contains("disabled") { + eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); + if hf_crashes == "0" { + eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │{gray}crashes saved :{reset} {hf_crashes:17.17} │"); + } else { + eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │{gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); + } + eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); + } + eprintln!("└──────────────────────────────────┴──────────────────────────────────┘"); } } From 3c1bc9a1705698c6ef86efaf07ba9b2be6164264 Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 5 Oct 2023 16:04:40 +0200 Subject: [PATCH 2/3] Add timeout and name to output --- src/bin/cargo-ziggy/fuzz.rs | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index bf34ee8..ece6f4c 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -563,6 +563,8 @@ impl Fuzz { } pub fn print_stats(&self) { + let fuzzer_name = format!(" {} ", self.target); + let reset = "\x1b[0m"; let gray = "\x1b[1;90m"; let red = "\x1b[1;91m"; @@ -578,6 +580,7 @@ impl Fuzz { let mut afl_speed = String::new(); let mut afl_coverage = String::new(); let mut afl_crashes = String::new(); + let mut afl_timeouts = String::new(); let mut afl_new_finds = String::new(); let mut afl_faves = String::new(); @@ -610,6 +613,8 @@ impl Fuzz { afl_coverage = String::from(coverage); } else if let Some(crashes) = line.strip_prefix("Crashes saved : ") { afl_crashes = String::from(crashes); + } else if let Some(timeouts) = line.strip_prefix("Hangs saved : ") { + afl_timeouts = String::from(timeouts.split(' ').next().unwrap_or_default()); } else if let Some(new_finds) = line.strip_prefix("Time without finds : ") { afl_new_finds = String::from(new_finds.split(',').next().unwrap_or_default()); @@ -634,6 +639,7 @@ impl Fuzz { let mut hf_speed = String::new(); let mut hf_coverage = String::new(); let mut hf_crashes = String::new(); + let mut hf_timeouts = String::new(); let mut hf_new_finds = String::new(); if self.no_honggfuzz || (self.jobs == 1 && !self.no_afl) { @@ -676,6 +682,8 @@ impl Fuzz { ); } else if let Some(crashes) = line.strip_prefix("Crashes : ") { hf_crashes = String::from(crashes.split(' ').next().unwrap_or_default()); + } else if let Some(timeouts) = line.strip_prefix("Timeouts : ") { + hf_timeouts = String::from(timeouts.split(' ').next().unwrap_or_default()); } else if let Some(new_finds) = line.strip_prefix("Cov Update : ") { hf_new_finds = String::from(new_finds.trim()); hf_new_finds = String::from( @@ -714,36 +722,37 @@ impl Fuzz { // Fourth step: Print stats // We start by clearing the screen eprint!("\x1B[1;1H\x1B[2J"); - eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ────────────────────────────────────────────────────{blue}/{red}///{reset}───┐"); + eprintln!("┌─ {blue}ziggy{reset} {purple}rocking{reset} ─────────{fuzzer_name:─^25.25}──────────────────{blue}/{red}///{reset}───┐"); eprintln!( "│{gray}run time :{reset} {total_run_time:17.17} {blue}/{red}//////{reset} │" ); eprintln!("├─ {blue}afl++{reset} {afl_status:0}────────────────────┬────────────────────────────────{blue}/{red}//{reset}──┤"); if !afl_status.contains("disabled") { - eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │{gray}best coverage :{reset} {afl_coverage:8.8} {blue}/{red}//{reset} │"); + eprintln!("│ {gray}instances :{reset} {afl_instances:17.17} │ {gray}best coverage :{reset} {afl_coverage:11.11} {blue}/{red}//{reset} │"); if afl_crashes == "0" { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │{gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}//{reset} │"); + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}//{reset} │"); } else { eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │{gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}//{reset} │"); } eprintln!( - "│ {gray}total execs :{reset} {afl_total_execs:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │" + "│ {gray}total execs :{reset} {afl_total_execs:17.17} │{gray}timeouts saved :{reset} {afl_timeouts:17.17} │" ); - eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ │"); + eprintln!("│ {gray}top inputs todo :{reset} {afl_faves:17.17} │ {gray}no find for :{reset} {afl_new_finds:17.17} │"); } eprintln!( - "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴───────────────────────────────┬─────┘" + "├─ {blue}honggfuzz{reset} {hf_status:0}─────────────┬──┴────────────────────────────────┬────┘" ); if !hf_status.contains("disabled") { - eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); + eprintln!("│ {gray}threads :{reset} {hf_threads:17.17} │ {gray}coverage :{reset} {hf_coverage:17.17} │"); if hf_crashes == "0" { - eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │{gray}crashes saved :{reset} {hf_crashes:17.17} │"); + eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {hf_crashes:17.17} │"); } else { - eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │{gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); + eprintln!("│{gray}average Speed :{reset} {hf_speed:17.17} │ {gray}crashes saved :{reset} {red}{hf_crashes:17.17}{reset} │"); } - eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); + eprintln!("│ {gray}total execs :{reset} {hf_total_execs:17.17} │{gray}timeouts saved :{reset} {hf_timeouts:17.17} │"); + eprintln!("│ │ {gray}no find for :{reset} {hf_new_finds:17.17} │"); } - eprintln!("└──────────────────────────────────┴──────────────────────────────────┘"); + eprintln!("└──────────────────────────────────┴───────────────────────────────────┘"); } } From 8075739e60392b286a6cf803b38762f9ccdad91b Mon Sep 17 00:00:00 2001 From: Louis Merlin Date: Thu, 5 Oct 2023 16:12:15 +0200 Subject: [PATCH 3/3] Fix display glitch --- src/bin/cargo-ziggy/fuzz.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/cargo-ziggy/fuzz.rs b/src/bin/cargo-ziggy/fuzz.rs index ece6f4c..d07b608 100644 --- a/src/bin/cargo-ziggy/fuzz.rs +++ b/src/bin/cargo-ziggy/fuzz.rs @@ -732,7 +732,7 @@ impl Fuzz { if afl_crashes == "0" { eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {afl_crashes:11.11} {blue}/{red}//{reset} │"); } else { - eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │{gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}//{reset} │"); + eprintln!("│{gray}cumulative speed :{reset} {afl_speed:17.17} │ {gray}crashes saved :{reset} {red}{afl_crashes:11.11}{reset} {blue}/{red}//{reset} │"); } eprintln!( "│ {gray}total execs :{reset} {afl_total_execs:17.17} │{gray}timeouts saved :{reset} {afl_timeouts:17.17} │"