vmi_os_windows/comps/
peb.rs

1use vmi_core::{Architecture, Pa, Va, VmiDriver, VmiError, VmiState, VmiVa};
2
3use super::{macros::impl_offsets, process_parameters::WindowsProcessParameters};
4use crate::{ArchAdapter, WindowsOs};
5
6/// The address space type in a WoW64 process.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum WindowsWow64Kind {
9    /// Native address space.
10    Native = 0,
11
12    /// x86 (32-bit) address space under WoW64.
13    X86 = 1,
14    // Arm32 = 2,
15    // Amd64 = 3,
16    // ChpeX86 = 4,
17    // VsmEnclave = 5,
18}
19
20/// A Windows process environment block (PEB).
21///
22/// The PEB is a user-mode structure that stores process-wide information,
23/// such as loaded modules, heap data, and environment settings.
24/// This structure supports both **32-bit and 64-bit** PEBs.
25///
26/// # Implementation Details
27///
28/// Corresponds to `_PEB`.
29pub struct WindowsPeb<'a, Driver>
30where
31    Driver: VmiDriver,
32    Driver::Architecture: Architecture + ArchAdapter<Driver>,
33{
34    /// The VMI state.
35    vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
36
37    /// The virtual address of the `_PEB` structure.
38    va: Va,
39
40    /// The translation root.
41    root: Pa,
42
43    /// The kind of the process.
44    kind: WindowsWow64Kind,
45}
46
47impl<Driver> VmiVa for WindowsPeb<'_, Driver>
48where
49    Driver: VmiDriver,
50    Driver::Architecture: Architecture + ArchAdapter<Driver>,
51{
52    fn va(&self) -> Va {
53        self.va
54    }
55}
56
57impl<Driver> std::fmt::Debug for WindowsPeb<'_, Driver>
58where
59    Driver: VmiDriver,
60    Driver::Architecture: Architecture + ArchAdapter<Driver>,
61{
62    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
63        let process_parameters = self.process_parameters();
64
65        f.debug_struct("WindowsOsPeb")
66            .field("process_parameters", &process_parameters)
67            .finish()
68    }
69}
70
71impl<'a, Driver> WindowsPeb<'a, Driver>
72where
73    Driver: VmiDriver,
74    Driver::Architecture: Architecture + ArchAdapter<Driver>,
75{
76    impl_offsets!();
77
78    /// Creates a new Windows PEB object.
79    pub fn new(
80        vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
81        va: Va,
82        root: Pa,
83        kind: WindowsWow64Kind,
84    ) -> Self {
85        Self {
86            vmi,
87            va,
88            root,
89            kind,
90        }
91    }
92
93    /// Returns the process parameters of the process.
94    ///
95    /// # Implementation Details
96    ///
97    /// Corresponds to `_PEB.ProcessParameters`.
98    pub fn process_parameters(&self) -> Result<WindowsProcessParameters<'a, Driver>, VmiError> {
99        let va = match self.kind {
100            WindowsWow64Kind::Native => {
101                let offsets = self.offsets();
102                let PEB = &offsets.common._PEB;
103
104                self.vmi
105                    .read_va_native_in((self.va + PEB.ProcessParameters.offset(), self.root))?
106            }
107            WindowsWow64Kind::X86 => {
108                const PEB32_ProcessParameters_offset: u64 = 0x10;
109
110                self.vmi
111                    .read_va_native_in((self.va + PEB32_ProcessParameters_offset, self.root))?
112            }
113        };
114
115        Ok(WindowsProcessParameters::new(
116            self.vmi, va, self.root, self.kind,
117        ))
118    }
119
120    /// Returns the current directory.
121    ///
122    /// Shortcut for [`self.process_parameters()?.current_directory()`].
123    ///
124    /// [`self.process_parameters()?.current_directory()`]: WindowsProcessParameters::current_directory
125    pub fn current_directory(&self) -> Result<String, VmiError> {
126        self.process_parameters()?.current_directory()
127    }
128
129    /// Returns the DLL search path.
130    ///
131    /// Shortcut for [`self.process_parameters()?.dll_path()`].
132    ///
133    /// [`self.process_parameters()?.dll_path()`]: WindowsProcessParameters::dll_path
134    pub fn dll_path(&self) -> Result<String, VmiError> {
135        self.process_parameters()?.dll_path()
136    }
137
138    /// Returns the full path of the executable image.
139    ///
140    /// Shortcut for [`self.process_parameters()?.image_path_name()`].
141    ///
142    /// [`self.process_parameters()?.image_path_name()`]: WindowsProcessParameters::image_path_name
143    pub fn image_path_name(&self) -> Result<String, VmiError> {
144        self.process_parameters()?.image_path_name()
145    }
146
147    /// Returns the command line used to launch the process.
148    ///
149    /// Shortcut for [`self.process_parameters()?.command_line()`].
150    ///
151    /// [`self.process_parameters()?.command_line()`]: WindowsProcessParameters::command_line
152    pub fn command_line(&self) -> Result<String, VmiError> {
153        self.process_parameters()?.command_line()
154    }
155}