如何在linux中不使用dlsym ?

时间:2020-12-14 23:55:18

I'm trying to hook some functions of glibc, like fopen, fread etc. But in the hook function, i have to use the same function as in glibc. Like this:

我想要勾选glibc的一些函数,比如fopen, fread等等,但是在钩子函数中,我必须使用和glibc相同的函数。是这样的:

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

I have found one way to do this using dlsym, but in this way i have to replace all the glibc function calls with wrappers inside which call glibc function using dlsym. I'm curious whether where is another way to do the same job without coding wrapper functions. I ever tryed this :

我已经找到了一种使用dlsym来实现这一点的方法,但是通过这种方法,我必须用包装器替换所有glibc函数调用,其中包装器使用dlsym调用glibc函数。我很好奇,在没有编写包装函数的情况下,在哪里做同样的工作?我曾经尝试过:

fopen.c

fopen.c

....fopen(..)
{
  myfopen(..);
}

myfopen.c

myfopen.c

myfopen(..)
{
  fopen(...);// glibc version
}

main.c

c

int main()
{
  fopen(...);
}

$ gcc -c *.c
$ gcc -shared -o libmyopen.so myopen.o
$ gcc -o test main.o fopen.o libmyopen.so

In 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. But when running, i got a segment fault, gdb shows there is a recusive call of fopen and myfopen. I'm a little confused. Can anyone explain why ?

在我的理解中,gcc将按照命令行so main的要求从左到右进行链接。o将在fopen中使用fopen。o,打开外部文件。o将在libmyfopen中使用myfopen。所以,libmyfopen。所以将在glibc中使用fopen。但是在运行时,我得到了一个段错误,gdb显示有一个fopen和myfopen的重新调用。我有点困惑。谁能解释一下原因吗?

1 个解决方案

#1


2  

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

我的理解是,gcc将按照命令行中指定的从左到右进行链接,即main。o将在fopen中使用fopen。o,打开外部文件。o将在libmyfopen中使用myfopen。所以,libmyfopen。所以将在glibc中使用fopen

Your understanding is incorrect. The myfopen from libmyfopen.so will use the first definition of fopen available to it. In your setup, that definition will come from fopen.o linked into the test program, and you'll end up with infinite recursion, and a crash due to stack exhaustion.

你的理解是不正确的。从libmyfopen myfopen。因此将使用fopen的第一个定义。在您的设置中,该定义将来自fopen。o连接到测试程序中,最终会得到无限递归,以及堆栈耗尽导致的崩溃。

You can observe this by running gdb ./test, running until crash, and using backtrace. You will see an unending sequence of fopen and myfopen calls.

您可以通过运行gdb ./test、运行直到崩溃和使用回溯来观察这一点。您将看到一个无止境的fopen和myfopen调用序列。

the symbol fopen is not bond to that in libc when compiling

fopen符号在编译时不与libc中的符号绑定

That is correct: in ELF format, the library records that it needs the symbol (fopen in this case) to be defined, but it doesn't "remember" or care which other module defines that symbol.

这是正确的:在ELF格式中,库记录它需要定义符号(在本例中为fopen),但它不“记住”或不关心其他模块定义该符号。

You can see this by running readelf -Wr libmyfopen.so | grep fopen.

您可以通过运行readelf -Wr libmyfopen看到这一点。所以| grep fopen。

That's different from windows DLL.

这与windows DLL不同。

Yes.

是的。

#1


2  

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

我的理解是,gcc将按照命令行中指定的从左到右进行链接,即main。o将在fopen中使用fopen。o,打开外部文件。o将在libmyfopen中使用myfopen。所以,libmyfopen。所以将在glibc中使用fopen

Your understanding is incorrect. The myfopen from libmyfopen.so will use the first definition of fopen available to it. In your setup, that definition will come from fopen.o linked into the test program, and you'll end up with infinite recursion, and a crash due to stack exhaustion.

你的理解是不正确的。从libmyfopen myfopen。因此将使用fopen的第一个定义。在您的设置中,该定义将来自fopen。o连接到测试程序中,最终会得到无限递归,以及堆栈耗尽导致的崩溃。

You can observe this by running gdb ./test, running until crash, and using backtrace. You will see an unending sequence of fopen and myfopen calls.

您可以通过运行gdb ./test、运行直到崩溃和使用回溯来观察这一点。您将看到一个无止境的fopen和myfopen调用序列。

the symbol fopen is not bond to that in libc when compiling

fopen符号在编译时不与libc中的符号绑定

That is correct: in ELF format, the library records that it needs the symbol (fopen in this case) to be defined, but it doesn't "remember" or care which other module defines that symbol.

这是正确的:在ELF格式中,库记录它需要定义符号(在本例中为fopen),但它不“记住”或不关心其他模块定义该符号。

You can see this by running readelf -Wr libmyfopen.so | grep fopen.

您可以通过运行readelf -Wr libmyfopen看到这一点。所以| grep fopen。

That's different from windows DLL.

这与windows DLL不同。

Yes.

是的。