Skip to main content

klib_rs/
lib.rs

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
48// NTSTATUS codes (small)
49pub 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}