我已经包装了一些系统调用函数,如 write()、open() 等,LD-PRELOAD 用于覆盖原始系统调用。此外,我还定义了一些函数,并将其变成了一个 shred 库。
我想在它们进入共享库之前捕获来自不同应用程序进程对这些共享库的所有系统调用。我怎样才能做到这一点?
谢谢
我已经包装了一些系统调用函数,如 write()、open() 等,LD-PRELOAD 用于覆盖原始系统调用。此外,我还定义了一些函数,并将其变成了一个 shred 库。
我想在它们进入共享库之前捕获来自不同应用程序进程对这些共享库的所有系统调用。我怎样才能做到这一点?
谢谢
LD_PRELOAD 不一定是插入系统调用的好方法,因为a)它只允许你拦截库调用,b)它只允许你拦截库调用。;)
A) 虽然系统调用通常由系统中的共享 libC 包装,但没有人阻止您自己调用系统调用,例如,设置正确的寄存器内容,然后在 x86 系统上发出 INT 0x80。如果您感兴趣的程序这样做,您将永远无法使用基于 LD_PRELOAD 的 libc-interposition 捕获那些程序。
B) 虽然一般来说,大多数程序使用系统中的共享 libC 来进行系统调用,但有时应用程序是静态链接的,这意味着 libC 代码是应用程序的一部分,而不来自共享库。在这种情况下,LD_PRELOAD 也无济于事。
已经有评论建议使用 strace/ltrace —— 我的一般建议是查看 ptrace() ,这两个工具都使用了它,它应该给你你想要的东西,而不需要修改内核。
系统调用的无补丁用户级链接时间拦截和库函数的插入可能会奏效,但我还没有测试过。
我很确定您可以做到这一点的唯一方法是修改系统调用表。HIDS 系统(例如 Samhain)会将其报告为入侵,Linux 内核开发人员对此表示不满。实现细节是针对操作系统的(即在 FreeBSD 上运行的不一定在 Linux 上运行),但一般的实现细节将是相同的。内核模块可能是使用更清洁、更标准化的 API 的更好方法。