1use vmi_core::{Architecture, Pa, Va, VmiDriver, VmiError, VmiState, VmiVa};
2
3use super::{macros::impl_offsets, peb::WindowsWow64Kind};
4use crate::{ArchAdapter, WindowsOs, WindowsOsExt as _};
5
6pub struct WindowsProcessParameters<'a, Driver>
12where
13 Driver: VmiDriver,
14 Driver::Architecture: Architecture + ArchAdapter<Driver>,
15{
16 inner: Inner<'a, Driver>,
17}
18
19impl<Driver> VmiVa for WindowsProcessParameters<'_, Driver>
20where
21 Driver: VmiDriver,
22 Driver::Architecture: Architecture + ArchAdapter<Driver>,
23{
24 fn va(&self) -> Va {
25 match &self.inner {
26 Inner::Native(inner) => inner.va,
27 Inner::X86(inner) => inner.va,
28 }
29 }
30}
31
32impl<Driver> std::fmt::Debug for WindowsProcessParameters<'_, Driver>
33where
34 Driver: VmiDriver,
35 Driver::Architecture: Architecture + ArchAdapter<Driver>,
36{
37 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
38 let current_directory = self.current_directory();
39 let dll_path = self.dll_path();
40 let image_path_name = self.image_path_name();
41 let command_line = self.command_line();
42
43 f.debug_struct("WindowsOsProcessParameters")
44 .field("current_directory", ¤t_directory)
45 .field("dll_path", &dll_path)
46 .field("image_path_name", &image_path_name)
47 .field("command_line", &command_line)
48 .finish()
49 }
50}
51
52impl<'a, Driver> WindowsProcessParameters<'a, Driver>
53where
54 Driver: VmiDriver,
55 Driver::Architecture: Architecture + ArchAdapter<Driver>,
56{
57 pub(crate) fn new(
59 vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
60 va: Va,
61 root: Pa,
62 kind: WindowsWow64Kind,
63 ) -> Self {
64 let inner = match kind {
65 WindowsWow64Kind::Native => {
66 Inner::Native(WindowsProcessParametersNative::new(vmi, va, root))
67 }
68 WindowsWow64Kind::X86 => Inner::X86(WindowsProcessParameters32::new(vmi, va, root)),
69 };
70
71 Self { inner }
72 }
73
74 pub fn current_directory(&self) -> Result<String, VmiError> {
83 match &self.inner {
84 Inner::Native(inner) => inner.current_directory(),
85 Inner::X86(inner) => inner.current_directory(),
86 }
87 }
88
89 pub fn dll_path(&self) -> Result<String, VmiError> {
98 match &self.inner {
99 Inner::Native(inner) => inner.dll_path(),
100 Inner::X86(inner) => inner.dll_path(),
101 }
102 }
103
104 pub fn image_path_name(&self) -> Result<String, VmiError> {
113 match &self.inner {
114 Inner::Native(inner) => inner.image_path_name(),
115 Inner::X86(inner) => inner.image_path_name(),
116 }
117 }
118
119 pub fn command_line(&self) -> Result<String, VmiError> {
128 match &self.inner {
129 Inner::Native(inner) => inner.command_line(),
130 Inner::X86(inner) => inner.command_line(),
131 }
132 }
133}
134
135enum Inner<'a, Driver>
137where
138 Driver: VmiDriver,
139 Driver::Architecture: Architecture + ArchAdapter<Driver>,
140{
141 Native(WindowsProcessParametersNative<'a, Driver>),
143
144 X86(WindowsProcessParameters32<'a, Driver>),
146}
147
148struct WindowsProcessParametersNative<'a, Driver>
149where
150 Driver: VmiDriver,
151 Driver::Architecture: Architecture + ArchAdapter<Driver>,
152{
153 vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
155
156 va: Va,
158
159 root: Pa,
161}
162
163impl<'a, Driver> WindowsProcessParametersNative<'a, Driver>
164where
165 Driver: VmiDriver,
166 Driver::Architecture: Architecture + ArchAdapter<Driver>,
167{
168 impl_offsets!();
169
170 fn new(vmi: VmiState<'a, Driver, WindowsOs<Driver>>, va: Va, root: Pa) -> Self {
171 Self { vmi, va, root }
172 }
173
174 fn current_directory(&self) -> Result<String, VmiError> {
175 let offsets = self.offsets();
176 let CURDIR = &offsets._CURDIR;
177 let RTL_USER_PROCESS_PARAMETERS = &offsets._RTL_USER_PROCESS_PARAMETERS;
178
179 self.vmi.os().read_unicode_string_in((
180 self.va
181 + RTL_USER_PROCESS_PARAMETERS.CurrentDirectory.offset()
182 + CURDIR.DosPath.offset(),
183 self.root,
184 ))
185 }
186
187 fn dll_path(&self) -> Result<String, VmiError> {
188 let offsets = self.offsets();
189 let RTL_USER_PROCESS_PARAMETERS = &offsets._RTL_USER_PROCESS_PARAMETERS;
190
191 self.vmi.os().read_unicode_string_in((
192 self.va + RTL_USER_PROCESS_PARAMETERS.DllPath.offset(),
193 self.root,
194 ))
195 }
196
197 fn image_path_name(&self) -> Result<String, VmiError> {
198 let offsets = self.offsets();
199 let RTL_USER_PROCESS_PARAMETERS = &offsets._RTL_USER_PROCESS_PARAMETERS;
200
201 self.vmi.os().read_unicode_string_in((
202 self.va + RTL_USER_PROCESS_PARAMETERS.ImagePathName.offset(),
203 self.root,
204 ))
205 }
206
207 fn command_line(&self) -> Result<String, VmiError> {
208 let offsets = self.offsets();
209 let RTL_USER_PROCESS_PARAMETERS = &offsets._RTL_USER_PROCESS_PARAMETERS;
210
211 self.vmi.os().read_unicode_string_in((
212 self.va + RTL_USER_PROCESS_PARAMETERS.CommandLine.offset(),
213 self.root,
214 ))
215 }
216}
217
218struct WindowsProcessParameters32<'a, Driver>
219where
220 Driver: VmiDriver,
221 Driver::Architecture: Architecture + ArchAdapter<Driver>,
222{
223 vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
225
226 va: Va,
228
229 root: Pa,
231}
232
233impl<'a, Driver> WindowsProcessParameters32<'a, Driver>
234where
235 Driver: VmiDriver,
236 Driver::Architecture: Architecture + ArchAdapter<Driver>,
237{
238 fn new(vmi: VmiState<'a, Driver, WindowsOs<Driver>>, va: Va, root: Pa) -> Self {
239 Self { vmi, va, root }
240 }
241
242 fn current_directory(&self) -> Result<String, VmiError> {
243 const RTL_USER_PROCESS_PARAMETERS32_CurrentDirectory_offset: u64 = 0x24;
244
245 self.vmi.os().read_unicode_string32_in((
246 self.va + RTL_USER_PROCESS_PARAMETERS32_CurrentDirectory_offset,
247 self.root,
248 ))
249 }
250
251 fn dll_path(&self) -> Result<String, VmiError> {
252 const RTL_USER_PROCESS_PARAMETERS32_DllPath_offset: u64 = 0x30;
253
254 self.vmi.os().read_unicode_string32_in((
255 self.va + RTL_USER_PROCESS_PARAMETERS32_DllPath_offset,
256 self.root,
257 ))
258 }
259
260 fn image_path_name(&self) -> Result<String, VmiError> {
261 const RTL_USER_PROCESS_PARAMETERS32_ImagePathName_offset: u64 = 0x38;
262
263 self.vmi.os().read_unicode_string32_in((
264 self.va + RTL_USER_PROCESS_PARAMETERS32_ImagePathName_offset,
265 self.root,
266 ))
267 }
268
269 fn command_line(&self) -> Result<String, VmiError> {
270 const RTL_USER_PROCESS_PARAMETERS32_CommandLine_offset: u64 = 0x40;
271
272 self.vmi.os().read_unicode_string32_in((
273 self.va + RTL_USER_PROCESS_PARAMETERS32_CommandLine_offset,
274 self.root,
275 ))
276 }
277}