diff --git a/cheat/Cargo.toml b/cheat/Cargo.toml index 30eaa53..483b3f6 100644 --- a/cheat/Cargo.toml +++ b/cheat/Cargo.toml @@ -18,7 +18,6 @@ crate-type = ["cdylib"] path = "src/entry_point.rs" [dependencies] -minhook-sys = "0.1.1" lazy_static = "1.5" once_cell = "1.19" paste = "1.0" @@ -32,6 +31,7 @@ tracing = "0.1.40" tracing-subscriber = "0.3.18" thiserror = "1.0.63" iced-x86 = "1.21.0" +retour = "0.3.1" [dependencies.windows] version = "0.51.0" diff --git a/cheat/src/core/hooks/mod.rs b/cheat/src/core/hooks/mod.rs index a2c819d..3ed8ddd 100644 --- a/cheat/src/core/hooks/mod.rs +++ b/cheat/src/core/hooks/mod.rs @@ -77,11 +77,6 @@ unsafe extern "system" fn hk_create_move( /// /// If `MinHook` fails to initialize, an error is returned with a message indicating the failure. pub fn initialize_hooks() -> anyhow::Result<()> { - // Initialize MinHook - if let Err(status) = utils::hook_system::initialize_minhook() { - bail!("failed to initialize MinHook: {status}"); - } - // Find the target addresses for the game functions let create_move_target = cs2::modules::client() .find_seq_of_bytes("48 8B C4 4C 89 48 20 55") diff --git a/cheat/src/utils/hook_system/mod.rs b/cheat/src/utils/hook_system/mod.rs index 355388d..4608483 100644 --- a/cheat/src/utils/hook_system/mod.rs +++ b/cheat/src/utils/hook_system/mod.rs @@ -1,5 +1,5 @@ use crate::common; -use anyhow::bail; +use anyhow::{bail, Context}; use common::{c_void, from_mut, null_mut}; use lazy_static::lazy_static; @@ -16,6 +16,8 @@ pub struct Hook { detour: *mut c_void, /// A pointer to the original function. original: *mut c_void, + /// A place to store the RawDetour object so that it won't get dropped. + _hook: retour::RawDetour, } lazy_static! { @@ -69,59 +71,29 @@ impl Hook { /// # Panics /// /// Panics if it fails to lock the `TARGETS` mutex. - #[must_use] - pub fn hook(target: *const c_void, detour: *const c_void) -> bool { + pub fn hook(target: *const c_void, detour: *const c_void) -> anyhow::Result<()> { let Ok(mut targets) = TARGETS.lock() else { tracing::error!("failed to lock TARGETS"); - return false; + bail!("failed to lock TARGETS"); }; - let mut hk = - Self { target: target.cast_mut(), detour: detour.cast_mut(), original: null_mut() }; + let hook = unsafe { retour::RawDetour::new(target as _, detour as _)? }; - // SAFETY: Creating the hook with MinHook library. - let create_hook_result = - unsafe { minhook_sys::MH_CreateHook(hk.target, hk.detour, from_mut(&mut hk.original)) }; - - if create_hook_result == 0 { - // SAFETY: Enabling the hook with MinHook library. - unsafe { - minhook_sys::MH_EnableHook(hk.target); - } - - targets.push_back(hk); - - true - } else { - false + unsafe { + hook.enable() + .with_context(|| format!("failed to enable hook {target:p} -> {detour:p}"))?; } - } -} -/// Initializes the `MinHook` library. -/// -/// # Returns -/// -/// Returns an `anyhow::Result` indicating success or failure. On success, it returns `Ok(())`. On failure, it returns an `Err` with a description of the error. -/// -/// # Errors -/// -/// - Returns an `Err` with a description if `MinHook` fails to initialize. -/// -/// # Panics -/// -/// This function does not panic, but it relies on `minhook_sys::MH_Initialize`, which may potentially fail. -pub fn initialize_minhook() -> anyhow::Result<()> { - // Safety: We are calling an external C library function that initializes MinHook. - // The function `MH_Initialize` is expected to return 0 on success and a non-zero value on failure. - // We assume the library's documentation and contract are correct, and we handle the error accordingly. - if unsafe { minhook_sys::MH_Initialize() } != 0 { - bail!("failed to initialize MinHook"); - } - - tracing::info!("MinHook initialized successfully"); + let hk = Self { + target: target.cast_mut(), + detour: detour.cast_mut(), + original: hook.trampoline() as *const () as *const c_void as *mut c_void, + _hook: hook, + }; - Ok(()) + targets.push_back(hk); + Ok(()) + } } #[macro_export] @@ -132,8 +104,8 @@ macro_rules! create_hook { tracing::info!("hooking target function: {target_function:p}"); - if !hook_system::Hook::hook(target_function, detour_function_ptr) { - bail!("failed to enable hook"); + if let Err(err) = hook_system::Hook::hook(target_function, detour_function_ptr) { + bail!("failed to create hook: {err}"); } }; }