#hook #closures #libc #command #debugging #function #methods

rhook

使用简单的 API 钩子 libc 函数

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

MIT 许可证

76KB
1.5K SLoC

rhook

使用简单的 API 钩子 libc 函数

使用方法

1- 导入 trait [RunHook]

2- 使用 Command::new 创建一个 Command,并通过 add_hookadd_hooks 方法添加钩子

3- 使用 set_hooks 方法确认钩子,这一步是必要的

3.1- 钩子是接受无输入并返回 libc 函数输出选项的闭包。

如果闭包返回 None,则相当于返回 Some(original_function(args)),换句话说,它将运行并使用原始函数的输出

在闭包内部,您可以访问 libc 函数输入和从 std 导入的一些内容(见 src/scaffold.rs)

4- 现在,您可以使用通常的 Command 方法(outputspawnstatus 等)

技巧

用于钩子的闭包可以访问许多内容:(由 https://github.com/sigmaSd/Rhook/blob/master/src/scaffold.rs 导入)

  • 闭包输入(即 libc 函数输入)
  • 闭包输出(即 libc 函数输出)
  • 具有以下名称的原始函数 original_$libcfn,这在避免递归特别有用
  • 一些变量以简化编码:transmuteManuallyDropCString 和静态 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

依赖项