Crates.io | retour |
lib.rs | retour |
version | |
source | src |
created_at | 2023-02-15 00:34:25.291103 |
updated_at | 2024-10-25 00:58:09.467494 |
description | A cross-platform detour library written in Rust |
homepage | https://github.com/Hpmason/retour-rs |
repository | https://github.com/Hpmason/retour-rs |
max_upload_size | |
id | 785419 |
Cargo.toml error: | TOML parse error at line 22, column 1 | 22 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
(Fork of original detour-rs that works on nightly after nightly-2022-11-07)
This is a cross-platform detour library developed in Rust. Beyond the basic functionality, this library handles branch redirects, RIP-relative instructions, hot-patching, NOP-padded functions, and allows the original function to be called using a trampoline whilst hooked.
This is one of few cross-platform detour libraries that exists, and to maintain this feature, not all desired functionality can be supported due to lack of cross-platform APIs. Therefore EIP relocation is not supported.
NOTE: Nightly is currently required for static_detour!
and is enabled with the static-detour
feature flag.
This library provides CI for these targets:
i686-unknown-linux-gnu
x86_64-unknown-linux-gnu
x86_64-unknown-linux-musl
i686-pc-windows-gnu
i686-pc-windows-msvc
x86_64-pc-windows-gnu
x86_64-pc-windows-msvc
i686-apple-darwin
x86_64-apple-darwin
Add this to your Cargo.toml
:
[dependencies]
# `static-detour` feature requires nightly
retour = { version = "0.3", features = ["static-detour"] }
This crate, with default features, will support the MSRV in Cargo.toml
(currently 1.60.0). Certain features may require newer versions of the compiler,
which will be documented here and in the docs. Any features that require the
nightly compiler will always target the newest version.
Feature versions:
static-detour
: nightlythiscall-abi
: 1.73.0 or neweruse std::error::Error;
use retour::static_detour;
static_detour! {
static Test: /* extern "X" */ fn(i32) -> i32;
}
fn add5(val: i32) -> i32 {
val + 5
}
fn add10(val: i32) -> i32 {
val + 10
}
fn main() -> Result<(), Box<dyn Error>> {
// Reroute the 'add5' function to 'add10' (can also be a closure)
unsafe { Test.initialize(add5, add10)? };
assert_eq!(add5(1), 6);
assert_eq!(Test.call(1), 6);
// Hooks must be enabled to take effect
unsafe { Test.enable()? };
// The original function is detoured to 'add10'
assert_eq!(add5(1), 11);
// The original function can still be invoked using 'call'
assert_eq!(Test.call(1), 6);
// It is also possible to change the detour whilst hooked
Test.set_detour(|val| val - 5);
assert_eq!(add5(5), 0);
unsafe { Test.disable()? };
assert_eq!(add5(1), 6);
Ok(())
}
$ cargo +nightly build --features="static-detour" --example messageboxw_detour
$ cargo build --example kernel32_detour
This is fork of the original detour-rs creator darfink that put so much work into the original crate.
Part of the library's external user interface was inspired by minhook-rs, created by Jascha-N, and it contains derivative code of his work.
This crate provides the ability to hook functions in other applications, but does not provide the utilities necessary for injecting/attaching to another process. If you're looking for ways to inject your hooking library here are some approaches you can look into:
EIP relocation
Should be performed whenever a function's prolog instructions
are being executed, simultaneously as the function itself is being
detoured. This is done by halting all affected threads, copying the affected
instructions and appending a JMP
to return to the function. This is
barely ever an issue, and never in single-threaded environments, but YMMV.
NOP-padding
int function() { return 0; }
// xor eax, eax
// ret
// nop
// nop
// ...
Functions such as this one, lacking a hot-patching area, and too small to
be hooked with a 5-byte jmp
, are supported thanks to the detection of
code padding (NOP/INT3
instructions). Therefore the required amount of
trailing NOP
instructions will be replaced, to make room for the detour.