diff --git a/fuzzers/binary_only/qemu_coverage/src/fuzzer.rs b/fuzzers/binary_only/qemu_coverage/src/fuzzer.rs index 8744dc48b4..a7171fd343 100644 --- a/fuzzers/binary_only/qemu_coverage/src/fuzzer.rs +++ b/fuzzers/binary_only/qemu_coverage/src/fuzzer.rs @@ -31,7 +31,7 @@ use libafl_qemu::{ elf::EasyElf, modules::{drcov::DrCovModule, SnapshotModule}, ArchExtras, CallingConvention, Emulator, GuestAddr, GuestReg, MmapPerms, Qemu, QemuExecutor, - QemuExitReason, QemuRWError, QemuShutdownCause, Regs, + QemuExitReason, QemuMappingsViewer, QemuRWError, QemuShutdownCause, Regs, }; #[derive(Default)] @@ -156,14 +156,8 @@ pub fn fuzz() { qemu.entry_break(test_one_input_ptr); - for m in qemu.mappings() { - log::info!( - "Mapping: 0x{:016x}-0x{:016x}, {}", - m.start(), - m.end(), - m.path().unwrap_or(&"".to_string()) - ); - } + let mappings = QemuMappingsViewer::new(&qemu); + println!("{:#?}", mappings); let pc: GuestReg = qemu.read_reg(Regs::Pc).unwrap(); log::info!("Break at {pc:#x}"); diff --git a/libafl_qemu/src/qemu/usermode.rs b/libafl_qemu/src/qemu/usermode.rs index c7f2a93c5f..a3e18feae8 100644 --- a/libafl_qemu/src/qemu/usermode.rs +++ b/libafl_qemu/src/qemu/usermode.rs @@ -16,6 +16,52 @@ use pyo3::{pyclass, pymethods, IntoPyObject, Py, PyRef, PyRefMut, Python}; use crate::{qemu::QEMU_IS_RUNNING, Qemu, CPU}; +pub struct QemuMappingsViewer<'a> { + qemu: &'a Qemu, + mappings: Vec, +} + +impl<'a> QemuMappingsViewer<'a> { + /// Capture the memory mappings of Qemu at the moment when we create this object + /// Thus if qemu make updates to the mappings, they won't be reflected to this object. + #[must_use] + pub fn new(qemu: &'a Qemu) -> Self { + let mut mappings: Vec = vec![]; + for m in qemu.mappings() { + mappings.push(m); + } + Self { qemu, mappings } + } + + /// Update the mappings + pub fn update(&mut self) { + let mut mappings: Vec = vec![]; + for m in self.qemu.mappings() { + mappings.push(m); + } + self.mappings = mappings; + } +} + +impl core::fmt::Debug for QemuMappingsViewer<'_> { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + for m in &self.mappings { + let flags = format!("Flags: {:?}", m.flags()); + let padded = format!("{flags:<20}"); + writeln!( + f, + "Mapping: 0x{:016x}-0x{:016x}, {:>10} IsPriv: {:?} Path: {}", + m.start(), + m.end(), + padded, + m.is_priv(), + m.path().unwrap_or(&"".to_string()) + )?; + } + Ok(()) + } +} + #[cfg_attr(feature = "python", pyclass(unsendable))] pub struct GuestMaps { self_maps_root: *mut IntervalTreeRoot,