Skip to content
This repository was archived by the owner on Aug 10, 2024. It is now read-only.

Commit 3c8e694

Browse files
authored
Merge pull request #2 from sn99/master
Enable communication with user space application
2 parents d27422e + ed1635e commit 3c8e694

File tree

13 files changed

+537
-43
lines changed

13 files changed

+537
-43
lines changed

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ thiserror = "1.0"
2121
winreg = "0.11.0"
2222

2323
[dependencies]
24-
windows-kernel-sys = { path = "windows-kernel-sys"}
24+
windows-kernel-sys = { path = "windows-kernel-sys" }
25+
windows-kernel-macros = { path = "windows-kernel-macros" }
26+
windows-kernel-string = {path = "windows-kernel-string"}
27+
windows-kernel-alloc = {path = "windows-kernel-alloc"}

src/lib.rs

Lines changed: 106 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,40 @@
11
#![no_std]
22
#![allow(non_snake_case)]
33

4+
extern crate alloc;
5+
use windows_kernel_alloc;
6+
use windows_kernel_alloc::kernel_alloc::POOL_TAG;
7+
8+
pub mod shared_def;
9+
410
use core::panic::PanicInfo;
511
use core::ptr::null_mut;
12+
use windows_kernel_macros::{InitializeObjectAttributes, NT_SUCCESS, PAGED_CODE};
13+
use windows_kernel_string::UNICODE_STRING;
614

715
use windows_kernel_sys::base::_FLT_PREOP_CALLBACK_STATUS::FLT_PREOP_SUCCESS_NO_CALLBACK;
816
use windows_kernel_sys::base::{
917
DRIVER_OBJECT, FLT_FILESYSTEM_TYPE, FLT_FILTER_UNLOAD_FLAGS, FLT_INSTANCE_QUERY_TEARDOWN_FLAGS,
1018
FLT_INSTANCE_SETUP_FLAGS, FLT_INSTANCE_TEARDOWN_FLAGS, FLT_OPERATION_REGISTRATION,
11-
FLT_PREOP_CALLBACK_STATUS, FLT_REGISTRATION, FLT_REGISTRATION_VERSION, NTSTATUS,
12-
PCFLT_RELATED_OBJECTS, PFLT_CALLBACK_DATA, PFLT_FILTER, PVOID, STATUS_SUCCESS, ULONG,
13-
UNICODE_STRING, USHORT,
19+
FLT_PORT_ALL_ACCESS, FLT_PREOP_CALLBACK_STATUS, FLT_REGISTRATION, FLT_REGISTRATION_VERSION,
20+
NTSTATUS, OBJECT_ATTRIBUTES, OBJ_CASE_INSENSITIVE, OBJ_KERNEL_HANDLE, PCFLT_RELATED_OBJECTS,
21+
PCHAR, PFLT_CALLBACK_DATA, PFLT_FILTER, PFLT_PORT, PSECURITY_DESCRIPTOR, PULONG, PVOID,
22+
STATUS_SUCCESS, ULONG, USHORT,
1423
};
1524
use windows_kernel_sys::fltmgr::{
16-
DbgPrint, FltRegisterFilter, FltStartFiltering, FltUnregisterFilter,
25+
strcpy, DbgPrint, FltBuildDefaultSecurityDescriptor, FltCloseClientPort,
26+
FltCloseCommunicationPort, FltCreateCommunicationPort, FltFreeSecurityDescriptor,
27+
FltRegisterFilter, FltStartFiltering, FltUnregisterFilter,
1728
};
1829

19-
#[panic_handler]
20-
fn panic(_info: &PanicInfo) -> ! {
21-
loop {}
22-
}
23-
24-
#[macro_export]
25-
macro_rules! NT_SUCCESS {
26-
($status:expr) => {
27-
$status as NTSTATUS >= 0
28-
};
29-
}
30+
static mut PORT: PFLT_PORT = null_mut();
31+
static mut CLIENT_PORT: PFLT_PORT = null_mut();
3032

31-
#[macro_export]
32-
macro_rules! PAGED_CODE {
33-
() => {
34-
unsafe {
35-
if u64::from(windows_kernel_sys::fltmgr::KeGetCurrentIrql())
36-
> windows_kernel_sys::base::APC_LEVEL as u64
37-
{
38-
return windows_kernel_sys::base::STATUS_UNSUCCESSFUL;
39-
}
40-
}
41-
};
42-
}
43-
44-
///
4533
/// The minifilter handle that results from a call to FltRegisterFilter
4634
/// NOTE: This handle must be passed to FltUnregisterFilter during minifilter unloading
47-
///
4835
static mut G_MINIFILTER_HANDLE: PFLT_FILTER = null_mut();
4936

