• Stars
    star
    356
  • Rank 116,856 (Top 3 %)
  • Language
    Rust
  • License
    Other
  • Created over 7 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A cross-platform detour library written in Rust

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

    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.

More Repositories

1

region-rs

A cross-platform virtual memory API written in Rust
Rust
89
star
2

vim-plist

Add plist editing support to Vim
Vim Script
86
star
3

tap-rs

Generic extensions for tapping values in Rust.
Rust
47
star
4

chakracore-rs

An idiomatic Rust wrapper for the JSRT interface
Rust
39
star
5

muonline-packet

An implementation Mu Online's network packet
Rust
18
star
6

mutool-rs

A utility/cheat for Mu Online classic
Rust
7
star
7

radix-tree-map-lua

A radix tree map implemented in Lua
Lua
7
star
8

MuRust

An implementation of the MMORPG Mu Online (Season 2) in Rust
Rust
5
star
9

hlsl-mode

Emacs Lisp
4
star
10

dotfiles

.files โ€” my own preferences for Ubuntu and macOS
Emacs Lisp
4
star
11

Ainomis

My basal attempt at a Pokรฉmon clone
C#
4
star
12

ItemAutocomplete

Chat autocomplete for item links in WoW Classic
Lua
3
star
13

alfred-tpb

View torrents from The Pirate Bay using Alfred
JavaScript
3
star
14

Muwesome

C#
2
star
15

libudis86-sys

Rust FFI bindings to libudis86
C
2
star
16

GoldMeta

GoldMeta is a plugin manager that inter-operates between the Half-Life engine and game modifications
C++
2
star
17

InstanceTracker

A World of Warcraft Classic addon which tracks instance limits
Lua
2
star
18

slice-pool-rs

A Rust library for using a slice as a memory pool
Rust
2
star
19

listener-rs

An event listener library
Rust
1
star
20

cpm-udis86

CPM external for udis86, a disassembler library for x86 / x86-x64
1
star
21

starsearch.vim

Improvements to VIM's default asterisk (*) search
Vim Script
1
star
22

Computer

An extremely simple implementation of a virtual computer
Java
1
star
23

proximity-allocator

A library for allocating memory in proximity
Rust
1
star