vmi_os_windows/comps/object/
thread.rs

1use vmi_core::{
2    Architecture, Va, VmiDriver, VmiError, VmiState, VmiVa,
3    os::{ProcessObject, ThreadId, ThreadObject, VmiOsThread},
4};
5
6use super::{super::macros::impl_offsets, WindowsObject, WindowsProcess};
7use crate::{ArchAdapter, WindowsOs};
8
9/// A Windows thread.
10///
11/// A thread in Windows is represented by the `_ETHREAD` structure,
12/// which contains metadata about its execution state, context, and scheduling.
13///
14/// # Implementation Details
15///
16/// Corresponds to `_ETHREAD`.
17pub struct WindowsThread<'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 `_ETHREAD` structure.
26    va: Va,
27}
28
29impl<'a, Driver> From<WindowsThread<'a, Driver>> for WindowsObject<'a, Driver>
30where
31    Driver: VmiDriver,
32    Driver::Architecture: Architecture + ArchAdapter<Driver>,
33{
34    fn from(value: WindowsThread<'a, Driver>) -> Self {
35        Self::new(value.vmi, value.va)
36    }
37}
38
39impl<Driver> VmiVa for WindowsThread<'_, 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> WindowsThread<'a, Driver>
50where
51    Driver: VmiDriver,
52    Driver::Architecture: Architecture + ArchAdapter<Driver>,
53{
54    impl_offsets!();
55
56    /// Creates a new Windows thread.
57    pub fn new(vmi: VmiState<'a, Driver, WindowsOs<Driver>>, thread: ThreadObject) -> Self {
58        Self { vmi, va: thread.0 }
59    }
60
61    /// Returns the process object associated with the thread.
62    ///
63    /// # Implementation Details
64    ///
65    /// Corresponds to `_KTHREAD.Process`.
66    pub fn process(&self) -> Result<WindowsProcess<'a, Driver>, VmiError> {
67        let offsets = self.offsets();
68        let KTHREAD = &offsets._KTHREAD;
69
70        let process = self
71            .vmi
72            .read_va_native(self.va + KTHREAD.Process.offset())?;
73
74        Ok(WindowsProcess::new(self.vmi, ProcessObject(process)))
75    }
76
77    /// Returns the process attached to the thread.
78    ///
79    /// # Implementation Details
80    ///
81    /// Corresponds to `_KTHREAD.ApcState.Process`.
82    pub fn attached_process(&self) -> Result<WindowsProcess<'a, Driver>, VmiError> {
83        let offsets = self.offsets();
84        let KTHREAD = &offsets._KTHREAD;
85        let KAPC_STATE = &offsets._KAPC_STATE;
86
87        let process = self
88            .vmi
89            .read_va_native(self.va + KTHREAD.ApcState.offset() + KAPC_STATE.Process.offset())?;
90
91        Ok(WindowsProcess::new(self.vmi, ProcessObject(process)))
92    }
93}
94
95impl<'a, Driver> VmiOsThread<'a, Driver> for WindowsThread<'a, Driver>
96where
97    Driver: VmiDriver,
98    Driver::Architecture: Architecture + ArchAdapter<Driver>,
99{
100    type Os = WindowsOs<Driver>;
101
102    /// Returns the thread ID.
103    ///
104    /// # Implementation Details
105    ///
106    /// Corresponds to `_ETHREAD.Cid.UniqueThread`.
107    fn id(&self) -> Result<ThreadId, VmiError> {
108        let offsets = self.offsets();
109        let ETHREAD = &offsets._ETHREAD;
110        let CLIENT_ID = &offsets._CLIENT_ID;
111
112        let result = self
113            .vmi
114            .read_u32(self.va + ETHREAD.Cid.offset() + CLIENT_ID.UniqueThread.offset())?;
115
116        Ok(ThreadId(result))
117    }
118
119    /// Returns the thread object.
120    fn object(&self) -> Result<ThreadObject, VmiError> {
121        Ok(ThreadObject(self.va))
122    }
123}