hook 方式
这里采用编译成 dll 后注入,这里有两点需要注意:
- 目标程序为 32/64 位 rust 编译工具链也需要对应 32/64 位
- 编译需要用 release 模式,防止注入编译器在 debug 下为了调试附加的数据
Cargo.toml 中需要说明将其编译为库且类型为动态的,如果编译时显示找不到编译目标则手动添加一行路径:
[lib]
crate-type = ["dylib"]
path = "src/lib.rs"
当然你还可以通过创建远程线程来 hook,不过过程比较繁琐这里就提一下。
以下所有例子都以 hook MessageBoxW 为目标。
IAT Hook
IAT hook 即为导入表 hook,原理是 PE 文件中有个导入表,其中记录了该模块调用了哪些外部API,模块被加载到内存后,PE 加载器会修改该表,地址改成外部 API 重定位后的真实地址,我们只要直接把里面的地址改成我们新函数的地址,就可以完成对相应 API 的 Hook。
直接上代码,特别提醒一点所有的字符串结尾是没有 \0 的,要想像 C 一样正常工作需要自己添加:
extern crate libc;
extern crate winapi;
// 代表 c 中的 nullptr,只不过 rust 中分为可变和不可变两种
use std::ptr::{null, null_mut};
// 这几个东西是什么也不多说了,熟悉 Windows.h 的应该都知道:
use winapi::shared::{
minwindef::LPVOID,
ntdef::LPCWSTR,
windef::HWND,
};
// 定义一个别名,省的后面类型转换的时候写一大堆
type MessageBoxWHook = *const unsafe extern "system" fn(HWND, LPCWSTR, LPCWSTR, u32) -> i32;
// 保存原函数地址,当然这里可以用指针具体写法后面单独介绍
static mut MESSAGE_BOX_W_HOOK_ADDRESS: u64 = 0;
// for Debug
unsafe fn clear_last_error() {
use winapi::um::errhandlingapi::SetLastError;
SetLastError(0);
}
// for Debug
unsafe fn show_last_error() {
use winapi::um::{
errhandlingapi::GetLastError,
winuser::{MB_OK, MessageBoxA},
};
let e = GetLastError();
let e = format!("{}\0", e.to_string());
MessageBoxA(null_mut(), e.as_ptr() as _, "\0".as_ptr() as _, MB_OK);
}
// 我们自己的 MessageBoxW
unsafe extern "syst

本文详细介绍了在Rust中实现API Hook的四种方法:IATHook、EATHook、InlineHook和VMTHook。通过编译DLL注入、修改导入表和导出表、插入汇编指令以及利用虚函数表,展示了如何在不同场景下实现函数拦截。文中给出了具体的代码示例,包括对MessageBoxW函数的hook,并强调了各种hook技术的适用条件和注意事项。
最低0.47元/天 解锁文章
19万+





