diff options
author | Andrzej Janik <[email protected]> | 2020-11-23 20:00:16 +0100 |
---|---|---|
committer | Andrzej Janik <[email protected]> | 2020-11-23 20:01:10 +0100 |
commit | eb7c9aeeee4cf20a4d81a319f4ebf9329efb819f (patch) | |
tree | af96435ca89cb36ffd414be99acdd1f91c701787 /zluda_redirect | |
parent | 0415f873ae15aceda87758f9fcce5d38aa68ca75 (diff) | |
download | ZLUDA-eb7c9aeeee4cf20a4d81a319f4ebf9329efb819f.tar.gz ZLUDA-eb7c9aeeee4cf20a4d81a319f4ebf9329efb819f.zip |
Rename everything
Diffstat (limited to 'zluda_redirect')
-rw-r--r-- | zluda_redirect/Cargo.toml | 14 | ||||
-rw-r--r-- | zluda_redirect/src/lib.rs | 105 |
2 files changed, 119 insertions, 0 deletions
diff --git a/zluda_redirect/Cargo.toml b/zluda_redirect/Cargo.toml new file mode 100644 index 0000000..46069bc --- /dev/null +++ b/zluda_redirect/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "zluda_redirect" +version = "0.0.0" +authors = ["Andrzej Janik <[email protected]>"] +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[target.'cfg(windows)'.dependencies] +detours-sys = "0.1" +wchar = "0.6" +guid = "0.1" +winapi = { version = "0.3", features = ["processthreadsapi", "winbase", "winnt", "winerror", "libloaderapi", "std"] }
\ No newline at end of file diff --git a/zluda_redirect/src/lib.rs b/zluda_redirect/src/lib.rs new file mode 100644 index 0000000..c6cd4be --- /dev/null +++ b/zluda_redirect/src/lib.rs @@ -0,0 +1,105 @@ +#![cfg(windows)] + +extern crate detours_sys; +#[macro_use] +extern crate guid; +extern crate winapi; + +use std::mem; + +use detours_sys::{ + DetourAttach, DetourDetach, DetourRestoreAfterWith, DetourTransactionBegin, + DetourTransactionCommit, DetourUpdateThread, +}; +use wchar::{wch, wch_c}; +use winapi::shared::minwindef::{DWORD, FALSE, HMODULE, TRUE}; +use winapi::um::libloaderapi::LoadLibraryExW; +use winapi::um::processthreadsapi::GetCurrentThread; +use winapi::um::winbase::lstrcmpiW; +use winapi::um::winnt::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, HANDLE, LPCWSTR}; + +const NVCUDA_PATH: &[u16] = wch_c!(r"C:\WINDOWS\system32\nvcuda.dll"); +const ZLUDA_DLL: &[u16] = wch!(r"nvcuda.dll"); +static mut ZLUDA_PATH: Option<Vec<u16>> = None; + +static mut LOAD_LIBRARY_EX: unsafe extern "system" fn( + lpLibFileName: LPCWSTR, + hFile: HANDLE, + dwFlags: DWORD, +) -> HMODULE = LoadLibraryExW; + +#[allow(non_snake_case)] +#[no_mangle] +unsafe extern "system" fn ZludaLoadLibraryExW( + lpLibFileName: LPCWSTR, + hFile: HANDLE, + dwFlags: DWORD, +) -> HMODULE { + let nvcuda_file_name = if lstrcmpiW(lpLibFileName, NVCUDA_PATH.as_ptr()) == 0 { + ZLUDA_PATH.as_ref().unwrap().as_ptr() + } else { + lpLibFileName + }; + (LOAD_LIBRARY_EX)(nvcuda_file_name, hFile, dwFlags) +} + +#[allow(non_snake_case)] +#[no_mangle] +unsafe extern "system" fn DllMain(_: *const u8, dwReason: u32, _: *const u8) -> i32 { + if dwReason == DLL_PROCESS_ATTACH { + DetourRestoreAfterWith(); + match get_zluda_dll_path() { + Some((path, len)) => set_zluda_dll_path(path, len), + None => return FALSE, + } + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourAttach( + std::mem::transmute(&mut LOAD_LIBRARY_EX), + ZludaLoadLibraryExW as *mut _, + ); + DetourTransactionCommit(); + } else if dwReason == DLL_PROCESS_DETACH { + DetourTransactionBegin(); + DetourUpdateThread(GetCurrentThread()); + DetourDetach( + std::mem::transmute(&mut LOAD_LIBRARY_EX), + ZludaLoadLibraryExW as *mut _, + ); + DetourTransactionCommit(); + } + TRUE +} + +fn get_zluda_dll_path() -> Option<(*const u16, usize)> { + let guid = guid! {"C225FC0C-00D7-40B8-935A-7E342A9344C1"}; + let mut module = std::ptr::null_mut(); + loop { + module = unsafe { detours_sys::DetourEnumerateModules(module) }; + if module == std::ptr::null_mut() { + break; + } + let mut size = 0; + let payload = unsafe { + detours_sys::DetourFindPayload(module, std::mem::transmute(&guid), &mut size) + }; + if payload != std::ptr::null_mut() { + return Some((payload as *const _, (size as usize) / mem::size_of::<u16>())); + } + } + None +} + +unsafe fn set_zluda_dll_path(path: *const u16, len: usize) { + let len = len as usize; + let mut result = Vec::<u16>::with_capacity(len + ZLUDA_DLL.len() + 2); + for i in 0..len { + result.push(*path.add(i)); + } + result.push(0x5c); // \ + for c in ZLUDA_DLL.iter().copied() { + result.push(c); + } + result.push(0); + ZLUDA_PATH = Some(result); +} |