使用Rust编写 Windows dll 并注入进第三方进程后对 Windows API MessageBoxW 进行 Hook

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

hook 方式

这里采用编译成 dll 后注入,这里有两点需要注意:

  1. 目标程序为 32/64 位 rust 编译工具链也需要对应 32/64 位
  2. 编译需要用 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
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值