#syscalls #interceptor #linux #ptrace #lib #calls #write

interceptor-rs

Interceptor 是一个基于 ptrace 的库,用于拦截和修改 Linux 系统调用

1 个不稳定版本

0.1.0 2023 年 3 月 28 日

626Unix APIs

MIT 许可证

35KB
761 行代码

interceptor

Interceptor 是一个基于 ptrace 的库,用于拦截和修改 Linux 系统调用。它目前仅支持 x86_64 架构。

用法

编写一个与系统调用签名相同的函数,并将其标记为 #[syscall],然后您就完成了。

#[syscall]
fn openat(dfd: i32, mut filename: *const c_char, flags: i32, mode: i32) -> i32 {
    // do something before syscall, logging, changing arguments, etc.

    let ret = real!(dfd, filename, flags, mode);

    // do something after syscall, modifing return value..
}

更多详细信息请参阅示例

附加信息

目标中的内存

我们使用 "LD_PRELOAD" 技巧将 so 插入目标进程,以在修改具有较大长度的指针参数时分配额外内存。

删除依赖 libgcc_s.so.1

一些 glibc 版本未包含 libgcc_s.so.1,我们使用链接脚本 "linker_without_libgcc.wrap" 删除了这个依赖。

对 "*const *const c_char" 参数的特殊处理

该参数用于类似 execve 的系统调用,如 const char *const argv[]

我们为方便起见,将 *const *const c_char 视为 *const c_char。也就是说,原始的指针到指针已经转换为指针的内容。例如

原始

这个指针的地址在目标进程中,不能直接使用。

ptr (*const *const c_char) ptr to ptr (*const c_char) 内容
0x12345678 0x11111111 "aaaa\0"
0x22222222 "bbbb\0"
0x33333333 "cccc\0"
0x44444444 "\0"

转换后

内存是在拦截器实例中重新分配的,因此地址已更改。

ptr (*const c_char) 内容
0x87654321 "aaaa\0bbbb\0cccc\0\0"

用法

您可以使用辅助函数 read_ptr_to_ptr 从转换后的指针中读取内容。并使用 write_ptr_to_ptr 将内容写回。

依赖项

~4–9.5MB
~96K SLoC