vmi_os_windows/comps/
session.rs

1use vmi_core::{Architecture, Va, VmiDriver, VmiError, VmiState, VmiVa, os::ProcessObject};
2
3use super::{WindowsObject, WindowsProcess, macros::impl_offsets};
4use crate::{ArchAdapter, ListEntryIterator, WindowsOs};
5
6/// A Windows session space.
7///
8/// The session space is a kernel structure that contains the
9/// session-specific data for a process.
10///
11/// Each logon session (e.g., when a user connects via Remote Desktop) gets
12/// a separate instance of `_MM_SESSION_SPACE`.
13///
14/// # Implementation Details
15///
16/// Corresponds to `_MM_SESSION_SPACE`.
17pub struct WindowsSession<'a, Driver>
18where
19    Driver: VmiDriver,
20    Driver::Architecture: Architecture + ArchAdapter<Driver>,
21{
22    /// The VMI state.
23    vmi: VmiState<'a, Driver, WindowsOs<Driver>>,
24
25    /// The virtual address of the `_MM_SESSION_SPACE` structure.
26    va: Va,
27}
28
29impl<'a, Driver> From<WindowsSession<'a, Driver>> for WindowsObject<'a, Driver>
30where
31    Driver: VmiDriver,
32    Driver::Architecture: Architecture + ArchAdapter<Driver>,
33{
34    fn from(value: WindowsSession<'a, Driver>) -> Self {
35        Self::new(value.vmi, value.va)
36    }
37}
38
39impl<Driver> VmiVa for WindowsSession<'_, Driver>
40where
41    Driver: VmiDriver,
42    Driver::Architecture: Architecture + ArchAdapter<Driver>,
43{
44    fn va(&self) -> Va {
45        self.va
46    }
47}
48
49impl<'a, Driver> WindowsSession<'a, Driver>
50where
51    Driver: VmiDriver,
52    Driver::Architecture: Architecture + ArchAdapter<Driver>,
53{
54    impl_offsets!();
55
56    /// Creates a new Windows session space.
57    pub fn new(vmi: VmiState<'a, Driver, WindowsOs<Driver>>, va: Va) -> Self {
58        Self { vmi, va }
59    }
60
61    /// Returns the session ID.
62    ///
63    /// # Implementation Details
64    ///
65    /// Corresponds to `_MM_SESSION_SPACE.SessionId`.
66    pub fn id(&self) -> Result<u32, VmiError> {
67        let offsets = self.offsets();
68        let MM_SESSION_SPACE = &offsets._MM_SESSION_SPACE;
69
70        self.vmi
71            .read_u32(self.va + MM_SESSION_SPACE.SessionId.offset())
72    }
73
74    /// Returns the list of processes in the session.
75    ///
76    /// # Implementation Details
77    ///
78    /// Corresponds to `_MM_SESSION_SPACE.ProcessList`.
79    pub fn processes(
80        &'a self,
81    ) -> Result<impl Iterator<Item = Result<WindowsProcess<'a, Driver>, VmiError>>, VmiError> {
82        let offsets = self.offsets();
83        let MM_SESSION_SPACE = &offsets._MM_SESSION_SPACE;
84        let EPROCESS = &offsets._EPROCESS;
85
86        Ok(ListEntryIterator::new(
87            self.vmi,
88            self.va + MM_SESSION_SPACE.ProcessList.offset(),
89            EPROCESS.SessionProcessLinks.offset(),
90        )
91        .map(move |result| result.map(|entry| WindowsProcess::new(self.vmi, ProcessObject(entry)))))
92    }
93}