【问题标题】:How to hook without using dlsym in linux如何在不使用 dlsym 的情况下在 linux 中挂钩
【发布时间】:2012-05-22 00:31:09
【问题描述】:

我正在尝试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 的递归调用。我有点困惑。谁能解释一下为什么?

【问题讨论】:

    标签: linux gcc hook shared-libraries glibc


    【解决方案1】:

    我的理解,gcc会按照命令行指定的从左到右链接,所以main.o会在fopen.o中使用fopen,fopen.o会在libmyfopen.so中使用myfopen,libmyfopen.so会在fopen中使用glibc

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

    您可以通过运行gdb ./test、运行直到崩溃并使用backtrace 来观察这一点。您将看到fopenmyfopen 调用的无休止序列。

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

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

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

    这与 windows DLL 不同。

    是的。

    【讨论】:

    • 所以你的意思是 libmyfopen.so 将使用第一个加载的 fopen,而不是 libc 中的那个。编译时符号 fopen 与 libc 中的符号不​​绑定?这与 Windows DLL 不同。我想我需要学习一些关于精灵加载过程的知识。感谢您的回复,非常感谢。
    猜你喜欢
    • 2011-09-03
    • 2019-08-17
    • 2021-11-16
    • 1970-01-01
    • 2012-11-08
    • 2022-12-10
    • 1970-01-01
    • 2021-02-13
    • 1970-01-01
    相关资源
    最近更新 更多