如何挂钩而不使用linux中的dlsym

时间:2012-05-14 13:56:00

标签: linux gcc hook shared-libraries glibc

我正在尝试挂钩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的重复调用。我有点困惑。任何人都可以解释原因吗?

1 个答案:

答案 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来观察此情况。您会看到无休止的backtracefopen来电序列。

  

编译

时符号fopen与libc中的符号不​​相关

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

您可以通过运行fopen来查看此内容。

  

这与Windows DLL不同。