Skip to content

Commit

Permalink
fix qemu cov
Browse files Browse the repository at this point in the history
  • Loading branch information
rmalmain committed Jan 21, 2025
1 parent 7e18887 commit 60c5219
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 25 deletions.
2 changes: 1 addition & 1 deletion fuzzers/binary_only/qemu_coverage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This folder contains an example fuzzer which runs each entry in the input corpus and collects
the cumuative coverage data in drcov format. This fuzzer also distributes the test cases in
the input corupus evenly across the selected cores.
the input corpus evenly across the selected cores.

The following architectures are supported:
* arm
Expand Down
32 changes: 20 additions & 12 deletions fuzzers/binary_only/qemu_coverage/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use core::mem::size_of;
use core::time::Duration;
use std::{env, fmt::Write, fs::DirEntry, io, path::PathBuf, process};

use clap::{builder::Str, Parser};
use libafl::{
corpus::{Corpus, InMemoryCorpus},
Expand All @@ -29,9 +28,9 @@ use libafl_bolts::{
};
use libafl_qemu::{
elf::EasyElf,
modules::{drcov::DrCovModule, utils::filters::StdAddressFilter},
modules::{drcov::DrCovModule},
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, QemuExecutor,
QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
QemuExitReason, QemuRWError, QemuShutdownCause, Regs, Qemu,
};

#[derive(Default)]
Expand Down Expand Up @@ -127,9 +126,14 @@ pub fn fuzz() {
mut mgr: LlmpRestartingEventManager<_, _, _, _, _>,
client_description: ClientDescription| {
let mut cov_path = options.coverage_path.clone();
let core_id = client_description.core_id();

let coverage_name = cov_path.file_stem().unwrap().to_str().unwrap();
let coverage_extension = cov_path.extension().unwrap_or_default().to_str().unwrap();
let core = core_id.0;
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));

let emulator_modules = tuple_list!(DrCovModule::builder()
.filter(StdAddressFilter::default())
.filename(cov_path.clone())
.full_trace(false)
.build());
Expand Down Expand Up @@ -175,7 +179,7 @@ pub fn fuzz() {

let stack_ptr: GuestAddr = qemu.read_reg(Regs::Sp).unwrap();

let reset = |buf: &[u8], len: GuestReg| -> Result<(), QemuRWError> {
let reset = |qemu: Qemu, buf: &[u8], len: GuestReg| -> Result<(), QemuRWError> {
unsafe {
let _ = qemu.write_mem(input_addr, buf);
qemu.write_reg(Regs::Pc, test_one_input_ptr)?;
Expand All @@ -197,7 +201,9 @@ pub fn fuzz() {
};

let mut harness =
|_emulator: &mut Emulator<_, _, _, _, _, _, _>, _state: &mut _, input: &BytesInput| {
|emulator: &mut Emulator<_, _, _, _, _, _, _>, state: &mut _, input: &BytesInput| {
let qemu = emulator.qemu();

let target = input.target_bytes();
let mut buf = target.as_slice();
let mut len = buf.len();
Expand All @@ -206,7 +212,13 @@ pub fn fuzz() {
len = MAX_INPUT_SIZE;
}
let len = len as GuestReg;
reset(buf, len).unwrap();
reset(qemu, buf, len).unwrap();

unsafe {
let ret = emulator.run(state, input);
log::warn!("ret = {ret:?}");
}

ExitKind::Ok
};

Expand All @@ -215,6 +227,7 @@ pub fn fuzz() {
.cores
.position(core_id)
.expect("Failed to get core index");

let files = corpus_files
.iter()
.skip(files_per_core * core_idx)
Expand Down Expand Up @@ -245,11 +258,6 @@ pub fn fuzz() {
let scheduler = QueueScheduler::new();
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

let coverage_name = cov_path.file_stem().unwrap().to_str().unwrap();
let coverage_extension = cov_path.extension().unwrap_or_default().to_str().unwrap();
let core = core_id.0;
cov_path.set_file_name(format!("{coverage_name}-{core:03}.{coverage_extension}"));

let mut executor = QemuExecutor::new(
emulator,
&mut harness,
Expand Down
2 changes: 1 addition & 1 deletion libafl_qemu/src/modules/cmplog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ where
return None;
}
}
let state = state.expect("The gen_unique_cmp_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_cmp_ids hook works only for in-process fuzzing. Is the Executor initialized?");
if state.metadata_map().get::<QemuCmpsMapMetadata>().is_none() {
state.add_metadata(QemuCmpsMapMetadata::new());
}
Expand Down
20 changes: 10 additions & 10 deletions libafl_qemu/src/modules/drcov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,26 +265,26 @@ where
I: Unpin,
S: Unpin + HasMetadata,
{
fn post_qemu_init<ET>(&mut self, _qemu: Qemu, emulator_modules: &mut EmulatorModules<ET, I, S>)
fn post_qemu_init<ET>(&mut self, _qemu: Qemu, _emulator_modules: &mut EmulatorModules<ET, I, S>)
where
ET: EmulatorModuleTuple<I, S>,
{
emulator_modules.blocks(
Hook::Function(gen_unique_block_ids::<ET, F, I, S>),
Hook::Function(gen_block_lengths::<ET, F, I, S>),
Hook::Function(exec_trace_block::<ET, F, I, S>),
);
}
{}

#[cfg(feature = "usermode")]
fn first_exec<ET>(
&mut self,
qemu: Qemu,
_emulator_modules: &mut EmulatorModules<ET, I, S>,
emulator_modules: &mut EmulatorModules<ET, I, S>,
_state: &mut S,
) where
ET: EmulatorModuleTuple<I, S>,
{
emulator_modules.blocks(
Hook::Function(gen_unique_block_ids::<ET, F, I, S>),
Hook::Function(gen_block_lengths::<ET, F, I, S>),
Hook::Function(exec_trace_block::<ET, F, I, S>),
);

if self.module_mapping.is_none() {
log::info!("Auto-filling module mapping for DrCov module from QEMU mapping.");

Expand Down Expand Up @@ -392,7 +392,7 @@ where
return None;
}

let state = state.expect("The gen_unique_block_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_block_ids hook works only for in-process fuzzing. Is the Executor initialized?");
if state
.metadata_map_mut()
.get_mut::<DrCovMetadata>()
Expand Down
2 changes: 1 addition & 1 deletion libafl_qemu/src/modules/edges/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ mod generators {

let mask: usize = get_mask::<IS_CONST_MAP, MAP_SIZE>();

let state = state.expect("The gen_unique_edge_ids hook works only for in-process fuzzing");
let state = state.expect("The gen_unique_edge_ids hook works only for in-process fuzzing. Is the Executor initialized?");
let meta = state.metadata_or_insert_with(QemuEdgesMapMetadata::new);

match meta.map.entry((src, dest)) {
Expand Down

0 comments on commit 60c5219

Please sign in to comment.