vmi_core/os/mod.rs
1#![doc = include_str!("../../docs/os.md")]
2
3mod dummy;
4mod image;
5mod mapped;
6mod module;
7mod process;
8mod region;
9mod struct_reader;
10mod thread;
11
12use vmi_macros::derive_os_wrapper;
13
14pub use self::{
15 dummy::NoOS,
16 image::{VmiOsImage, VmiOsImageArchitecture, VmiOsImageSymbol},
17 mapped::VmiOsMapped,
18 module::VmiOsModule,
19 process::{ProcessId, ProcessObject, VmiOsProcess},
20 region::{VmiOsRegion, VmiOsRegionKind},
21 struct_reader::StructReader,
22 thread::{ThreadId, ThreadObject, VmiOsThread},
23};
24use crate::{Va, VmiDriver, VmiError, VmiOsState, VmiState};
25
26/// Operating system trait.
27#[derive_os_wrapper(VmiOsState)]
28pub trait VmiOs<Driver>: Sized
29where
30 Driver: VmiDriver,
31{
32 /// The process type.
33 type Process<'a>: VmiOsProcess<'a, Driver> + 'a
34 where
35 Self: 'a;
36
37 /// The thread type.
38 type Thread<'a>: VmiOsThread<'a, Driver> + 'a
39 where
40 Self: 'a;
41
42 /// The image type.
43 type Image<'a>: VmiOsImage<'a, Driver> + 'a
44 where
45 Self: 'a;
46
47 /// The kernel module type.
48 type Module<'a>: VmiOsModule<'a, Driver> + 'a
49 where
50 Self: 'a;
51
52 /// The memory region type.
53 type Region<'a>: VmiOsRegion<'a, Driver> + 'a
54 where
55 Self: 'a;
56
57 /// The memory mapped region type.
58 type Mapped<'a>: VmiOsMapped<'a, Driver> + 'a
59 where
60 Self: 'a;
61
62 /// Retrieves the base address of the kernel image.
63 ///
64 /// The kernel image base address is usually found using some special
65 /// CPU register - for example, a register that contains the address of
66 /// the system call handler. Such register is set by the operating system
67 /// during boot and is left unchanged (unless some rootkits are involved).
68 ///
69 /// Therefore, this function can accept the CPU registers from any point
70 /// of the VM execution (except for the early boot stage).
71 ///
72 /// For catching the exact moment when the kernel image base address is
73 /// set, you can monitor the `MSR_LSTAR` register (on AMD64) for writes.
74 ///
75 /// # Architecture-specific
76 ///
77 /// - **AMD64**: The kernel image base address is usually found using the
78 /// `MSR_LSTAR` register.
79 ///
80 /// # Notes
81 ///
82 /// A malicious code (such as a rootkit) could modify values of the
83 /// registers, so the returned value might not be accurate.
84 fn kernel_image_base(vmi: VmiState<Driver, Self>) -> Result<Va, VmiError>;
85
86 /// Retrieves an implementation-specific string containing kernel
87 /// information.
88 ///
89 /// # Platform-specific
90 ///
91 /// - **Windows**: Retrieves the `NtBuildLab` string from the kernel image.
92 /// - **Linux**: Retrieves the `linux_banner` string from the kernel image.
93 fn kernel_information_string(vmi: VmiState<Driver, Self>) -> Result<String, VmiError>;
94
95 /// Checks if Kernel Page Table Isolation (KPTI) is enabled.
96 ///
97 /// # Platform-specific
98 ///
99 /// - **Windows**: Retrieves the `KiKvaShadow` global variable, if it exists.
100 fn kpti_enabled(vmi: VmiState<Driver, Self>) -> Result<bool, VmiError>;
101
102 /// Returns an iterator over the loaded kernel modules.
103 ///
104 /// # Platform-specific
105 ///
106 /// - **Windows**: Retrieves information from the `PsLoadedModuleList`.
107 /// - **Linux**: Retrieves information from the `modules` list.
108 fn modules<'a>(
109 vmi: VmiState<'a, Driver, Self>,
110 ) -> Result<impl Iterator<Item = Result<Self::Module<'a>, VmiError>> + 'a, VmiError>;
111
112 /// Returns an iterator over the processes.
113 ///
114 /// # Platform-specific
115 ///
116 /// - **Windows**: Retrieves information from the `PsActiveProcessHead` list.
117 /// - **Linux**: Retrieves information from the `tasks` list.
118 fn processes<'a>(
119 vmi: VmiState<'a, Driver, Self>,
120 ) -> Result<impl Iterator<Item = Result<Self::Process<'a>, VmiError>> + 'a, VmiError>;
121
122 /// Returns the process corresponding to the given process object.
123 fn process<'a>(
124 vmi: VmiState<'a, Driver, Self>,
125 process: ProcessObject,
126 ) -> Result<Self::Process<'a>, VmiError>;
127
128 /// Returns the currently executing process.
129 fn current_process<'a>(vmi: VmiState<'a, Driver, Self>) -> Result<Self::Process<'a>, VmiError>;
130
131 /// Returns the system process object.
132 ///
133 /// The system process is the first process created by the kernel.
134 ///
135 /// # Platform-specific
136 ///
137 /// - **Windows**: Retrieves the `PsInitialSystemProcess` global variable.
138 /// - **Linux**: Retrieves the `init_task` global variable.
139 fn system_process<'a>(vmi: VmiState<'a, Driver, Self>) -> Result<Self::Process<'a>, VmiError>;
140
141 /// Returns the thread corresponding to the given thread object.
142 fn thread<'a>(
143 vmi: VmiState<'a, Driver, Self>,
144 thread: ThreadObject,
145 ) -> Result<Self::Thread<'a>, VmiError>;
146
147 /// Returns the currently executing thread.
148 fn current_thread<'a>(vmi: VmiState<'a, Driver, Self>) -> Result<Self::Thread<'a>, VmiError>;
149
150 /// Returns the image corresponding to the given base address.
151 fn image<'a>(
152 vmi: VmiState<'a, Driver, Self>,
153 image_base: Va,
154 ) -> Result<Self::Image<'a>, VmiError>;
155
156 /// Returns the kernel module corresponding to the given base address.
157 fn module<'a>(
158 vmi: VmiState<'a, Driver, Self>,
159 module: Va,
160 ) -> Result<Self::Module<'a>, VmiError>;
161
162 /// Returns the memory region corresponding to the given address.
163 ///
164 /// # Platform-specific
165 ///
166 /// - **Windows**: The region is represented by the `_MMVAD` structure.
167 /// - **Linux**: The region is represented by the `vm_area_struct` structure.
168 fn region<'a>(
169 vmi: VmiState<'a, Driver, Self>,
170 region: Va,
171 ) -> Result<Self::Region<'a>, VmiError>;
172
173 /// Retrieves a specific syscall argument according to the system call ABI.
174 ///
175 /// This function assumes that it is called in the prologue of the system
176 /// call handler, i.e., the instruction pointer is pointing to the first
177 /// instruction of the function.
178 fn syscall_argument(vmi: VmiState<Driver, Self>, index: u64) -> Result<u64, VmiError>;
179
180 /// Retrieves a specific function argument according to the calling
181 /// convention of the operating system.
182 ///
183 /// This function assumes that it is called in the function prologue,
184 /// i.e., the instruction pointer is pointing to the first instruction of
185 /// the function.
186 ///
187 /// # Platform-specific
188 ///
189 /// - **Windows**: Assumes that the function is using the `stdcall`
190 /// calling convention.
191 fn function_argument(vmi: VmiState<Driver, Self>, index: u64) -> Result<u64, VmiError>;
192
193 /// Retrieves the return value of a function.
194 ///
195 /// This function assumes that it is called immediately after the function
196 /// returns.
197 fn function_return_value(vmi: VmiState<Driver, Self>) -> Result<u64, VmiError>;
198
199 /// Retrieves the last error value.
200 ///
201 /// # Platform-specific
202 ///
203 /// - **Windows**: Retrieves the value of the `NtCurrentTeb()->LastErrorValue`
204 /// field.
205 /// - See also: [`WindowsOs::last_status()`](../../../../vmi_os_windows/struct.WindowsOs.html#method.last_status)
206 fn last_error(vmi: VmiState<Driver, Self>) -> Result<Option<u32>, VmiError>;
207}