1 个不稳定版本
0.9.0 | 2022年8月26日 |
---|
#2153 在 Rust模式
在 2 crate 中使用
80KB
1.5K SLoC
这是一个用Rust开发的跨平台旁路库。除了基本功能外,此库还处理分支重定向、RIP相关指令、热修补、NOP填充函数,并允许在挂钩时使用跳板调用原始函数。
这是少数几个存在的跨平台旁路库之一,由于缺乏跨平台API,为了维护这一特性,无法支持所有期望的功能。因此不支持EIP重定位。
注意:目前需要Nightly版本才能使用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]
detour = "0.8.0"
示例
- 静态旁路(三种不同的旁路之一)
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(())
}
- Windows API挂钩示例在此处可用;通过运行以下命令构建它
$ cargo build --example messageboxw_detour
提及
库的外部用户界面部分受到了minhook-rs的启发,由Jascha-N创建,并包含了他工作的派生代码。
附录
-
EIP重定位
应该在执行函数的前置指令时执行,同时函数本身被旁路。这是通过停止所有受影响的线程、复制受影响的指令并在返回函数时追加一个
JMP
来完成的。这几乎永远不会是一个问题,在单线程环境中永远不会是问题,但YMMV。 -
NOP填充
int function() { return 0; } // xor eax, eax // ret // nop // nop // ...
此函数缺少热修补区域,且太小,无法使用5字节
jmp
进行挂钩,但由于检测到代码填充(NOP/INT3
指令),因此支持此类函数。因此,将替换所需的尾部NOP
指令,为旁路腾出空间。
依赖关系
~0.8–8MB
~62K SLoC