Mar*_*eck 2 linux elf ld-preload
我试图拦截所有动态加载的函数,这些函数使用openat库comm.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(有很多)?
可以在不使用标准库中的函数的情况下调用系统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 HowTo和Linux 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