无法加载LD_PRELOAD指定的lib

时间:2016-02-20 14:39:26

标签: gcc shared-libraries shared ldd ld-preload

使用LD_PRELOAD加载我的时候遇到了一些麻烦。

步骤如下:

  1. libtest.c:

    void fun()
    {
        return 
    }
    
  2. gcc -o libtest.so libtest.c -fPIC --shared

  3. export LD_PRELOAD = pwd / libtest.so

  4. 的main.c

    extern void fun(); void main() { fun() }

  5. gcc -o main -L。 main.c -ltest

  6. 然后ldd main

    ldd main linux-vdso.so.1=>(0x00007ffff7ffd000) /home/shiyanlou/Code/libtest.so(0x00007ffff7df9000) libtest.so=>not found libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6 (0x00007ffffa29000) /lib64/ld-linux-x86-64.so.2 (0x0000555555554000)

  7. 执行主./main 它促进: 加载共享库时出错:libtest.so。无法打开共享对象文件:没有这样的文件或目录。
  8. 我想知道为什么它在我导出LD_PRELOAD变量后提示无法找到libtest.so。但是,我也尝试使用LD_PRELOAD指定一个不同的共享库(而不是" libc.so")来注入malloc函数,它的工作原理! 为什么LD_PRELOAD仅适用于链接???

    时未使用的共享库

2 个答案:

答案 0 :(得分:1)

您需要创建* .so的2个版本。一个具有默认行为,并通过" -ltest"

加载和硬链接

现在构建您的默认libtest.so并使用nm -B证明您希望拦截的符号是动态链接的。

现在将main.c构建到main.o中,然后使用nm检查main.o,看它在符号上有一个外部不满足的链接要求。

现在将./main与main.o和libtest.so链接,然后运行它。 默认情况下,./main需要使用此副本运行,演示默认行为,并通过ldd命令显示正确DSO的正确路径。

...

现在,您将采取步骤创建LD_PRELOAD版本。

你应该打电话给libtest2.so。您不使用-ltest2

重点是,无论谁构建./main根本不了解libtest2.so,都没有硬链接依赖。

libtest2.so具有替代行为,例如make foo()返回不同的字符串/数字),现在的目标是在运行时拦截第二个版本,因此默认情况下不会调用第一个版本(或根本不调用)。通过使用LD_PRELOAD环境。

LD_PRELOAD=./libtest2.so ./main

...

祝你好运。

答案 1 :(得分:0)

我将DSO复制并重命名为libtest2.so并将LD_PRELOAD重置为重命名的DSO(带绝对路径),它还提示无法找到libtest.so。

我认为它提示的原因是无法加载用于硬依赖的libtest.so。

也就是说,虽然已加载LD_PRELOAD,但无法满足硬依赖性,因此无法执行./main

现在我可以得出结论,当执行./main时,必须满足硬依赖DSO,因为每个硬依赖DSO也必须加载(虽然这个DSO应该被完全替换!),否则会提示DSO不能找到了!

感谢您的帮助@Darryl Miles