aboutsummaryrefslogtreecommitdiffhomepage
path: root/zluda_redirect
diff options
context:
space:
mode:
authorAndrzej Janik <[email protected]>2020-11-23 20:00:16 +0100
committerAndrzej Janik <[email protected]>2020-11-23 20:01:10 +0100
commiteb7c9aeeee4cf20a4d81a319f4ebf9329efb819f (patch)
treeaf96435ca89cb36ffd414be99acdd1f91c701787 /zluda_redirect
parent0415f873ae15aceda87758f9fcce5d38aa68ca75 (diff)
downloadZLUDA-eb7c9aeeee4cf20a4d81a319f4ebf9329efb819f.tar.gz
ZLUDA-eb7c9aeeee4cf20a4d81a319f4ebf9329efb819f.zip
Rename everything
Diffstat (limited to 'zluda_redirect')
-rw-r--r--zluda_redirect/Cargo.toml14
-rw-r--r--zluda_redirect/src/lib.rs105
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);
+}