vmi_os_windows/comps/
module.rs

1use vmi_core::{Architecture, Va, VmiDriver, VmiError, VmiState, VmiVa, os::VmiOsModule};
2
3use super::macros::impl_offsets;
4use crate::{ArchAdapter, WindowsOs, WindowsOsExt as _};
5
6/// A Windows kernel module.
7///
8/// A module in Windows refers to a loaded executable or driver,
9/// typically tracked in the kernel's module list.
10///
11/// # Implementation Details
12///
13/// Corresponds to `_KLDR_DATA_TABLE_ENTRY`.
14pub struct WindowsModule<'a, Driver>
15where
16    Driver: VmiDriver,
17    Driver::Architecture: Architecture + ArchAdapter<Driver>,
18{
19    /// The VMI state.
20    vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
21
22    /// The virtual address of the `_KLDR_DATA_TABLE_ENTRY` structure.
23    va: Va,
24}
25
26impl<Driver> VmiVa for WindowsModule<'_, Driver>
27where
28    Driver: VmiDriver,
29    Driver::Architecture: Architecture + ArchAdapter<Driver>,
30{
31    fn va(&self) -> Va {
32        self.va
33    }
34}
35
36impl<'a, Driver> WindowsModule<'a, Driver>
37where
38    Driver: VmiDriver,
39    Driver::Architecture: Architecture + ArchAdapter<Driver>,
40{
41    impl_offsets!();
42
43    /// Creates a new Windows kernel module.
44    pub fn new(vmi: VmiState<'a, Driver, WindowsOs<Driver>>, va: Va) -> Self {
45        Self { vmi, va }
46    }
47
48    /// Returns the entry point of the module.
49    ///
50    /// # Implementation Details
51    ///
52    /// Corresponds to `_KLDR_DATA_TABLE_ENTRY.EntryPoint`.
53    pub fn entry_point(&self) -> Result<Va, VmiError> {
54        let offsets = self.offsets();
55        let KLDR_DATA_TABLE_ENTRY = &offsets._KLDR_DATA_TABLE_ENTRY;
56
57        self.vmi
58            .read_va_native(self.va + KLDR_DATA_TABLE_ENTRY.EntryPoint.offset())
59    }
60
61    /// Returns the full name of the module.
62    ///
63    /// # Implementation Details
64    ///
65    /// Corresponds to `_KLDR_DATA_TABLE_ENTRY.FullDllName`.
66    pub fn full_name(&self) -> Result<String, VmiError> {
67        let offsets = self.offsets();
68        let KLDR_DATA_TABLE_ENTRY = &offsets._KLDR_DATA_TABLE_ENTRY;
69
70        self.vmi
71            .os()
72            .read_unicode_string(self.va + KLDR_DATA_TABLE_ENTRY.FullDllName.offset())
73    }
74}
75
76impl<'a, Driver> VmiOsModule<'a, Driver> for WindowsModule<'a, Driver>
77where
78    Driver: VmiDriver,
79    Driver::Architecture: Architecture + ArchAdapter<Driver>,
80{
81    type Os = WindowsOs<Driver>;
82
83    /// Returns the base address of the module.
84    ///
85    /// # Implementation Details
86    ///
87    /// Corresponds to `_KLDR_DATA_TABLE_ENTRY.DllBase`.
88    fn base_address(&self) -> Result<Va, VmiError> {
89        let offsets = self.offsets();
90        let KLDR_DATA_TABLE_ENTRY = &offsets._KLDR_DATA_TABLE_ENTRY;
91
92        self.vmi
93            .read_va_native(self.va + KLDR_DATA_TABLE_ENTRY.DllBase.offset())
94    }
95
96    /// Returns the size of the module.
97    ///
98    /// # Implementation Details
99    ///
100    /// Corresponds to `_KLDR_DATA_TABLE_ENTRY.SizeOfImage`.
101    fn size(&self) -> Result<u64, VmiError> {
102        let offsets = self.offsets();
103        let KLDR_DATA_TABLE_ENTRY = &offsets._KLDR_DATA_TABLE_ENTRY;
104
105        Ok(self
106            .vmi
107            .read_u32(self.va + KLDR_DATA_TABLE_ENTRY.SizeOfImage.offset())? as u64)
108    }
109
110    /// Returns the name of the module.
111    ///
112    /// # Implementation Details
113    ///
114    /// Corresponds to `_KLDR_DATA_TABLE_ENTRY.BaseDllName`.
115    fn name(&self) -> Result<String, VmiError> {
116        let offsets = self.offsets();
117        let KLDR_DATA_TABLE_ENTRY = &offsets._KLDR_DATA_TABLE_ENTRY;
118
119        self.vmi
120            .os()
121            .read_unicode_string(self.va + KLDR_DATA_TABLE_ENTRY.BaseDllName.offset())
122    }
123}