use super::{RegionPredicate, VmiOs, VmiOsImageArchitecture, impl_ops, impl_predicate};
use crate::{Pa, Va, VmiDriver, VmiError, VmiVa};
impl_ops! {
pub struct ProcessId(pub u32);
}
impl_ops! {
pub struct ProcessObject(pub Va);
}
impl VmiVa for ProcessObject {
fn va(&self) -> Va {
self.0
}
}
impl ProcessObject {
pub fn is_null(&self) -> bool {
self.0.0 == 0
}
pub fn to_u64(&self) -> u64 {
self.0.0
}
}
impl_predicate! {
pub trait ProcessPredicate & impl for &str {
fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
Ok(process.name()?.eq_ignore_ascii_case(self))
}
}
#[any]
pub struct AnyProcess;
}
impl<Os> ProcessPredicate<Os> for ProcessId
where
Os: VmiOs,
{
fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
Ok(process.id()? == *self)
}
}
pub trait VmiOsProcess<'a, Driver>: VmiVa + 'a
where
Driver: VmiDriver,
{
type Os: VmiOs<Driver = Driver, Process<'a> = Self>;
fn id(&self) -> Result<ProcessId, VmiError>;
fn object(&self) -> Result<ProcessObject, VmiError>;
fn name(&self) -> Result<String, VmiError>;
fn parent_id(&self) -> Result<ProcessId, VmiError>;
fn architecture(&self) -> Result<VmiOsImageArchitecture, VmiError>;
fn translation_root(&self) -> Result<Pa, VmiError>;
fn user_translation_root(&self) -> Result<Pa, VmiError>;
fn image_base(&self) -> Result<Va, VmiError>;
fn regions(
&self,
) -> Result<
impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>> + use<'a, Driver, Self>,
VmiError,
>;
fn lookup_region(
&self,
address: Va,
) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError>;
fn threads(
&self,
) -> Result<
impl Iterator<Item = Result<<Self::Os as VmiOs>::Thread<'a>, VmiError>> + use<'a, Driver, Self>,
VmiError,
>;
fn is_valid_address(&self, address: Va) -> Result<Option<bool>, VmiError>;
}
pub trait VmiOsProcessExt<'a, Driver>: VmiOsProcess<'a, Driver>
where
Driver: VmiDriver,
{
fn find_region(
&self,
predicate: impl RegionPredicate<Self::Os>,
) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError> {
for region in self.regions()? {
let region = region?;
if predicate.matches(®ion)? {
return Ok(Some(region));
}
}
Ok(None)
}
fn filter_regions(
&self,
predicate: impl RegionPredicate<Self::Os>,
) -> Result<impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>>, VmiError>
{
let mut regions = self.regions()?;
Ok(std::iter::from_fn(move || {
for region in regions.by_ref() {
let region = match region {
Ok(region) => region,
Err(err) => return Some(Err(err)),
};
match predicate.matches(®ion) {
Ok(true) => return Some(Ok(region)),
Ok(false) => continue,
Err(err) => return Some(Err(err)),
}
}
None
}))
}
}
impl<'a, Driver, T> VmiOsProcessExt<'a, Driver> for T
where
Driver: VmiDriver,
T: VmiOsProcess<'a, Driver>,
{
}