我试图拦截使用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
。在递归结束时,我有以下函数列表,其中包含open
和at
:
openat
openat64
open_by_handle_at
__openat64_2
这些都不起作用 - 它们不会拦截返回文件描述符3的调用。
好的,那么如何找出我需要拦截的其他功能呢?我是否必须通过readelf
命令显示的所有函数,并逐个递归(其中有很多)?
答案 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}})找出每个原始系统调用(可能"在"中断)。
catch syscall
可能正在使用ptrace PTRACE_SYSCALL
系统调用(或在其他地方使用gdb
)实现其open
C函数。通过研究特定openat
的源代码(可能是GNU C standard libraries,也许glibc)来检查。