6 个版本 (3 个重大更新)

0.4.0-alpha.22023年11月15日
0.4.0-alpha.12023年9月13日
0.3.1 2023年7月18日
0.3.0 2023年6月6日
0.1.0 2023年2月15日

Rust 模式 中排名第 172

Download history 347/week @ 2024-04-14 540/week @ 2024-04-21 824/week @ 2024-04-28 468/week @ 2024-05-05 486/week @ 2024-05-12 377/week @ 2024-05-19 227/week @ 2024-05-26 219/week @ 2024-06-02 213/week @ 2024-06-09 161/week @ 2024-06-16 200/week @ 2024-06-23 196/week @ 2024-06-30 509/week @ 2024-07-07 352/week @ 2024-07-14 706/week @ 2024-07-21 832/week @ 2024-07-28

每月下载量 2,430
10 包中使用(7 个直接使用)

BSD-2-Clause

83KB
1.5K SLoC

retour(一个 detour 分支)

Crates.io docs.rs Lcense Cargo Check/Tests

(原 detour-rs 的分支,在 nightly-2022-11-07 之后可在 nightly 上运行)

这是一个用 Rust 开发的跨平台重定向库。除了基本功能外,这个库还处理分支重定向、RIP 相对指令、热修复、NOP 填充函数,并允许在挂钩时通过跳跃台调用原始函数。

这是少数几个存在的 跨平台 重定向库之一,由于缺少跨平台 API,因此无法支持所有期望的功能。因此,不支持 EIP 重定位

注意:目前需要 nightly 来使用 static_detour!,可以通过 static-detour 功能标志启用。

平台

此库为以下目标提供 CI

  • 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

安装

将此添加到您的 Cargo.toml

[dependencies]
# `static-detour` feature requires nightly
retour = { version = "0.3", features = ["static-detour"] }

支持的版本

此包,使用默认功能,将支持 Cargo.toml 中的 MSRV(目前为 1.60.0)。某些功能可能需要编译器的较新版本,这些版本将在此处和文档中记录。任何需要 nightly 编译器的功能都将始终针对最新版本。

功能版本

  • static-detour: nightly
  • thiscall-abi: 1.73.0 或更高版本

示例

  • 静态重定向(三种不同重定向之一)
use 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(())
}
  • 一个 Windows API 挂钩示例在此处可用 这里;通过运行构建它
$ cargo +nightly build --features="static-detour" --example messageboxw_detour
  • 一个使用 GenericDetour 的非 nightly 示例在此处可用 这里;通过运行构建它
$ cargo build --example kernel32_detour

提及

这是对原始的 detour-rs 的分支,原始crate的创作者 darfink 在原始crate上投入了大量的工作。

库的部分外部用户界面受到了 minhook-rs 的启发,由 Jascha-N 创建,并包含了他工作的派生代码。

注入方法

这个crate提供了在其他应用程序中挂钩函数的能力,但不提供注入/附加到另一个进程所需的实用工具。如果您正在寻找注入挂钩库的方法,以下是一些您可以考虑的途径:

  • dll-syringe 这样的dll注入库
  • *nix平台上的LD_PRELOAD
  • 各种调试器,包括x64dbg和Cheat Engine

附录

  • EIP重定位

    应在函数的前置指令正在执行时进行,同时函数本身正在被重定向。这通过暂停所有受影响的线程,复制受影响的指令,并将一个 JMP 添加回函数来完成。这几乎从未成为问题,在单线程环境中从未成为问题,但YMMV。

  • NOP填充

    int function() { return 0; }
    // xor eax, eax
    // ret
    // nop
    // nop
    // ...
    

    像这样没有热补丁区域且太小的函数,无法用5字节 jmp 挂钩,但由于检测到代码填充(NOP/INT3 指令),得到了支持。因此,将替换所需的尾部 NOP 指令的数量,为重定向腾出空间。

依赖关系

~0.8–8.5MB
~59K SLoC