use vmi_core::{VmiContext, VmiError, VmiEventResponse, VmiHandler, VmiSession, os::ProcessId};
mod arch;
pub use self::arch::ArchAdapter;
mod os;
pub use self::os::OsAdapter;
mod argument;
pub use self::argument::{Argument, ArgumentData};
mod call;
pub use self::call::CallBuilder;
#[doc(hidden)]
pub mod macros;
#[doc(inline)]
pub use crate::_private_recipe as recipe;
use crate::bridge::BridgeDispatch;
mod recipe;
pub use self::recipe::{
ImageSymbolCache, Recipe, RecipeContext, RecipeControlFlow, RecipeExecutor,
};
pub type InjectorResultCode = u64;
pub trait ExecutionMode {}
pub struct KernelMode;
impl ExecutionMode for KernelMode {}
pub struct UserMode;
impl ExecutionMode for UserMode {}
pub trait InjectorExecutionAdapter<Mode, T, Bridge>: OsAdapter
where
Mode: ExecutionMode,
Bridge: BridgeDispatch<Self, InjectorResultCode>,
{
type Handler: InjectorHandlerAdapter<Self, Mode, T, Bridge>;
}
pub trait InjectorHandlerAdapter<Os, Mode, T, Bridge>: VmiHandler<Os> + Sized
where
Os: InjectorExecutionAdapter<Mode, T, Bridge>,
Mode: ExecutionMode,
Bridge: BridgeDispatch<Os, InjectorResultCode>,
{
fn with_bridge(
vmi: &VmiSession<Os>,
bridge: Bridge,
recipe: Recipe<Os, T>,
) -> Result<Self, VmiError>;
fn with_pid(self, pid: ProcessId) -> Result<Self, VmiError>;
}
pub struct InjectorHandler<Os, Mode, T, Bridge = ()>
where
Os: InjectorExecutionAdapter<Mode, T, Bridge>,
Mode: ExecutionMode,
Bridge: BridgeDispatch<Os, InjectorResultCode>,
{
inner: <Os as InjectorExecutionAdapter<Mode, T, Bridge>>::Handler,
_marker: std::marker::PhantomData<(Os, Mode, T, Bridge)>,
}
impl<Os, Mode, T, Bridge> InjectorHandler<Os, Mode, T, Bridge>
where
Os: InjectorExecutionAdapter<Mode, T, Bridge>,
Mode: ExecutionMode,
Bridge: BridgeDispatch<Os, InjectorResultCode>,
{
pub fn new(vmi: &VmiSession<Os>, recipe: Recipe<Os, T>) -> Result<Self, VmiError>
where
Bridge: Default,
{
Self::with_bridge(vmi, Bridge::default(), recipe)
}
pub fn with_bridge(
vmi: &VmiSession<Os>,
bridge: Bridge,
recipe: Recipe<Os, T>,
) -> Result<Self, VmiError> {
Ok(Self {
inner: <Os as InjectorExecutionAdapter<Mode, T, Bridge>>::Handler::with_bridge(
vmi, bridge, recipe,
)?,
_marker: std::marker::PhantomData,
})
}
pub fn with_pid(self, pid: ProcessId) -> Result<Self, VmiError> {
Ok(Self {
inner: self.inner.with_pid(pid)?,
_marker: std::marker::PhantomData,
})
}
}
impl<Os, Mode, T, Bridge> VmiHandler<Os> for InjectorHandler<Os, Mode, T, Bridge>
where
Os: InjectorExecutionAdapter<Mode, T, Bridge>,
Mode: ExecutionMode,
Bridge: BridgeDispatch<Os, InjectorResultCode>,
{
type Output =
<<Os as InjectorExecutionAdapter<Mode, T, Bridge>>::Handler as VmiHandler<Os>>::Output;
fn handle_event(&mut self, vmi: VmiContext<Os>) -> VmiEventResponse<Os::Architecture> {
self.inner.handle_event(vmi)
}
fn poll(&self) -> Option<Self::Output> {
self.inner.poll()
}
}
pub type KernelInjectorHandler<Os, T> = InjectorHandler<Os, KernelMode, T>;
pub type UserInjectorHandler<Os, T> = InjectorHandler<Os, UserMode, T>;