MCPcopy Index your code
hub / github.com/darfink/detour-rs

github.com/darfink/detour-rs @v0.8.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.8.0 ↗ · + Follow
154 symbols 265 edges 28 files 103 documented · 67%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

detour-rs

Azure build Status crates.io version Documentation Language (Rust)

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 by default.

Platforms

This library provides CI for these targets:

  • Linux
  • i686-unknown-linux-gnu
  • x86_64-unknown-linux-gnu
  • x86_64-unknown-linux-musl
  • Windows
  • i686-pc-windows-gnu
  • i686-pc-windows-msvc
  • x86_64-pc-windows-gnu
  • x86_64-pc-windows-msvc
  • macOS
  • ~~i686-apple-darwin~~
  • x86_64-apple-darwin

Installation

Add this to your Cargo.toml:

[dependencies]
detour = "0.8.0"

Example

  • A static detour (one of three different detours):
use std::error::Error;
use detour::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(())
}
  • A Windows API hooking example is available here; build it by running:
$ cargo build --example messageboxw_detour

Mentions

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.

Appendix

  • 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 c 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.

Extension points exported contracts — how you extend this code

Thunkable (Interface)
An interface for generating PIC thunks. [3 implementers]
src/pic/mod.rs
HookableWith (Interface)
Trait indicating that `Self` can be detoured by the given function `D`. [1 implementers]
src/traits.rs
Function (Interface)
Traits describing detours and applicable functions. Several of the traits in this module are automatically implemented
src/traits.rs

Core symbols most depended-on inside this repo

len
called by 17
src/arch/x86/trampoline/disasm.rs
enable
called by 7
src/arch/detour.rs
as_ref
called by 7
src/alloc/proximity.rs
as_slice
called by 6
src/arch/x86/trampoline/disasm.rs
add_thunk
called by 6
src/pic/emitter.rs
detour_test
called by 5
src/arch/x86/mod.rs
disable
called by 4
src/arch/detour.rs
is_executable_address
called by 3
src/util.rs

Shape

Method 83
Function 43
Class 23
Interface 3
Enum 2

Languages

Rust100%

Modules by API surface

src/arch/x86/trampoline/disasm.rs14 symbols
src/arch/x86/mod.rs14 symbols
src/arch/x86/trampoline/mod.rs11 symbols
src/alloc/proximity.rs11 symbols
src/detours/statik.rs10 symbols
src/arch/x86/thunk/x86.rs10 symbols
src/arch/detour.rs9 symbols
src/arch/x86/patcher.rs8 symbols
src/alloc/mod.rs7 symbols
src/detours/raw.rs6 symbols
src/detours/generic.rs6 symbols
src/arch/x86/thunk/x64.rs6 symbols

For agents

$ claude mcp add detour-rs \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact