问题
I use the LD_PRELOAD
trick to catch open64()
calls and I think I know how to do it correctly: with the program foobar
compiled from
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
open64("foobar.txt", 0);
return 0;
}
I catch open64
as I expect:
>LD_PRELOAD=$PWD/catch.so ./foobar
open64 called
However, when open64
is replaced with fopen64
:
#include <stdio.h>
int main() {
fopen64("foobar.txt", "r");
return 0;
}
now open64
is not caught. Why?
In case that fopen64
calls open
, I do have both open
and open64
intercepted, none is caught.
Both versions of the program foobar
, when executed with strace
, show that open
is called, which means that fopen64
does call internally open
or open64
.
I thought that perhaps something is statically linked, but that seems not the case:
>ldd foobar
shows
libc.so.6 => /lib64/libc.so.6
which is a shared library, and
>nm /lib64/libc.so.6
shows both open64
and fopen64
as defined (but not fopen
, that's why in the question, I used the "64" versions for the purpose of argument; perhaps fopen
is a macro to fopen64
or something like that, does not matter, since the problem happens with or without 64).
回答1:
I think it works like this: user space programs call library functions in libc, and libc calls system calls in the kernel. With LD_PRELOAD it is possible to intercept libc calls between the program and libc. You can not intercept system calls. If glibc calls another function internally (e.g. fopen calls open), you can not intercept it.
Instead of using strace
, it is better to use ltrace
in this case because that shows which library calls are done. These are the calls that you can intercept.
回答2:
You want ptrace with PTRACE_SYSCALL
. Here's an blog on it.
来源:https://stackoverflow.com/questions/35771395/why-doesnt-ld-preload-trick-catch-open-when-called-by-fopen