我使用LD_PRELOAD
技巧来捕获open64()
次调用,我想我知道如何正确地执行此操作:使用从
foobar
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
open64("foobar.txt", 0);
return 0;
}
我按照我的期望抓住了open64
:
>LD_PRELOAD=$PWD/catch.so ./foobar
open64 called
但是,当open64
替换为fopen64
时:
#include <stdio.h>
int main() {
fopen64("foobar.txt", "r");
return 0;
}
现在open64
没有被捕获。为什么呢?
如果fopen64
调用open
,我会截获open
和open64
,但没有一个被捕获。
程序foobar
的两个版本在使用strace
执行时都会显示open
被调用,这意味着fopen64
会在内部调用open
或open64
。
我认为也许某些东西是静态链接的,但事实并非如此:
>ldd foobar
显示
libc.so.6 => /lib64/libc.so.6
这是一个共享库,
>nm /lib64/libc.so.6
显示open64
和fopen64
已定义(但不是fopen
,这就是为什么在问题中,我使用“64”版本作为参数;也许{{1是fopen
或类似的东西的宏,无关紧要,因为问题发生在有或没有64)。
答案 0 :(得分:6)
我认为它的工作原理如下:用户空间程序在libc中调用库函数,而libc在内核中调用系统调用。使用LD_PRELOAD,可以拦截程序和libc之间的libc调用。您无法拦截系统调用。如果glibc在内部调用另一个函数(例如fopen调用open),则无法拦截它。
在这种情况下,最好使用strace
,而不是使用ltrace
,因为它显示了哪些库调用已完成。这些是你可以拦截的电话。
答案 1 :(得分:0)
您需要ptrace
与PTRACE_SYSCALL
。这是一个blog on it。