Skip to content
Draft
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: 5 additions & 1 deletion crates/libafl/src/executors/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ pub mod inprocess;
pub mod timer;

/// Intel Processor Trace (PT)
#[cfg(all(feature = "intel_pt", target_os = "linux", target_arch = "x86_64"))]
#[cfg(all(
feature = "intel_pt",
any(windows, target_os = "linux"),
target_arch = "x86_64"
))]
pub mod intel_pt;

/// The hook that runs before and after the executor runs the target
Expand Down
14 changes: 11 additions & 3 deletions crates/libafl_intelpt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ export_raw = []

[dev-dependencies]
static_assertions = { workspace = true }
proc-maps = "0.4.0"
env_logger = "0.11.10"

[target.'cfg(target_os = "linux" )'.dev-dependencies]
nix = { workspace = true }
proc-maps = "0.4.0"

[dependencies]
arbitrary-int = { workspace = true }
Expand All @@ -32,15 +33,22 @@ libc = { workspace = true }
log = { workspace = true }
num_enum = { workspace = true, default-features = false }
num-traits = { workspace = true, default-features = false }
ptcov = { version = "0.1.0" }
ptcov = { git = "https://github.com/Marcondiro/ptcov", branch = "fix_pgd" }
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"] }
hashbrown = { workspace = true }
ptcov = { features = [
"retc",
], git = "https://github.com/Marcondiro/ptcov", branch = "fix_pgd" }
windows = { workspace = true, features = [
"Win32_System_IO",
"Win32_Storage_FileSystem",
] }

[lints]
workspace = true
26 changes: 25 additions & 1 deletion crates/libafl_intelpt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ mod linux;
#[cfg(target_os = "linux")]
pub use linux::*;

#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
pub use windows::*;

#[cfg(any(target_os = "linux", target_os = "windows"))]
mod utils;

/// Size of a memory page
pub const PAGE_SIZE: usize = 4096;

Expand All @@ -41,6 +49,7 @@ pub fn availability() -> Result<(), String> {
let mut reasons = Vec::new();

let cpuid = CpuId::new();

if let Some(vendor) = cpuid.get_vendor_info() {
if vendor.as_str() != "GenuineIntel" && vendor.as_str() != "GenuineIotel" {
reasons.push("Only Intel CPUs are supported".to_owned());
Expand All @@ -57,11 +66,26 @@ pub fn availability() -> Result<(), String> {
reasons.push("Failed to read CPU Extended Features".to_owned());
}

if let Some(pti) = cpuid.get_processor_trace_info() {
if pti.configurable_address_ranges() == 0 {
reasons.push(
"The current CPU does not support Intel PT filtering: no address filters available"
.to_owned(),
);
}
} else {
reasons.push("Failed to read CPU Processor Trace Info".to_owned());
}

#[cfg(target_os = "linux")]
if let Err(r) = availability_in_linux() {
reasons.push(r);
}
#[cfg(not(target_os = "linux"))]
#[cfg(target_os = "windows")]
if let Err(r) = availability_in_windows() {
reasons.push(r);
}
#[cfg(not(any(target_os = "linux", target_os = "windows")))]
reasons.push("Only linux hosts are supported at the moment".to_owned());

if reasons.is_empty() {
Expand Down
18 changes: 2 additions & 16 deletions crates/libafl_intelpt/src/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@ use perf_event_open_sys::{
perf_event_open,
};
pub use ptcov::{CoverageEntry, PtCoverageDecoder, PtCoverageDecoderBuilder, PtImage};
use ptcov::{PtCpu, PtCpuVendor};
use raw_cpuid::CpuId;

use super::{PAGE_SIZE, availability};
use crate::utils::current_cpu;

const PT_EVENT_PATH: &str = "/sys/bus/event_source/devices/intel_pt";

Expand Down Expand Up @@ -107,7 +106,6 @@ impl<'a> IntelPT<'a> {
/// Set filters based on Instruction Pointer (IP)
///
/// Only instructions in `filters` ranges will be traced.
/// NOTE: only filters of type `AddrFilterType::FILTER` are supported.
fn set_ip_filters(&mut self, filters: &[RangeInclusive<u64>]) -> Result<(), Error> {
let str_filter = filters
.iter()
Expand Down Expand Up @@ -296,7 +294,7 @@ impl<'a> IntelPT<'a> {
}

/// Dump the raw trace used in the last decoding to the file
/// /// `./traces/trace_<unix epoch in micros>`
/// `./traces/trace_<unix epoch in micros>`
#[cfg(feature = "export_raw")]
pub fn dump_last_trace_to_file(&self) -> Result<(), Error> {
use std::{fs, io::Write, path::Path, time};
Expand Down Expand Up @@ -761,18 +759,6 @@ const fn wrap_aux_pointer(ptr: u64, perf_aux_buffer_size: usize) -> u64 {
ptr & (perf_aux_buffer_size as u64 - 1)
}

fn current_cpu() -> Option<PtCpu> {
let cpuid = CpuId::new();
cpuid.get_feature_info().map(|fi| {
PtCpu::new(
PtCpuVendor::Intel,
fi.family_id().into(),
fi.model_id(),
fi.stepping_id(),
)
})
}

#[cfg(test)]
mod test {
use std::path::PathBuf;
Expand Down
14 changes: 14 additions & 0 deletions crates/libafl_intelpt/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use ptcov::{PtCpu, PtCpuVendor};
use raw_cpuid::CpuId;

pub fn current_cpu() -> Option<PtCpu> {
let cpuid = CpuId::new();
cpuid.get_feature_info().map(|fi| {
PtCpu::new(
PtCpuVendor::Intel,
fi.family_id().into(),
fi.model_id(),
fi.stepping_id(),
)
})
}
Loading
Loading