From 3df82c0fd17b7a68083325b4fe3f70ef9694b624 Mon Sep 17 00:00:00 2001 From: elia <176603882+7elia@users.noreply.github.com> Date: Sat, 2 May 2026 14:16:15 +0200 Subject: [PATCH] feat(native): use slimdetours --- .github/workflows/build_mod.yml | 4 +- .github/workflows/build_native.yml | 12 ++- Cargo.lock | 59 +++---------- packages/native/Cargo.toml | 2 +- packages/native/src/win/mod.rs | 137 ++++++++++++++++------------- 5 files changed, 94 insertions(+), 120 deletions(-) diff --git a/.github/workflows/build_mod.yml b/.github/workflows/build_mod.yml index e99bf5f..4d8bfa8 100644 --- a/.github/workflows/build_mod.yml +++ b/.github/workflows/build_mod.yml @@ -4,10 +4,8 @@ on: workflow_dispatch: push: paths: ['packages/mod/**'] - branches: [master] pull_request: paths: ['packages/mod/**'] - branches: [master] jobs: build-mod: @@ -36,7 +34,7 @@ jobs: path: packages/mod/dist/ - name: Update Release - if: github.event_name != 'pull_request' + if: github.ref == 'refs/heads/master' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload artifacts packages/mod/dist/* --clobber diff --git a/.github/workflows/build_native.yml b/.github/workflows/build_native.yml index b342fe0..c37e8ba 100644 --- a/.github/workflows/build_native.yml +++ b/.github/workflows/build_native.yml @@ -4,10 +4,8 @@ on: workflow_dispatch: push: paths: ['packages/native/**'] - branches: [master] pull_request: paths: ['packages/native/**'] - branches: [master] jobs: build: @@ -22,10 +20,10 @@ jobs: output: extendify_native target: windows_x86_64 extension: .dll - # - os: windows-11-arm - # output: extendify_native - # target: windows_aarch64 - # extension: .dll + - os: windows-11-arm + output: extendify_native + target: windows_aarch64 + extension: .dll # - os: macos-latest # output: libextendify_native # target: macos_arm64 @@ -56,7 +54,7 @@ jobs: run: cp target/release/${{ matrix.output }}${{ matrix.extension }} ${{ matrix.target }}${{ matrix.extension }} - name: Update Release - if: github.event_name != 'pull_request' + if: github.ref == 'refs/heads/master' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: gh release upload native ${{ matrix.target }}${{ matrix.extension }} --clobber diff --git a/Cargo.lock b/Cargo.lock index c97f4be..1ce9e69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,7 +111,7 @@ name = "extendify-native" version = "0.1.0" dependencies = [ "bindgen", - "minhook", + "slim-detours-sys", "ureq", "windows-sys 0.61.2", ] @@ -208,16 +208,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" -[[package]] -name = "minhook" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455e088cb1600ffa5f1524c9702c9eeb0ba3604e0f4932efa165b99973272a8d" -dependencies = [ - "cc", - "tracing", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -256,12 +246,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "pin-project-lite" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" - [[package]] name = "prettyplease" version = "0.2.37" @@ -386,6 +370,15 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "slim-detours-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19a519e4f3dc47c5f55a3c1d87b6ba499a11bd81c3a3ca2ed0c835f5e120fd32" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "subtle" version = "2.6.1" @@ -403,38 +396,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tracing" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" -dependencies = [ - "once_cell", -] - [[package]] name = "unicode-ident" version = "1.0.24" diff --git a/packages/native/Cargo.toml b/packages/native/Cargo.toml index 9bc8e5f..d66e813 100644 --- a/packages/native/Cargo.toml +++ b/packages/native/Cargo.toml @@ -8,7 +8,7 @@ name = "extendify_native" crate-type = ["cdylib"] [target.'cfg(windows)'.dependencies] -minhook = "0.9.0" +slim-detours-sys = "0.4.0" [target.'cfg(windows)'.dependencies.windows-sys] version = "0.61.2" diff --git a/packages/native/src/win/mod.rs b/packages/native/src/win/mod.rs index dae730f..7bab83c 100644 --- a/packages/native/src/win/mod.rs +++ b/packages/native/src/win/mod.rs @@ -4,10 +4,12 @@ use crate::cef::{ _cef_settings_t, cef_string_t, }; use crate::{log, vtable_hooks}; -use minhook::MinHook; -use std::ffi::{c_int, c_void}; +use slim_detours_sys::{ + SlimDetoursAttach, SlimDetoursTransactionBegin, SlimDetoursTransactionCommit, +}; +use std::ffi::{CString, c_int, c_void}; use windows_sys::Win32::Foundation::HINSTANCE; -use windows_sys::Win32::System::LibraryLoader::LoadLibraryW; +use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleW, GetProcAddress, LoadLibraryW}; use windows_sys::Win32::System::SystemServices::{DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH}; use windows_sys::core::BOOL; @@ -28,59 +30,84 @@ pub extern "system" fn DllMain( 1 } +fn get_libcef_name() -> Vec { + "libcef.dll" + .encode_utf16() + .chain(std::iter::once(0)) + .collect() +} + +fn ensure_libcef() { + let name = get_libcef_name(); + + unsafe { + let module = GetModuleHandleW(name.as_ptr()); + if module.is_null() { + log("Force loading CEF"); + + LoadLibraryW(name.as_ptr()); + } + } +} + macro_rules! define_hook { ($symbol:expr, $hook:expr, $original:expr) => { unsafe { - match MinHook::create_hook_api("libcef.dll", $symbol, $hook as _) { - Ok(original) => { - $original = Some(std::mem::transmute(original)); - log(format!("Created {} hook", stringify!($symbol))); - } - Err(e) => { - log(format!( - "Couldn't create {} hook {}", - stringify!($symbol), - e - )); + let module = GetModuleHandleW(get_libcef_name().as_ptr()); + if module.is_null() { + log("Cef is not loaded"); + return; + } + + let symbol_c = CString::new($symbol).unwrap(); + if let Some(target) = GetProcAddress(module, symbol_c.as_ptr() as _) { + $original = Some(std::mem::transmute(target)); + + SlimDetoursTransactionBegin(); + SlimDetoursAttach(std::ptr::addr_of_mut!($original) as _, $hook as _); + let status = SlimDetoursTransactionCommit(); + + if status >= 0 { + log(format!("Created hook for {}", $symbol)); + } else { + log(format!("Hook for {} failed {}", $symbol, status)); } + } else { + log(format!("Couldn't find target symbol {}", $symbol)); } } }; } -fn init_hooks() { - log("Force-loading CEF"); - - let name: Vec = "libcef.dll" - .encode_utf16() - .chain(std::iter::once(0)) - .collect(); - unsafe { LoadLibraryW(name.as_ptr()) }; +macro_rules! define_inline_hook { + ($target: expr, $hook: expr, $original: expr) => { + $original = Some(std::mem::transmute($target)); + + SlimDetoursTransactionBegin(); + SlimDetoursAttach(std::ptr::addr_of_mut!($original) as _, $hook as _); + let status = SlimDetoursTransactionCommit(); + + if status >= 0 { + log(format!("Created inline hook {}", stringify!($hook))); + } else { + log(format!( + "Failed to create inlike hook {} {}", + stringify!($hook), + status + )); + } + }; +} - log(format!("Initializing hooks on PID {}", std::process::id())); +fn init_hooks() { + ensure_libcef(); define_hook!("cef_initialize", cef_initialize_hook, CEF_INITIALIZE_OG); define_hook!("cef_execute_process", cef_process_hook, CEF_PROCESS_OG); define_hook!("cef_browser_view_create", cef_view_hook, CEF_VIEW_OG); - - unsafe { - if let Err(e) = MinHook::enable_all_hooks() { - log(format!("Couldn't enable hooks {e}")); - } - } } -fn deinit_hooks() { - log("Uninitializing hooks"); - - unsafe { - if let Err(e) = MinHook::disable_all_hooks() { - log(format!("Couldn't disable hooks {e}")); - } - - MinHook::uninitialize(); - } -} +fn deinit_hooks() {} static mut CEF_INITIALIZE_OG: Option< unsafe extern "C" fn( @@ -125,21 +152,11 @@ unsafe extern "C" fn cef_process_hook( let rph = (*app).get_render_process_handler.unwrap()(app); if !rph.is_null() { if let Some(og) = (*rph).on_context_created { - match MinHook::create_hook(og as _, vtable_hooks::on_context_created_hook as _) - { - Ok(original) => { - vtable_hooks::ON_CONTEXT_CREATED_OG = - Some(std::mem::transmute(original)); - log("Created on_context_created hook"); - } - Err(e) => { - log(format!("Failed to hook on_context_created {e}")); - } - } - - if let Err(e) = MinHook::enable_hook(og as _) { - log(format!("couldn't enable on_context_created hook {e}")); - } + define_inline_hook!( + og, + vtable_hooks::on_context_created_hook, + vtable_hooks::ON_CONTEXT_CREATED_OG + ); } } } @@ -175,11 +192,11 @@ unsafe extern "C" fn cef_view_hook( let req_handler = (*client).get_request_handler.unwrap()(client); let og = (*req_handler).get_resource_request_handler.unwrap(); - if let Ok(original) = MinHook::create_hook(og as _, vtable_hooks::res_handler_hook as _) { - vtable_hooks::RES_HANDLER_OG = std::mem::transmute(original); - log("Created res handler hook"); - } - let _ = MinHook::enable_hook(og as _); + define_inline_hook!( + og, + vtable_hooks::res_handler_hook, + vtable_hooks::RES_HANDLER_OG + ); if let Some(func) = CEF_VIEW_OG { return func(client, url, settings, extra_info, request_context, delegate);