如何找出LD_PRELOAD要拦截哪些函数?

Mar*_*eck 2 linux elf ld-preload

我试图拦截所有动态加载的函数,这些函数使用openatcomm.so使用LD_PRELOAD机制调用系统调用。

考虑以下/sbin/depmod命令的使用:

#strace -f /sbin/depmod 3.10.0-693.17.1.el7.x86_64
Run Code Online (Sandbox Code Playgroud)

(...)

openat(AT_FDCWD, "/lib/modules/3.10.0-693.17.1.el7.x86_64", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
Run Code Online (Sandbox Code Playgroud)

我想拦截调用此系统调用的函数openat

如何找出该功能是什么? openat,这可能是一个别名,以及任何其他类似的函数,都不起作用 - 没有任何内容被拦截。

我尝试使用此命令来查找我的命令正在使用哪些动态加载的函数:

#readelf -p .dynstr /sbin/depmod 
Run Code Online (Sandbox Code Playgroud)

这会打印出一些.so库,所以我readelf递归地使用它们。在递归结束时,我得到了以下包含open和 的函数列表at

openat
openat64
open_by_handle_at
__openat64_2
Run Code Online (Sandbox Code Playgroud)

这些都不起作用 - 它们不会拦截返回文件描述符 3 的调用。

好的,那么如何找出我还需要拦截哪些其他函数呢?我是否必须一一递归地遍历命令显示的所有函数readelf(有很多)?

Bas*_*tch 5

可以在不使用标准库中的函数的情况下调用系统openat 调用(或任何其他调用,请参阅syscalls(2)了解列表) ;并且可以从ld-linux(8)处理openat)调用它。在我的 Debian/Sid 系统上,动态链接器似乎 正在使用系统调用(例如尝试),当然它使用自己的或函数(不是 中的函数)。 LD_PRELOAD/lib/ld-linux.so.2openatstrace /bin/trueopenopenatlibc.so

任何系统调用(原则上)都可以通过直接机器代码(例如某些适当的SYSENTER机器指令)或通过某些间接系统调用(2)来调用(并且在这两种情况下都openat不会使用 C 函数)。有关更多信息,请参阅Linux Assembly HowToLinux x86 ABI规范。

如果你想拦截所有这些(包括那些由 完成的ld-linux,这很奇怪),你需要以类似于strace(1)的方式使用ptrace(2)。此时您将能够获取程序计数器和调用堆栈。PTRACE_SYSCALL

如果您关心以下文件和文件描述符,还可以考虑inotify(7)设施。

如果您使用(在没有DWARF 调试信息的gdb程序上使用它可能会很痛苦),您可以使用(使用in 的方式)来找出(并且可能“中断”)每个原始系统调用。catch syscallptrace PTRACE_SYSCALLgdb

顺便说一句,某些C 标准库可能正在通过系统调用(或在其他地方使用)来实现其openC 函数。通过研究您特定的源代码(可能是 GNU glibc,可能是musl-libc)进行检查。openatopenatlibc.so