Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix drcov path parsing #2884

Merged
merged 31 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 6 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
8 changes: 4 additions & 4 deletions fuzzers/binary_only/qemu_coverage/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ windows_alias = "unsupported"
command = "${TARGET_DIR}/${PROFILE_DIR}/qemu_coverage-${CARGO_MAKE_PROFILE}"
args = [
"--coverage-path",
"${TARGET_DIR}/drcov.log",
"${TARGET_DIR}/cov.drcov",
"--input-dir",
"./corpus",
"--",
Expand Down Expand Up @@ -294,11 +294,11 @@ script = '''
cargo make ${FEATURE} || exit 1

cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_merge -- \
-i ${TARGET_DIR}/drcov-000.log ${TARGET_DIR}/drcov-001.log ${TARGET_DIR}/drcov-002.log ${TARGET_DIR}/drcov-003.log \
--output ${TARGET_DIR}/drcov-merged.log || exit 1
-i ${TARGET_DIR}/cov-000.drcov ${TARGET_DIR}/cov-001.drcov ${TARGET_DIR}/cov-002.drcov ${TARGET_DIR}/cov-003.drcov \
--output ${TARGET_DIR}/cov-merged.drcov || exit 1

TMP=$(cargo run --manifest-path ../../../utils/drcov_utils/Cargo.toml --bin drcov_dump_addrs -- \
-i ${TARGET_DIR}/drcov-merged.log | wc -l || exit 1)
-i ${TARGET_DIR}/cov-merged.drcov | wc -l || exit 1)

NB_BLOCKS=$((TMP - 1))

Expand Down
18 changes: 17 additions & 1 deletion libafl_targets/src/drcov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,22 @@ fn parse_hex_to_u64(str: &str) -> Result<u64, ParseIntError> {
u64::from_str_radix(&str[2..], 16)
}

fn parse_path(s: &str) -> Option<PathBuf> {
let mut chars = s.trim().chars();

// first char must be a quote
if chars.next()? != '\"' {
return None
}

// last char must be a quote as well
if chars.next_back()? != '\"' {
return None
}

Some(PathBuf::from(chars.as_str()))
}

impl DrCovReader {
/// Parse a `drcov` file to memory.
pub fn read<P: AsRef<Path> + ?Sized>(file: &P) -> Result<Self, Error> {
Expand Down Expand Up @@ -336,7 +352,7 @@ impl DrCovReader {
return Err(err("timestamp"));
};

let Some(path) = split.next().map(|s| PathBuf::from(s.trim())) else {
let Some(path) = split.next().and_then(parse_path) else {
rmalmain marked this conversation as resolved.
Show resolved Hide resolved
return Err(err("path"));
};

Expand Down
1 change: 1 addition & 0 deletions utils/drcov_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ categories = ["development-tools"]
keywords = ["fuzzing", "libafl", "drcov"]

[dependencies]
env_logger = "0.11.6"
libafl_targets = { workspace = true, default-features = true }
clap = { workspace = true, features = ["derive", "wrap_help"] }

Expand Down
42 changes: 35 additions & 7 deletions utils/drcov_utils/src/bin/drcov_dump_addrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ pub struct Opt {
help = "Output folder to write address files to. If none is set, this will output all addresses to stdout."
)]
pub out_dir: Option<PathBuf>,
#[arg(
short,
long,
help = "Print all the addresses when printing to stdout. Does not have any impact when writing addresses to a file."
)]
pub verbose: bool,
}

fn main() {
Expand All @@ -45,6 +51,9 @@ fn main() {
continue;
};

let mut blocks = drcov.basic_block_addresses_u64();
blocks.sort();

if let Some(out_dir) = &opts.out_dir {
// Write files to a directory
let out_file = out_dir.join(
Expand All @@ -59,21 +68,40 @@ fn main() {
continue;
};

println!("Dumping addresses from drcov file {input:?} to {out_file:?}");
println!(
"Dumping {} addresses from drcov file {input:?} to {out_file:?}",
blocks.len()
);

for line in drcov.basic_block_addresses_u64() {
for line in blocks {
file.write_all(format!("{line:#x}\n").as_bytes())
.expect("Could not write to file");
}
} else {
// dump to stdout
println!("# Blocks covered in {input:?}:");

for line in drcov.basic_block_addresses_u64() {
println!("{line:#x}");
let modules = &drcov.module_entries;
println!("# {} Modules:", modules.len());
for module in &drcov.module_entries {
println!(
"\t{} - [{:#020x}-{:#020x}] {}",
module.id,
module.base,
module.end,
module.path.display()
);
}

println!();

print!("# {} Blocks covered in {input:?}", blocks.len());
if opts.verbose {
println!(":");
for line in blocks {
println!("{line:#x}");
}
println!();
} else {
println!(".");
}
}
}
}
1 change: 1 addition & 0 deletions utils/drcov_utils/src/bin/drcov_merge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub struct Opt {
}

fn main() {
env_logger::init();
let opts = Opt::parse();

assert!(
Expand Down
Loading