POC: fix(win,nap): load node.exe symbols from current executable

This commit is contained in:
Bert Belder 2024-06-10 16:48:06 -07:00
parent e3b2ee183b
commit 955cf3441d
No known key found for this signature in database
GPG Key ID: 7A77887B2E2ED461
3 changed files with 66 additions and 1 deletions

14
Cargo.lock generated
View File

@ -1637,6 +1637,9 @@ dependencies = [
"deno_core",
"deno_permissions",
"libloading 0.7.4",
"minhook",
"widestring",
"winapi",
]
[[package]]
@ -4075,6 +4078,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minhook"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a48ae87876aaa4622bad562f6565cc1961ab8a3394e45247211f20f110286b5e"
dependencies = [
"cc",
"tracing",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@ -6999,6 +7012,7 @@ version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",

View File

@ -17,3 +17,8 @@ path = "lib.rs"
deno_core.workspace = true
deno_permissions.workspace = true
libloading = { version = "0.7" }
[target.'cfg(windows)'.dependencies]
minhook = "0.5.0"
widestring = "1.1.0"
winapi.workspace = true

View File

@ -532,7 +532,10 @@ where
// SAFETY: opening a DLL calls dlopen
#[cfg(not(unix))]
let library = match unsafe { Library::load_with_flags(&path, flags) } {
let library = match unsafe {
install_load_library_hook();
Library::load_with_flags(&path, flags)
} {
Ok(lib) => lib,
Err(e) => return Err(type_error(e.to_string())),
};
@ -569,3 +572,46 @@ where
Ok(exports)
}
use minhook::MinHook;
use widestring::U16CStr;
use winapi::shared::minwindef::{DWORD, HMODULE, LPVOID};
use winapi::shared::ntdef::HANDLE;
use winapi::um::libloaderapi::GetModuleHandleW;
use winapi::um::winnt::LPCWSTR;
type LoadLibraryExWType =
unsafe extern "system" fn(LPCWSTR, HANDLE, DWORD) -> HMODULE;
static ORIGINAL_LOAD_LIBRARY_EX_W: std::sync::OnceLock<LoadLibraryExWType> =
std::sync::OnceLock::new();
fn install_load_library_hook() {
ORIGINAL_LOAD_LIBRARY_EX_W.get_or_init(|| unsafe {
let original = MinHook::create_hook_api(
"KernelBase.dll",
"LoadLibraryExW",
load_library_ex_w_hook as LPVOID,
)
.unwrap();
MinHook::enable_all_hooks().expect("Failed to enable hooks");
std::mem::transmute(original)
});
}
unsafe extern "system" fn load_library_ex_w_hook(
lib_file_name: LPCWSTR,
file: HANDLE,
flags: DWORD,
) -> HMODULE {
if U16CStr::from_ptr_str(lib_file_name)
.to_string_lossy()
.to_lowercase()
== "node.exe"
{
// Return HMODULE of current process
return GetModuleHandleW(std::ptr::null());
}
let original_load_library_ex_w = ORIGINAL_LOAD_LIBRARY_EX_W.get().unwrap();
original_load_library_ex_w(lib_file_name, file, flags)
}