2012-05-14 38 views
2

我试图挂钩glibc的一些函数,如fopen,fread等。但是在hook函数中,我必须使用与glibc中相同的函数。就像这样:如何在linux中不使用dlsym挂钩

// this is my fopen 
FILE *fopen(.....) 
{ 
    fopen(....);// this is glibc fopen 
} 

我发现做到这一点使用dlsym的一种方式,但这种方式我不得不更换所有的glibc的功能与包装内,其使用dlsym调用glibc的函数调用。 我很好奇,在没有对包装函数进行编码的情况下,另一种方式可以做同样的工作。我曾经tryed这一点:

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.o,fopen.o将在libmyfopen.so中使用myfopen,libmyfopen.so将在glibc中使用fopen。但是在运行时,我得到了段错误,gdb显示有一个fopen和myfopen的recusive调用。我有点困惑。谁能解释为什么?

回答

2

我的理解,GCC将连接左在命令行中指定,所以main.o将在fopen.o使用的fopen,fopen.o将在libmyfopen.so使用myfopen,libmyfopen.so将右在glibc中使用fopen

你的理解是不正确。来自libmyfopen.somyfopen将使用的第一个定义fopen可用于它。在你的设置中,该定义将来自链接到test程序的fopen.o,并且最终会导致无限递归,并且由于堆栈耗尽而导致崩溃。

您可以通过运行gdb ./test来观察此情况,运行至崩溃并使用backtrace。你会看到一个无休止的序列fopenmyfopen调用。

符号的fopen编译

时,这是正确的不粘结到libc中:在ELF格式来定义,它需要(在这种情况下fopen)符号库记录,但它不会“记住”或关心哪个其他模块定义该符号。

您可以通过运行readelf -Wr libmyfopen.so | grep fopen来查看。

这与Windows DLL不同。

是的。

+0

所以你的意思是libmyfopen.so将使用第一个加载的fopen,而不是libc中的那个。编译时符号fopen与libc中的符号没有联系?这与Windows DLL不同。 我想我需要学习一些关于精灵加载过程的东西。 感谢您的回复,非常感谢。 – D3Hunter