我正在尝试 Hook glibc 的一些函数,例如 fopen、fread 等。但是在 Hook 函数中,我必须使用与 glibc 中相同的函数。像这样:
// this is my fopen
FILE *fopen(.....)
{
fopen(....);// this is glibc fopen
}
我找到了一种使用 dlsym 执行此操作的方法,但这样我必须用包装器替换所有 glibc 函数调用,其中使用 dlsym 调用 glibc 函数。 我很好奇是否有另一种方法可以在不编码包装函数的情况下完成相同的工作。我曾经尝试过这个:
fopen.c
....fopen(..)
{
myfopen(..);
}
myfopen.c
myfopen(..)
{
fopen(...);// glibc version
}
main.c
int main()
{
fopen(...);
}
$ gcc -c *.c
$ gcc -shared -o libmyopen.so myopen.o
$ gcc -o test main.o fopen.o libmyopen.so
根据我的理解,gcc将按照命令行中指定的从左到右链接,因此main.o将在fopen.o中使用fopen,fopen.o将在libmyfopen.so中使用myfopen,libmyfopen.so将使用fopen在 glibc 中。但是运行时,我遇到了段错误,gdb 显示存在 fopen 和 myfopen 的递归调用。我有点困惑。谁能解释一下为什么?
最佳答案
my understanding, gcc will link from left to right as specified in the command line, so main.o will use fopen in fopen.o, fopen.o will use myfopen in libmyfopen.so, libmyfopen.so will use fopen in glibc
您的理解不正确。 myfopen
来自libmyfopen.so
将使用 fopen
的第一个定义可供它使用。在您的设置中,该定义将来自 fopen.o
链接到test
程序,最终会出现无限递归,并因堆栈耗尽而崩溃。
您可以通过运行 gdb ./test
来观察这一点,运行直到崩溃,并使用 backtrace
。您将看到一个无止尽的序列 fopen
和myfopen
来电。
the symbol fopen is not bond to that in libc when compiling
这是正确的:在 ELF
中格式,库记录它需要定义符号(在本例中为 fopen
),但它不“记住”或关心哪个其他模块定义了该符号。
您可以通过运行 readelf -Wr libmyfopen.so | grep fopen
来看到这一点.
That's different from windows DLL.
是的。
关于linux - 如何在linux中不使用dlsym进行hook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10584757/