Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions crates/libafl/src/executors/hooks/intel_pt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use crate::executors::hooks::ExecutorHook;

/// Hook to enable Intel Processor Trace (PT) tracing
#[derive(Debug, TypedBuilder)]
pub struct IntelPTHook<T> {
intel_pt: IntelPT,
pub struct IntelPTHook<'a, T> {
intel_pt: IntelPT<'a>,
map_ptr: *mut T,
map_len: usize,
}

impl<I, S, T> ExecutorHook<I, S> for IntelPTHook<T>
impl<I, S, T> ExecutorHook<I, S> for IntelPTHook<'_, T>
where
S: Serialize,
T: CoverageEntry,
Expand Down
5 changes: 4 additions & 1 deletion crates/libafl_intelpt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,15 @@ libc = { workspace = true }
log = { workspace = true }
num_enum = { workspace = true, default-features = false }
num-traits = { workspace = true, default-features = false }
ptcov = { version = "0.0.6" }
ptcov = { version = "0.1.0" }
raw-cpuid = { version = "11.1.0" }

[target.'cfg(target_os = "linux" )'.dependencies]
caps = { version = "0.5.5" }
perf-event-open-sys = { version = "5.0.0" }

[target.'cfg(target_os = "windows" )'.dependencies]
ptcov = { version = "0.1.0", features = ["retc"] }

