Skip to main content

vmi_core/os/
process.rs

1use super::{VmiOs, VmiOsImageArchitecture, impl_ops};
2use crate::{Pa, Va, VmiDriver, VmiError, VmiVa};
3
4impl_ops! {
5    /// A process ID within a system.
6    ProcessId, u32
7}
8
9impl_ops! {
10    /// A process object within a system.
11    ///
12    /// Equivalent to `EPROCESS*` on Windows or `task_struct*` on Linux.
13    ProcessObject, Va
14}
15
16impl VmiVa for ProcessObject {
17    fn va(&self) -> Va {
18        self.0
19    }
20}
21
22impl ProcessObject {
23    /// Checks if the process object is a null reference.
24    pub fn is_null(&self) -> bool {
25        self.0.0 == 0
26    }
27
28    /// Converts the process object to a 64-bit unsigned integer.
29    pub fn to_u64(&self) -> u64 {
30        self.0.0
31    }
32}
33
34/// A trait for process objects.
35///
36/// This trait provides an abstraction over processes within a guest OS.
37pub trait VmiOsProcess<'a, Driver>: VmiVa + 'a
38where
39    Driver: VmiDriver,
40{
41    /// The VMI OS type.
42    type Os: VmiOs<Driver = Driver>;
43
44    /// Returns the process ID.
45    fn id(&self) -> Result<ProcessId, VmiError>;
46
47    /// Returns the process object.
48    fn object(&self) -> Result<ProcessObject, VmiError>;
49
50    /// Returns the name of the process.
51    ///
52    /// # Platform-specific
53    ///
54    /// - **Windows**: `_EPROCESS.ImageFileName` (limited to 16 characters).
55    /// - **Linux**: `_task_struct.comm` (limited to 16 characters).
56    fn name(&self) -> Result<String, VmiError>;
57
58    /// Returns the parent process ID.
59    fn parent_id(&self) -> Result<ProcessId, VmiError>;
60
61    /// Returns the architecture of the process.
62    fn architecture(&self) -> Result<VmiOsImageArchitecture, VmiError>;
63
64    /// Returns the process's page table translation root.
65    fn translation_root(&self) -> Result<Pa, VmiError>;
66
67    /// Returns the user-mode page table translation root.
68    ///
69    /// If KPTI is disabled, this function will return the same value as
70    /// [`translation_root`](Self::translation_root).
71    fn user_translation_root(&self) -> Result<Pa, VmiError>;
72
73    /// Returns the base address of the process image.
74    fn image_base(&self) -> Result<Va, VmiError>;
75
76    /// Returns an iterator over the process's memory regions.
77    fn regions(
78        &self,
79    ) -> Result<
80        impl Iterator<Item = Result<<Self::Os as VmiOs>::Region<'a>, VmiError>> + use<'a, Driver, Self>,
81        VmiError,
82    >;
83
84    /// Finds the memory region containing the given address.
85    fn find_region(&self, address: Va)
86    -> Result<Option<<Self::Os as VmiOs>::Region<'a>>, VmiError>;
87
88    /// Returns an iterator over the threads in the process.
89    ///
90    /// # Platform-specific
91    ///
92    /// - **Windows**: `_EPROCESS.ThreadListHead`.
93    fn threads(
94        &self,
95    ) -> Result<
96        impl Iterator<Item = Result<<Self::Os as VmiOs>::Thread<'a>, VmiError>> + use<'a, Driver, Self>,
97        VmiError,
98    >;
99
100    /// Checks whether the given virtual address is valid in the process.
101    ///
102    /// This method checks if page-faulting on the address would result in
103    /// a successful access.
104    fn is_valid_address(&self, address: Va) -> Result<Option<bool>, VmiError>;
105}