我试图拦截所有动态加载的函数,这些openat
函数comm.so
使用库使用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
,并且递归地这样做(有很多)?
的openat
系统调用(或任何其它一个,见系统调用(2)对的列表)可以被称为不使用openat
从标准库函数; 它可以从ld-linux(8)(处理 LD_PRELOAD
)调用。在我的 Debian/Sid 系统上,看起来动态链接器/lib/ld-linux.so.2
正在使用openat
系统调用(例如尝试strace /bin/true
),当然它使用自己的open
或openat
函数(不是 中的libc.so
)。
任何系统调用都可以(原则上)由直接机器代码(例如一些适当的SYSENTER
机器指令)调用,或者通过一些间接syscall(2) 调用(并且在这两种情况下openat
都不会使用 C 函数)。有关更多信息,请参阅Linux Assembly HowTo和Linux x86 ABI规范。
如果你想拦截所有的人(包括那些通过做ld-linux
,这是奇怪的),你需要使用ptrace的(2)用PTRACE_SYSCALL
类似的方式使用strace(1) 。此时您将能够获得程序计数器和调用堆栈。
如果您关心以下文件和文件描述符,还可以考虑inotify(7)工具。
如果您使用gdb
(在没有DWARF 调试信息的程序上使用它会很痛苦),您可以使用catch syscall
(使用ptrace PTRACE_SYSCALL
in的方式gdb
)找出(并且可能“中断”)每个原始系统调用。
顺便说一句,有可能一些C 标准库正在open
通过openat
系统调用(或openat
在其他地方使用)来实现它们的C 函数。通过研究您的特定源代码libc.so
(可能是 GNU glibc,可能是musl-libc)来检查。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句