如何找出用LD_PRELOAD拦截的函数?

时间:2018-03-16 05:54:49

标签: linux elf ld-preload

我试图拦截使用openat机制使用库comm.so调用syscall LD_PRELOAD的所有动态加载的函数。

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

#strace -f /sbin/depmod 3.10.0-693.17.1.el7.x86_64

(...)

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

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

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

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

#readelf -p .dynstr /sbin/depmod 

这会打印出一些.so个库,所以我递归使用了readelf。在递归结束时,我有以下函数列表,其中包含openat

openat
openat64
open_by_handle_at
__openat64_2

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

好的,那么如何找出我需要拦截的其他功能呢?我是否必须通过readelf命令显示的所有函数,并逐个递归(其中有很多)?

1 个答案:

答案 0 :(得分:3)

可以在不使用标准库中的openat函数的情况下调用openat 系统调用(或任何其他函数,请参阅syscalls(2)获取列表) ;它可以从ld-linux(8)调用(处理 LD_PRELOAD)。在我的Debian / Sid系统上,它看起来动态链接器/lib/ld-linux.so.2正在使用openat系统调用(例如strace /bin/true尝试),当然它使用自己的open或{ {1}}函数(不是openat中的函数)。

任何系统调用(原则上)都可以通过直接机器代码(例如一些适当的libc.so机器指令)调用,或通过一些间接syscall(2)调用(在两种情况下都是SYSENTER C函数不会被使用)。

如果您想截取所有这些内容(包括openat完成的内容,这很奇怪),您需要ptrace(2)使用ld-linux,其方式与{{3}类似}}。您将能够在此时获得程序计数器和调用堆栈。

如果您关心以下文件和文件描述符,请同时考虑strace(1)设施。

如果你使用PTRACE_SYSCALL(可以在没有 DWARF调试信息的程序上痛苦地使用它),你可以inotify(7)(在{中使用gdb的方式{1}})找出每个原始系统调用(可能"在"中断)。

顺便说一下,某些use catch syscall可能正在使用ptrace PTRACE_SYSCALL系统调用(或在其他地方使用gdb)实现其open C函数。通过研究特定openat的源代码(可能是GNU C standard libraries,也许glibc)来检查。