1#![no_std]
2#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals, dead_code, improper_ctypes)]
3extern crate alloc;
4#[cfg(feature = "kernel")]
5use alloc::vec::Vec;
6#[cfg(feature = "kernel")]
7use core::ffi::c_void;
8use core::{ptr, slice};
9pub use crate::wdm::*;
10pub mod wdm;
11#[cfg(feature = "kernel")]
12pub mod memory;
13#[cfg(feature = "kernel")]
14pub mod khook;
15#[cfg(feature = "kernel")]
16pub mod kalloc;
17#[cfg(feature = "ntddk")]
18pub mod ntddk;
19#[cfg(feature = "ntifs")]
20pub mod ntifs;
21
22
23
24#[inline(always)]
25pub fn segment_limit(selector: u16) -> Option<u32> {
26 let mut limit;
27 let mut ok: u8;
28
29 unsafe {
30 core::arch::asm!(
31 "lsl {limit:e}, {selector:x}",
32 "setz {ok}",
33 limit = out(reg) limit,
34 selector = in(reg) selector,
35 ok = out(reg_byte) ok,
36 options(nomem, nostack, preserves_flags),
37 );
38 }
39 if ok != 0 {
40 Some(limit)
41 } else {
42 None
43 }
44}
45
46pub type NTSTATUS = i32;
47
48pub const STATUS_SUCCESS: NTSTATUS = 0x00000000;
50pub const STATUS_UNSUCCESSFUL: NTSTATUS = 0xC0000001u32 as i32;
51pub const STATUS_INVALID_PARAMETER: NTSTATUS = 0xC000000Du32 as i32;
52pub const STATUS_INFO_LENGTH_MISMATCH: NTSTATUS = 0xC0000004u32 as i32;
53pub const STATUS_NO_MEMORY: NTSTATUS = 0xC0000017u32 as i32;
54pub const STATUS_INSUFFICIENT_RESOURCES: NTSTATUS = 0xC000009Au32 as i32;
55pub const STATUS_OBJECT_NAME_NOT_FOUND: NTSTATUS = 0xC0000034u32 as i32;
56pub const STATUS_BUFFER_TOO_SMALL: NTSTATUS = 0xC0000023u32 as i32;
57
58
59#[inline(always)]
60pub const fn NT_SUCCESS(status: NTSTATUS) -> bool {
61 status >= 0
62}
63
64
65pub const IRP_MJ_MAXIMUM_FUNCTION: usize = 0x1b;
66
67
68#[repr(C)]
69#[derive(Copy, Clone)]
70pub struct RTL_PROCESS_MODULE_INFORMATION {
71 pub Section: PVOID,
72 pub MappedBase: PVOID,
73 pub ImageBase: PVOID,
74 pub ImageSize: ULONG,
75 pub Flags: ULONG,
76 pub LoadOrderIndex: USHORT,
77 pub InitOrderIndex: USHORT,
78 pub LoadCount: USHORT,
79 pub OffsetToFileName: USHORT,
80 pub FullPathName: [UCHAR; 256],
81}
82
83#[repr(C)]
84#[derive(Copy, Clone)]
85pub struct RTL_PROCESS_MODULES {
86 pub NumberOfModules: ULONG,
87 pub Modules: [RTL_PROCESS_MODULE_INFORMATION; 1],
88}
89
90
91pub const SystemModuleInformation: u32 = 11;
92pub const SystemProcessInformation: u32 = 5;
93pub const IoReadAccess: i32 = 1;
94pub const MmNonCached: i32 = 0;
95
96
97#[repr(C)]
98pub struct SYSTEM_PROCESS_INFORMATION {
99 pub NextEntryOffset: ULONG,
100 pub NumberOfThreads: ULONG,
101 pub Reserved1: [u64; 3],
102 pub CreateTime: i64,
103 pub UserTime: i64,
104 pub KernelTime: i64,
105 pub ImageName: UNICODE_STRING,
106 pub BasePriority: i32,
107 pub UniqueProcessId: PVOID,
108 pub InheritedFromUniqueProcessId: PVOID,
109}
110
111
112
113#[repr(C)]
114#[derive(Copy, Clone)]
115pub union MouseButtons {
116 pub Buttons: ULONG,
117 pub ButtonFields: ButtonFields,
118}
119
120#[repr(C)]
121#[derive(Debug, Copy, Clone)]
122pub struct ButtonFields {
123 pub ButtonFlags: USHORT,
124 pub ButtonData: USHORT,
125}
126
127#[repr(C)]
128#[derive(Copy, Clone)]
129pub struct MOUSE_INPUT_DATA {
130 pub UnitId: USHORT,
131 pub Flags: USHORT,
132 pub u: MouseButtons,
133 pub RawButtons: ULONG,
134 pub LastX: LONG,
135 pub LastY: LONG,
136 pub ExtraInformation: ULONG,
137}
138
139
140pub type PMOUSE_INPUT_DATA = *mut MOUSE_INPUT_DATA;
141
142pub type MouseClassServiceCallbackFn = Option<unsafe extern "system" fn(DeviceObject: PDEVICE_OBJECT, InputDataStart: PMOUSE_INPUT_DATA, InputDataEnd: PMOUSE_INPUT_DATA, InputDataConsumed: PULONG)>;
143
144
145
146#[derive(Copy, Clone)]
147pub struct MOUSE_OBJECT {
148 pub mouse_device: PDEVICE_OBJECT,
149 pub service_call_back: MouseClassServiceCallbackFn,
150 pub use_mouse: i32,
151}
152
153
154
155#[cfg(feature = "kernel")]
156unsafe extern "C" {
157 pub static IoDriverObjectType: *mut *mut u8;
158 pub fn PsLookupProcessByProcessId(ProcessId: HANDLE, Process: *mut PEPROCESS) -> wdm::NTSTATUS;
159 pub fn ZwQuerySystemInformation(SystemInformationClass: u32, SystemInformation: PVOID, SystemInformationLength: ULONG, ReturnLength: *mut ULONG) -> NTSTATUS;
160 pub fn RtlSecureZeroMemory(Destination: PVOID, Length: SIZE_T) -> PVOID;
161 pub fn RtlFindExportedRoutineByName(image_base: PVOID, routine_name: *const u8) -> PVOID;
162 pub fn PsGetProcessPeb(pep: PEPROCESS) -> u64;
163 pub fn MmCopyVirtualMemory(FromProcess: PEPROCESS, FromAddress: PVOID, ToProcess: PEPROCESS, ToAddress: PVOID, BufferSize: SIZE_T,
164 PreviousMode: KPROCESSOR_MODE, NumberOfBytesCopied: *mut SIZE_T) -> NTSTATUS;
165
166 pub fn PsGetCurrentProcess() -> PEPROCESS;
167 pub fn PsGetProcessSectionBaseAddress(Process: PEPROCESS) -> PVOID;
168 pub fn ObReferenceObjectByName(ObjectName: *mut UNICODE_STRING, Attributes: ULONG, PassedAccessState: *mut ACCESS_STATE, DesiredAccess: ACCESS_MASK, ObjectType: *mut u8,
169 AccessMode: u8, ParseContext: *mut c_void, Object: *mut *mut c_void) -> NTSTATUS;
170 pub fn ZwCurrentProcess() -> HANDLE;
171 pub fn IoCreateDriver(DriverName: *mut UNICODE_STRING, InitializationFunction: extern "system" fn(*mut c_void, *mut UNICODE_STRING) -> NTSTATUS) -> NTSTATUS;
172}
173
174
175
176
177pub fn modules_from_ptr<'a>(ptr: *const RTL_PROCESS_MODULES) -> &'a [RTL_PROCESS_MODULE_INFORMATION] {
178 unsafe {
179 if ptr.is_null() {
180 &[]
181 } else {
182 let count = (*ptr).NumberOfModules as usize;
183 let first = &(*ptr).Modules as *const RTL_PROCESS_MODULE_INFORMATION;
184 slice::from_raw_parts(first, count)
185 }
186 }
187}
188
189
190pub fn filename_from_info(info: &RTL_PROCESS_MODULE_INFORMATION) -> &[u8] {
191 let off = info.OffsetToFileName as usize;
192 if off >= info.FullPathName.len() {
193 if let Some(pos) = info.FullPathName.iter().position(|&b| b == 0) {
194 &info.FullPathName[..pos]
195 } else {
196 &info.FullPathName[..]
197 }
198 } else {
199 let slice = &info.FullPathName[off..];
200 if let Some(pos) = slice.iter().position(|&b| b == 0) {
201 &slice[..pos]
202 } else {
203 slice
204 }
205 }
206}
207
208pub fn module_base_and_name(info: &RTL_PROCESS_MODULE_INFORMATION) -> (PVOID, &[u8]) {
209 (info.ImageBase, filename_from_info(info))
210}
211
212
213pub fn init_object_attributes(obj: &mut OBJECT_ATTRIBUTES, name: *mut UNICODE_STRING, attributes: u32) {
214 obj.Length = size_of::<OBJECT_ATTRIBUTES>() as u32;
215 obj.RootDirectory = ptr::null_mut();
216 obj.ObjectName = name;
217 obj.Attributes = attributes;
218 obj.SecurityDescriptor = ptr::null_mut();
219 obj.SecurityQualityOfService = ptr::null_mut();
220}