From 47e03ee91f75396b902999086076c7227c70e955 Mon Sep 17 00:00:00 2001 From: Avery Date: Wed, 11 Jun 2025 15:24:13 -0400 Subject: [PATCH 1/4] swap llvm_asm with naked_asm --- .cargo/{config => config.toml} | 0 src/lib.rs | 163 +++++++++++++++++++-------------- 2 files changed, 95 insertions(+), 68 deletions(-) rename .cargo/{config => config.toml} (100%) diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/src/lib.rs b/src/lib.rs index 0490a64..8feafa0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,40 +1,42 @@ -#![feature(llvm_asm)] -#![feature(naked_functions)] - +use std::arch::naked_asm; use std::ffi::{CStr, CString}; use std::fs; use std::io::Result as Res; -use std::os::raw::c_char; - -static mut FUNCS: [FARPROC; 5] = [0 as FARPROC; 5]; -static mut HAS_CONSOLE: bool = false; - +use std::os::raw::{c_char, c_void}; use winapi::{ - shared::{ - minwindef::{BOOL, DWORD, FALSE, FARPROC, HINSTANCE, LPVOID, TRUE}, - ntdef::HANDLE, - }, - um::{ - libloaderapi::{GetProcAddress, LoadLibraryA}, - consoleapi::AllocConsole, - processenv::SetStdHandle, - winbase::STD_OUTPUT_HANDLE, - } + shared::{ + minwindef::{BOOL, DWORD, FALSE, HINSTANCE, LPVOID, TRUE}, + ntdef::HANDLE, + }, + um::{ + consoleapi::AllocConsole, + libloaderapi::{GetProcAddress, LoadLibraryA}, + processenv::SetStdHandle, + winbase::STD_OUTPUT_HANDLE, + }, }; +static mut FUNC_1: *const c_void = std::ptr::null(); +static mut FUNC_2: *const c_void = std::ptr::null(); +static mut FUNC_3: *const c_void = std::ptr::null(); +static mut FUNC_4: *const c_void = std::ptr::null(); +static mut FUNC_5: *const c_void = std::ptr::null(); + +static mut HAS_CONSOLE: bool = false; + #[no_mangle] #[allow(unused_variables)] pub extern "system" fn DllMain( - dll_module: HINSTANCE, - call_reason: DWORD, - reserved: LPVOID) - -> BOOL { - const DLL_PROCESS_ATTACH: DWORD = 1; + dll_module: HINSTANCE, + call_reason: DWORD, + reserved: LPVOID, +) -> BOOL { + const DLL_PROCESS_ATTACH: DWORD = 1; - match call_reason { - DLL_PROCESS_ATTACH => init(), - _ => TRUE - } + match call_reason { + DLL_PROCESS_ATTACH => init(), + _ => TRUE, + } } macro_rules! error { @@ -51,53 +53,78 @@ macro_rules! error { } unsafe fn s(bytes: &[u8]) -> *const c_char { - CStr::from_bytes_with_nul_unchecked(bytes).as_ptr() + CStr::from_bytes_with_nul_unchecked(bytes).as_ptr() } fn init() -> BOOL { - let dinput = unsafe { LoadLibraryA(s(b"C:\\Windows\\System32\\dinput8.dll\0")) }; - if dinput.is_null() { - error!("modloader error: could not load real dinput8"); - return FALSE; - } - unsafe { - FUNCS[0] = GetProcAddress(dinput, s(b"DirectInput8Create\0")); - FUNCS[1] = GetProcAddress(dinput, s(b"DllCanUnloadNow\0")); - FUNCS[2] = GetProcAddress(dinput, s(b"DllGetClassObject\0")); - FUNCS[3] = GetProcAddress(dinput, s(b"DllRegisterServer\0")); - FUNCS[4] = GetProcAddress(dinput, s(b"DllUnregisterServer\0")); - } + let dinput = unsafe { LoadLibraryA(s(b"C:\\Windows\\System32\\dinput8.dll\0")) }; + if dinput.is_null() { + error!("modloader error: could not load real dinput8"); + return FALSE; + } + unsafe { + FUNC_1 = std::mem::transmute(GetProcAddress(dinput, s(b"DirectInput8Create\0"))); + FUNC_2 = std::mem::transmute(GetProcAddress(dinput, s(b"DllCanUnloadNow\0"))); + FUNC_3 = std::mem::transmute(GetProcAddress(dinput, s(b"DllGetClassObject\0"))); + FUNC_4 = std::mem::transmute(GetProcAddress(dinput, s(b"DllRegisterServer\0"))); + FUNC_5 = std::mem::transmute(GetProcAddress(dinput, s(b"DllUnregisterServer\0"))); + } - match load_mods() { - Ok(()) => TRUE, - Err(e) => { - error!("modloader error: {}", e); - FALSE - } - } + match load_mods() { + Ok(()) => TRUE, + Err(e) => { + error!("modloader error: {}", e); + FALSE + } + } } fn load_mods() -> Res<()> { - for entry in fs::read_dir("mods")? { - let entry = entry.unwrap(); - if entry.file_type()?.is_dir() { - let mut path = entry.path(); - path.push("mod.dll"); - let string = path.as_os_str().to_str().unwrap(); - let cstring = CString::new(string)?; - let m = unsafe { LoadLibraryA(cstring.as_c_str().as_ptr()) }; - if m.is_null() { - error!("modloader error: could not load mod: {}", string); - } else { - println!("modloader: sucessfully loaded {}", string); - } - } - } - Ok(()) + for entry in fs::read_dir("mods")? { + let entry = entry.unwrap(); + if entry.file_type()?.is_dir() { + let mut path = entry.path(); + path.push("mod.dll"); + let string = path.as_os_str().to_str().unwrap(); + let cstring = CString::new(string)?; + let m = unsafe { LoadLibraryA(cstring.as_c_str().as_ptr()) }; + if m.is_null() { + error!("modloader error: could not load mod: {string}"); + } else { + println!("modloader: sucessfully loaded {string}"); + } + } + } + + Ok(()) +} + +#[unsafe(naked)] +#[no_mangle] +pub extern "system" fn DirectInput8Create() { + naked_asm!("jmp [{}]", sym FUNC_1); } -#[naked]#[no_mangle]pub extern "system" fn DirectInput8Create() { unsafe { llvm_asm!("jmp *$0":: "r"(FUNCS[0])); }} -#[naked]#[no_mangle]pub extern "system" fn DllCanUnloadNow() { unsafe { llvm_asm!("jmp *$0":: "r"(FUNCS[1])); }} -#[naked]#[no_mangle]pub extern "system" fn DllGetClassObject() { unsafe { llvm_asm!("jmp *$0":: "r"(FUNCS[2])); }} -#[naked]#[no_mangle]pub extern "system" fn DllRegisterServer() { unsafe { llvm_asm!("jmp *$0":: "r"(FUNCS[3])); }} -#[naked]#[no_mangle]pub extern "system" fn DllUnregisterServer() { unsafe { llvm_asm!("jmp *$0":: "r"(FUNCS[4])); }} +#[unsafe(naked)] +#[no_mangle] +pub extern "system" fn DllCanUnloadNow() { + naked_asm!("jmp [{}]", sym FUNC_2); +} + +#[unsafe(naked)] +#[no_mangle] +pub extern "system" fn DllGetClassObject() { + naked_asm!("jmp [{}]", sym FUNC_3); +} + +#[unsafe(naked)] +#[no_mangle] +pub extern "system" fn DllRegisterServer() { + naked_asm!("jmp [{}]", sym FUNC_4); +} + +#[unsafe(naked)] +#[no_mangle] +pub extern "system" fn DllUnregisterServer() { + naked_asm!("jmp [{}]", sym FUNC_5); +} From 2928aa25f6e17afe8be5b29800acfcf4c4f87b4c Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Wed, 11 Jun 2025 15:34:57 -0400 Subject: [PATCH 2/4] Create rust.yml --- .github/workflows/rust.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..93774ce --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,26 @@ +name: Rust + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + - name: Build + run: cargo build --verbose + - name: Upload release artifact + uses: actions/upload-artifact@v4 + with: + name: dinput8.dll + path: target/${{ matrix.BUILD_TARGET }}/dinput8.dll + From 095118e203cba8cba623884a86162357ab200619 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Wed, 11 Jun 2025 15:38:47 -0400 Subject: [PATCH 3/4] Update rust.yml --- .github/workflows/rust.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 93774ce..413414d 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -11,16 +11,19 @@ env: jobs: build: - runs-on: windows-latest steps: - uses: actions/checkout@v4 - - name: Build - run: cargo build --verbose + + - name: Install target + run: rustup target add i686-pc-windows-msvc + + - name: Build (Release, i686) + run: cargo build --release --target i686-pc-windows-msvc --verbose + - name: Upload release artifact uses: actions/upload-artifact@v4 with: name: dinput8.dll - path: target/${{ matrix.BUILD_TARGET }}/dinput8.dll - + path: target/i686-pc-windows-msvc/release/dinput8.dll From bf7e705c873fba19a39e124dbe22a5f7f3517fd1 Mon Sep 17 00:00:00 2001 From: Avery Townsend Date: Wed, 11 Jun 2025 15:39:52 -0400 Subject: [PATCH 4/4] Update rust.yml --- .github/workflows/rust.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 413414d..d6c9b17 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -19,10 +19,10 @@ jobs: - name: Install target run: rustup target add i686-pc-windows-msvc - - name: Build (Release, i686) + - name: Build run: cargo build --release --target i686-pc-windows-msvc --verbose - - name: Upload release artifact + - name: Upload artifact uses: actions/upload-artifact@v4 with: name: dinput8.dll