Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cheat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
5 changes: 0 additions & 5 deletions cheat/src/core/hooks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
68 changes: 20 additions & 48 deletions cheat/src/utils/hook_system/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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! {
Expand Down Expand Up @@ -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 _)? };
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can also be wrapped in ManuallyDrop instead of storing it in the struct below


// 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]
Expand All @@ -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}");
}
};
}
Expand Down