50-
51-
///
5237
/// The FLT_REGISTRATION structure provides information about a file system minifilter to the filter manager.
53-
///
5438
const G_FILTER_REGISTRATION: FLT_REGISTRATION = FLT_REGISTRATION {
5539
Size: core::mem::size_of::<FLT_REGISTRATION>() as USHORT, // Size
5640
Version: FLT_REGISTRATION_VERSION as USHORT,
@@ -122,9 +106,9 @@ unsafe extern "C" fn PreOperationCreate(
122106
extern "C" fn InstanceFilterUnloadCallback(_Flags: FLT_FILTER_UNLOAD_FLAGS) -> NTSTATUS {
123107
PAGED_CODE!();
124108

125-
126109
unsafe {
127-
DbgPrint("Unloading\0\n".as_ptr() as _);
110+
DbgPrint("Unloading rust minifilter\0\n".as_ptr() as _);
111+
FltCloseCommunicationPort(PORT);
128112

129113
FltUnregisterFilter(G_MINIFILTER_HANDLE);
130114
}
@@ -170,6 +154,10 @@ pub extern "system" fn DriverEntry(
170154
driver: &mut DRIVER_OBJECT,
171155
_registry_path: *const UNICODE_STRING,
172156
) -> NTSTATUS {
157+
let mut sd: PSECURITY_DESCRIPTOR = null_mut();
158+
let mut oa: OBJECT_ATTRIBUTES = unsafe { core::mem::zeroed() };
159+
let mut name: UNICODE_STRING = UNICODE_STRING::create("\\mf");
160+
173161
unsafe {
174162
DbgPrint("Hello from Rust!\0".as_ptr() as _);
175163
}
@@ -184,27 +172,103 @@ pub extern "system" fn DriverEntry(
184172
return status;
185173
}
186174

187-
driver.DriverUnload = Some(driver_exit);
175+
status = unsafe { FltBuildDefaultSecurityDescriptor(&mut sd, FLT_PORT_ALL_ACCESS) };
188176

177+
if NT_SUCCESS!(status) {
178+
unsafe {
179+
InitializeObjectAttributes(
180+
&mut oa,
181+
&mut name,
182+
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
183+
null_mut(),
184+
sd,
185+
);
186+
}
189187

190-
//
191-
// start minifilter driver
192-
//
193-
status = unsafe { FltStartFiltering(G_MINIFILTER_HANDLE) };
188+
status = unsafe {
189+
FltCreateCommunicationPort(
190+
G_MINIFILTER_HANDLE,
191+
&mut PORT,
192+
&mut oa,
193+
null_mut(),
194+
Some(MiniConnect),
195+
Some(MiniDisconnect),
196+
Some(MiniSendRec),
197+
1,
198+
)
199+
};
194200

195-
if !NT_SUCCESS!(status) {
196201
unsafe {
197-
FltUnregisterFilter(G_MINIFILTER_HANDLE);
202+
FltFreeSecurityDescriptor(sd);
203+
}
204+
205+
if NT_SUCCESS!(status) {
206+
// driver.DriverUnload = Some(driver_exit);
207+
208+
// start minifilter driver
209+
status = unsafe { FltStartFiltering(G_MINIFILTER_HANDLE) };
210+
211+
if !NT_SUCCESS!(status) {
212+
unsafe {
213+
FltUnregisterFilter(G_MINIFILTER_HANDLE);
214+
}
215+
}
198216
}
199217
}
200218

201219
status
202220
}
203221

222+
unsafe extern "C" fn MiniConnect(
223+
ClientPort: PFLT_PORT,
224+
ServerPortCookie: PVOID,
225+
ConnectionContext: PVOID,
226+
SizeOfContext: ULONG,
227+
ConnectionPortCookie: *mut PVOID,
228+
) -> NTSTATUS {
229+
CLIENT_PORT = ClientPort;
230+
DbgPrint("Rust connect fromm application\n\0".as_ptr() as _);
231+
232+
STATUS_SUCCESS
233+
}
234+
235+
unsafe extern "C" fn MiniDisconnect(ConnectionCookie: PVOID) {
236+
DbgPrint("Rust disconnect form application\n\0".as_ptr() as _);
237+
FltCloseClientPort(G_MINIFILTER_HANDLE, &mut CLIENT_PORT);
238+
}
239+
240+
unsafe extern "C" fn MiniSendRec(
241+
PortCookie: PVOID,
242+
InputBuffer: PVOID,
243+
InputBufferLength: ULONG,
244+
OutputBuffer: PVOID,
245+
OutputBufferLength: ULONG,
246+
ReturnOutputBufferLength: PULONG,
247+
) -> NTSTATUS {
248+
// let mut msg: PCHAR = "Rust from kernel".as_mut_ptr() as *mut i8;
249+
unsafe {
250+
DbgPrint(
251+
"Rust message from application: %s\n\0".as_ptr() as _,
252+
InputBuffer as PCHAR,
253+
);
254+
}
255+
256+
unsafe {
257+
strcpy(
258+
OutputBuffer as PCHAR,
259+
"Rust from kernel".as_ptr() as *mut i8,
260+
);
261+
}
262+
263+
STATUS_SUCCESS
264+
}
265+
266+
/*
204267
unsafe extern "C" fn driver_exit(_driver: *mut DRIVER_OBJECT) {
205268
FltUnregisterFilter(G_MINIFILTER_HANDLE);
206269
207270
unsafe {
208271
DbgPrint("\nBye bye from Rust!\0".as_ptr() as _);
209272
}
210273
}
274+
*/

src/shared_def.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

windows-kernel-alloc/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cargo.lock
2+
target

windows-kernel-alloc/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "windows-kernel-alloc"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
windows-kernel-sys = {path = "../windows-kernel-sys"}
10+
11+
[features]
12+
default = []
13+
alloc_panic = []
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//it must be defined in lib.rs
2+
//#![feature(alloc_error_handler)]
3+
#[allow(unused_imports)]
4+
use alloc::alloc::handle_alloc_error;
5+
use core::alloc::{GlobalAlloc, Layout};
6+
use windows_kernel_sys::base::{SIZE_T, ULONG64};
7+
use windows_kernel_sys::ntoskrnl::{ExAllocatePool2, ExFreePool};
8+
9+
10+
pub const POOL_TAG: u32 = u32::from_ne_bytes(*b"TSUR");
11+
pub const POOL_FLAG_PAGED: ULONG64 = 0x0000000000000100;
12+
13+
pub struct KernelAlloc;
14+
15+
unsafe impl GlobalAlloc for KernelAlloc {
16+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
17+
let pool = ExAllocatePool2(POOL_FLAG_PAGED, layout.size() as SIZE_T, POOL_TAG);
18+
19+
#[cfg(feature = "alloc_panic")]
20+
if pool.is_null() {
21+
handle_alloc_error(layout);
22+
}
23+
24+
pool as _
25+
}
26+
27+
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
28+
ExFreePool(ptr as _);
29+
}
30+
}
31+
32+
#[alloc_error_handler]
33+
fn alloc_error(layout: Layout) -> ! {
34+
panic!("allocation error: {:?}", layout);
35+
}

windows-kernel-alloc/src/lib.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//source idea: https://os.phil-opp.com/minimal-rust-kernel/
2+
#![no_std]
3+
#![feature(lang_items)]
4+
#![feature(alloc_error_handler)]
5+
6+
extern crate alloc;
7+
8+
use alloc::string::ToString;
9+
use core::{ffi::c_void, panic::PanicInfo};
10+
11+
pub mod kernel_alloc;
12+
13+
#[cfg(not(test))]
14+
#[global_allocator]
15+
static GLOBAL: kernel_alloc::KernelAlloc = kernel_alloc::KernelAlloc;
16+
17+
#[cfg(not(test))]
18+
#[export_name = "_fltused"]
19+
static _FLTUSED: i32 = 0;
20+
21+
#[cfg(not(test))]
22+
#[no_mangle]
23+
extern "system" fn __CxxFrameHandler3(_: *mut u8, _: *mut u8, _: *mut u8, _: *mut u8) -> i32 {
24+
unimplemented!()
25+
}
26+
27+
/// Base code
28+
const BUGCHECK_CODE: u32 = 0xDEAD0000;
29+
30+
#[cfg(not(test))]
31+
#[cfg_attr(all(target_env = "msvc", feature = "kernel"), link(name = "ntoskrnl"))]
32+
extern "system" {
33+
fn KeBugCheckEx(
34+
BugCheckCode: u32,
35+
BugCheckParameter1: u32,
36+
BugCheckParameter2: u32,
37+
BugCheckParameter3: u32,
38+
BugCheckParameter4: u32,
39+
) -> c_void;
40+
}
41+
42+
#[cfg(not(test))]
43+
/// An unrecoverable error will cause the kernel to crash.
44+
fn unrecoverable_error(info: &PanicInfo) {
45+
let msg = info.to_string();
46+
unsafe {
47+
KeBugCheckEx(BUGCHECK_CODE, msg.as_ptr() as u32, 0, 0, 0);
48+
}
49+
}
50+
51+
#[cfg(not(test))]
52+
#[panic_handler]
53+
fn panic(info: &PanicInfo) -> ! {
54+
unrecoverable_error(info);
55+
loop {}
56+
}
57+
58+
#[cfg(not(test))]
59+
#[lang = "eh_personality"]
60+
extern "C" fn eh_personality() {}

windows-kernel-macros/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Cargo.lock
2+
target

windows-kernel-macros/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "windows-kernel-macros"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
windows-kernel-sys = { path = "../windows-kernel-sys"}
10+
windows-kernel-string = { path = "../windows-kernel-string"}

0 commit comments

Comments
 (0)