linux - 如何在linux中不使用dlsym进行hook

标签 linux gcc hook shared-libraries glibc

我正在尝试 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 。您将看到一个无止尽的序列 fopenmyfopen来电。

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/

相关文章:

c++ - 继承共享方法名的接口(interface)

c++ - 如何在 GCC 中使用 Container Overflow Bugs 检测?

linux - 从文件 shell 脚本中获取子字符串

linux - 如何仅在文件更改时自动增加 RPM 版本

sql - sphinx 运算符(operator) "less"

c - 当C中没有左侧时,&&运算符会做什么?

C++ Alt-Tab 钩子(Hook)

git - 使用 git 处理配置文件的最佳方式是什么?

windows - 用于保护驱动程序的注册表访问 Hook

C 死锁检测线程库