Build RE baseline and initial Rust workspace
This commit is contained in:
parent
8d1f280e2e
commit
ffaf155ef0
39 changed files with 5974 additions and 8 deletions
9
crates/rrt-hook/Cargo.toml
Normal file
9
crates/rrt-hook/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "rrt-hook"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[lib]
|
||||
name = "dinput8"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
170
crates/rrt-hook/src/lib.rs
Normal file
170
crates/rrt-hook/src/lib.rs
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#![cfg_attr(not(windows), allow(dead_code))]
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows_hook {
|
||||
use core::ffi::{c_char, c_void};
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
|
||||
const DLL_PROCESS_ATTACH: u32 = 1;
|
||||
const E_FAIL: i32 = 0x8000_4005_u32 as i32;
|
||||
const FILE_APPEND_DATA: u32 = 0x0000_0004;
|
||||
const FILE_SHARE_READ: u32 = 0x0000_0001;
|
||||
const OPEN_ALWAYS: u32 = 4;
|
||||
const FILE_ATTRIBUTE_NORMAL: u32 = 0x0000_0080;
|
||||
const INVALID_HANDLE_VALUE: isize = -1;
|
||||
const FILE_END: u32 = 2;
|
||||
|
||||
static LOG_PATH: &[u8] = b"rrt_hook_attach.log\0";
|
||||
static ATTACH_MESSAGE: &[u8] = b"rrt-hook: process attach\n";
|
||||
static DEBUG_MESSAGE: &[u8] = b"rrt-hook: DllMain process attach\0";
|
||||
static DIRECT_INPUT8_CREATE_NAME: &[u8] = b"DirectInput8Create\0";
|
||||
static mut REAL_DINPUT8_CREATE: Option<DirectInput8CreateFn> = None;
|
||||
|
||||
unsafe extern "system" {
|
||||
fn CreateFileA(
|
||||
lp_file_name: *const c_char,
|
||||
desired_access: u32,
|
||||
share_mode: u32,
|
||||
security_attributes: *mut c_void,
|
||||
creation_disposition: u32,
|
||||
flags_and_attributes: u32,
|
||||
template_file: *mut c_void,
|
||||
) -> isize;
|
||||
fn SetFilePointer(
|
||||
file: isize,
|
||||
distance: i32,
|
||||
distance_high: *mut i32,
|
||||
move_method: u32,
|
||||
) -> u32;
|
||||
fn WriteFile(
|
||||
file: isize,
|
||||
buffer: *const c_void,
|
||||
bytes_to_write: u32,
|
||||
bytes_written: *mut u32,
|
||||
overlapped: *mut c_void,
|
||||
) -> i32;
|
||||
fn CloseHandle(handle: isize) -> i32;
|
||||
fn DisableThreadLibraryCalls(module: *mut c_void) -> i32;
|
||||
fn GetSystemDirectoryA(buffer: *mut u8, size: u32) -> u32;
|
||||
fn GetProcAddress(module: isize, name: *const c_char) -> *mut c_void;
|
||||
fn LoadLibraryA(name: *const c_char) -> isize;
|
||||
fn OutputDebugStringA(output: *const c_char);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct Guid {
|
||||
data1: u32,
|
||||
data2: u16,
|
||||
data3: u16,
|
||||
data4: [u8; 8],
|
||||
}
|
||||
|
||||
type DirectInput8CreateFn = unsafe extern "system" fn(
|
||||
instance: *mut c_void,
|
||||
version: u32,
|
||||
riid: *const Guid,
|
||||
out: *mut *mut c_void,
|
||||
outer: *mut c_void,
|
||||
) -> i32;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "system" fn DllMain(
|
||||
module: *mut c_void,
|
||||
reason: u32,
|
||||
_reserved: *mut c_void,
|
||||
) -> i32 {
|
||||
if reason == DLL_PROCESS_ATTACH {
|
||||
unsafe {
|
||||
let _ = DisableThreadLibraryCalls(module);
|
||||
OutputDebugStringA(DEBUG_MESSAGE.as_ptr().cast());
|
||||
append_attach_log();
|
||||
}
|
||||
}
|
||||
1
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub extern "system" fn DirectInput8Create(
|
||||
instance: *mut c_void,
|
||||
version: u32,
|
||||
riid: *const Guid,
|
||||
out: *mut *mut c_void,
|
||||
outer: *mut c_void,
|
||||
) -> i32 {
|
||||
let direct_input8_create = unsafe { load_direct_input8_create() };
|
||||
match direct_input8_create {
|
||||
Some(callback) => unsafe { callback(instance, version, riid, out, outer) },
|
||||
None => E_FAIL,
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn append_attach_log() {
|
||||
let handle = unsafe {
|
||||
CreateFileA(
|
||||
LOG_PATH.as_ptr().cast(),
|
||||
FILE_APPEND_DATA,
|
||||
FILE_SHARE_READ,
|
||||
ptr::null_mut(),
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
if handle == INVALID_HANDLE_VALUE {
|
||||
return;
|
||||
}
|
||||
|
||||
let _ = unsafe { SetFilePointer(handle, 0, ptr::null_mut(), FILE_END) };
|
||||
let mut bytes_written = 0_u32;
|
||||
let _ = unsafe {
|
||||
WriteFile(
|
||||
handle,
|
||||
ATTACH_MESSAGE.as_ptr().cast(),
|
||||
ATTACH_MESSAGE.len() as u32,
|
||||
&mut bytes_written,
|
||||
ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
let _ = unsafe { CloseHandle(handle) };
|
||||
}
|
||||
|
||||
unsafe fn load_direct_input8_create() -> Option<DirectInput8CreateFn> {
|
||||
if let Some(callback) = unsafe { REAL_DINPUT8_CREATE } {
|
||||
return Some(callback);
|
||||
}
|
||||
|
||||
let mut system_directory = [0_u8; 260];
|
||||
let length = unsafe {
|
||||
GetSystemDirectoryA(system_directory.as_mut_ptr(), system_directory.len() as u32)
|
||||
};
|
||||
if length == 0 || length as usize >= system_directory.len() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut dll_path = system_directory[..length as usize].to_vec();
|
||||
dll_path.extend_from_slice(br"\dinput8.dll");
|
||||
dll_path.push(0);
|
||||
|
||||
let module = unsafe { LoadLibraryA(dll_path.as_ptr().cast()) };
|
||||
if module == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let symbol = unsafe { GetProcAddress(module, DIRECT_INPUT8_CREATE_NAME.as_ptr().cast()) };
|
||||
if symbol.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let callback: DirectInput8CreateFn = unsafe { mem::transmute(symbol) };
|
||||
unsafe {
|
||||
REAL_DINPUT8_CREATE = Some(callback);
|
||||
}
|
||||
Some(callback)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn host_build_marker() -> &'static str {
|
||||
"rrt-hook host build"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue