我正在尝试挂钩glibc的一些函数,比如fopen,fread等。但是在钩子函数中,我必须使用与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的重复调用。我有点困惑。任何人都可以解释原因吗?
答案 0 :(得分:2)
我的理解,gcc将在命令行中指定从左到右链接,因此main.o将在fopen.o中使用fopen,fopen.o将在libmyfopen.so中使用myfopen,libmyfopen.so将使用fopen in glibc的
您的理解不正确。来自myfopen
的{{1}}将使用可用的{em>第一个定义libmyfopen.so
。在您的设置中,该定义将来自链接到fopen
程序的fopen.o
,您将最终得到无限递归,并且由于堆栈耗尽而导致崩溃。
您可以通过运行test
,运行直至崩溃并使用gdb ./test
来观察此情况。您会看到无休止的backtrace
和fopen
来电序列。
编译
时符号fopen与libc中的符号不相关
这是正确的:在myfopen
格式中,库记录它需要定义符号(在这种情况下为ELF
),但它不“记住”或关心哪个其他模块定义该符号。
您可以通过运行fopen
来查看此内容。
这与Windows DLL不同。
是