1use super::{RegionPredicate, VmiOs, VmiOsImageArchitecture, impl_ops, impl_predicate};
2use crate::{Pa, Va, VmiDriver, VmiError, VmiVa};
3
4impl_ops! {
5 pub struct ProcessId(pub u32);
7}
8
9impl_ops! {
10 pub struct ProcessObject(pub Va);
14}
15
16impl VmiVa for ProcessObject {
17 fn va(&self) -> Va {
18 self.0
19 }
20}
21
22impl ProcessObject {
23 pub fn is_null(&self) -> bool {
25 self.0.0 == 0
26 }
27
28 pub fn to_u64(&self) -> u64 {
30 self.0.0
31 }
32}
33
34impl_predicate! {
35 pub trait ProcessPredicate & impl for &str {
39 fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
40 Ok(process.name()?.eq_ignore_ascii_case(self))
41 }
42 }
43
44 #[any]
45 pub struct AnyProcess;
46}
47
48impl<Os> ProcessPredicate<Os> for ProcessId
49where
50 Os: VmiOs,
51{
52 fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
53 Ok(process.id()? == *self)
54 }
55}
56
57pub trait VmiOsProcess<'a, Driver>: VmiVa + 'a
61where
62 Driver: VmiDriver,
63{
64 type Os: VmiOs<Driver = Driver, Process<'a> = Self>;
66
67 fn id(&self) -> Result<ProcessId, VmiError>;
69
70 fn object(&self) -> Result<ProcessObject, VmiError>;
72
73 fn name(&self) -> Result<String, VmiError>;
80
81 fn parent_id(&self) -> Result<ProcessId, VmiError>;
83
84 fn architecture(&self) -> Result<VmiOsImageArchitecture, VmiError>;
86
87 fn translation_root(&self) -> Result<Pa, VmiError>;
89
90 fn user_translation_root(&self) -> Result<Pa, VmiError>;
95
96 fn image_base(&self) -> Result<Va, VmiError>;
98
99 fn regions(
101 &self,
102 ) -> Result<
103 impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>> + use<'a, Driver, Self>,
104 VmiError,
105 >;
106
107 fn lookup_region(
109 &self,
110 address: Va,
111 ) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError>;
112
113 fn threads(
119 &self,
120 ) -> Result<
121 impl Iterator<Item = Result<<Self::Os as VmiOs>::Thread<'a>, VmiError>> + use<'a, Driver, Self>,
122 VmiError,
123 >;
124
125 fn is_valid_address(&self, address: Va) -> Result<Option<bool>, VmiError>;
130}
131
132pub trait VmiOsProcessExt<'a, Driver>: VmiOsProcess<'a, Driver>
137where
138 Driver: VmiDriver,
139{
140 fn find_region(
143 &self,
144 predicate: impl RegionPredicate<Self::Os>,
145 ) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError> {
146 for region in self.regions()? {
147 let region = region?;
148
149 if predicate.matches(®ion)? {
150 return Ok(Some(region));
151 }
152 }
153
154 Ok(None)
155 }
156
157 fn filter_regions(
159 &self,
160 predicate: impl RegionPredicate<Self::Os>,
161 ) -> Result<impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>>, VmiError>
162 {
163 let mut regions = self.regions()?;
164
165 Ok(std::iter::from_fn(move || {
166 for region in regions.by_ref() {
167 let region = match region {
168 Ok(region) => region,
169 Err(err) => return Some(Err(err)),
170 };
171
172 match predicate.matches(®ion) {
173 Ok(true) => return Some(Ok(region)),
174 Ok(false) => continue,
175 Err(err) => return Some(Err(err)),
176 }
177 }
178
179 None
180 }))
181 }
182}
183
184impl<'a, Driver, T> VmiOsProcessExt<'a, Driver> for T
185where
186 Driver: VmiDriver,
187 T: VmiOsProcess<'a, Driver>,
188{
189}