Move all unnecessary std uses to core,alloc (#3027)
* Move all unnecessary std uses to core,alloc * More * more fix * more * more * Remove libafl-fuzz grimoire * more * more * more cleanup * remove bins * fix * more fix
This commit is contained in:
parent
c7207dceb0
commit
ce5fd435ea
3
.gitignore
vendored
3
.gitignore
vendored
@ -76,3 +76,6 @@ program
|
|||||||
fuzzer_libpng*
|
fuzzer_libpng*
|
||||||
|
|
||||||
*.patch
|
*.patch
|
||||||
|
|
||||||
|
# Sometimes this happens
|
||||||
|
rustc-ice-*
|
@ -148,6 +148,10 @@ all = { level = "deny", priority = -1 }
|
|||||||
pedantic = { level = "deny", priority = -1 }
|
pedantic = { level = "deny", priority = -1 }
|
||||||
cargo_common_metadata = "deny"
|
cargo_common_metadata = "deny"
|
||||||
|
|
||||||
|
alloc_instead_of_core = "deny"
|
||||||
|
std_instead_of_alloc = "deny"
|
||||||
|
std_instead_of_core = "deny"
|
||||||
|
|
||||||
# Warn
|
# Warn
|
||||||
cargo = { level = "warn", priority = -1 }
|
cargo = { level = "warn", priority = -1 }
|
||||||
|
|
||||||
|
2
fuzzers/binary_only/qemu_launcher/injection_test/.gitignore
vendored
Normal file
2
fuzzers/binary_only/qemu_launcher/injection_test/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
injection_test
|
||||||
|
static
|
@ -1,7 +1,8 @@
|
|||||||
//! An example for TUI that uses the TUI without any real data.
|
//! An example for TUI that uses the TUI without any real data.
|
||||||
//! This is mainly to fix the UI without having to run a real fuzzer.
|
//! This is mainly to fix the UI without having to run a real fuzzer.
|
||||||
|
|
||||||
use std::{thread::sleep, time::Duration};
|
use core::time::Duration;
|
||||||
|
use std::thread::sleep;
|
||||||
|
|
||||||
use libafl::monitors::{
|
use libafl::monitors::{
|
||||||
Monitor,
|
Monitor,
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
use std::{
|
use core::sync::atomic::AtomicBool;
|
||||||
fs::File,
|
use std::{fs::File, io::Write, sync::RwLock};
|
||||||
io::Write,
|
|
||||||
sync::{RwLock, atomic::AtomicBool},
|
|
||||||
};
|
|
||||||
|
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use libafl_bolts::rands::Rand;
|
use libafl_bolts::rands::Rand;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::ops::Add;
|
use core::ops::Add;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#![allow(clippy::useless_conversion)] // This seems to be a false-positive(?)
|
#![allow(clippy::useless_conversion)] // This seems to be a false-positive(?)
|
||||||
|
|
||||||
use std::{ffi::CString, string::String, vec::Vec};
|
use alloc::{ffi::CString, string::String, vec::Vec};
|
||||||
|
|
||||||
use pyo3::{prelude::*, pyclass, types::IntoPyDict};
|
use pyo3::{prelude::*, pyclass, types::IntoPyDict};
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use alloc::vec::Vec;
|
use alloc::{fmt, vec::Vec};
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
@ -25,7 +25,7 @@ static SPLITTER: OnceLock<regex::Regex> = OnceLock::new();
|
|||||||
static TOKENIZER: OnceLock<regex::bytes::Regex> = OnceLock::new();
|
static TOKENIZER: OnceLock<regex::bytes::Regex> = OnceLock::new();
|
||||||
|
|
||||||
fn show_bytes(bs: &[u8]) -> String {
|
fn show_bytes(bs: &[u8]) -> String {
|
||||||
use std::{ascii::escape_default, str};
|
use core::{ascii::escape_default, str};
|
||||||
|
|
||||||
let mut visible = String::new();
|
let mut visible = String::new();
|
||||||
for &b in bs {
|
for &b in bs {
|
||||||
@ -265,7 +265,7 @@ impl Rule {
|
|||||||
if let Some(sub) = cap.get(1) {
|
if let Some(sub) = cap.get(1) {
|
||||||
//println!("cap.get(1): {}", sub.as_str());
|
//println!("cap.get(1): {}", sub.as_str());
|
||||||
RuleChild::from_nt(
|
RuleChild::from_nt(
|
||||||
std::str::from_utf8(sub.as_bytes())
|
core::str::from_utf8(sub.as_bytes())
|
||||||
.expect("nonterminals need to be valid strings"),
|
.expect("nonterminals need to be valid strings"),
|
||||||
ctx,
|
ctx,
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use std::{cmp, io, io::Write, marker::Sized};
|
use core::{cmp, marker::Sized};
|
||||||
|
use std::io::{Cursor, Write, stdout};
|
||||||
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use libafl_bolts::rands::Rand;
|
use libafl_bolts::rands::Rand;
|
||||||
@ -28,7 +29,7 @@ enum UnparseStep<'dat> {
|
|||||||
struct Unparser<'data, 'tree: 'data, 'ctx: 'data, W: Write, T: TreeLike> {
|
struct Unparser<'data, 'tree: 'data, 'ctx: 'data, W: Write, T: TreeLike> {
|
||||||
tree: &'tree T,
|
tree: &'tree T,
|
||||||
stack: Vec<UnparseStep<'data>>,
|
stack: Vec<UnparseStep<'data>>,
|
||||||
buffers: Vec<io::Cursor<Vec<u8>>>,
|
buffers: Vec<Cursor<Vec<u8>>>,
|
||||||
w: W,
|
w: W,
|
||||||
i: usize,
|
i: usize,
|
||||||
ctx: &'ctx Context,
|
ctx: &'ctx Context,
|
||||||
@ -81,10 +82,7 @@ impl<'data, 'tree: 'data, 'ctx: 'data, W: Write, T: TreeLike> Unparser<'data, 't
|
|||||||
}
|
}
|
||||||
fn script(&mut self, py: Python, num: usize, expr: &PyObject) -> PyResult<()> {
|
fn script(&mut self, py: Python, num: usize, expr: &PyObject) -> PyResult<()> {
|
||||||
let bufs = self.buffers.split_off(self.buffers.len() - num);
|
let bufs = self.buffers.split_off(self.buffers.len() - num);
|
||||||
let bufs = bufs
|
let bufs = bufs.into_iter().map(Cursor::into_inner).collect::<Vec<_>>();
|
||||||
.into_iter()
|
|
||||||
.map(io::Cursor::into_inner)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
let byte_arrays = bufs.iter().map(|b| PyBytes::new(py, b));
|
let byte_arrays = bufs.iter().map(|b| PyBytes::new(py, b));
|
||||||
let res = expr.call1(py, PyTuple::new(py, byte_arrays)?)?;
|
let res = expr.call1(py, PyTuple::new(py, byte_arrays)?)?;
|
||||||
let bound = res.bind(py);
|
let bound = res.bind(py);
|
||||||
@ -103,7 +101,7 @@ impl<'data, 'tree: 'data, 'ctx: 'data, W: Write, T: TreeLike> Unparser<'data, 't
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn push_buffer(&mut self) {
|
fn push_buffer(&mut self) {
|
||||||
self.buffers.push(io::Cursor::new(vec![]));
|
self.buffers.push(Cursor::new(vec![]));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_rule(&mut self, nt: NTermId) {
|
fn next_rule(&mut self, nt: NTermId) {
|
||||||
@ -184,7 +182,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unparse_print(&self, ctx: &Context) {
|
fn unparse_print(&self, ctx: &Context) {
|
||||||
self.unparse_to(ctx, &mut io::stdout());
|
self.unparse_to(ctx, &mut stdout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ fn append_unicode_range<R: Rand>(
|
|||||||
let a = u32::from_le_bytes(chr_a_buf);
|
let a = u32::from_le_bytes(chr_a_buf);
|
||||||
let b = u32::from_le_bytes(chr_b_buf);
|
let b = u32::from_le_bytes(chr_b_buf);
|
||||||
let c = scr.get_range(rand, a as usize, (b + 1) as usize) as u32;
|
let c = scr.get_range(rand, a as usize, (b + 1) as usize) as u32;
|
||||||
append_char(res, std::char::from_u32(c).unwrap());
|
append_char(res, core::char::from_u32(c).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_byte_range<R: Rand>(
|
fn append_byte_range<R: Rand>(
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use std::{
|
use alloc::{sync::Arc, vec::Vec};
|
||||||
|
use core::{
|
||||||
fmt::{Debug, Display},
|
fmt::{Debug, Display},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
slice,
|
slice,
|
||||||
sync::Arc,
|
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
|
@ -12,12 +12,13 @@
|
|||||||
//! On `Unix` systems, the [`Launcher`] will use `fork` if the `fork` feature is used for `LibAFL`.
|
//! On `Unix` systems, the [`Launcher`] will use `fork` if the `fork` feature is used for `LibAFL`.
|
||||||
//! Else, it will start subsequent nodes with the same commandline, and will set special `env` variables accordingly.
|
//! Else, it will start subsequent nodes with the same commandline, and will set special `env` variables accordingly.
|
||||||
|
|
||||||
|
use alloc::string::String;
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
|
net::SocketAddr,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use std::{net::SocketAddr, string::String};
|
|
||||||
|
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
core_affinity::{CoreId, Cores},
|
core_affinity::{CoreId, Cores},
|
||||||
@ -32,13 +33,13 @@ use {
|
|||||||
events::{CentralizedLlmpHook, StdLlmpEventHook, centralized::CentralizedEventManager},
|
events::{CentralizedLlmpHook, StdLlmpEventHook, centralized::CentralizedEventManager},
|
||||||
inputs::Input,
|
inputs::Input,
|
||||||
},
|
},
|
||||||
|
alloc::boxed::Box,
|
||||||
alloc::string::ToString,
|
alloc::string::ToString,
|
||||||
libafl_bolts::{
|
libafl_bolts::{
|
||||||
core_affinity::get_core_ids,
|
core_affinity::get_core_ids,
|
||||||
llmp::{Broker, Brokers, LlmpBroker},
|
llmp::{Broker, Brokers, LlmpBroker},
|
||||||
os::{ForkResult, fork},
|
os::{ForkResult, fork},
|
||||||
},
|
},
|
||||||
std::boxed::Box,
|
|
||||||
};
|
};
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use {
|
use {
|
||||||
|
@ -8,11 +8,11 @@ use alloc::string::ToString;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{
|
use core::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
net::SocketAddr,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
sync::atomic::{Ordering, compiler_fence},
|
sync::atomic::{Ordering, compiler_fence},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use std::net::SocketAddr;
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
|
|
||||||
|
@ -1,16 +1,10 @@
|
|||||||
use core::fmt::Display;
|
use alloc::{boxed::Box, sync::Arc, vec::Vec};
|
||||||
use std::{
|
use core::{
|
||||||
boxed::Box,
|
fmt::Display,
|
||||||
collections::HashMap,
|
sync::atomic::{AtomicU64, Ordering},
|
||||||
io::ErrorKind,
|
|
||||||
process,
|
|
||||||
sync::{
|
|
||||||
Arc, OnceLock,
|
|
||||||
atomic::{AtomicU64, Ordering},
|
|
||||||
},
|
|
||||||
time::Duration,
|
time::Duration,
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
|
use std::{collections::HashMap, io::ErrorKind, process, sync::OnceLock};
|
||||||
|
|
||||||
use enumflags2::{BitFlags, bitflags};
|
use enumflags2::{BitFlags, bitflags};
|
||||||
#[cfg(feature = "llmp_compression")]
|
#[cfg(feature = "llmp_compression")]
|
||||||
@ -407,9 +401,9 @@ where
|
|||||||
|
|
||||||
/// Write an [`OwnedTcpMultiMachineMsg`] to a stream.
|
/// Write an [`OwnedTcpMultiMachineMsg`] to a stream.
|
||||||
/// Can be read back using [`TcpMultiMachineState::read_msg`].
|
/// Can be read back using [`TcpMultiMachineState::read_msg`].
|
||||||
async fn write_msg<'a, I: Input>(
|
async fn write_msg<I: Input>(
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
msg: &MultiMachineMsg<'a, I>,
|
msg: &MultiMachineMsg<'_, I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let serialized_msg = msg.serialize_as_ref();
|
let serialized_msg = msg.serialize_as_ref();
|
||||||
let msg_len = u32::to_le_bytes(serialized_msg.len() as u32);
|
let msg_len = u32::to_le_bytes(serialized_msg.len() as u32);
|
||||||
@ -451,9 +445,9 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn send_interesting_event_to_nodes<'a, I: Input>(
|
pub(crate) async fn send_interesting_event_to_nodes<I: Input>(
|
||||||
&mut self,
|
&mut self,
|
||||||
msg: &MultiMachineMsg<'a, I>,
|
msg: &MultiMachineMsg<'_, I>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
log::debug!("Sending interesting events to nodes...");
|
log::debug!("Sending interesting events to nodes...");
|
||||||
|
|
||||||
@ -503,9 +497,9 @@ where
|
|||||||
|
|
||||||
/// Flush the message queue from other nodes and add incoming events to the
|
/// Flush the message queue from other nodes and add incoming events to the
|
||||||
/// centralized event manager queue.
|
/// centralized event manager queue.
|
||||||
pub(crate) async fn receive_new_messages_from_nodes<'a, I: Input>(
|
pub(crate) async fn receive_new_messages_from_nodes<I: Input>(
|
||||||
&mut self,
|
&mut self,
|
||||||
msgs: &mut Vec<MultiMachineMsg<'a, I>>,
|
msgs: &mut Vec<MultiMachineMsg<'_, I>>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
log::debug!("Checking for new events from other nodes...");
|
log::debug!("Checking for new events from other nodes...");
|
||||||
// let mut nb_received = 0usize;
|
// let mut nb_received = 0usize;
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//! TCP-backed event manager for scalable multi-processed fuzzing
|
//! TCP-backed event manager for scalable multi-processed fuzzing
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::{sync::Arc, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
|
net::SocketAddr,
|
||||||
num::NonZeroUsize,
|
num::NonZeroUsize,
|
||||||
sync::atomic::{Ordering, compiler_fence},
|
sync::atomic::{Ordering, compiler_fence},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
@ -10,8 +11,7 @@ use core::{
|
|||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
io::{ErrorKind, Read, Write},
|
io::{ErrorKind, Read, Write},
|
||||||
net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs},
|
net::{TcpListener, TcpStream, ToSocketAddrs},
|
||||||
sync::Arc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "tcp_compression")]
|
#[cfg(feature = "tcp_compression")]
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
//! The command executor executes a sub program for each run
|
//! The command executor executes a sub program for each run
|
||||||
|
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
||||||
|
use alloc::ffi::CString;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
||||||
|
use core::ffi::CStr;
|
||||||
use core::{
|
use core::{
|
||||||
fmt::{self, Debug, Formatter},
|
fmt::{self, Debug, Formatter},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
ops::IndexMut,
|
ops::IndexMut,
|
||||||
|
time::Duration,
|
||||||
};
|
};
|
||||||
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
||||||
use std::{
|
use std::os::fd::AsRawFd;
|
||||||
ffi::{CStr, CString},
|
|
||||||
os::fd::AsRawFd,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
ffi::{OsStr, OsString},
|
ffi::{OsStr, OsString},
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
os::unix::ffi::OsStrExt,
|
os::unix::ffi::OsStrExt,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::{Child, Command, Stdio},
|
process::{Child, Command, Stdio},
|
||||||
time::Duration,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
#[cfg(all(feature = "intel_pt", target_os = "linux"))]
|
||||||
|
@ -464,7 +464,7 @@ impl InProcessExecutorHandlerData {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Ok(bsod) = bsod {
|
if let Ok(bsod) = bsod {
|
||||||
if let Ok(r) = std::str::from_utf8(&bsod) {
|
if let Ok(r) = core::str::from_utf8(&bsod) {
|
||||||
log::error!("{}", r);
|
log::error!("{}", r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ pub mod unix_signal_handler {
|
|||||||
}
|
}
|
||||||
let _ = writer.flush();
|
let _ = writer.flush();
|
||||||
}
|
}
|
||||||
if let Ok(r) = std::str::from_utf8(&bsod) {
|
if let Ok(r) = core::str::from_utf8(&bsod) {
|
||||||
log::error!("{}", r);
|
log::error!("{}", r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@ pub mod unix_signal_handler {
|
|||||||
}
|
}
|
||||||
let _ = writer.flush();
|
let _ = writer.flush();
|
||||||
}
|
}
|
||||||
if let Ok(r) = std::str::from_utf8(&bsod) {
|
if let Ok(r) = core::str::from_utf8(&bsod) {
|
||||||
log::error!("{}", r);
|
log::error!("{}", r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
//! Feedback that captures Timeouts for re-running
|
//! Feedback that captures Timeouts for re-running
|
||||||
use std::{borrow::Cow, cell::RefCell, fmt::Debug, rc::Rc};
|
use alloc::{borrow::Cow, rc::Rc};
|
||||||
|
use core::{cell::RefCell, fmt::Debug};
|
||||||
|
|
||||||
use libafl_bolts::{Error, Named};
|
use libafl_bolts::{Error, Named};
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
|
@ -25,7 +25,7 @@ pub struct NautilusChunksMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusChunksMetadata {
|
impl Debug for NautilusChunksMetadata {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"NautilusChunksMetadata {{ {} }}",
|
"NautilusChunksMetadata {{ {} }}",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! The [`NewHashFeedback`] uses the backtrace hash and a hashset to only keep novel cases
|
//! The [`NewHashFeedback`] uses the backtrace hash and a hashset to only keep novel cases
|
||||||
|
|
||||||
use alloc::{borrow::Cow, string::ToString};
|
use alloc::{borrow::Cow, string::ToString};
|
||||||
use std::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use libafl_bolts::{
|
use libafl_bolts::{
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
//! The `Fuzzer` is the main struct for a fuzz campaign.
|
//! The `Fuzzer` is the main struct for a fuzz campaign.
|
||||||
|
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
use core::{fmt::Debug, time::Duration};
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::hash::Hash;
|
use core::hash::Hash;
|
||||||
|
use core::{fmt::Debug, time::Duration};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use fastbloom::BloomFilter;
|
use fastbloom::BloomFilter;
|
||||||
|
@ -21,7 +21,7 @@ pub struct NautilusContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusContext {
|
impl Debug for NautilusContext {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "NautilusContext {{}}",)
|
write!(f, "NautilusContext {{}}",)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ pub struct NautilusGenerator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusGenerator<'_> {
|
impl Debug for NautilusGenerator<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "NautilusGenerator {{}}",)
|
write!(f, "NautilusGenerator {{}}",)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//! An input composed of multiple parts identified by a key.
|
//! An input composed of multiple parts identified by a key.
|
||||||
|
|
||||||
use alloc::{fmt::Debug, string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
use core::hash::Hash;
|
use core::{fmt::Debug, hash::Hash};
|
||||||
|
|
||||||
use serde::{Serialize, de::DeserializeOwned};
|
use serde::{Serialize, de::DeserializeOwned};
|
||||||
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
//! Input for the [`Nautilus`](https://github.com/RUB-SysSec/nautilus) grammar fuzzer methods
|
//! Input for the [`Nautilus`](https://github.com/RUB-SysSec/nautilus) grammar fuzzer methods
|
||||||
use alloc::{rc::Rc, vec::Vec};
|
use alloc::{rc::Rc, vec::Vec};
|
||||||
use core::cell::RefCell;
|
use core::{
|
||||||
use std::hash::{Hash, Hasher};
|
cell::RefCell,
|
||||||
|
hash::{Hash, Hasher},
|
||||||
|
};
|
||||||
|
|
||||||
use libafl_bolts::{HasLen, ownedref::OwnedSlice};
|
use libafl_bolts::{HasLen, ownedref::OwnedSlice};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -138,8 +138,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use {
|
use {
|
||||||
super::ValueInput, crate::mutators::numeric::Numeric, alloc::fmt::Debug,
|
super::ValueInput, crate::mutators::numeric::Numeric, core::any::type_name,
|
||||||
std::any::type_name,
|
core::fmt::Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -29,10 +29,13 @@ pub mod prometheus;
|
|||||||
#[cfg(feature = "statsd_monitor")]
|
#[cfg(feature = "statsd_monitor")]
|
||||||
pub mod statsd;
|
pub mod statsd;
|
||||||
|
|
||||||
use alloc::fmt::Debug;
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{fmt, fmt::Write, time::Duration};
|
use core::{
|
||||||
|
fmt,
|
||||||
|
fmt::{Debug, Write},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use libafl_bolts::ClientId;
|
use libafl_bolts::ClientId;
|
||||||
#[cfg(feature = "prometheus_monitor")]
|
#[cfg(feature = "prometheus_monitor")]
|
||||||
|
@ -27,13 +27,18 @@
|
|||||||
//!
|
//!
|
||||||
//! When using docker, you may need to point `prometheus.yml` to the `docker0` interface or `host.docker.internal`
|
//! When using docker, you may need to point `prometheus.yml` to the `docker0` interface or `host.docker.internal`
|
||||||
|
|
||||||
use alloc::{borrow::Cow, fmt::Debug, string::String};
|
use alloc::{
|
||||||
use core::{fmt, fmt::Write, time::Duration};
|
borrow::Cow,
|
||||||
use std::{
|
string::{String, ToString},
|
||||||
string::ToString,
|
sync::Arc,
|
||||||
sync::{Arc, atomic::AtomicU64},
|
|
||||||
thread,
|
|
||||||
};
|
};
|
||||||
|
use core::{
|
||||||
|
fmt,
|
||||||
|
fmt::{Debug, Write},
|
||||||
|
sync::atomic::AtomicU64,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
// using thread in order to start the HTTP server in a separate thread
|
// using thread in order to start the HTTP server in a separate thread
|
||||||
use futures::executor::block_on;
|
use futures::executor::block_on;
|
||||||
|
@ -2,17 +2,21 @@
|
|||||||
//!
|
//!
|
||||||
//! It's based on [ratatui](https://ratatui.rs/)
|
//! It's based on [ratatui](https://ratatui.rs/)
|
||||||
|
|
||||||
use alloc::{borrow::Cow, boxed::Box, string::ToString};
|
use alloc::{
|
||||||
use std::{
|
borrow::Cow,
|
||||||
|
boxed::Box,
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
fmt::Write as _,
|
string::{String, ToString},
|
||||||
|
sync::Arc,
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
use core::{fmt::Write as _, time::Duration};
|
||||||
|
use std::{
|
||||||
io::{self, BufRead, Write},
|
io::{self, BufRead, Write},
|
||||||
panic,
|
panic,
|
||||||
string::String,
|
sync::RwLock,
|
||||||
sync::{Arc, RwLock},
|
|
||||||
thread,
|
thread,
|
||||||
time::{Duration, Instant},
|
time::Instant,
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
//! The UI-specific parts of [`super::TuiMonitor`]
|
//! The UI-specific parts of [`super::TuiMonitor`]
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, sync::Arc, vec::Vec};
|
||||||
use std::{
|
use core::cmp::{max, min};
|
||||||
cmp::{max, min},
|
use std::sync::RwLock;
|
||||||
sync::{Arc, RwLock},
|
|
||||||
};
|
|
||||||
|
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
Frame,
|
Frame,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! A wrapper around a [`Mutator`] that ensures an input really changed [`MutationResult::Mutated`]
|
//! A wrapper around a [`Mutator`] that ensures an input really changed [`MutationResult::Mutated`]
|
||||||
//! by hashing pre- and post-mutation
|
//! by hashing pre- and post-mutation
|
||||||
use std::{borrow::Cow, hash::Hash};
|
use alloc::borrow::Cow;
|
||||||
|
use core::hash::Hash;
|
||||||
|
|
||||||
use libafl_bolts::{Error, Named, generic_hash_std};
|
use libafl_bolts::{Error, Named, generic_hash_std};
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ pub struct NautilusRandomMutator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusRandomMutator<'_> {
|
impl Debug for NautilusRandomMutator<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "NautilusRandomMutator {{}}")
|
write!(f, "NautilusRandomMutator {{}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ pub struct NautilusRecursionMutator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusRecursionMutator<'_> {
|
impl Debug for NautilusRecursionMutator<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "NautilusRecursionMutator {{}}")
|
write!(f, "NautilusRecursionMutator {{}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ pub struct NautilusSpliceMutator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for NautilusSpliceMutator<'_> {
|
impl Debug for NautilusSpliceMutator<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "NautilusSpliceMutator {{}}")
|
write!(f, "NautilusSpliceMutator {{}}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2130,7 +2130,7 @@ token2="B"
|
|||||||
let taint_len = 0;
|
let taint_len = 0;
|
||||||
let input_len = 0;
|
let input_len = 0;
|
||||||
let hshape = 0;
|
let hshape = 0;
|
||||||
let mut vec = std::vec::Vec::new();
|
let mut vec = alloc::vec::Vec::new();
|
||||||
|
|
||||||
let _res = rq.cmp_extend_encoding(
|
let _res = rq.cmp_extend_encoding(
|
||||||
pattern,
|
pattern,
|
||||||
|
@ -16,7 +16,7 @@ impl ConcolicMetadata {
|
|||||||
/// Iterates over all messages in the buffer. Does not consume the buffer.
|
/// Iterates over all messages in the buffer. Does not consume the buffer.
|
||||||
pub fn iter_messages(&self) -> impl Iterator<Item = (SymExprRef, SymExpr)> + '_ {
|
pub fn iter_messages(&self) -> impl Iterator<Item = (SymExprRef, SymExpr)> + '_ {
|
||||||
let mut parser = MessageFileReader::from_buffer(&self.buffer);
|
let mut parser = MessageFileReader::from_buffer(&self.buffer);
|
||||||
std::iter::from_fn(move || parser.next_message()).flatten()
|
core::iter::from_fn(move || parser.next_message()).flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_buffer(buffer: Vec<u8>) -> Self {
|
pub(crate) fn from_buffer(buffer: Vec<u8>) -> Self {
|
||||||
|
@ -42,10 +42,8 @@
|
|||||||
//!
|
//!
|
||||||
//! ... making for a total of 5 bytes.
|
//! ... making for a total of 5 bytes.
|
||||||
|
|
||||||
use std::{
|
use core::fmt::{self, Debug, Formatter};
|
||||||
fmt::{self, Debug, Formatter},
|
use std::io::{self, Cursor, Read, Seek, SeekFrom, Write};
|
||||||
io::{self, Cursor, Read, Seek, SeekFrom, Write},
|
|
||||||
};
|
|
||||||
|
|
||||||
use bincode::{DefaultOptions, Options};
|
use bincode::{DefaultOptions, Options};
|
||||||
pub use bincode::{ErrorKind, Result};
|
pub use bincode::{ErrorKind, Result};
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
//! the ``StacktraceObserver`` looks up the stacktrace on the execution thread and computes a hash for it for dedupe
|
//! the ``StacktraceObserver`` looks up the stacktrace on the execution thread and computes a hash for it for dedupe
|
||||||
|
|
||||||
use alloc::{borrow::Cow, string::String, vec::Vec};
|
|
||||||
#[cfg(feature = "casr")]
|
#[cfg(feature = "casr")]
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use alloc::{borrow::Cow, string::String, vec::Vec};
|
||||||
|
use core::fmt::Debug;
|
||||||
|
#[cfg(feature = "casr")]
|
||||||
|
use core::hash::{Hash, Hasher};
|
||||||
|
#[cfg(feature = "casr")]
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map::DefaultHasher,
|
|
||||||
hash::{Hash, Hasher},
|
|
||||||
string::ToString,
|
|
||||||
};
|
|
||||||
use std::{
|
|
||||||
fmt::Debug,
|
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::Read,
|
io::Read,
|
||||||
path::Path,
|
path::Path,
|
||||||
|
@ -7,9 +7,8 @@
|
|||||||
doc = r"For example, they are supported on the [`crate::executors::CommandExecutor`]."
|
doc = r"For example, they are supported on the [`crate::executors::CommandExecutor`]."
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use alloc::borrow::Cow;
|
use alloc::{borrow::Cow, vec::Vec};
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
use libafl_bolts::Named;
|
use libafl_bolts::Named;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
//! Stage to compute and report AFL++ stats
|
//! Stage to compute and report AFL++ stats
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{borrow::Cow, string::String, vec::Vec};
|
||||||
use core::{marker::PhantomData, time::Duration};
|
use core::{fmt::Display, marker::PhantomData, time::Duration};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
|
||||||
fmt::Display,
|
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
io::{BufRead, BufReader, Write},
|
io::{BufRead, BufReader, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
@ -563,7 +561,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for AFLPlotData<'_> {
|
impl Display for AFLPlotData<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
write!(f, "{},", self.relative_time)?;
|
write!(f, "{},", self.relative_time)?;
|
||||||
write!(f, "{},", self.cycles_done)?;
|
write!(f, "{},", self.cycles_done)?;
|
||||||
write!(f, "{},", self.cur_item)?;
|
write!(f, "{},", self.cur_item)?;
|
||||||
@ -586,7 +584,7 @@ impl AFLPlotData<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Display for AFLFuzzerStats<'_> {
|
impl Display for AFLFuzzerStats<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
writeln!(f, "start_time : {}", &self.start_time)?;
|
writeln!(f, "start_time : {}", &self.start_time)?;
|
||||||
writeln!(f, "start_time : {}", &self.start_time)?;
|
writeln!(f, "start_time : {}", &self.start_time)?;
|
||||||
writeln!(f, "last_update : {}", &self.last_update)?;
|
writeln!(f, "last_update : {}", &self.last_update)?;
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
//! The [`DumpToDiskStage`] is a stage that dumps the corpus and the solutions to disk to e.g. allow AFL to sync
|
//! The [`DumpToDiskStage`] is a stage that dumps the corpus and the solutions to disk to e.g. allow AFL to sync
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::{
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
use core::{clone::Clone, marker::PhantomData};
|
use core::{clone::Clone, marker::PhantomData};
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::Write,
|
io::Write,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
string::{String, ToString},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use libafl_bolts::impl_serdeany;
|
use libafl_bolts::impl_serdeany;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
//! Stage that wraps another stage and tracks it's execution time in `State`
|
//! Stage that wraps another stage and tracks it's execution time in `State`
|
||||||
use std::{marker::PhantomData, time::Duration};
|
use core::{marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
use libafl_bolts::{Error, current_time};
|
use libafl_bolts::{Error, current_time};
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
//! Note: To capture the timeouts, use in conjunction with `CaptureTimeoutFeedback`
|
//! Note: To capture the timeouts, use in conjunction with `CaptureTimeoutFeedback`
|
||||||
//! Note: Will NOT work with in process executors due to the potential for restarts/crashes when
|
//! Note: Will NOT work with in process executors due to the potential for restarts/crashes when
|
||||||
//! running inputs.
|
//! running inputs.
|
||||||
use core::time::Duration;
|
use alloc::{collections::VecDeque, rc::Rc};
|
||||||
use std::{cell::RefCell, collections::VecDeque, fmt::Debug, marker::PhantomData, rc::Rc};
|
use core::{cell::RefCell, fmt::Debug, marker::PhantomData, time::Duration};
|
||||||
|
|
||||||
use libafl_bolts::Error;
|
use libafl_bolts::Error;
|
||||||
use serde::{Deserialize, Serialize, de::DeserializeOwned};
|
use serde::{Deserialize, Serialize, de::DeserializeOwned};
|
||||||
|
@ -3,11 +3,13 @@ This shows how llmp can be used directly, without libafl abstractions
|
|||||||
*/
|
*/
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
||||||
|
use core::num::NonZeroUsize;
|
||||||
#[cfg(not(target_os = "haiku"))]
|
#[cfg(not(target_os = "haiku"))]
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
use std::marker::PhantomData;
|
|
||||||
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
||||||
use std::{num::NonZeroUsize, thread, time};
|
use std::{thread, time};
|
||||||
|
|
||||||
use libafl_bolts::llmp::{LlmpBrokerInner, LlmpMsgHookResult};
|
use libafl_bolts::llmp::{LlmpBrokerInner, LlmpMsgHookResult};
|
||||||
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
||||||
@ -37,7 +39,7 @@ const SLEEP_BETWEEN_FORWARDS: Duration = Duration::from_millis(5);
|
|||||||
static LOGGER: SimpleStderrLogger = SimpleStderrLogger::new();
|
static LOGGER: SimpleStderrLogger = SimpleStderrLogger::new();
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
||||||
fn adder_loop(port: u16) -> Result<(), Box<dyn std::error::Error>> {
|
fn adder_loop(port: u16) -> Result<(), Box<dyn core::error::Error>> {
|
||||||
let shmem_provider = StdShMemProvider::new()?;
|
let shmem_provider = StdShMemProvider::new()?;
|
||||||
let mut client = llmp::LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
let mut client = llmp::LlmpClient::create_attach_to_tcp(shmem_provider, port)?;
|
||||||
let mut last_result: u32 = 0;
|
let mut last_result: u32 = 0;
|
||||||
@ -75,7 +77,7 @@ fn adder_loop(port: u16) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(feature = "std", not(target_os = "haiku")))]
|
||||||
fn large_msg_loop(port: u16) -> Result<(), Box<dyn std::error::Error>> {
|
fn large_msg_loop(port: u16) -> Result<(), Box<dyn core::error::Error>> {
|
||||||
let mut client = llmp::LlmpClient::create_attach_to_tcp(StdShMemProvider::new()?, port)?;
|
let mut client = llmp::LlmpClient::create_attach_to_tcp(StdShMemProvider::new()?, port)?;
|
||||||
|
|
||||||
#[cfg(not(target_vendor = "apple"))]
|
#[cfg(not(target_vendor = "apple"))]
|
||||||
@ -165,7 +167,7 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "haiku"))]
|
#[cfg(not(target_os = "haiku"))]
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn core::error::Error>> {
|
||||||
/* The main node has a broker, and a few worker threads */
|
/* The main node has a broker, and a few worker threads */
|
||||||
|
|
||||||
use libafl_bolts::llmp::Broker;
|
use libafl_bolts::llmp::Broker;
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
//! Based on <https://github.com/alecmocatta/build_id>
|
//! Based on <https://github.com/alecmocatta/build_id>
|
||||||
//! (C) Alec Mocatta <alec@mocatta.net> under license MIT or Apache 2
|
//! (C) Alec Mocatta <alec@mocatta.net> under license MIT or Apache 2
|
||||||
|
|
||||||
use std::{
|
use core::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
env,
|
|
||||||
fs::File,
|
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
io,
|
|
||||||
sync::OnceLock,
|
|
||||||
};
|
};
|
||||||
|
use std::{env, fs::File, io, sync::OnceLock};
|
||||||
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -64,9 +64,10 @@
|
|||||||
#[cfg(feature = "frida_cli")]
|
#[cfg(feature = "frida_cli")]
|
||||||
use alloc::{boxed::Box, string::ToString};
|
use alloc::{boxed::Box, string::ToString};
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
|
use core::{net::SocketAddr, time::Duration};
|
||||||
#[cfg(feature = "frida_cli")]
|
#[cfg(feature = "frida_cli")]
|
||||||
use std::error;
|
use std::error;
|
||||||
use std::{net::SocketAddr, path::PathBuf, time::Duration};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[cfg(feature = "frida_cli")]
|
#[cfg(feature = "frida_cli")]
|
||||||
use clap::ValueEnum;
|
use clap::ValueEnum;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
//! `LibAFL` functionality for filesystem interaction
|
//! `LibAFL` functionality for filesystem interaction
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::{borrow::ToOwned, vec::Vec};
|
use alloc::{borrow::ToOwned, vec::Vec};
|
||||||
|
use alloc::{rc::Rc, string::String};
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
@ -14,7 +14,6 @@ use std::{
|
|||||||
fs::{self, File, OpenOptions, remove_file},
|
fs::{self, File, OpenOptions, remove_file},
|
||||||
io::{Seek, Write},
|
io::{Seek, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
string::String,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
@ -145,13 +145,14 @@ use alloc::{borrow::Cow, vec::Vec};
|
|||||||
use core::hash::BuildHasher;
|
use core::hash::BuildHasher;
|
||||||
#[cfg(any(feature = "xxh3", feature = "alloc"))]
|
#[cfg(any(feature = "xxh3", feature = "alloc"))]
|
||||||
use core::hash::{Hash, Hasher};
|
use core::hash::{Hash, Hasher};
|
||||||
|
#[cfg(all(unix, feature = "std"))]
|
||||||
|
use core::mem;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{Write, stderr, stdout},
|
io::{Write, stderr, stdout},
|
||||||
mem,
|
|
||||||
os::fd::{AsRawFd, FromRawFd, RawFd},
|
os::fd::{AsRawFd, FromRawFd, RawFd},
|
||||||
panic,
|
panic,
|
||||||
};
|
};
|
||||||
|
@ -57,9 +57,13 @@ Check out the `llmp_test` example in ./examples, or build it with `cargo run --e
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use alloc::boxed::Box;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::string::ToString;
|
use alloc::string::ToString;
|
||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{string::String, vec::Vec};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use core::net::SocketAddr;
|
||||||
#[cfg(not(target_pointer_width = "64"))]
|
#[cfg(not(target_pointer_width = "64"))]
|
||||||
use core::sync::atomic::AtomicU32;
|
use core::sync::atomic::AtomicU32;
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
@ -77,10 +81,9 @@ use core::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::{
|
use std::{
|
||||||
boxed::Box,
|
|
||||||
env,
|
env,
|
||||||
io::{ErrorKind, Read, Write},
|
io::{ErrorKind, Read, Write},
|
||||||
net::{SocketAddr, TcpListener, TcpStream, ToSocketAddrs},
|
net::{TcpListener, TcpStream, ToSocketAddrs},
|
||||||
sync::mpsc::channel,
|
sync::mpsc::channel,
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
@ -3864,7 +3867,8 @@ impl<SHM, SP> LlmpClient<SHM, SP> {
|
|||||||
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
#[cfg(all(unix, feature = "std", not(target_os = "haiku")))]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use std::{thread::sleep, time::Duration};
|
use core::time::Duration;
|
||||||
|
use std::thread::sleep;
|
||||||
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
//! Implements a mini-bsod generator.
|
//! Implements a mini-bsod generator.
|
||||||
//! It dumps all important registers and prints a stacktrace.
|
//! It dumps all important registers and prints a stacktrace.
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
use alloc::vec::Vec;
|
||||||
#[cfg(any(target_vendor = "apple", target_os = "openbsd"))]
|
#[cfg(any(target_vendor = "apple", target_os = "openbsd"))]
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
#[cfg(unix)]
|
|
||||||
use std::vec::Vec;
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use libc::siginfo_t;
|
use libc::siginfo_t;
|
||||||
@ -999,7 +999,7 @@ fn write_minibsod<W: Write>(writer: &mut BufWriter<W>) -> Result<(), std::io::Er
|
|||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
fn write_minibsod<W: Write>(writer: &mut BufWriter<W>) -> Result<(), std::io::Error> {
|
fn write_minibsod<W: Write>(writer: &mut BufWriter<W>) -> Result<(), std::io::Error> {
|
||||||
let mut ptask = std::mem::MaybeUninit::<mach_port_t>::uninit();
|
let mut ptask = core::mem::MaybeUninit::<mach_port_t>::uninit();
|
||||||
// We start by the lowest virtual address from the userland' standpoint
|
// We start by the lowest virtual address from the userland' standpoint
|
||||||
let mut addr: mach_vm_address_t = 0;
|
let mut addr: mach_vm_address_t = 0;
|
||||||
let mut _cnt: mach_msg_type_number_t = 0;
|
let mut _cnt: mach_msg_type_number_t = 0;
|
||||||
@ -1014,7 +1014,7 @@ fn write_minibsod<W: Write>(writer: &mut BufWriter<W>) -> Result<(), std::io::Er
|
|||||||
let task = unsafe { ptask.assume_init() };
|
let task = unsafe { ptask.assume_init() };
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut pvminfo = std::mem::MaybeUninit::<vm_region_submap_info_64>::uninit();
|
let mut pvminfo = core::mem::MaybeUninit::<vm_region_submap_info_64>::uninit();
|
||||||
_cnt = mach_msg_type_number_t::try_from(
|
_cnt = mach_msg_type_number_t::try_from(
|
||||||
size_of::<vm_region_submap_info_64>() / size_of::<natural_t>(),
|
size_of::<vm_region_submap_info_64>() / size_of::<natural_t>(),
|
||||||
)
|
)
|
||||||
|
@ -15,15 +15,17 @@ pub use unix_signals::CTRL_C_EXIT;
|
|||||||
pub mod pipes;
|
pub mod pipes;
|
||||||
|
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use alloc::borrow::Cow;
|
use alloc::{borrow::Cow, ffi::CString};
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use core::ffi::CStr;
|
use core::ffi::CStr;
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::{env, process::Command};
|
use std::{env, process::Command};
|
||||||
#[cfg(all(unix, feature = "std"))]
|
#[cfg(all(unix, feature = "std"))]
|
||||||
use std::{ffi::CString, os::fd::RawFd};
|
use std::{
|
||||||
#[cfg(all(unix, feature = "std"))]
|
fs::File,
|
||||||
use std::{fs::File, os::fd::AsRawFd, sync::OnceLock};
|
os::fd::{AsRawFd, RawFd},
|
||||||
|
sync::OnceLock,
|
||||||
|
};
|
||||||
|
|
||||||
// Allow a few extra features we need for the whole module
|
// Allow a few extra features we need for the whole module
|
||||||
#[cfg(all(windows, feature = "std"))]
|
#[cfg(all(windows, feature = "std"))]
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
//! Unix `pipe` wrapper for `LibAFL`
|
//! Unix `pipe` wrapper for `LibAFL`
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
use alloc::rc::Rc;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use core::{borrow::Borrow, cell::RefCell};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Borrow,
|
|
||||||
cell::RefCell,
|
|
||||||
io::{self, ErrorKind, Read, Write},
|
io::{self, ErrorKind, Read, Write},
|
||||||
os::{
|
os::{
|
||||||
fd::{AsFd, AsRawFd, OwnedFd},
|
fd::{AsFd, AsRawFd, OwnedFd},
|
||||||
unix::io::RawFd,
|
unix::io::RawFd,
|
||||||
},
|
},
|
||||||
rc::Rc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
@ -5,26 +5,29 @@ Hence, the `unix_shmem_server` keeps track of existing maps, creates new maps fo
|
|||||||
and forwards them over unix domain sockets.
|
and forwards them over unix domain sockets.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use alloc::{
|
||||||
|
rc::{Rc, Weak},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use alloc::{
|
use alloc::{
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
|
cell::RefCell,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
|
marker::PhantomData,
|
||||||
mem::ManuallyDrop,
|
mem::ManuallyDrop,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
};
|
};
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
|
||||||
env,
|
env,
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
marker::PhantomData,
|
|
||||||
os::fd::{AsFd, BorrowedFd},
|
os::fd::{AsFd, BorrowedFd},
|
||||||
rc::{Rc, Weak},
|
sync::{Condvar, Mutex},
|
||||||
sync::{Arc, Condvar, Mutex},
|
|
||||||
thread::JoinHandle,
|
thread::JoinHandle,
|
||||||
};
|
};
|
||||||
#[cfg(all(feature = "std", unix))]
|
#[cfg(all(feature = "std", unix))]
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
//! Signal handling for unix
|
//! Signal handling for unix
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use alloc::ffi::CString;
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
#[cfg(all(target_vendor = "apple", target_arch = "aarch64"))]
|
||||||
@ -13,8 +15,6 @@ use core::{
|
|||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
mem,
|
mem,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use std::ffi::CString;
|
|
||||||
|
|
||||||
/// armv7 `libc` does not feature a `uncontext_t` implementation
|
/// armv7 `libc` does not feature a `uncontext_t` implementation
|
||||||
#[cfg(target_arch = "arm")]
|
#[cfg(target_arch = "arm")]
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
//! Wrappers that abstracts references (or pointers) and owned data accesses.
|
//! Wrappers that abstracts references (or pointers) and owned data accesses.
|
||||||
// The serialization is towards owned, allowing to serialize pointers without troubles.
|
// The serialization is towards owned, allowing to serialize pointers without troubles.
|
||||||
|
|
||||||
use alloc::{
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
boxed::Box,
|
|
||||||
slice::{Iter, IterMut},
|
|
||||||
vec::Vec,
|
|
||||||
};
|
|
||||||
use core::{
|
use core::{
|
||||||
clone::Clone,
|
clone::Clone,
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
ops::{Deref, DerefMut, RangeBounds},
|
ops::{Deref, DerefMut, RangeBounds},
|
||||||
ptr::NonNull,
|
ptr::NonNull,
|
||||||
slice,
|
slice,
|
||||||
slice::SliceIndex,
|
slice::{Iter, IterMut, SliceIndex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
@ -36,10 +36,8 @@ fn random_seed_deterministic() -> u64 {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn random_seed_from_random_state() -> u64 {
|
fn random_seed_from_random_state() -> u64 {
|
||||||
use std::{
|
use core::hash::{BuildHasher, Hasher};
|
||||||
collections::hash_map::RandomState,
|
use std::collections::hash_map::RandomState;
|
||||||
hash::{BuildHasher, Hasher},
|
|
||||||
};
|
|
||||||
RandomState::new().build_hasher().finish()
|
RandomState::new().build_hasher().finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ impl ShMemId {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
alloc::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
core::str::from_utf8(&self.id[..self.null_pos()]).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,12 +1165,11 @@ pub mod unix_shmem {
|
|||||||
/// Module containing `ashmem` shared memory support, commonly used on Android.
|
/// Module containing `ashmem` shared memory support, commonly used on Android.
|
||||||
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "std"))]
|
#[cfg(all(any(target_os = "linux", target_os = "android"), feature = "std"))]
|
||||||
pub mod ashmem {
|
pub mod ashmem {
|
||||||
use alloc::string::ToString;
|
use alloc::{ffi::CString, string::ToString};
|
||||||
use core::{
|
use core::{
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
ptr, slice,
|
ptr, slice,
|
||||||
};
|
};
|
||||||
use std::ffi::CString;
|
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
MAP_SHARED, O_RDWR, PROT_READ, PROT_WRITE, c_uint, c_ulong, c_void, close, ioctl, mmap,
|
MAP_SHARED, O_RDWR, PROT_READ, PROT_WRITE, c_uint, c_ulong, c_void, close, ioctl, mmap,
|
||||||
@ -1386,12 +1385,12 @@ pub mod unix_shmem {
|
|||||||
any(target_os = "linux", target_os = "android", target_os = "freebsd")
|
any(target_os = "linux", target_os = "android", target_os = "freebsd")
|
||||||
))]
|
))]
|
||||||
pub mod memfd {
|
pub mod memfd {
|
||||||
use alloc::string::ToString;
|
use alloc::{ffi::CString, string::ToString};
|
||||||
use core::{
|
use core::{
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
ptr, slice,
|
ptr, slice,
|
||||||
};
|
};
|
||||||
use std::{ffi::CString, os::fd::IntoRawFd};
|
use std::os::fd::IntoRawFd;
|
||||||
|
|
||||||
use libc::{
|
use libc::{
|
||||||
MAP_SHARED, PROT_READ, PROT_WRITE, c_void, close, fstat, ftruncate, mmap, munmap,
|
MAP_SHARED, PROT_READ, PROT_WRITE, c_void, close, fstat, ftruncate, mmap, munmap,
|
||||||
@ -1454,7 +1453,7 @@ pub mod unix_shmem {
|
|||||||
fn shmem_from_id_and_size(id: ShMemId, map_size: usize) -> Result<Self, Error> {
|
fn shmem_from_id_and_size(id: ShMemId, map_size: usize) -> Result<Self, Error> {
|
||||||
let fd = i32::from(id);
|
let fd = i32::from(id);
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut stat = std::mem::zeroed();
|
let mut stat = core::mem::zeroed();
|
||||||
if fstat(fd, &mut stat) == -1 {
|
if fstat(fd, &mut stat) == -1 {
|
||||||
return Err(Error::unknown(
|
return Err(Error::unknown(
|
||||||
"Failed to map the memfd mapping".to_string(),
|
"Failed to map the memfd mapping".to_string(),
|
||||||
@ -1880,11 +1879,11 @@ mod tests {
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
#[cfg_attr(miri, ignore)]
|
#[cfg_attr(miri, ignore)]
|
||||||
fn test_persist_shmem() -> Result<(), Error> {
|
fn test_persist_shmem() -> Result<(), Error> {
|
||||||
|
use alloc::string::ToString;
|
||||||
use core::ffi::CStr;
|
use core::ffi::CStr;
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
string::ToString,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::shmem::{MmapShMemProvider, ShMem as _, ShMemId};
|
use crate::shmem::{MmapShMemProvider, ShMem as _, ShMemId};
|
||||||
|
@ -5,14 +5,15 @@ use core::{
|
|||||||
hash::{BuildHasher, Hasher},
|
hash::{BuildHasher, Hasher},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem::size_of,
|
mem::size_of,
|
||||||
ptr, slice,
|
ptr,
|
||||||
|
ptr::read_volatile,
|
||||||
|
slice,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
env::temp_dir,
|
env::temp_dir,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
ptr::read_volatile,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use ahash::RandomState;
|
use ahash::RandomState;
|
||||||
|
@ -1014,11 +1014,11 @@ mod test {
|
|||||||
fn test_macros() {
|
fn test_macros() {
|
||||||
let mut t = tuple_list!(1, "a");
|
let mut t = tuple_list!(1, "a");
|
||||||
|
|
||||||
tuple_for_each!(f1, std::fmt::Display, t, |x| {
|
tuple_for_each!(f1, core::fmt::Display, t, |x| {
|
||||||
log::info!("{x}");
|
log::info!("{x}");
|
||||||
});
|
});
|
||||||
|
|
||||||
tuple_for_each_mut!(f2, std::fmt::Display, t, |x| {
|
tuple_for_each_mut!(f2, core::fmt::Display, t, |x| {
|
||||||
log::info!("{x}");
|
log::info!("{x}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use core::str;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
target_vendor = "apple",
|
target_vendor = "apple",
|
||||||
feature = "ddg-instr",
|
feature = "ddg-instr",
|
||||||
@ -11,7 +12,7 @@
|
|||||||
feature = "profiling",
|
feature = "profiling",
|
||||||
))]
|
))]
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{env, fs::File, io::Write, path::Path, process::Command, str};
|
use std::{env, fs::File, io::Write, path::Path, process::Command};
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
//! Ar Wrapper from `LibAFL`
|
//! Ar Wrapper from `LibAFL`
|
||||||
// pass to e.g. cmake with -DCMAKE_AR=/path/to/fuzzer/target/release/libafl_ar
|
// pass to e.g. cmake with -DCMAKE_AR=/path/to/fuzzer/target/release/libafl_ar
|
||||||
|
|
||||||
use std::{env, path::PathBuf, str::FromStr};
|
use core::str::FromStr;
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use crate::{Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
use crate::{Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
//! LLVM style control flow graph with information of AFL-style index of the each
|
//! LLVM style control flow graph with information of AFL-style index of the each
|
||||||
//! edges, use together with ``AFLCoverage`` pass having --dump-afl-cfg flag enabled.
|
//! edges, use together with ``AFLCoverage`` pass having --dump-afl-cfg flag enabled.
|
||||||
use std::{
|
|
||||||
collections::{BinaryHeap, HashMap, HashSet},
|
extern crate alloc;
|
||||||
marker::PhantomData,
|
|
||||||
};
|
use alloc::collections::BinaryHeap;
|
||||||
|
use core::marker::PhantomData;
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
//! LLVM compiler Wrapper from `LibAFL`
|
//! LLVM compiler Wrapper from `LibAFL`
|
||||||
|
|
||||||
use std::{
|
use core::{env, str::FromStr};
|
||||||
env,
|
use std::path::{Path, PathBuf};
|
||||||
path::{Path, PathBuf},
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{CompilerWrapper, Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
use crate::{CompilerWrapper, Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for Configuration {
|
impl str::FromStr for Configuration {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(input: &str) -> Result<Configuration, Self::Err> {
|
fn from_str(input: &str) -> Result<Configuration, Self::Err> {
|
||||||
Ok(match input {
|
Ok(match input {
|
||||||
@ -159,8 +159,8 @@ impl std::str::FromStr for Configuration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Configuration {
|
impl core::fmt::Display for Configuration {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Configuration::Default => write!(f, ""),
|
Configuration::Default => write!(f, ""),
|
||||||
Configuration::AddressSanitizer => write!(f, "asan"),
|
Configuration::AddressSanitizer => write!(f, "asan"),
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
//! Libtool Wrapper from `LibAFL`
|
//! Libtool Wrapper from `LibAFL`
|
||||||
// call make passing LIBTOOL=/path/to/target/release/libafl_libtool
|
// call make passing LIBTOOL=/path/to/target/release/libafl_libtool
|
||||||
|
|
||||||
use std::{env, path::PathBuf, str::FromStr};
|
use core::str::FromStr;
|
||||||
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use crate::{Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
use crate::{Error, LIB_EXT, LIB_PREFIX, ToolWrapper};
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use core::cell::RefCell;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
|
||||||
env,
|
env,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::Write,
|
io::Write,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::{
|
use core::{
|
||||||
collections::hash_map::DefaultHasher,
|
|
||||||
hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
|
hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
};
|
};
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
|
||||||
use libafl_bolts::shmem::ShMem;
|
use libafl_bolts::shmem::ShMem;
|
||||||
|
|
||||||
|
@ -189,12 +189,12 @@ macro_rules! impl_nop_runtime_fn {
|
|||||||
// special case for expression_unreachable, because it has a different signature in our runtime trait than in the c interface.
|
// special case for expression_unreachable, because it has a different signature in our runtime trait than in the c interface.
|
||||||
(pub fn expression_unreachable(expressions: *mut RSymExpr, num_elements: usize), $c_name:ident;) => {
|
(pub fn expression_unreachable(expressions: *mut RSymExpr, num_elements: usize), $c_name:ident;) => {
|
||||||
// #[expect(clippy::default_trait_access)]
|
// #[expect(clippy::default_trait_access)]
|
||||||
fn expression_unreachable(&mut self, _exprs: &[RSymExpr]) {std::default::Default::default()}
|
fn expression_unreachable(&mut self, _exprs: &[RSymExpr]) {core::default::Default::default()}
|
||||||
};
|
};
|
||||||
|
|
||||||
(pub fn $name:ident($( $arg:ident : $type:ty ),*$(,)?)$( -> $ret:ty)?, $c_name:ident;) => {
|
(pub fn $name:ident($( $arg:ident : $type:ty ),*$(,)?)$( -> $ret:ty)?, $c_name:ident;) => {
|
||||||
// #[expect(clippy::default_trait_access)]
|
// #[expect(clippy::default_trait_access)]
|
||||||
fn $name(&mut self, $( _ : $type),*)$( -> Option<$ret>)? {std::default::Default::default()}
|
fn $name(&mut self, $( _ : $type),*)$( -> Option<$ret>)? {core::default::Default::default()}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,17 @@
|
|||||||
target_os = "android"
|
target_os = "android"
|
||||||
)
|
)
|
||||||
))]
|
))]
|
||||||
use std::{collections::BTreeMap, ffi::c_void};
|
use alloc::collections::BTreeMap;
|
||||||
|
#[cfg(any(
|
||||||
|
windows,
|
||||||
|
target_os = "linux",
|
||||||
|
target_vendor = "apple",
|
||||||
|
all(
|
||||||
|
any(target_arch = "aarch64", target_arch = "x86_64"),
|
||||||
|
target_os = "android"
|
||||||
|
)
|
||||||
|
))]
|
||||||
|
use core::ffi::c_void;
|
||||||
|
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use frida_gum::{PageProtection, RangeDetails};
|
use frida_gum::{PageProtection, RangeDetails};
|
||||||
@ -183,12 +193,12 @@ impl Allocator {
|
|||||||
panic!("ASAN: Allocation is too large: 0x{size:x}");
|
panic!("ASAN: Allocation is too large: 0x{size:x}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::ptr::null_mut();
|
return core::ptr::null_mut();
|
||||||
}
|
}
|
||||||
let rounded_up_size = self.round_up_to_page(size) + 2 * self.page_size;
|
let rounded_up_size = self.round_up_to_page(size) + 2 * self.page_size;
|
||||||
|
|
||||||
if self.total_allocation_size + rounded_up_size > self.max_total_allocation {
|
if self.total_allocation_size + rounded_up_size > self.max_total_allocation {
|
||||||
return std::ptr::null_mut();
|
return core::ptr::null_mut();
|
||||||
}
|
}
|
||||||
self.total_allocation_size += rounded_up_size;
|
self.total_allocation_size += rounded_up_size;
|
||||||
|
|
||||||
@ -212,7 +222,7 @@ impl Allocator {
|
|||||||
Ok(mapping) => mapping,
|
Ok(mapping) => mapping,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::error!("An error occurred while mapping memory: {err:?}");
|
log::error!("An error occurred while mapping memory: {err:?}");
|
||||||
return std::ptr::null_mut();
|
return core::ptr::null_mut();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.current_mapping_addr += ((rounded_up_size
|
self.current_mapping_addr += ((rounded_up_size
|
||||||
@ -241,7 +251,7 @@ impl Allocator {
|
|||||||
metadata
|
metadata
|
||||||
};
|
};
|
||||||
|
|
||||||
self.largest_allocation = std::cmp::max(self.largest_allocation, metadata.actual_size);
|
self.largest_allocation = core::cmp::max(self.largest_allocation, metadata.actual_size);
|
||||||
// unpoison the shadow memory for the allocation itself
|
// unpoison the shadow memory for the allocation itself
|
||||||
unsafe {
|
unsafe {
|
||||||
Self::unpoison(
|
Self::unpoison(
|
||||||
@ -308,7 +318,7 @@ impl Allocator {
|
|||||||
let new_offset = if hint_base == metadata.address {
|
let new_offset = if hint_base == metadata.address {
|
||||||
(ptr - address).abs()
|
(ptr - address).abs()
|
||||||
} else {
|
} else {
|
||||||
std::cmp::min(offset_to_closest, (ptr - address).abs())
|
core::cmp::min(offset_to_closest, (ptr - address).abs())
|
||||||
};
|
};
|
||||||
if new_offset < offset_to_closest {
|
if new_offset < offset_to_closest {
|
||||||
offset_to_closest = new_offset;
|
offset_to_closest = new_offset;
|
||||||
@ -370,7 +380,7 @@ impl Allocator {
|
|||||||
/// start needs to be a valid address, We need to be able to fill `size / 8` bytes.
|
/// start needs to be a valid address, We need to be able to fill `size / 8` bytes.
|
||||||
unsafe fn unpoison(start: usize, size: usize) {
|
unsafe fn unpoison(start: usize, size: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts_mut(start as *mut u8, size / 8).fill(0xff);
|
core::slice::from_raw_parts_mut(start as *mut u8, size / 8).fill(0xff);
|
||||||
|
|
||||||
let remainder = size % 8;
|
let remainder = size % 8;
|
||||||
if remainder > 0 {
|
if remainder > 0 {
|
||||||
@ -387,7 +397,7 @@ impl Allocator {
|
|||||||
/// start needs to be a valid address, We need to be able to fill `size / 8` bytes.
|
/// start needs to be a valid address, We need to be able to fill `size / 8` bytes.
|
||||||
pub unsafe fn poison(start: usize, size: usize) {
|
pub unsafe fn poison(start: usize, size: usize) {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts_mut(start as *mut u8, size / 8).fill(0x0);
|
core::slice::from_raw_parts_mut(start as *mut u8, size / 8).fill(0x0);
|
||||||
|
|
||||||
let remainder = size % 8;
|
let remainder = size % 8;
|
||||||
if remainder > 0 {
|
if remainder > 0 {
|
||||||
@ -485,7 +495,7 @@ impl Allocator {
|
|||||||
|
|
||||||
let shadow_addr = map_to_shadow!(self, (address as usize));
|
let shadow_addr = map_to_shadow!(self, (address as usize));
|
||||||
let shadow_size = size >> 3;
|
let shadow_size = size >> 3;
|
||||||
let buf = unsafe { std::slice::from_raw_parts_mut(shadow_addr as *mut u8, shadow_size) };
|
let buf = unsafe { core::slice::from_raw_parts_mut(shadow_addr as *mut u8, shadow_size) };
|
||||||
let (prefix, aligned, suffix) = unsafe { buf.align_to::<u128>() };
|
let (prefix, aligned, suffix) = unsafe { buf.align_to::<u128>() };
|
||||||
if !prefix.iter().all(|&x| x == 0xff)
|
if !prefix.iter().all(|&x| x == 0xff)
|
||||||
|| !suffix.iter().all(|&x| x == 0xff)
|
|| !suffix.iter().all(|&x| x == 0xff)
|
||||||
@ -605,7 +615,7 @@ impl Allocator {
|
|||||||
unsafe {
|
unsafe {
|
||||||
println!(
|
println!(
|
||||||
"{:x?}",
|
"{:x?}",
|
||||||
std::slice::from_raw_parts(metadata.address as *const u8, metadata.size)
|
core::slice::from_raw_parts(metadata.address as *const u8, metadata.size)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
panic!("ASAN: Crashing target!");
|
panic!("ASAN: Crashing target!");
|
@ -6,14 +6,14 @@ even if the target would not have crashed under normal conditions.
|
|||||||
this helps finding mem errors early.
|
this helps finding mem errors early.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use core::fmt::{self, Debug, Formatter};
|
use alloc::rc::Rc;
|
||||||
use std::{
|
use core::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
ffi::{c_char, c_void},
|
ffi::{c_char, c_void},
|
||||||
|
fmt::{self, Debug, Formatter},
|
||||||
ptr::write_volatile,
|
ptr::write_volatile,
|
||||||
rc::Rc,
|
|
||||||
sync::{Mutex, MutexGuard},
|
|
||||||
};
|
};
|
||||||
|
use std::sync::{Mutex, MutexGuard};
|
||||||
|
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use dynasmrt::{DynasmApi, DynasmLabelApi, dynasm};
|
use dynasmrt::{DynasmApi, DynasmLabelApi, dynasm};
|
||||||
@ -47,7 +47,7 @@ use crate::utils::{AccessType, operand_details};
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use crate::utils::{instruction_width, writer_register};
|
use crate::utils::{instruction_width, writer_register};
|
||||||
use crate::{
|
use crate::{
|
||||||
alloc::Allocator,
|
allocator::Allocator,
|
||||||
asan::errors::{ASAN_ERRORS, AsanError, AsanErrors, AsanReadWriteError},
|
asan::errors::{ASAN_ERRORS, AsanError, AsanErrors, AsanReadWriteError},
|
||||||
helper::{FridaRuntime, SkipRange},
|
helper::{FridaRuntime, SkipRange},
|
||||||
utils::disas_count,
|
utils::disas_count,
|
||||||
@ -95,7 +95,7 @@ impl Default for AsanInHookGuard {
|
|||||||
/// This is a simple way to prevent reentrancy in the hooks when we don't have TLS.
|
/// This is a simple way to prevent reentrancy in the hooks when we don't have TLS.
|
||||||
/// This is not a perfect solution, as it is global so it orders all threads without TLS.
|
/// This is not a perfect solution, as it is global so it orders all threads without TLS.
|
||||||
/// However, this is a rare situation and should not affect performance significantly.
|
/// However, this is a rare situation and should not affect performance significantly.
|
||||||
use std::sync::atomic::{AtomicU64, Ordering};
|
use core::sync::atomic::{AtomicU64, Ordering};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Lock {
|
struct Lock {
|
||||||
@ -612,7 +612,7 @@ impl AsanRuntime {
|
|||||||
|
|
||||||
static [<$name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
static [<$name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
let _ = [<$name:snake:upper _PTR>].set(unsafe {std::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap();
|
let _ = [<$name:snake:upper _PTR>].set(unsafe {core::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap();
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn [<replacement_ $name>]($($param: $param_type),*) -> $return_type {
|
unsafe extern "C" fn [<replacement_ $name>]($($param: $param_type),*) -> $return_type {
|
||||||
@ -662,7 +662,7 @@ impl AsanRuntime {
|
|||||||
|
|
||||||
static [<$lib_ident:snake:upper _ $name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
static [<$lib_ident:snake:upper _ $name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
let _ = [<$lib_ident:snake:upper _ $name:snake:upper _PTR>].set(unsafe {std::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap();
|
let _ = [<$lib_ident:snake:upper _ $name:snake:upper _PTR>].set(unsafe {core::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap();
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe extern "C" fn [<replacement_ $name>]($($param: $param_type),*) -> $return_type {
|
unsafe extern "C" fn [<replacement_ $name>]($($param: $param_type),*) -> $return_type {
|
||||||
@ -707,7 +707,7 @@ impl AsanRuntime {
|
|||||||
log::warn!("Hooking {} = {:?}", stringify!($name), target_function.0);
|
log::warn!("Hooking {} = {:?}", stringify!($name), target_function.0);
|
||||||
static [<$name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
static [<$name:snake:upper _PTR>]: std::sync::OnceLock<extern "C" fn($($param: $param_type),*) -> $return_type> = std::sync::OnceLock::new();
|
||||||
|
|
||||||
let _ = [<$name:snake:upper _PTR>].set(unsafe {std::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap_or_else(|e| println!("{:?}", e));
|
let _ = [<$name:snake:upper _PTR>].set(unsafe {core::mem::transmute::<*const c_void, extern "C" fn($($param: $param_type),*) -> $return_type>(target_function.0)}).unwrap_or_else(|e| println!("{:?}", e));
|
||||||
|
|
||||||
#[allow(non_snake_case)] // depends on the values the macro is invoked with
|
#[allow(non_snake_case)] // depends on the values the macro is invoked with
|
||||||
#[allow(clippy::redundant_else)]
|
#[allow(clippy::redundant_else)]
|
||||||
@ -1522,7 +1522,7 @@ impl AsanRuntime {
|
|||||||
|
|
||||||
let instructions: Vec<Instruction> = disas_count(
|
let instructions: Vec<Instruction> = disas_count(
|
||||||
&decoder,
|
&decoder,
|
||||||
unsafe { std::slice::from_raw_parts(actual_pc as *mut u8, 24) },
|
unsafe { core::slice::from_raw_parts(actual_pc as *mut u8, 24) },
|
||||||
3,
|
3,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
//! Errors that can be caught by the `libafl_frida` address sanitizer.
|
//! Errors that can be caught by the `libafl_frida` address sanitizer.
|
||||||
|
use alloc::borrow::Cow;
|
||||||
|
use core::{fmt::Debug, marker::PhantomData};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
|
||||||
fmt::Debug,
|
|
||||||
io::Write,
|
io::Write,
|
||||||
marker::PhantomData,
|
|
||||||
sync::{Mutex, MutexGuard},
|
sync::{Mutex, MutexGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -38,7 +37,7 @@ use yaxpeax_x86::amd64::InstDecoder;
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use crate::asan::asan_rt::ASAN_SAVE_REGISTER_NAMES;
|
use crate::asan::asan_rt::ASAN_SAVE_REGISTER_NAMES;
|
||||||
use crate::{
|
use crate::{
|
||||||
alloc::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, utils::disas_count,
|
allocator::AllocationMetadata, asan::asan_rt::ASAN_SAVE_REGISTER_COUNT, utils::disas_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
@ -263,7 +262,7 @@ impl AsanErrors {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let insts = disas_count(
|
let insts = disas_count(
|
||||||
&decoder,
|
&decoder,
|
||||||
unsafe { std::slice::from_raw_parts(start_pc as *mut u8, 15 * 11) },
|
unsafe { core::slice::from_raw_parts(start_pc as *mut u8, 15 * 11) },
|
||||||
11,
|
11,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -534,7 +533,7 @@ impl AsanErrors {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
let insts = disas_count(
|
let insts = disas_count(
|
||||||
&decoder,
|
&decoder,
|
||||||
unsafe { std::slice::from_raw_parts(*start_pc as *mut u8, 15 * 11) },
|
unsafe { core::slice::from_raw_parts(*start_pc as *mut u8, 15 * 11) },
|
||||||
11,
|
11,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//! The allocator hooks for address sanitizer.
|
//! The allocator hooks for address sanitizer.
|
||||||
use std::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
|
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use libc::{c_char, wchar_t};
|
use libc::{c_char, wchar_t};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
alloc::Allocator,
|
allocator::Allocator,
|
||||||
asan::{
|
asan::{
|
||||||
asan_rt::AsanRuntime,
|
asan_rt::AsanRuntime,
|
||||||
errors::{AsanError, AsanErrors},
|
errors::{AsanError, AsanErrors},
|
||||||
@ -21,7 +21,7 @@ unsafe extern "system" {
|
|||||||
fn memset(s: *mut c_void, c: i32, n: usize) -> *mut c_void;
|
fn memset(s: *mut c_void, c: i32, n: usize) -> *mut c_void;
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use winapi::um::memoryapi::VirtualQuery;
|
use winapi::um::memoryapi::VirtualQuery;
|
||||||
@ -2371,7 +2371,7 @@ impl AsanRuntime {
|
|||||||
{
|
{
|
||||||
panic!("ASAN: Crashing target!");
|
panic!("ASAN: Crashing target!");
|
||||||
}
|
}
|
||||||
let mn = std::cmp::min(n, unsafe { strlen(src) } + 1);
|
let mn = core::cmp::min(n, unsafe { strlen(src) } + 1);
|
||||||
if !self.allocator_mut().check_shadow(src as *const c_void, mn)
|
if !self.allocator_mut().check_shadow(src as *const c_void, mn)
|
||||||
&& AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead((
|
&& AsanErrors::get_mut_blocking().report_error(AsanError::BadFuncArgRead((
|
||||||
"strncpy".to_string(),
|
"strncpy".to_string(),
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
//! related to the input.
|
//! related to the input.
|
||||||
//! Read the [`RedQueen`](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/) paper for the general concepts.
|
//! Read the [`RedQueen`](https://www.ndss-symposium.org/ndss-paper/redqueen-fuzzing-with-input-to-state-correspondence/) paper for the general concepts.
|
||||||
|
|
||||||
|
use alloc::rc::Rc;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use core::ffi::c_void;
|
use core::ffi::c_void;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use dynasmrt::dynasm;
|
use dynasmrt::dynasm;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
//! Functionality regarding binary-only coverage collection.
|
//! Functionality regarding binary-only coverage collection.
|
||||||
|
|
||||||
use std::{cell::RefCell, marker::PhantomPinned, pin::Pin, rc::Rc};
|
use alloc::rc::Rc;
|
||||||
|
use core::{cell::RefCell, marker::PhantomPinned, pin::Pin};
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
use dynasmrt::DynasmLabelApi;
|
use dynasmrt::DynasmLabelApi;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
//! Generates `DrCov` traces
|
//! Generates `DrCov` traces
|
||||||
use std::{
|
use alloc::rc::Rc;
|
||||||
hash::{BuildHasher, Hasher},
|
use core::hash::{BuildHasher, Hasher};
|
||||||
path::{Path, PathBuf},
|
use std::path::{Path, PathBuf};
|
||||||
rc::Rc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use ahash::RandomState;
|
use ahash::RandomState;
|
||||||
use frida_gum::ModuleMap;
|
use frida_gum::ModuleMap;
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
use core::fmt::{self, Debug, Formatter};
|
use alloc::rc::Rc;
|
||||||
|
use core::{
|
||||||
|
cell::RefCell,
|
||||||
|
ffi::c_void,
|
||||||
|
fmt::{self, Debug, Formatter},
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
#[cfg(all(windows, not(test)))]
|
#[cfg(all(windows, not(test)))]
|
||||||
use std::process::abort;
|
use std::process::abort;
|
||||||
use std::{cell::RefCell, ffi::c_void, marker::PhantomData, rc::Rc};
|
|
||||||
|
|
||||||
use frida_gum::{
|
use frida_gum::{
|
||||||
Gum, MemoryRange, NativePointer,
|
Gum, MemoryRange, NativePointer,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::{borrow::Cow, cell::RefCell, fmt, rc::Rc};
|
use alloc::{borrow::Cow, rc::Rc};
|
||||||
|
use core::{cell::RefCell, fmt};
|
||||||
|
|
||||||
use libafl::{executors::ExitKind, inputs::HasTargetBytes, observers::Observer};
|
use libafl::{executors::ExitKind, inputs::HasTargetBytes, observers::Observer};
|
||||||
use libafl_bolts::{Error, Named};
|
use libafl_bolts::{Error, Named};
|
||||||
@ -65,7 +66,7 @@ impl<'de, RT> Deserialize<'de> for FridaHelperObserver<'_, RT> {
|
|||||||
{
|
{
|
||||||
struct FridaHelperObserverVisitor<'a, RT> {
|
struct FridaHelperObserverVisitor<'a, RT> {
|
||||||
// marker: std::marker::PhantomData<&'b mut FridaInstrumentationHelper<'a, RT>>,
|
// marker: std::marker::PhantomData<&'b mut FridaInstrumentationHelper<'a, RT>>,
|
||||||
marker: std::marker::PhantomData<&'a RT>,
|
marker: core::marker::PhantomData<&'a RT>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'a, RT> Visitor<'de> for FridaHelperObserverVisitor<'a, RT> {
|
impl<'de, 'a, RT> Visitor<'de> for FridaHelperObserverVisitor<'a, RT> {
|
||||||
@ -90,7 +91,7 @@ impl<'de, RT> Deserialize<'de> for FridaHelperObserver<'_, RT> {
|
|||||||
"FridaHelperObserver",
|
"FridaHelperObserver",
|
||||||
&[], // No fields to deserialize
|
&[], // No fields to deserialize
|
||||||
FridaHelperObserverVisitor {
|
FridaHelperObserverVisitor {
|
||||||
marker: std::marker::PhantomData,
|
marker: core::marker::PhantomData,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use core::fmt::{self, Debug, Formatter};
|
use alloc::rc::Rc;
|
||||||
use std::{
|
use core::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
cell::{Ref, RefCell, RefMut},
|
cell::{Ref, RefCell, RefMut},
|
||||||
ffi::CStr,
|
ffi::CStr,
|
||||||
|
fmt::{self, Debug, Formatter},
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
fs::{self, read_to_string},
|
fs::{self, read_to_string},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
rc::Rc,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use frida_gum::{
|
use frida_gum::{
|
||||||
@ -35,7 +37,7 @@ use crate::cmplog_rt::CmpLogRuntime;
|
|||||||
use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime};
|
use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime};
|
||||||
|
|
||||||
/// The Runtime trait
|
/// The Runtime trait
|
||||||
pub trait FridaRuntime: 'static + Debug + std::any::Any {
|
pub trait FridaRuntime: 'static + Debug + core::any::Any {
|
||||||
/// Initialization
|
/// Initialization
|
||||||
fn init(
|
fn init(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -65,7 +67,7 @@ where
|
|||||||
FR1: Debug,
|
FR1: Debug,
|
||||||
FR2: Debug,
|
FR2: Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
Debug::fmt(&self.if_runtimes, f)?;
|
Debug::fmt(&self.if_runtimes, f)?;
|
||||||
Debug::fmt(&self.else_runtimes, f)?;
|
Debug::fmt(&self.else_runtimes, f)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -202,7 +204,7 @@ impl MatchFirstType for FridaRuntimeVec {
|
|||||||
fn match_first_type<T: 'static>(&self) -> Option<&T> {
|
fn match_first_type<T: 'static>(&self) -> Option<&T> {
|
||||||
for member in &self.0 {
|
for member in &self.0 {
|
||||||
if TypeId::of::<T>() == member.type_id() {
|
if TypeId::of::<T>() == member.type_id() {
|
||||||
let raw = std::ptr::from_ref::<dyn FridaRuntime>(&**member) as *const T;
|
let raw = core::ptr::from_ref::<dyn FridaRuntime>(&**member) as *const T;
|
||||||
return unsafe { raw.as_ref() };
|
return unsafe { raw.as_ref() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -213,7 +215,7 @@ impl MatchFirstType for FridaRuntimeVec {
|
|||||||
fn match_first_type_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
fn match_first_type_mut<T: 'static>(&mut self) -> Option<&mut T> {
|
||||||
for member in &mut self.0 {
|
for member in &mut self.0 {
|
||||||
if TypeId::of::<T>() == member.type_id() {
|
if TypeId::of::<T>() == member.type_id() {
|
||||||
let raw = std::ptr::from_mut::<dyn FridaRuntime>(&mut **member) as *mut T;
|
let raw = core::ptr::from_mut::<dyn FridaRuntime>(&mut **member) as *mut T;
|
||||||
return unsafe { raw.as_mut() };
|
return unsafe { raw.as_mut() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,7 +261,7 @@ impl FridaRuntimeTuple for FridaRuntimeVec {
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub enum SkipRange {
|
pub enum SkipRange {
|
||||||
/// An absolute range
|
/// An absolute range
|
||||||
Absolute(std::ops::Range<usize>),
|
Absolute(core::ops::Range<usize>),
|
||||||
|
|
||||||
/// A range relative to the module with the given name
|
/// A range relative to the module with the given name
|
||||||
ModuleRelative {
|
ModuleRelative {
|
||||||
@ -267,7 +269,7 @@ pub enum SkipRange {
|
|||||||
name: String,
|
name: String,
|
||||||
|
|
||||||
/// The address range
|
/// The address range
|
||||||
range: std::ops::Range<usize>,
|
range: core::ops::Range<usize>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,14 +812,14 @@ where
|
|||||||
for _ in 0..512 {
|
for _ in 0..512 {
|
||||||
mmap_anonymous(
|
mmap_anonymous(
|
||||||
None,
|
None,
|
||||||
std::num::NonZeroUsize::new_unchecked(128 * 1024),
|
core::num::NonZeroUsize::new_unchecked(128 * 1024),
|
||||||
ProtFlags::PROT_NONE,
|
ProtFlags::PROT_NONE,
|
||||||
MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
|
MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
|
||||||
)
|
)
|
||||||
.expect("Failed to map dummy regions for frida workaround");
|
.expect("Failed to map dummy regions for frida workaround");
|
||||||
mmap_anonymous(
|
mmap_anonymous(
|
||||||
None,
|
None,
|
||||||
std::num::NonZeroUsize::new_unchecked(4 * 1024 * 1024),
|
core::num::NonZeroUsize::new_unchecked(4 * 1024 * 1024),
|
||||||
ProtFlags::PROT_NONE,
|
ProtFlags::PROT_NONE,
|
||||||
MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
|
MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
|
||||||
)
|
)
|
||||||
|
@ -43,8 +43,10 @@ Additional documentation is available in [the `LibAFL` book](https://aflplus.plu
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
/// The frida-asan allocator
|
/// The frida-asan allocator
|
||||||
pub mod alloc;
|
pub mod allocator;
|
||||||
|
|
||||||
pub mod asan;
|
pub mod asan;
|
||||||
|
|
||||||
@ -325,8 +327,9 @@ impl Default for FridaOptions {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use core::num::NonZero;
|
use alloc::rc::Rc;
|
||||||
use std::{cell::RefCell, rc::Rc, sync::OnceLock};
|
use core::{cell::RefCell, num::NonZero};
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use frida_gum::Gum;
|
use frida_gum::Gum;
|
||||||
@ -365,180 +368,182 @@ mod tests {
|
|||||||
|
|
||||||
#[expect(clippy::too_many_lines)]
|
#[expect(clippy::too_many_lines)]
|
||||||
unsafe fn test_asan(options: &FuzzerOptions) {
|
unsafe fn test_asan(options: &FuzzerOptions) {
|
||||||
// The names of the functions to run
|
unsafe {
|
||||||
let tests = vec![
|
// The names of the functions to run
|
||||||
("LLVMFuzzerTestOneInput", None),
|
let tests = vec![
|
||||||
("heap_oob_read", Some("heap out-of-bounds read")),
|
("LLVMFuzzerTestOneInput", None),
|
||||||
("heap_oob_write", Some("heap out-of-bounds write")),
|
("heap_oob_read", Some("heap out-of-bounds read")),
|
||||||
("heap_uaf_write", Some("heap use-after-free write")),
|
("heap_oob_write", Some("heap out-of-bounds write")),
|
||||||
("heap_uaf_read", Some("heap use-after-free read")),
|
("heap_uaf_write", Some("heap use-after-free write")),
|
||||||
("malloc_heap_oob_read", Some("heap out-of-bounds read")),
|
("heap_uaf_read", Some("heap use-after-free read")),
|
||||||
("malloc_heap_oob_write", Some("heap out-of-bounds write")),
|
("malloc_heap_oob_read", Some("heap out-of-bounds read")),
|
||||||
(
|
("malloc_heap_oob_write", Some("heap out-of-bounds write")),
|
||||||
"malloc_heap_oob_write_0x12",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x12",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
(
|
),
|
||||||
"malloc_heap_oob_write_0x14",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x14",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
(
|
),
|
||||||
"malloc_heap_oob_write_0x17",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x17",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
(
|
),
|
||||||
"malloc_heap_oob_write_0x17_int_at_0x16",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x17_int_at_0x16",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
(
|
),
|
||||||
"malloc_heap_oob_write_0x17_int_at_0x15",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x17_int_at_0x15",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
("malloc_heap_oob_write_0x17_int_at_0x13", None),
|
),
|
||||||
(
|
("malloc_heap_oob_write_0x17_int_at_0x13", None),
|
||||||
"malloc_heap_oob_write_0x17_int_at_0x14",
|
(
|
||||||
Some("heap out-of-bounds write"),
|
"malloc_heap_oob_write_0x17_int_at_0x14",
|
||||||
),
|
Some("heap out-of-bounds write"),
|
||||||
("malloc_heap_uaf_write", Some("heap use-after-free write")),
|
),
|
||||||
("malloc_heap_uaf_read", Some("heap use-after-free read")),
|
("malloc_heap_uaf_write", Some("heap use-after-free write")),
|
||||||
(
|
("malloc_heap_uaf_read", Some("heap use-after-free read")),
|
||||||
"heap_oob_memcpy_read",
|
(
|
||||||
Some("function arg resulting in bad read"),
|
"heap_oob_memcpy_read",
|
||||||
),
|
Some("function arg resulting in bad read"),
|
||||||
(
|
),
|
||||||
"heap_oob_memcpy_write",
|
(
|
||||||
Some("function arg resulting in bad write"),
|
"heap_oob_memcpy_write",
|
||||||
),
|
Some("function arg resulting in bad write"),
|
||||||
];
|
),
|
||||||
|
];
|
||||||
|
|
||||||
//NOTE: RTLD_NOW is required on linux as otherwise the hooks will NOT work
|
//NOTE: RTLD_NOW is required on linux as otherwise the hooks will NOT work
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
let lib = libloading::os::unix::Library::open(
|
let lib = libloading::os::unix::Library::open(
|
||||||
Some(options.clone().harness.unwrap()),
|
Some(options.clone().harness.unwrap()),
|
||||||
libloading::os::unix::RTLD_NOW,
|
libloading::os::unix::RTLD_NOW,
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
|
||||||
let lib = libloading::Library::new(options.clone().harness.unwrap()).unwrap();
|
|
||||||
|
|
||||||
let coverage = CoverageRuntime::new();
|
|
||||||
let asan = AsanRuntime::new(options);
|
|
||||||
// let mut frida_helper = FridaInstrumentationHelper::new(
|
|
||||||
// GUM.get().expect("Gum uninitialized"),
|
|
||||||
// options,
|
|
||||||
// tuple_list!(coverage, asan),
|
|
||||||
// );
|
|
||||||
let frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
|
|
||||||
GUM.get().expect("Gum uninitialized"),
|
|
||||||
options,
|
|
||||||
tuple_list!(coverage, asan),
|
|
||||||
)));
|
|
||||||
|
|
||||||
// Run the tests for each function
|
|
||||||
for test in tests {
|
|
||||||
let (function_name, expected_error) = test;
|
|
||||||
log::info!("Testing with harness function {}", function_name);
|
|
||||||
|
|
||||||
let mut corpus = InMemoryCorpus::<BytesInput>::new();
|
|
||||||
|
|
||||||
//TODO - make sure we use the right one
|
|
||||||
let testcase = Testcase::new(vec![0; 4].into());
|
|
||||||
corpus.add(testcase).unwrap();
|
|
||||||
|
|
||||||
let rand = StdRand::with_seed(0);
|
|
||||||
|
|
||||||
let mut feedback = ConstFeedback::new(true);
|
|
||||||
|
|
||||||
let asan_obs = AsanErrorsObserver::from_static_asan_errors();
|
|
||||||
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));
|
|
||||||
|
|
||||||
// Feedbacks to recognize an input as solution
|
|
||||||
let mut objective = feedback_or_fast!(
|
|
||||||
// true enables the AsanErrorFeedback
|
|
||||||
feedback_and_fast!(
|
|
||||||
ConstFeedback::from(true),
|
|
||||||
AsanErrorsFeedback::new(&asan_obs)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut state = StdState::new(
|
|
||||||
rand,
|
|
||||||
corpus,
|
|
||||||
InMemoryCorpus::<BytesInput>::new(),
|
|
||||||
&mut feedback,
|
|
||||||
&mut objective,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut event_manager = NopEventManager::new();
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
let lib = libloading::Library::new(options.clone().harness.unwrap()).unwrap();
|
||||||
|
|
||||||
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
|
let coverage = CoverageRuntime::new();
|
||||||
|
let asan = AsanRuntime::new(options);
|
||||||
|
// let mut frida_helper = FridaInstrumentationHelper::new(
|
||||||
|
// GUM.get().expect("Gum uninitialized"),
|
||||||
|
// options,
|
||||||
|
// tuple_list!(coverage, asan),
|
||||||
|
// );
|
||||||
|
let frida_helper = Rc::new(RefCell::new(FridaInstrumentationHelper::new(
|
||||||
|
GUM.get().expect("Gum uninitialized"),
|
||||||
|
options,
|
||||||
|
tuple_list!(coverage, asan),
|
||||||
|
)));
|
||||||
|
|
||||||
let observers = tuple_list!(
|
// Run the tests for each function
|
||||||
frida_helper_observer,
|
for test in tests {
|
||||||
asan_obs //,
|
let (function_name, expected_error) = test;
|
||||||
);
|
log::info!("Testing with harness function {}", function_name);
|
||||||
|
|
||||||
{
|
let mut corpus = InMemoryCorpus::<BytesInput>::new();
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
let target_func: libloading::os::unix::Symbol<
|
|
||||||
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
|
||||||
> = lib.get(function_name.as_bytes()).unwrap();
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
//TODO - make sure we use the right one
|
||||||
let target_func: libloading::Symbol<
|
let testcase = Testcase::new(vec![0; 4].into());
|
||||||
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
corpus.add(testcase).unwrap();
|
||||||
> = lib.get(function_name.as_bytes()).unwrap();
|
|
||||||
|
|
||||||
let mut harness = |input: &BytesInput| {
|
let rand = StdRand::with_seed(0);
|
||||||
let target = input.target_bytes();
|
|
||||||
let buf = target.as_slice();
|
|
||||||
(target_func)(buf.as_ptr(), buf.len());
|
|
||||||
ExitKind::Ok
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut executor = FridaInProcessExecutor::new(
|
let mut feedback = ConstFeedback::new(true);
|
||||||
GUM.get().expect("Gum uninitialized"),
|
|
||||||
InProcessExecutor::new(
|
let asan_obs = AsanErrorsObserver::from_static_asan_errors();
|
||||||
&mut harness,
|
let frida_helper_observer = FridaHelperObserver::new(Rc::clone(&frida_helper));
|
||||||
observers, // tuple_list!(),
|
|
||||||
&mut fuzzer,
|
// Feedbacks to recognize an input as solution
|
||||||
&mut state,
|
let mut objective = feedback_or_fast!(
|
||||||
&mut event_manager,
|
// true enables the AsanErrorFeedback
|
||||||
|
feedback_and_fast!(
|
||||||
|
ConstFeedback::from(true),
|
||||||
|
AsanErrorsFeedback::new(&asan_obs)
|
||||||
)
|
)
|
||||||
.unwrap(),
|
|
||||||
// &mut frida_helper,
|
|
||||||
Rc::clone(&frida_helper),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let mutator = StdScheduledMutator::new(tuple_list!(BitFlipMutator::new()));
|
let mut state = StdState::new(
|
||||||
let mut stages = tuple_list!(StdMutationalStage::with_max_iterations(
|
rand,
|
||||||
mutator,
|
corpus,
|
||||||
NonZero::new(1).unwrap()
|
InMemoryCorpus::<BytesInput>::new(),
|
||||||
));
|
&mut feedback,
|
||||||
|
&mut objective,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
log::info!("Starting fuzzing!");
|
let mut event_manager = NopEventManager::new();
|
||||||
fuzzer
|
|
||||||
.fuzz_one(&mut stages, &mut executor, &mut state, &mut event_manager)
|
|
||||||
.unwrap_or_else(|_| panic!("Error in fuzz_one"));
|
|
||||||
|
|
||||||
log::info!("Done fuzzing! Got {} solutions", state.solutions().count());
|
let mut fuzzer = StdFuzzer::new(StdScheduler::new(), feedback, objective);
|
||||||
if let Some(expected_error) = expected_error {
|
|
||||||
assert_eq!(state.solutions().count(), 1);
|
let observers = tuple_list!(
|
||||||
if let Some(error) = AsanErrors::get_mut_blocking().errors.first() {
|
frida_helper_observer,
|
||||||
assert_eq!(error.description(), expected_error);
|
asan_obs //,
|
||||||
|
);
|
||||||
|
|
||||||
|
{
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let target_func: libloading::os::unix::Symbol<
|
||||||
|
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
||||||
|
> = lib.get(function_name.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
let target_func: libloading::Symbol<
|
||||||
|
unsafe extern "C" fn(data: *const u8, size: usize) -> i32,
|
||||||
|
> = lib.get(function_name.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
let mut harness = |input: &BytesInput| {
|
||||||
|
let target = input.target_bytes();
|
||||||
|
let buf = target.as_slice();
|
||||||
|
(target_func)(buf.as_ptr(), buf.len());
|
||||||
|
ExitKind::Ok
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut executor = FridaInProcessExecutor::new(
|
||||||
|
GUM.get().expect("Gum uninitialized"),
|
||||||
|
InProcessExecutor::new(
|
||||||
|
&mut harness,
|
||||||
|
observers, // tuple_list!(),
|
||||||
|
&mut fuzzer,
|
||||||
|
&mut state,
|
||||||
|
&mut event_manager,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
// &mut frida_helper,
|
||||||
|
Rc::clone(&frida_helper),
|
||||||
|
);
|
||||||
|
|
||||||
|
let mutator = StdScheduledMutator::new(tuple_list!(BitFlipMutator::new()));
|
||||||
|
let mut stages = tuple_list!(StdMutationalStage::with_max_iterations(
|
||||||
|
mutator,
|
||||||
|
NonZero::new(1).unwrap()
|
||||||
|
));
|
||||||
|
|
||||||
|
log::info!("Starting fuzzing!");
|
||||||
|
fuzzer
|
||||||
|
.fuzz_one(&mut stages, &mut executor, &mut state, &mut event_manager)
|
||||||
|
.unwrap_or_else(|_| panic!("Error in fuzz_one"));
|
||||||
|
|
||||||
|
log::info!("Done fuzzing! Got {} solutions", state.solutions().count());
|
||||||
|
if let Some(expected_error) = expected_error {
|
||||||
|
assert_eq!(state.solutions().count(), 1);
|
||||||
|
if let Some(error) = AsanErrors::get_mut_blocking().errors.first() {
|
||||||
|
assert_eq!(error.description(), expected_error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert_eq!(state.solutions().count(), 0);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
assert_eq!(state.solutions().count(), 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
frida_helper
|
frida_helper
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.deinit(GUM.get().expect("Gum uninitialized"));
|
.deinit(GUM.get().expect("Gum uninitialized"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
//! This crate interacts with the linux kernel (specifically with perf) and therefore it only works
|
//! This crate interacts with the linux kernel (specifically with perf) and therefore it only works
|
||||||
//! on linux hosts
|
//! on linux hosts
|
||||||
|
|
||||||
// Just in case this crate will have real no_std support in the future
|
// Just in case this crate will have real `no_std` support in the future
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![cfg(target_arch = "x86_64")]
|
#![cfg(target_arch = "x86_64")]
|
||||||
#![cfg(feature = "std")]
|
#![cfg(feature = "std")]
|
||||||
@ -12,9 +12,11 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate std;
|
extern crate std;
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::{borrow::ToOwned, string::String, vec::Vec};
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::{borrow::ToOwned, string::String, vec::Vec};
|
|
||||||
|
|
||||||
use raw_cpuid::CpuId;
|
use raw_cpuid::CpuId;
|
||||||
|
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
use std::{
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::{
|
||||||
borrow::ToOwned,
|
borrow::ToOwned,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
ffi::{CStr, CString},
|
ffi::CString,
|
||||||
fmt::Debug,
|
format,
|
||||||
format, fs,
|
string::{String, ToString},
|
||||||
ops::RangeInclusive,
|
vec::Vec,
|
||||||
|
};
|
||||||
|
use core::{ffi::CStr, fmt::Debug, ops::RangeInclusive, ptr};
|
||||||
|
use std::{
|
||||||
|
fs,
|
||||||
os::{
|
os::{
|
||||||
fd::{AsRawFd, FromRawFd, OwnedFd},
|
fd::{AsRawFd, FromRawFd, OwnedFd},
|
||||||
raw::c_void,
|
raw::c_void,
|
||||||
},
|
},
|
||||||
path::Path,
|
path::Path,
|
||||||
ptr,
|
|
||||||
string::{String, ToString},
|
|
||||||
sync::LazyLock,
|
sync::LazyLock,
|
||||||
vec::Vec,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use arbitrary_int::u4;
|
use arbitrary_int::u4;
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
#![cfg(feature = "libipt")]
|
#![cfg(feature = "libipt")]
|
||||||
#![cfg(target_os = "linux")]
|
#![cfg(target_os = "linux")]
|
||||||
|
|
||||||
use std::{arch::asm, process};
|
use core::arch::asm;
|
||||||
|
use std::process;
|
||||||
|
|
||||||
use libafl_intelpt::{Image, IntelPT, availability};
|
use libafl_intelpt::{Image, IntelPT, availability};
|
||||||
use nix::{
|
use nix::{
|
||||||
|
@ -7,6 +7,7 @@ readme = "../README.md"
|
|||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
keywords = ["fuzzing", "testing", "security"]
|
keywords = ["fuzzing", "testing", "security"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
rust-version = "1.85"
|
||||||
categories = ["development-tools::testing"]
|
categories = ["development-tools::testing"]
|
||||||
|
|
||||||
include = [
|
include = [
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
use core::error::Error;
|
||||||
use std::{
|
use std::{
|
||||||
error::Error,
|
|
||||||
fs,
|
fs,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{BufRead, BufReader, BufWriter, Write},
|
io::{BufRead, BufReader, BufWriter, Write},
|
||||||
|
@ -95,7 +95,6 @@ pub fn merge(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(clippy::deref_addrof)]
|
|
||||||
let edges = unsafe { core::mem::take(&mut *(counters_maps_ptr_mut())) };
|
let edges = unsafe { core::mem::take(&mut *(counters_maps_ptr_mut())) };
|
||||||
let edges_observer = MultiMapObserver::new("edges", edges);
|
let edges_observer = MultiMapObserver::new("edges", edges);
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@
|
|||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
|
|
||||||
use std::ffi::{c_char, c_int};
|
use core::ffi::{c_char, c_int};
|
||||||
|
|
||||||
pub use libfuzzer_sys::*;
|
pub use libfuzzer_sys::*;
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
//! The Nyx `CmpLog` Observer
|
//! The Nyx `CmpLog` Observer
|
||||||
//!
|
//!
|
||||||
//! Reads and parses the redqueen results written by QEMU-Nyx and adds them to the state as `CmpValuesMetadata`.
|
//! Reads and parses the redqueen results written by QEMU-Nyx and adds them to the state as `CmpValuesMetadata`.
|
||||||
use std::borrow::Cow;
|
|
||||||
|
extern crate alloc;
|
||||||
|
|
||||||
|
use alloc::borrow::Cow;
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
Error, HasMetadata,
|
Error, HasMetadata,
|
||||||
@ -43,7 +46,7 @@ impl NyxCmpObserver {
|
|||||||
impl<I, S> Observer<I, S> for NyxCmpObserver
|
impl<I, S> Observer<I, S> for NyxCmpObserver
|
||||||
where
|
where
|
||||||
S: HasMetadata + HasExecutions,
|
S: HasMetadata + HasExecutions,
|
||||||
I: std::fmt::Debug,
|
I: core::fmt::Debug,
|
||||||
{
|
{
|
||||||
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
fn pre_exec(&mut self, _state: &mut S, _input: &I) -> Result<(), Error> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
use core::marker::PhantomData;
|
||||||
use std::{
|
use std::{
|
||||||
io::{Read, Seek},
|
io::{Read, Seek},
|
||||||
marker::PhantomData,
|
|
||||||
os::fd::AsRawFd,
|
os::fd::AsRawFd,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -135,11 +135,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S, OT> HasTimeout for NyxExecutor<S, OT> {
|
impl<S, OT> HasTimeout for NyxExecutor<S, OT> {
|
||||||
fn timeout(&self) -> std::time::Duration {
|
fn timeout(&self) -> core::time::Duration {
|
||||||
self.helper.timeout
|
self.helper.timeout
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_timeout(&mut self, timeout: std::time::Duration) {
|
fn set_timeout(&mut self, timeout: core::time::Duration) {
|
||||||
let micros = 1000000;
|
let micros = 1000000;
|
||||||
let mut timeout_secs = timeout.as_secs();
|
let mut timeout_secs = timeout.as_secs();
|
||||||
let mut timeout_micros = timeout.as_micros() - u128::from(timeout.as_secs() * micros);
|
let mut timeout_micros = timeout.as_micros() - u128::from(timeout.as_secs() * micros);
|
||||||
@ -163,7 +163,7 @@ impl<S, OT> NyxExecutor<S, OT> {
|
|||||||
/// Mutable borrow may only be used once at a time.
|
/// Mutable borrow may only be used once at a time.
|
||||||
pub unsafe fn trace_bits(self) -> &'static mut [u8] {
|
pub unsafe fn trace_bits(self) -> &'static mut [u8] {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts_mut(self.helper.bitmap_buffer, self.helper.bitmap_size)
|
core::slice::from_raw_parts_mut(self.helper.bitmap_buffer, self.helper.bitmap_size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/// [`NyxHelper`] is used to wrap `NyxProcess`
|
/// [`NyxHelper`] is used to wrap `NyxProcess`
|
||||||
use std::{fmt::Debug, fs::File, path::Path, time::Duration};
|
use core::{fmt::Debug, time::Duration};
|
||||||
|
use std::{fs::File, path::Path};
|
||||||
|
|
||||||
use libafl::Error;
|
use libafl::Error;
|
||||||
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole};
|
use libnyx::{NyxConfig, NyxProcess, NyxProcessRole};
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
use core::str::FromStr;
|
||||||
use std::{
|
use std::{
|
||||||
env, fs,
|
env, fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
str::FromStr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use which::which;
|
use which::which;
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
// #[rustversion::nightly]
|
// #[rustversion::nightly]
|
||||||
// use std::io::{BufRead, BufReader};
|
extern crate alloc;
|
||||||
|
|
||||||
|
use core::hash::Hasher;
|
||||||
use std::{
|
use std::{
|
||||||
collections::hash_map,
|
collections::hash_map,
|
||||||
env,
|
env,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
hash::Hasher,
|
|
||||||
io::{Read, Seek, SeekFrom, Write},
|
io::{Read, Seek, SeekFrom, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
process::Command,
|
process::Command,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,9 +7,9 @@ __Warning__: The documentation is built by default for `x86_64` in `usermode`. T
|
|||||||
|
|
||||||
#![cfg_attr(nightly, feature(used_with_arg))]
|
#![cfg_attr(nightly, feature(used_with_arg))]
|
||||||
|
|
||||||
|
use core::ffi::c_void;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use core::ops::BitAnd;
|
use core::ops::BitAnd;
|
||||||
use std::ffi::c_void;
|
|
||||||
|
|
||||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
#[cfg(feature = "python")]
|
||||||
|
use core::convert::Infallible;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use core::{slice::from_raw_parts, str::from_utf8_unchecked};
|
use core::{slice::from_raw_parts, str::from_utf8_unchecked};
|
||||||
#[cfg(feature = "python")]
|
|
||||||
use std::convert::Infallible;
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use libc::{c_char, strlen};
|
use libc::{c_char, strlen};
|
||||||
|
@ -361,9 +361,7 @@ where
|
|||||||
iaddr += insn.bytes().len() as GuestAddr;
|
iaddr += insn.bytes().len() as GuestAddr;
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
unsafe {
|
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
||||||
code = std::slice::from_raw_parts(qemu.g2h(iaddr), 512);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
if let Err(err) = qemu.read_mem(pc, code) {
|
if let Err(err) = qemu.read_mem(pc, code) {
|
||||||
// TODO handle faults
|
// TODO handle faults
|
||||||
|
@ -346,7 +346,7 @@ impl CmpLogRoutinesModule {
|
|||||||
let mut code = {
|
let mut code = {
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts(qemu.g2h(pc), 512)
|
std::slice::from_raw_parts(qemu.g2h(pc), 512);
|
||||||
}
|
}
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
&mut [0; 512]
|
&mut [0; 512]
|
||||||
@ -389,9 +389,7 @@ impl CmpLogRoutinesModule {
|
|||||||
iaddr += insn.bytes().len() as GuestAddr;
|
iaddr += insn.bytes().len() as GuestAddr;
|
||||||
|
|
||||||
#[cfg(feature = "usermode")]
|
#[cfg(feature = "usermode")]
|
||||||
unsafe {
|
code = unsafe { std::slice::from_raw_parts(qemu.g2h(iaddr), 512) };
|
||||||
code = std::slice::from_raw_parts(qemu.g2h(iaddr), 512);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "systemmode")]
|
#[cfg(feature = "systemmode")]
|
||||||
unsafe {
|
unsafe {
|
||||||
qemu.read_mem(pc, code);
|
qemu.read_mem(pc, code);
|
||||||
|
@ -323,7 +323,7 @@ mod tests {
|
|||||||
use libafl_bolts::tuples::tuple_list;
|
use libafl_bolts::tuples::tuple_list;
|
||||||
|
|
||||||
use crate::modules::{
|
use crate::modules::{
|
||||||
EmulatorModule, EmulatorModuleTuple,
|
EmulatorModule,
|
||||||
utils::filters::{
|
utils::filters::{
|
||||||
AddressFilter, NopAddressFilter, NopPageFilter, PageFilter, StdAddressFilter,
|
AddressFilter, NopAddressFilter, NopPageFilter, PageFilter, StdAddressFilter,
|
||||||
StdPageFilter,
|
StdPageFilter,
|
||||||
|
@ -63,7 +63,7 @@ impl From<DrCovBasicBlockEntry> for [u8; 8] {
|
|||||||
size_of::<[u8; 8]>(),
|
size_of::<[u8; 8]>(),
|
||||||
"`DrCovBasicBlockEntry` size changed!"
|
"`DrCovBasicBlockEntry` size changed!"
|
||||||
);
|
);
|
||||||
unsafe { std::slice::from_raw_parts(ptr::from_ref(&value).cast::<u8>(), 8) }
|
unsafe { core::slice::from_raw_parts(ptr::from_ref(&value).cast::<u8>(), 8) }
|
||||||
.try_into()
|
.try_into()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ impl From<&DrCovBasicBlockEntry> for &[u8] {
|
|||||||
// The value is a c struct.
|
// The value is a c struct.
|
||||||
// Casting its pointer to bytes should be safe.
|
// Casting its pointer to bytes should be safe.
|
||||||
unsafe {
|
unsafe {
|
||||||
std::slice::from_raw_parts(
|
core::slice::from_raw_parts(
|
||||||
ptr::from_ref(value).cast::<u8>(),
|
ptr::from_ref(value).cast::<u8>(),
|
||||||
size_of::<DrCovBasicBlockEntry>(),
|
size_of::<DrCovBasicBlockEntry>(),
|
||||||
)
|
)
|
||||||
@ -539,12 +539,8 @@ impl DrCovReader {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::{
|
use alloc::string::{String, ToString};
|
||||||
env::temp_dir,
|
use std::{env::temp_dir, fs, path::PathBuf};
|
||||||
fs,
|
|
||||||
path::PathBuf,
|
|
||||||
string::{String, ToString},
|
|
||||||
};
|
|
||||||
|
|
||||||
use rangemap::RangeMap;
|
use rangemap::RangeMap;
|
||||||
|
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
use alloc::{
|
use alloc::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
boxed::Box,
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use std::{
|
use core::{cell::RefCell, marker::PhantomData, ops::Deref};
|
||||||
cell::RefCell,
|
|
||||||
marker::PhantomData,
|
|
||||||
ops::Deref,
|
|
||||||
prelude::rust_2015::{Box, Vec},
|
|
||||||
};
|
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
Error,
|
Error,
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use alloc::borrow::Cow;
|
use alloc::borrow::Cow;
|
||||||
use core::{ffi::c_void, fmt::Debug};
|
use core::{
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
ffi::c_void,
|
||||||
|
fmt::Debug,
|
||||||
|
sync::atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
use libafl::{
|
use libafl::{
|
||||||
Error,
|
Error,
|
||||||
|
@ -11,6 +11,7 @@ pub static mut COUNTERS_MAPS: Vec<OwnedMutSlice<'static, u8>> = Vec::new();
|
|||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
/// The resulting pointer points to a global. Handle with care!
|
/// The resulting pointer points to a global. Handle with care!
|
||||||
|
#[must_use]
|
||||||
pub unsafe fn counters_maps_ptr() -> *const Vec<OwnedMutSlice<'static, u8>> {
|
pub unsafe fn counters_maps_ptr() -> *const Vec<OwnedMutSlice<'static, u8>> {
|
||||||
&raw const COUNTERS_MAPS
|
&raw const COUNTERS_MAPS
|
||||||
}
|
}
|
||||||
@ -29,8 +30,8 @@ pub unsafe fn counters_maps_ptr_mut() -> *mut Vec<OwnedMutSlice<'static, u8>> {
|
|||||||
/// You are responsible for ensuring there is no multi-mutability!
|
/// You are responsible for ensuring there is no multi-mutability!
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
|
pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
|
||||||
let counter_maps = unsafe { &*counters_maps_ptr() };
|
let counters_maps = unsafe { &*counters_maps_ptr() };
|
||||||
counter_maps
|
counters_maps
|
||||||
.iter()
|
.iter()
|
||||||
.map(|counters| unsafe {
|
.map(|counters| unsafe {
|
||||||
OwnedMutSlice::from_raw_parts_mut(
|
OwnedMutSlice::from_raw_parts_mut(
|
||||||
@ -49,8 +50,8 @@ pub unsafe fn extra_counters() -> Vec<OwnedMutSlice<'static, u8>> {
|
|||||||
#[expect(clippy::cast_sign_loss)]
|
#[expect(clippy::cast_sign_loss)]
|
||||||
pub unsafe extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
|
pub unsafe extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop: *mut u8) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let counter_maps = &mut *counters_maps_ptr_mut();
|
let counters_maps = &mut *counters_maps_ptr_mut();
|
||||||
for existing in counter_maps {
|
for existing in counters_maps {
|
||||||
let range = existing.as_slice_mut().as_mut_ptr()
|
let range = existing.as_slice_mut().as_mut_ptr()
|
||||||
..=existing
|
..=existing
|
||||||
.as_slice_mut()
|
.as_slice_mut()
|
||||||
@ -66,9 +67,9 @@ pub unsafe extern "C" fn __sanitizer_cov_8bit_counters_init(start: *mut u8, stop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let counter_maps = &mut *counters_maps_ptr_mut();
|
let counters_maps = &mut *counters_maps_ptr_mut();
|
||||||
// we didn't overlap; keep going
|
// we didn't overlap; keep going
|
||||||
counter_maps.push(OwnedMutSlice::from_raw_parts_mut(
|
counters_maps.push(OwnedMutSlice::from_raw_parts_mut(
|
||||||
start,
|
start,
|
||||||
stop.offset_from(start) as usize,
|
stop.offset_from(start) as usize,
|
||||||
));
|
));
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user