Make sure EM and Z remain consistent in InProcessExecutor (#2873)

* Make sure EM and Z remain consistent in InProcessExecutor

* first make them compile

* a

* hah

* fix intel pt

* decouple fuzzer from em

* lol

* 3

* fix tcp

* fix

* fix

* fix

* fixer

* std

* fixer

* plz

* plzplzplz

* plzplzplzplz

* mm

* more

* symbol

* a

* a

* mm

* mmm

* mmmm

* mmmmm

* ff

---------

Co-authored-by: Toka <tokazerkje@outlook.com>
This commit is contained in:
Dominik Maier 2025-02-01 08:23:40 +01:00 committed by GitHub
parent 6cd97e7105
commit 84702d12a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 124 additions and 103 deletions

View File

@ -122,8 +122,8 @@ pub fn main() {
}
.build();
type PTInProcessExecutor<'a, H, I, OT, S, T> =
GenericInProcessExecutor<H, &'a mut H, (IntelPTHook<T>, ()), I, OT, S>;
type PTInProcessExecutor<'a, EM, H, I, OT, S, T, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, (IntelPTHook<T>, ()), I, OT, S, Z>;
// Create the executor for an in-process function with just one observer
let mut executor = PTInProcessExecutor::with_timeout_generic(
tuple_list!(pt_hook),

View File

@ -1,6 +1,7 @@
use core::{
ffi::c_void,
fmt::{self, Debug, Formatter},
marker::PhantomData,
ptr::{self, null, write_volatile},
sync::atomic::{compiler_fence, Ordering},
time::Duration,
@ -33,14 +34,17 @@ use crate::{
};
/// The internal state of `GenericInProcessExecutor`.
pub struct GenericInProcessExecutorInner<HT, I, OT, S> {
pub struct GenericInProcessExecutorInner<EM, HT, I, OT, S, Z> {
/// The observers, observing each run
pub(super) observers: OT,
// Crash and timeout hah
/// Crash and timeout hooks
pub(super) hooks: (InProcessHooks<I, S>, HT),
/// `EM` and `Z` need to be tracked here to remain stable,
/// else we can run into type confusions between [`Self::enter_target`] and [`Self::leave_target`].
phantom: PhantomData<(EM, Z)>,
}
impl<HT, I, OT, S> Debug for GenericInProcessExecutorInner<HT, I, OT, S>
impl<EM, HT, I, OT, S, Z> Debug for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where
OT: Debug,
{
@ -51,7 +55,7 @@ where
}
}
impl<HT, I, OT, S> HasObservers for GenericInProcessExecutorInner<HT, I, OT, S> {
impl<EM, HT, I, OT, S, Z> HasObservers for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z> {
type Observers = OT;
#[inline]
@ -65,7 +69,7 @@ impl<HT, I, OT, S> HasObservers for GenericInProcessExecutorInner<HT, I, OT, S>
}
}
impl<HT, I, OT, S> GenericInProcessExecutorInner<HT, I, OT, S>
impl<EM, HT, I, OT, S, Z> GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where
OT: ObserversTuple<I, S>,
{
@ -76,7 +80,7 @@ where
/// the code.
// TODO: Remove EM and Z from function bound and add it to struct instead to avoid possible type confusion
#[inline]
pub unsafe fn enter_target<EM, Z>(
pub unsafe fn enter_target(
&mut self,
fuzzer: &mut Z,
state: &mut S,
@ -111,13 +115,7 @@ where
/// This function marks the boundary between the fuzzer and the target
#[inline]
pub fn leave_target<EM, Z>(
&mut self,
_fuzzer: &mut Z,
_state: &mut S,
_mgr: &mut EM,
_input: &I,
) {
pub fn leave_target(&mut self, _fuzzer: &mut Z, _state: &mut S, _mgr: &mut EM, _input: &I) {
unsafe {
let data = &raw mut GLOBAL_STATE;
@ -127,14 +125,14 @@ where
}
}
impl<HT, I, OT, S> GenericInProcessExecutorInner<HT, I, OT, S>
impl<EM, HT, I, OT, S, Z> GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
where
HT: ExecutorHooksTuple<I, S>,
OT: ObserversTuple<I, S>,
S: HasExecutions + HasSolutions<I>,
{
/// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<E, EM, OF, Z>(
pub fn generic<E, OF>(
user_hooks: HT,
observers: OT,
fuzzer: &mut Z,
@ -150,7 +148,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<E, EM, OF, Z>(
Self::with_timeout_generic::<E, OF>(
user_hooks,
observers,
fuzzer,
@ -162,7 +160,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout_generic<E, EM, OF, Z>(
pub fn batched_timeout_generic<E, OF>(
user_hooks: HT,
observers: OT,
fuzzer: &mut Z,
@ -179,7 +177,7 @@ where
S: HasCurrentTestcase<I> + HasSolutions<I>,
Z: HasObjective<Objective = OF>,
{
let mut me = Self::with_timeout_generic::<E, EM, OF, Z>(
let mut me = Self::with_timeout_generic::<E, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?;
me.hooks_mut().0.timer_mut().batch_mode = true;
@ -194,7 +192,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// This may return an error on unix, if signal handler setup fails
pub fn with_timeout_generic<E, EM, OF, Z>(
pub fn with_timeout_generic<E, OF>(
user_hooks: HT,
observers: OT,
_fuzzer: &mut Z,
@ -238,7 +236,11 @@ where
*hooks.0.millis_sec_mut() = timeout.as_millis() as i64;
}
Ok(Self { observers, hooks })
Ok(Self {
observers,
hooks,
phantom: PhantomData,
})
}
/// The inprocess handlers
@ -254,7 +256,9 @@ where
}
}
impl<HT, I, OT, S> HasInProcessHooks<I, S> for GenericInProcessExecutorInner<HT, I, OT, S> {
impl<EM, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>
{
/// the timeout handler
#[inline]
fn inprocess_hooks(&self) -> &InProcessHooks<I, S> {

View File

@ -40,29 +40,32 @@ pub mod inner;
pub mod stateful;
/// The process executor simply calls a target function, as mutable reference to a closure.
pub type InProcessExecutor<'a, H, I, OT, S> = GenericInProcessExecutor<H, &'a mut H, (), I, OT, S>;
pub type InProcessExecutor<'a, EM, H, I, OT, S, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, (), I, OT, S, Z>;
/// The inprocess executor that allows hooks
pub type HookableInProcessExecutor<'a, H, HT, I, OT, S> =
GenericInProcessExecutor<H, &'a mut H, HT, I, OT, S>;
pub type HookableInProcessExecutor<'a, EM, H, HT, I, OT, S, Z> =
GenericInProcessExecutor<EM, H, &'a mut H, HT, I, OT, S, Z>;
/// The process executor simply calls a target function, as boxed `FnMut` trait object
pub type OwnedInProcessExecutor<I, OT, S> = GenericInProcessExecutor<
pub type OwnedInProcessExecutor<EM, I, OT, S, Z> = GenericInProcessExecutor<
EM,
dyn FnMut(&I) -> ExitKind,
Box<dyn FnMut(&I) -> ExitKind>,
(),
I,
OT,
S,
Z,
>;
/// The inmem executor simply calls a target function, then returns afterwards.
pub struct GenericInProcessExecutor<H, HB, HT, I, OT, S> {
pub struct GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z> {
harness_fn: HB,
inner: GenericInProcessExecutorInner<HT, I, OT, S>,
inner: GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>,
phantom: PhantomData<(*const H, HB)>,
}
impl<H, HB, HT, I, OT, S> Debug for GenericInProcessExecutor<H, HB, HT, I, OT, S>
impl<EM, H, HB, HT, I, OT, S, Z> Debug for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where
OT: Debug,
{
@ -75,7 +78,7 @@ where
}
impl<EM, H, HB, HT, I, OT, S, Z> Executor<EM, I, S, Z>
for GenericInProcessExecutor<H, HB, HT, I, OT, S>
for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where
S: HasExecutions,
OT: ObserversTuple<I, S>,
@ -106,7 +109,9 @@ where
}
}
impl<H, HB, HT, I, OT, S> HasObservers for GenericInProcessExecutor<H, HB, HT, I, OT, S> {
impl<EM, H, HB, HT, I, OT, S, Z> HasObservers
for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
{
type Observers = OT;
#[inline]
@ -120,7 +125,7 @@ impl<H, HB, HT, I, OT, S> HasObservers for GenericInProcessExecutor<H, HB, HT, I
}
}
impl<'a, H, I, OT, S> InProcessExecutor<'a, H, I, OT, S>
impl<'a, EM, H, I, OT, S, Z> InProcessExecutor<'a, EM, H, I, OT, S, Z>
where
H: FnMut(&I) -> ExitKind + Sized,
OT: ObserversTuple<I, S>,
@ -128,7 +133,7 @@ where
I: Input,
{
/// Create a new in mem executor with the default timeout (5 sec)
pub fn new<EM, OF, Z>(
pub fn new<OF>(
harness_fn: &'a mut H,
observers: OT,
fuzzer: &mut Z,
@ -140,7 +145,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<EM, OF, Z>(
Self::with_timeout_generic::<OF>(
tuple_list!(),
harness_fn,
observers,
@ -153,7 +158,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout<EM, OF, Z>(
pub fn batched_timeout<OF>(
harness_fn: &'a mut H,
observers: OT,
fuzzer: &mut Z,
@ -166,7 +171,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
@ -190,7 +195,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// This may return an error on unix, if signal handler setup fails
pub fn with_timeout<EM, OF, Z>(
pub fn with_timeout<OF>(
harness_fn: &'a mut H,
observers: OT,
fuzzer: &mut Z,
@ -203,7 +208,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
@ -220,7 +225,7 @@ where
}
}
impl<H, HB, HT, I, OT, S> GenericInProcessExecutor<H, HB, HT, I, OT, S>
impl<EM, H, HB, HT, I, OT, S, Z> GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
where
H: FnMut(&I) -> ExitKind + Sized,
HB: BorrowMut<H>,
@ -230,7 +235,7 @@ where
I: Input,
{
/// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<EM, OF, Z>(
pub fn generic<OF>(
user_hooks: HT,
harness_fn: HB,
observers: OT,
@ -243,7 +248,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
Self::with_timeout_generic::<EM, OF, Z>(
Self::with_timeout_generic::<OF>(
user_hooks,
harness_fn,
observers,
@ -256,7 +261,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout_generic<EM, OF, Z>(
pub fn batched_timeout_generic<OF>(
user_hooks: HT,
harness_fn: HB,
observers: OT,
@ -271,7 +276,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?;
@ -290,7 +295,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// This may return an error on unix, if signal handler setup fails
pub fn with_timeout_generic<EM, OF, Z>(
pub fn with_timeout_generic<OF>(
user_hooks: HT,
harness_fn: HB,
observers: OT,
@ -304,7 +309,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?;
@ -349,8 +354,8 @@ pub trait HasInProcessHooks<I, S> {
fn inprocess_hooks_mut(&mut self) -> &mut InProcessHooks<I, S>;
}
impl<H, HB, HT, I, OT, S> HasInProcessHooks<I, S>
for GenericInProcessExecutor<H, HB, HT, I, OT, S>
impl<EM, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for GenericInProcessExecutor<EM, H, HB, HT, I, OT, S, Z>
{
/// the timeout handler
#[inline]

View File

@ -27,34 +27,37 @@ use crate::{
/// The process executor simply calls a target function, as mutable reference to a closure
/// The internal state of the executor is made available to the harness.
pub type StatefulInProcessExecutor<'a, ES, H, I, OT, S> =
StatefulGenericInProcessExecutor<ES, H, &'a mut H, (), I, OT, S>;
pub type StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z> =
StatefulGenericInProcessExecutor<EM, ES, H, &'a mut H, (), I, OT, S, Z>;
/// The process executor simply calls a target function, as boxed `FnMut` trait object
/// The internal state of the executor is made available to the harness.
pub type OwnedInProcessExecutor<I, OT, S, ES> = StatefulGenericInProcessExecutor<
pub type OwnedInProcessExecutor<EM, ES, I, OT, S, Z> = StatefulGenericInProcessExecutor<
EM,
ES,
dyn FnMut(&mut ES, &I) -> ExitKind,
Box<dyn FnMut(&mut ES, &I) -> ExitKind>,
(),
I,
OT,
S,
ES,
Z,
>;
/// The inmem executor simply calls a target function, then returns afterwards.
/// The harness can access the internal state of the executor.
pub struct StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> {
pub struct StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z> {
/// The harness function, being executed for each fuzzing loop execution
harness_fn: HB,
/// The state used as argument of the harness
pub exposed_executor_state: ES,
/// Inner state of the executor
pub inner: GenericInProcessExecutorInner<HT, I, OT, S>,
pub inner: GenericInProcessExecutorInner<EM, HT, I, OT, S, Z>,
phantom: PhantomData<(ES, *const H)>,
}
impl<H, HB, HT, I, OT, S, ES> Debug for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S>
impl<EM, ES, H, HB, HT, I, OT, S, Z> Debug
for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where
OT: Debug,
{
@ -67,7 +70,7 @@ where
}
impl<EM, H, HB, HT, I, OT, S, Z, ES> Executor<EM, I, S, Z>
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S>
for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>,
@ -98,8 +101,8 @@ where
}
}
impl<H, HB, HT, I, OT, S, ES> HasObservers
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S>
impl<EM, ES, H, HB, HT, I, OT, S, Z> HasObservers
for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>,
@ -118,7 +121,7 @@ where
}
}
impl<'a, H, I, OT, S, ES> StatefulInProcessExecutor<'a, ES, H, I, OT, S>
impl<'a, EM, ES, H, I, OT, S, Z> StatefulInProcessExecutor<'a, EM, ES, H, I, OT, S, Z>
where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
OT: ObserversTuple<I, S>,
@ -126,7 +129,7 @@ where
I: Clone + Input,
{
/// Create a new in mem executor with the default timeout (5 sec)
pub fn new<EM, OF, Z>(
pub fn new<OF>(
harness_fn: &'a mut H,
exposed_executor_state: ES,
observers: OT,
@ -153,7 +156,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
pub fn batched_timeout<EM, OF, Z>(
pub fn batched_timeout<OF>(
harness_fn: &'a mut H,
exposed_executor_state: ES,
observers: OT,
@ -167,7 +170,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
@ -192,7 +195,7 @@ where
/// * `observers` - the observers observing the target during execution
///
/// This may return an error on unix, if signal handler setup fails
pub fn with_timeout<EM, OF, Z>(
pub fn with_timeout<OF>(
harness_fn: &'a mut H,
exposed_executor_state: ES,
observers: OT,
@ -206,7 +209,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
tuple_list!(),
observers,
fuzzer,
@ -224,7 +227,9 @@ where
}
}
impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S> {
impl<EM, ES, H, HB, HT, I, OT, S, Z>
StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
{
/// The executor state given to the harness
pub fn exposed_executor_state(&self) -> &ES {
&self.exposed_executor_state
@ -236,7 +241,8 @@ impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I,
}
}
impl<H, HB, HT, I, OT, S, ES> StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S>
impl<EM, ES, H, HB, HT, I, OT, S, Z>
StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
where
H: FnMut(&mut ES, &mut S, &I) -> ExitKind + Sized,
HB: BorrowMut<H>,
@ -246,7 +252,7 @@ where
S: HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{
/// Create a new in mem executor with the default timeout (5 sec)
pub fn generic<EM, OF, Z>(
pub fn generic<OF>(
user_hooks: HT,
harness_fn: HB,
exposed_executor_state: ES,
@ -275,7 +281,7 @@ where
/// Create a new in mem executor with the default timeout and use batch mode(5 sec)
#[cfg(all(feature = "std", target_os = "linux"))]
#[expect(clippy::too_many_arguments)]
pub fn batched_timeout_generic<EM, OF, Z>(
pub fn batched_timeout_generic<OF>(
user_hooks: HT,
harness_fn: HB,
exposed_executor_state: ES,
@ -290,7 +296,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::batched_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, exec_tmout,
)?;
@ -311,7 +317,7 @@ where
///
/// This may return an error on unix, if signal handler setup fails
#[expect(clippy::too_many_arguments)]
pub fn with_timeout_generic<EM, OF, Z>(
pub fn with_timeout_generic<OF>(
user_hooks: HT,
harness_fn: HB,
exposed_executor_state: ES,
@ -326,7 +332,7 @@ where
OF: Feedback<EM, I, OT, S>,
Z: HasObjective<Objective = OF>,
{
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, EM, OF, Z>(
let inner = GenericInProcessExecutorInner::with_timeout_generic::<Self, OF>(
user_hooks, observers, fuzzer, state, event_mgr, timeout,
)?;
@ -363,8 +369,8 @@ where
}
}
impl<H, HB, HT, I, OT, S, ES> HasInProcessHooks<I, S>
for StatefulGenericInProcessExecutor<ES, H, HB, HT, I, OT, S>
impl<EM, ES, H, HB, HT, I, OT, S, Z> HasInProcessHooks<I, S>
for StatefulGenericInProcessExecutor<EM, ES, H, HB, HT, I, OT, S, Z>
{
/// the timeout handler
#[inline]

View File

@ -27,7 +27,7 @@ use crate::{
pub type StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z> =
StatefulGenericInProcessForkExecutor<'a, EM, ES, H, (), I, OT, S, SP, Z>;
impl<'a, H, I, OT, S, SP, ES, EM, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z>
impl<'a, H, I, OT, S, SP, EM, ES, Z> StatefulInProcessForkExecutor<'a, EM, ES, H, I, OT, S, SP, Z>
where
OT: ObserversTuple<I, S>,
SP: ShMemProvider,
@ -68,7 +68,7 @@ pub struct StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP,
pub inner: GenericInProcessForkExecutorInner<EM, HT, I, OT, S, SP, Z>,
}
impl<H, HT, I, OT, S, SP, ES, EM, Z> Debug
impl<H, HT, I, OT, S, SP, EM, ES, Z> Debug
for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z>
where
HT: Debug,
@ -131,7 +131,7 @@ where
}
}
impl<'a, H, HT, I, OT, S, SP, ES, EM, Z>
impl<'a, H, HT, I, OT, S, SP, EM, ES, Z>
StatefulGenericInProcessForkExecutor<'a, EM, ES, H, HT, I, OT, S, SP, Z>
where
HT: ExecutorHooksTuple<I, S>,
@ -178,7 +178,7 @@ where
}
}
impl<H, HT, I, OT, S, SP, ES, EM, Z> HasObservers
impl<H, HT, I, OT, S, SP, EM, ES, Z> HasObservers
for StatefulGenericInProcessForkExecutor<'_, EM, ES, H, HT, I, OT, S, SP, Z>
{
type Observers = OT;

View File

@ -29,8 +29,8 @@ use crate::helper::{FridaInstrumentationHelper, FridaRuntimeTuple};
use crate::windows_hooks::initialize;
/// The [`FridaInProcessExecutor`] is an [`Executor`] that executes the target in the same process, usinig [`frida`](https://frida.re/) for binary-only instrumentation.
pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> {
base: InProcessExecutor<'a, H, I, OT, S>,
pub struct FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> {
base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
/// `thread_id` for the Stalker
thread_id: Option<u32>,
/// Frida's dynamic rewriting engine
@ -42,7 +42,8 @@ pub struct FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC> {
_phantom: PhantomData<&'b u8>,
}
impl<H, I, OT, RT, S, TC> Debug for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC>
impl<EM, H, I, OT, RT, S, TC, Z> Debug
for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
where
OT: Debug,
{
@ -56,7 +57,7 @@ where
}
impl<EM, H, I, OT, RT, S, TC, Z> Executor<EM, I, S, Z>
for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC>
for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
where
H: FnMut(&I) -> ExitKind,
S: HasExecutions,
@ -111,7 +112,9 @@ where
}
}
impl<H, I, OT, RT, S, TC> HasObservers for FridaInProcessExecutor<'_, '_, '_, H, I, OT, RT, S, TC> {
impl<EM, H, I, OT, RT, S, TC, Z> HasObservers
for FridaInProcessExecutor<'_, '_, '_, EM, H, I, OT, RT, S, TC, Z>
{
type Observers = OT;
#[inline]
fn observers(&self) -> RefIndexable<&Self::Observers, Self::Observers> {
@ -124,15 +127,15 @@ impl<H, I, OT, RT, S, TC> HasObservers for FridaInProcessExecutor<'_, '_, '_, H,
}
}
impl<'a, 'b, 'c, H, I, OT, RT, S>
FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, NopTargetBytesConverter<I>>
impl<'a, 'b, 'c, EM, H, I, OT, RT, S, Z>
FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, NopTargetBytesConverter<I>, Z>
where
RT: FridaRuntimeTuple,
{
/// Creates a new [`FridaInProcessExecutor`].
pub fn new(
gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>,
base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>,
) -> Self {
FridaInProcessExecutor::with_target_bytes_converter(
@ -147,7 +150,7 @@ where
/// Creates a new [`FridaInProcessExecutor`] tracking the given `thread_id`.
pub fn on_thread(
gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>,
base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: u32,
) -> Self {
@ -161,14 +164,15 @@ where
}
}
impl<'a, 'b, 'c, H, I, OT, RT, S, TC> FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC>
impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
where
RT: FridaRuntimeTuple,
{
/// Creates a new [`FridaInProcessExecutor`].
pub fn with_target_bytes_converter(
gum: &'a Gum,
base: InProcessExecutor<'a, H, I, OT, S>,
base: InProcessExecutor<'a, EM, H, I, OT, S, Z>,
helper: &'c mut FridaInstrumentationHelper<'b, RT>,
thread_id: Option<u32>,
target_bytes_converter: TC,
@ -221,8 +225,8 @@ where
}
#[cfg(windows)]
impl<'a, 'b, 'c, H, I, OT, RT, S, TC> HasInProcessHooks<I, S>
for FridaInProcessExecutor<'a, 'b, 'c, H, I, OT, RT, S, TC>
impl<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z> HasInProcessHooks<I, S>
for FridaInProcessExecutor<'a, 'b, 'c, EM, H, I, OT, RT, S, TC, Z>
where
H: FnMut(&I) -> ExitKind,
S: HasSolutions<I> + HasCurrentTestcase<I> + HasExecutions,

View File

@ -42,11 +42,11 @@ use crate::EmulatorModules;
use crate::Qemu;
use crate::{command::CommandManager, modules::EmulatorModuleTuple, Emulator, EmulatorDriver};
type EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> =
StatefulInProcessExecutor<'a, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S>;
type EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> =
StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>;
pub struct QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> {
inner: EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM>,
pub struct QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
inner: EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>,
first_exec: bool,
}
@ -133,7 +133,8 @@ pub unsafe fn inproc_qemu_timeout_handler<E, EM, ET, I, OF, S, Z>(
}
}
impl<C, CM, ED, ET, H, I, OT, S, SM> Debug for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM>
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> Debug
for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where
OT: Debug,
{
@ -144,7 +145,8 @@ where
}
}
impl<'a, C, CM, ED, ET, H, I, OT, S, SM> QemuExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM>
impl<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
QemuExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where
ET: EmulatorModuleTuple<I, S>,
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,
@ -152,7 +154,7 @@ where
OT: ObserversTuple<I, S>,
S: Unpin + HasExecutions + HasSolutions<I> + HasCurrentTestcase<I>,
{
pub fn new<EM, OF, Z>(
pub fn new<OF>(
emulator: Emulator<C, CM, ED, ET, I, S, SM>,
harness_fn: &'a mut H,
observers: OT,
@ -207,7 +209,7 @@ where
}
inner.inprocess_hooks_mut().timeout_handler = inproc_qemu_timeout_handler::<
StatefulInProcessExecutor<'a, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S>,
StatefulInProcessExecutor<'a, EM, Emulator<C, CM, ED, ET, I, S, SM>, H, I, OT, S, Z>,
EM,
ET,
I,
@ -222,7 +224,7 @@ where
})
}
pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> {
pub fn inner(&self) -> &EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
&self.inner
}
@ -233,13 +235,13 @@ where
pub fn inner_mut(
&mut self,
) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, ET, H, I, OT, S, SM> {
) -> &mut EmulatorInProcessExecutor<'a, C, CM, ED, EM, ET, H, I, OT, S, SM, Z> {
&mut self.inner
}
}
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> Executor<EM, I, S, Z>
for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM>
for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where
C: Clone,
CM: CommandManager<C, ED, ET, I, S, SM, Commands = C>,
@ -279,8 +281,8 @@ where
}
}
impl<C, CM, ED, ET, H, I, OT, S, SM> HasObservers
for QemuExecutor<'_, C, CM, ED, ET, H, I, OT, S, SM>
impl<C, CM, ED, EM, ET, H, I, OT, S, SM, Z> HasObservers
for QemuExecutor<'_, C, CM, ED, EM, ET, H, I, OT, S, SM, Z>
where
ET: EmulatorModuleTuple<I, S>,
H: FnMut(&mut Emulator<C, CM, ED, ET, I, S, SM>, &mut S, &I) -> ExitKind,