8 个版本 (5 个重大变更)
0.8.0 | 2021年4月15日 |
---|---|
0.5.0 | 2021年4月9日 |
0.4.0 | 2021年4月8日 |
0.3.0 | 2021年4月7日 |
0.1.0 | 2021年4月3日 |
#37 in #libc
76KB
1.5K SLoC
rhook
使用简单的 API 钩子 libc 函数
使用方法
1- 导入 trait [RunHook]
2- 使用 Command::new 创建一个 Command,并通过 add_hook 和 add_hooks 方法添加钩子
3- 使用 set_hooks 方法确认钩子,这一步是必要的
3.1- 钩子是接受无输入并返回 libc 函数输出选项的闭包。
如果闭包返回 None
,则相当于返回 Some(original_function(args))
,换句话说,它将运行并使用原始函数的输出
在闭包内部,您可以访问 libc 函数输入和从 std 导入的一些内容(见 src/scaffold.rs)
4- 现在,您可以使用通常的 Command 方法(output,spawn,status 等)
技巧
用于钩子的闭包可以访问许多内容:(由 https://github.com/sigmaSd/Rhook/blob/master/src/scaffold.rs 导入)
- 闭包输入(即 libc 函数输入)
- 闭包输出(即 libc 函数输出)
- 具有以下名称的原始函数
original_$libcfn
,这在避免递归特别有用 - 一些变量以简化编码:
transmute
,ManuallyDrop
,CString 和静态
COUNTER
- 您可以通过在此处查找来找到函数的输入/输出 libc
- 在
set_hooks
之后添加.map_err(|e|println("{}",e))
以便在调试时美化动态库编译错误 - 如果在闭包内部获取了输入值的所有权,请确保使用 ManuallyDrop 以防止它被释放
示例
假设您想要限制程序的带宽
通常下载时会调用 libc::recv
函数
因此我们的目标是使用简单的暂停来限制它
使用这个crate来实现(以speedtest程序为例):
1- 在这里查找其文档 recv 以查看函数的输入/输出
2- 使用这个crate
use rhook::{RunHook, Hook};
std::process::Command::new("speedtest").add_hook(Hook::recv(stringify!(||{
std::thread::sleep(std::time::Duration::from_millis(10));
// since we're not doing any modification to the output you can just return None here
Some(original_recv(socket, buf, len, flags))
}))).set_hooks().unwrap().spawn();
这就是全部了!注意,在闭包内你可以访问带有前缀 original_
+ 函数名的原始函数
查看示例获取更多信息
许可证:MIT