1use super::{
2 RegionPredicate, UserModulePredicate, VmiOs, VmiOsImageArchitecture, impl_ops, impl_predicate,
3};
4use crate::{Pa, Va, VmiDriver, VmiError, VmiVa};
5
6impl_ops! {
7 pub struct ProcessId(pub u32);
9}
10
11impl_ops! {
12 pub struct ProcessObject(pub Va);
16}
17
18impl VmiVa for ProcessObject {
19 fn va(&self) -> Va {
20 self.0
21 }
22}
23
24impl ProcessObject {
25 pub fn is_null(&self) -> bool {
27 self.0.0 == 0
28 }
29
30 pub fn to_u64(&self) -> u64 {
32 self.0.0
33 }
34}
35
36impl_predicate! {
37 pub trait ProcessPredicate & impl for &str {
41 fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
42 Ok(process.name()?.eq_ignore_ascii_case(self))
43 }
44 }
45
46 #[any]
47 pub struct AnyProcess;
48}
49
50impl<Os> ProcessPredicate<Os> for ProcessId
51where
52 Os: VmiOs,
53{
54 fn matches(&self, process: &Os::Process<'_>) -> Result<bool, VmiError> {
55 Ok(process.id()? == *self)
56 }
57}
58
59pub trait VmiOsProcess<'a, Driver>: VmiVa + 'a
63where
64 Driver: VmiDriver,
65{
66 type Os: VmiOs<Driver = Driver, Process<'a> = Self>;
68
69 fn id(&self) -> Result<ProcessId, VmiError>;
71
72 fn object(&self) -> Result<ProcessObject, VmiError>;
74
75 fn name(&self) -> Result<String, VmiError>;
82
83 fn parent_id(&self) -> Result<ProcessId, VmiError>;
85
86 fn architecture(&self) -> Result<VmiOsImageArchitecture, VmiError>;
88
89 fn translation_root(&self) -> Result<Pa, VmiError>;
91
92 fn user_translation_root(&self) -> Result<Pa, VmiError>;
97
98 fn image_base(&self) -> Result<Va, VmiError>;
100
101 fn regions(
103 &self,
104 ) -> Result<
105 impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>> + use<'a, Driver, Self>,
106 VmiError,
107 >;
108
109 fn lookup_region(
111 &self,
112 address: Va,
113 ) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError>;
114
115 fn user_modules(
125 &self,
126 ) -> Result<
127 impl Iterator<Item = Result<<Self::Os as VmiOs>::UserModule<'a>, VmiError>>
128 + use<'a, Driver, Self>,
129 VmiError,
130 >;
131
132 fn lookup_user_module(
134 &self,
135 address: Va,
136 ) -> Result<Option<<Self::Os as VmiOs>::UserModule<'a>>, VmiError>;
137
138 fn threads(
144 &self,
145 ) -> Result<
146 impl Iterator<Item = Result<<Self::Os as VmiOs>::Thread<'a>, VmiError>> + use<'a, Driver, Self>,
147 VmiError,
148 >;
149
150 fn is_valid_address(&self, address: Va) -> Result<Option<bool>, VmiError>;
155}
156
157pub trait VmiOsProcessExt<'a, Driver>: VmiOsProcess<'a, Driver>
162where
163 Driver: VmiDriver,
164{
165 fn find_region(
168 &self,
169 predicate: impl RegionPredicate<Self::Os>,
170 ) -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError> {
171 for region in self.regions()? {
172 let region = region?;
173
174 if predicate.matches(®ion)? {
175 return Ok(Some(region));
176 }
177 }
178
179 Ok(None)
180 }
181
182 fn filter_regions(
184 &self,
185 predicate: impl RegionPredicate<Self::Os>,
186 ) -> Result<impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>>, VmiError>
187 {
188 let mut regions = self.regions()?;
189
190 Ok(std::iter::from_fn(move || {
191 for region in regions.by_ref() {
192 let region = match region {
193 Ok(region) => region,
194 Err(err) => return Some(Err(err)),
195 };
196
197 match predicate.matches(®ion) {
198 Ok(true) => return Some(Ok(region)),
199 Ok(false) => continue,
200 Err(err) => return Some(Err(err)),
201 }
202 }
203
204 None
205 }))
206 }
207
208 fn find_user_module(
211 &self,
212 predicate: impl UserModulePredicate<Self::Os>,
213 ) -> Result<Option<<Self::Os as VmiOs>::UserModule<'a>>, VmiError> {
214 for module in self.user_modules()? {
215 let module = module?;
216
217 if predicate.matches(&module)? {
218 return Ok(Some(module));
219 }
220 }
221
222 Ok(None)
223 }
224
225 fn filter_user_modules(
227 &self,
228 predicate: impl UserModulePredicate<Self::Os>,
229 ) -> Result<impl Iterator<Item = Result<<Self::Os as VmiOs>::UserModule<'a>, VmiError>>, VmiError>
230 {
231 let mut modules = self.user_modules()?;
232
233 Ok(std::iter::from_fn(move || {
234 for module in modules.by_ref() {
235 let module = match module {
236 Ok(module) => module,
237 Err(err) => return Some(Err(err)),
238 };
239
240 match predicate.matches(&module) {
241 Ok(true) => return Some(Ok(module)),
242 Ok(false) => continue,
243 Err(err) => return Some(Err(err)),
244 }
245 }
246
247 None
248 }))
249 }
250}
251
252impl<'a, Driver, T> VmiOsProcessExt<'a, Driver> for T
253where
254 Driver: VmiDriver,
255 T: VmiOsProcess<'a, Driver>,
256{
257}