[lints]
workspace = true
29 changes: 14 additions & 15 deletions crates/libafl_intelpt/src/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub enum KvmPTMode {

/// Intel Processor Trace (PT)
#[derive(Debug)]
pub struct IntelPT {
pub struct IntelPT<'a> {
fd: OwnedFd,
perf_buffer: *mut c_void,
perf_aux_buffer: *mut c_void,
Expand All @@ -90,17 +90,17 @@ pub struct IntelPT {
aux_head: *mut u64,
aux_tail: *mut u64,
previous_decode_head: u64,
ptcov_decoder: PtCoverageDecoder,
ptcov_decoder: PtCoverageDecoder<'a>,
#[cfg(feature = "export_raw")]
last_decode_trace: Vec<u8>,
}

impl IntelPT {
impl<'a> IntelPT<'a> {
/// Create a default builder
///
/// Checkout [`IntelPTBuilder::default()`] for more details
#[must_use]
pub fn builder() -> IntelPTBuilder {
pub fn builder() -> IntelPTBuilder<'a> {
IntelPTBuilder::default()
}

Expand Down Expand Up @@ -313,7 +313,7 @@ impl IntelPT {
}
}

impl Drop for IntelPT {
impl Drop for IntelPT<'_> {
fn drop(&mut self) {
unsafe {
let ret = libc::munmap(self.perf_aux_buffer, self.perf_aux_buffer_size);
Expand All @@ -326,7 +326,7 @@ impl Drop for IntelPT {

/// Builder for [`IntelPT`]
#[derive(Debug, Clone, PartialEq)]
pub struct IntelPTBuilder {
pub struct IntelPTBuilder<'a> {
pid: Option<i32>,
cpu: i32,
exclude_kernel: bool,
Expand All @@ -335,10 +335,10 @@ pub struct IntelPTBuilder {
perf_buffer_size: usize,
perf_aux_buffer_size: usize,
ip_filters: Vec<RangeInclusive<u64>>,
images: Vec<PtImage>,
images: &'a [PtImage<'a>],
}

impl Default for IntelPTBuilder {
impl Default for IntelPTBuilder<'_> {
/// Create a default builder for [`IntelPT`]
///
/// The default configuration corresponds to:
Expand All @@ -354,7 +354,7 @@ impl Default for IntelPTBuilder {
/// .unwrap()
/// .perf_aux_buffer_size(16 * 1024 * 1024)
/// .unwrap()
/// .images(Vec::new())
/// .images(&[])
/// .ip_filters(Default::default());
/// assert_eq!(builder, IntelPTBuilder::default());
/// ```
Expand All @@ -368,14 +368,14 @@ impl Default for IntelPTBuilder {
perf_buffer_size: 128 * PAGE_SIZE + PAGE_SIZE,
perf_aux_buffer_size: 16 * 1024 * 1024,
ip_filters: Vec::new(),
images: Vec::new(),
images: &[],
}
}
}

impl IntelPTBuilder {
impl<'a> IntelPTBuilder<'a> {
/// Build the [`IntelPT`] struct
pub fn build(self) -> Result<IntelPT, Error> {
pub fn build(self) -> Result<IntelPT<'a>, Error> {
self.check_config();
let mut perf_event_attr = new_perf_event_attr_intel_pt()?;
perf_event_attr.set_exclude_kernel(self.exclude_kernel.into());
Expand Down Expand Up @@ -435,8 +435,7 @@ impl IntelPTBuilder {
.cpu(current_cpu())
.filter_vmx_non_root(self.exclude_hv)
.images(self.images)
.build()
.unwrap();
.build();

let mut intel_pt = IntelPT {
fd,
Expand Down Expand Up @@ -554,7 +553,7 @@ impl IntelPTBuilder {
}

#[must_use]
pub fn images(mut self, images: Vec<PtImage>) -> Self {
pub fn images(mut self, images: &'a [PtImage<'_>]) -> Self {
self.images = images;
self
}
Expand Down
19 changes: 7 additions & 12 deletions crates/libafl_intelpt/tests/integration_tests_linux.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
#![cfg(feature = "std")]
#![cfg(target_os = "linux")]

extern crate alloc;
use alloc::slice;
use core::arch::asm;
use std::{
fs::File,
io::{Read, Seek, SeekFrom},
process,
};
use std::process;

use libafl_intelpt::{IntelPT, availability};
use nix::{
Expand Down Expand Up @@ -58,16 +56,13 @@ fn intel_pt_trace_fork() {
let images = maps
.iter()
.filter(|map| map.is_exec() && map.filename().is_some() && map.inode != 0)
.map(|map| {
let mut file = File::open(map.filename().unwrap()).unwrap();
let mut data = vec![0; map.size()];
file.seek(SeekFrom::Start(map.offset as u64)).unwrap();
file.read_exact(&mut data).unwrap();
PtImage::new(data, map.start() as u64)
.map(|pm| {
let data = unsafe { slice::from_raw_parts(pm.start() as *const u8, pm.size()) };
PtImage::new(data, pm.start() as u64)
})
.collect::<Vec<_>>();

let pt_builder = IntelPT::builder().pid(Some(pid.as_raw())).images(images);
let pt_builder = IntelPT::builder().pid(Some(pid.as_raw())).images(&images);
let mut pt = pt_builder.build().expect("Failed to create IntelPT");
pt.enable_tracing().expect("Failed to enable tracing");

Expand Down
6 changes: 3 additions & 3 deletions crates/libafl_qemu/src/modules/systemmode/intel_pt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ use crate::{
#[derive(Debug, TypedBuilder)]
pub struct IntelPTModule<T = u8> {
#[builder(setter(skip), default)]
pt: Option<IntelPT>,
pt: Option<IntelPT<'static>>,
#[builder(default = IntelPTModule::default_pt_builder())]
intel_pt_builder: IntelPTBuilder,
intel_pt_builder: IntelPTBuilder<'static>,
map_ptr: *mut T,
map_len: usize,
}

impl IntelPTModule {
#[must_use]
pub fn default_pt_builder() -> IntelPTBuilder {
pub fn default_pt_builder() -> IntelPTBuilder<'static> {
IntelPT::builder().exclude_kernel(false).exclude_hv(true)
}
}
Expand Down
15 changes: 5 additions & 10 deletions fuzzers/binary_only/intel_pt_baby_fuzzer/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::{
hint::black_box, num::NonZero, path::PathBuf, process, ptr::copy_nonoverlapping, time::Duration,
};
use std::{hint::black_box, num::NonZero, path::PathBuf, process, slice, time::Duration};

use libafl::{
corpus::{InMemoryCorpus, OnDiskCorpus},
Expand Down Expand Up @@ -92,10 +90,7 @@ pub fn main() {
.iter()
.filter_map(|pm| {
if pm.is_exec() && pm.filename().is_some() && pm.inode != 0 {
let mut data = vec![0; pm.size()];
unsafe {
copy_nonoverlapping(pm.start() as *const u8, data.as_mut_ptr(), data.len())
}
let data = unsafe { slice::from_raw_parts(pm.start() as *const u8, pm.size()) };
Some(PtImage::new(data, pm.start() as u64))
} else {
None
Expand All @@ -104,7 +99,7 @@ pub fn main() {
.collect::<Vec<_>>();

// Pass the executable memory to the code responsible for Intel PT trace decoding
let pt = IntelPT::builder().images(images).build().unwrap();
let pt = IntelPT::builder().images(&images).build().unwrap();
// Intel PT hook that will handle the setup of Intel PT for each execution and fill the map
let pt_hook = unsafe {
IntelPTHook::builder()
Expand All @@ -114,8 +109,8 @@ pub fn main() {
}
.build();

type PTInProcessExecutor<'a, EM, H, I, OT, S, T, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, (IntelPTHook<T>, ()), I, OT, S, Z>;
type PTInProcessExecutor<'a, 'b, EM, H, I, OT, S, T, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, (IntelPTHook<'b, T>, ()), I, OT, S, Z>;
// Create the executor for an in-process function with just one observer
let mut executor = PTInProcessExecutor::with_timeout_generic(
tuple_list!(pt_hook),
Expand Down
13 changes: 11 additions & 2 deletions fuzzers/binary_only/intel_pt_command_executor/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions fuzzers/binary_only/intel_pt_command_executor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut data = vec![0; executable_segment.size() as usize];
file.seek(SeekFrom::Start(executable_segment.file_range().0))?;
file.read_exact(&mut data)?;
let images = vec![PtImage::new(data, actual_virtual_address)];
let images = vec![PtImage::new(&data, actual_virtual_address)];

let intel_pt = IntelPT::builder()
.cpu(cpu.0)
.inherit(true)
.ip_filters(filters)
.images(images)
.images(&images)
.build()?;

let hook = unsafe { IntelPTHook::builder().map_ptr(MAP_PTR).map_len(MAP_SIZE) }
Expand Down
Loading