diff --git a/Cargo.lock b/Cargo.lock index 21c7d07e..743ec3fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1384,7 +1384,6 @@ dependencies = [ "tempfile", "thiserror 2.0.18", "uuid", - "windows-sys 0.52.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fb01891e..6af06d6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,11 +48,6 @@ procfs-core = { version = "0.18", default-features = false, features = ["serde1" [target.'cfg(target_os = "windows")'.dependencies] bitflags = "2.4" -windows-sys = { version = ">=0.52", features = [ - "Win32_Foundation", - "Win32_System_Diagnostics_Debug", - "Win32_System_ProcessStatus", -] } [target.'cfg(target_os = "macos")'.dependencies] # Binds some additional mac specifics not in libc, note that other dependents diff --git a/src/windows/ffi.rs b/src/windows/ffi.rs index 7dc209da..013c3f89 100644 --- a/src/windows/ffi.rs +++ b/src/windows/ffi.rs @@ -16,9 +16,13 @@ pub use crash_context::{CONTEXT, EXCEPTION_POINTERS, EXCEPTION_RECORD, capture_context}; +use core::ffi::c_void; + pub type HANDLE = isize; +pub type HMODULE = isize; pub type BOOL = i32; pub const FALSE: BOOL = 0; +pub const MAX_PATH: u32 = 260; pub type Hresult = i32; pub const STATUS_NONCONTINUABLE_EXCEPTION: i32 = -1073741787; @@ -144,7 +148,7 @@ pub type VS_FIXEDFILEINFO_FILE_FLAGS = u32; pub struct MINIDUMP_USER_STREAM { pub Type: u32, pub BufferSize: u32, - pub Buffer: *mut std::ffi::c_void, + pub Buffer: *mut c_void, } #[repr(C, packed(4))] pub struct MINIDUMP_USER_STREAM_INFORMATION { @@ -187,9 +191,9 @@ pub struct MINIDUMP_MODULE_CALLBACK { pub CheckSum: u32, pub TimeDateStamp: u32, pub VersionInfo: VS_FIXEDFILEINFO, - pub CvRecord: *mut std::ffi::c_void, + pub CvRecord: *mut c_void, pub SizeOfCvRecord: u32, - pub MiscRecord: *mut std::ffi::c_void, + pub MiscRecord: *mut c_void, pub SizeOfMiscRecord: u32, } @@ -207,7 +211,7 @@ pub struct MINIDUMP_INCLUDE_MODULE_CALLBACK { pub struct MINIDUMP_IO_CALLBACK { pub Handle: HANDLE, pub Offset: u64, - pub Buffer: *mut std::ffi::c_void, + pub Buffer: *mut c_void, pub BufferBytes: u32, } @@ -226,14 +230,14 @@ pub struct MINIDUMP_VM_QUERY_CALLBACK { #[repr(C, packed(4))] pub struct MINIDUMP_VM_PRE_READ_CALLBACK { pub Offset: u64, - pub Buffer: *mut std::ffi::c_void, + pub Buffer: *mut c_void, pub Size: u32, } #[repr(C, packed(4))] pub struct MINIDUMP_VM_POST_READ_CALLBACK { pub Offset: u64, - pub Buffer: *mut std::ffi::c_void, + pub Buffer: *mut c_void, pub Size: u32, pub Completed: u32, pub Status: Hresult, @@ -296,20 +300,22 @@ cfg_if::cfg_if! { } } +use std::mem::ManuallyDrop; + #[repr(C)] pub union MINIDUMP_CALLBACK_INPUT_0 { pub Status: Hresult, - pub Thread: std::mem::ManuallyDrop, - pub ThreadEx: std::mem::ManuallyDrop, - pub Module: std::mem::ManuallyDrop, - pub IncludeThread: std::mem::ManuallyDrop, - pub IncludeModule: std::mem::ManuallyDrop, - pub Io: std::mem::ManuallyDrop, - pub ReadMemoryFailure: std::mem::ManuallyDrop, + pub Thread: ManuallyDrop, + pub ThreadEx: ManuallyDrop, + pub Module: ManuallyDrop, + pub IncludeThread: ManuallyDrop, + pub IncludeModule: ManuallyDrop, + pub Io: ManuallyDrop, + pub ReadMemoryFailure: ManuallyDrop, pub SecondaryFlags: u32, - pub VmQuery: std::mem::ManuallyDrop, - pub VmPreRead: std::mem::ManuallyDrop, - pub VmPostRead: std::mem::ManuallyDrop, + pub VmQuery: ManuallyDrop, + pub VmPreRead: ManuallyDrop, + pub VmPostRead: ManuallyDrop, } #[repr(C, packed(4))] @@ -387,12 +393,12 @@ pub union MINIDUMP_CALLBACK_OUTPUT_0 { pub ModuleWriteFlags: ModuleWriteFlags, pub ThreadWriteFlags: u32, pub SecondaryFlags: u32, - pub Anonymous1: std::mem::ManuallyDrop, - pub Anonymous2: std::mem::ManuallyDrop, + pub Anonymous1: ManuallyDrop, + pub Anonymous2: ManuallyDrop, pub Handle: HANDLE, - pub Anonymous3: std::mem::ManuallyDrop, - pub Anonymous4: std::mem::ManuallyDrop, - pub Anonymous5: std::mem::ManuallyDrop, + pub Anonymous3: ManuallyDrop, + pub Anonymous4: ManuallyDrop, + pub Anonymous5: ManuallyDrop, pub Status: Hresult, } @@ -403,7 +409,7 @@ pub struct MINIDUMP_CALLBACK_OUTPUT { pub type MINIDUMP_CALLBACK_ROUTINE = Option< unsafe extern "system" fn( - CallbackParam: *mut std::ffi::c_void, + CallbackParam: *mut c_void, CallbackInput: *const MINIDUMP_CALLBACK_INPUT, CallbackOutput: *mut MINIDUMP_CALLBACK_OUTPUT, ) -> BOOL, @@ -412,7 +418,14 @@ pub type MINIDUMP_CALLBACK_ROUTINE = Option< #[repr(C, packed(4))] pub struct MINIDUMP_CALLBACK_INFORMATION { pub CallbackRoutine: MINIDUMP_CALLBACK_ROUTINE, - pub CallbackParam: *mut std::ffi::c_void, + pub CallbackParam: *mut c_void, +} + +#[repr(C)] +pub struct MODULEINFO { + pub base_of_dll: *mut c_void, + pub size_of_image: u32, + pub entry_point: *mut c_void, } #[link(name = "kernel32")] @@ -432,7 +445,32 @@ unsafe extern "system" { ) -> HANDLE; pub fn ResumeThread(thread: HANDLE) -> u32; pub fn SuspendThread(thread: HANDLE) -> u32; + pub fn ReadProcessMemory( + process: HANDLE, + base_addr: *const c_void, + buffer: *mut c_void, + size: usize, + bytes_read: *mut usize, + ) -> BOOL; pub fn GetThreadContext(thread: HANDLE, context: *mut CONTEXT) -> BOOL; + pub fn K32EnumProcessModules( + process: HANDLE, + module: *mut HMODULE, + size: u32, + needed: *mut u32, + ) -> BOOL; + pub fn K32GetModuleBaseNameW( + process: HANDLE, + module: HMODULE, + base_name: *mut u16, + size: u32, + ) -> u32; + pub fn K32GetModuleInformation( + process: HANDLE, + module: HMODULE, + mod_info: *mut MODULEINFO, + cb: u32, + ) -> BOOL; } #[link(name = "dbghelp")] diff --git a/src/windows/process_reader.rs b/src/windows/process_reader.rs index 9ddd145a..c8db14e9 100644 --- a/src/windows/process_reader.rs +++ b/src/windows/process_reader.rs @@ -1,23 +1,15 @@ use { - crate::{module_reader::ModuleMemory, serializers::*}, + super::ffi::{self, HMODULE}, + crate::{module_reader::ModuleMemory, serializers::serialize_io_error}, std::{ convert::TryInto, ffi::OsString, mem::{MaybeUninit, size_of}, os::windows::ffi::OsStringExt, }, - windows_sys::Win32::{ - Foundation::{FALSE, HMODULE, MAX_PATH}, - System::{ - Diagnostics::Debug::ReadProcessMemory, - ProcessStatus::{ - K32EnumProcessModules, K32GetModuleBaseNameW, K32GetModuleInformation, MODULEINFO, - }, - }, - }, }; -pub type ProcessHandle = windows_sys::Win32::Foundation::HANDLE; +pub type ProcessHandle = ffi::HANDLE; pub struct ProcessReader { process: ProcessHandle, @@ -51,7 +43,7 @@ impl ProcessReader { pub fn read(&self, src: usize, dst: &mut [u8]) -> Result { let mut size: usize = 0; let res = unsafe { - ReadProcessMemory( + ffi::ReadProcessMemory( self.process, src as _, dst.as_mut_ptr() as _, @@ -60,7 +52,7 @@ impl ProcessReader { ) }; - if res != FALSE { + if res != ffi::FALSE { Ok(size) } else { Err(CopyFromProcessError { @@ -81,7 +73,7 @@ impl ProcessReader { // sufficient for our use-cases. if name.is_some_and(|name| name.eq_ignore_ascii_case(module_name)) { self.get_module_info(module) - .map(|module| module.lpBaseOfDll as usize) + .map(|module| module.base_of_dll as usize) } else { None } @@ -102,7 +94,7 @@ impl ProcessReader { .try_into() .map_err(|_| FindModuleError::ModuleListTooLarge)?; let res = unsafe { - K32EnumProcessModules( + ffi::K32EnumProcessModules( self.process, module_array.as_mut_ptr() as *mut _, buffer_size, @@ -130,9 +122,12 @@ impl ProcessReader { } fn get_module_name(&self, module: HMODULE) -> Option { + use ffi::MAX_PATH; + let mut path: [u16; MAX_PATH as usize] = [0; MAX_PATH as usize]; - let res = - unsafe { K32GetModuleBaseNameW(self.process, module, path.as_mut_ptr(), MAX_PATH) }; + let res = unsafe { + ffi::K32GetModuleBaseNameW(self.process, module, path.as_mut_ptr(), MAX_PATH) + }; if res == 0 { None @@ -143,14 +138,14 @@ impl ProcessReader { } } - fn get_module_info(&self, module: HMODULE) -> Option { - let mut info: MaybeUninit = MaybeUninit::uninit(); + fn get_module_info(&self, module: HMODULE) -> Option { + let mut info: MaybeUninit = MaybeUninit::uninit(); let res = unsafe { - K32GetModuleInformation( + ffi::K32GetModuleInformation( self.process, module, info.as_mut_ptr(), - size_of::() as u32, + size_of::() as u32, ) };