Skip to content

Commit

Permalink
Fix qemu cov (#2875)
Browse files Browse the repository at this point in the history
* fix drcov module hooks setup
  • Loading branch information
rmalmain authored Jan 22, 2025
1 parent 2842f95 commit d9e8b59
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 24 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
33 changes: 20 additions & 13 deletions fuzzers/binary_only/qemu_coverage/src/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ use libafl_bolts::{
AsSlice,
};
use libafl_qemu::{
elf::EasyElf,
modules::{drcov::DrCovModule, utils::filters::StdAddressFilter},
ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, QemuExecutor,
QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
elf::EasyElf, modules::drcov::DrCovModule, ArchExtras, CallingConvention, Emulator, GuestAddr,
GuestReg, MmapPerms, Qemu, QemuExecutor, QemuExitReason, QemuRWError, QemuShutdownCause, Regs,
};

#[derive(Default)]
Expand Down Expand Up @@ -127,9 +125,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 +178,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 +200,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 +211,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 +226,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 +257,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
17 changes: 9 additions & 8 deletions libafl_qemu/src/modules/drcov.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,26 +265,27 @@ 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 +393,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 d9e8b59

Please sign in to comment.