无法加载 LD_PRELOAD 指定的库
lib specified by LD_PRELOAD can not be loaded
我在使用 LD_PRELOAD 加载我的 so 时遇到了一些问题。
步骤如下:
libtest.c:
void fun()
{
return
}
gcc -o libtest.so libtest.c -fPIC --shared
导出LD_PRELOAD=pwd
/libtest.so
main.c
extern void fun();
void main()
{
fun()
}
gcc -o main -L。 main.c-ltest
然后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)
- 执行主程序
./main
它促进:
加载共享 library:libtest.so 时出错。无法打开共享对象 file:No 这样的文件或目录。
不知为什么导出LD_PRELOAD变量后提示找不到libtest.so。但是,我也尝试使用 LD_PRELOAD 指定不同的共享库(而不是 "libc.so")来注入 malloc 函数,它有效!
为什么LD_PRELOAD只适用于链接时未使用的共享库???
您需要创建 2 个版本的 *.so。一个具有默认行为并通过“-ltest”加载和硬 linked。
现在构建您的默认 libtest.so 并用 nm -B
证明您期望拦截的符号是动态 linked.
现在将 main.c 构建到 main.o,然后检查 main.o 和 nm
也可以看到它在符号上有一个 extern unsatisfied linkage 要求.
现在 link ./main
与 main.o 和 libtest.so 然后 运行 它。
默认情况下,./main
需要使用此副本 运行,演示默认行为,并通过 ldd
命令显示正确 DSO 的正确路径。
...
现在您开始创建 LD_PRELOAD 版本。
你应该称之为libtest2.so
。您不使用 -ltest2
关键是建造 ./main
的人根本不知道 libtest2.so,没有硬性 link 年龄依赖性。
libtest2.so 具有替代行为,例如使 foo() returns 不同 string/number),现在的目标是在 运行 时拦截此第二个版本,所以默认情况下(或根本不调用)第一个版本。通过使用 LD_PRELOAD 环境。
LD_PRELOAD=./libtest2.so ./main
...
祝你好运。
我把DSO复制重命名为libtest2.so,将LD_PRELOAD重置为重命名后的DSO(带绝对路径),同样提示找不到libtest.so。
我认为之所以会提示,是因为硬依赖的libtest.so无法加载。
也就是说LD_PRELOAD已经加载了,但是硬依赖无法满足,所以也无法执行./main
。
现在我可以得出结论,执行./main时,必须满足硬依赖DSO,因为每一个硬依赖DSO也必须加载(虽然这个DSO应该被完全替换!),否则会提示DSO可以找不到!
感谢@Darryl Miles 的帮助
我在使用 LD_PRELOAD 加载我的 so 时遇到了一些问题。
步骤如下:
libtest.c:
void fun() { return }
gcc -o libtest.so libtest.c -fPIC --shared
导出LD_PRELOAD=
pwd
/libtest.somain.c
extern void fun(); void main() { fun() }
gcc -o main -L。 main.c-ltest
然后
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)
- 执行主程序
./main
它促进: 加载共享 library:libtest.so 时出错。无法打开共享对象 file:No 这样的文件或目录。
不知为什么导出LD_PRELOAD变量后提示找不到libtest.so。但是,我也尝试使用 LD_PRELOAD 指定不同的共享库(而不是 "libc.so")来注入 malloc 函数,它有效! 为什么LD_PRELOAD只适用于链接时未使用的共享库???
您需要创建 2 个版本的 *.so。一个具有默认行为并通过“-ltest”加载和硬 linked。
现在构建您的默认 libtest.so 并用 nm -B
证明您期望拦截的符号是动态 linked.
现在将 main.c 构建到 main.o,然后检查 main.o 和 nm
也可以看到它在符号上有一个 extern unsatisfied linkage 要求.
现在 link ./main
与 main.o 和 libtest.so 然后 运行 它。
默认情况下,./main
需要使用此副本 运行,演示默认行为,并通过 ldd
命令显示正确 DSO 的正确路径。
...
现在您开始创建 LD_PRELOAD 版本。
你应该称之为libtest2.so
。您不使用 -ltest2
关键是建造 ./main
的人根本不知道 libtest2.so,没有硬性 link 年龄依赖性。
libtest2.so 具有替代行为,例如使 foo() returns 不同 string/number),现在的目标是在 运行 时拦截此第二个版本,所以默认情况下(或根本不调用)第一个版本。通过使用 LD_PRELOAD 环境。
LD_PRELOAD=./libtest2.so ./main
...
祝你好运。
我把DSO复制重命名为libtest2.so,将LD_PRELOAD重置为重命名后的DSO(带绝对路径),同样提示找不到libtest.so。
我认为之所以会提示,是因为硬依赖的libtest.so无法加载。
也就是说LD_PRELOAD已经加载了,但是硬依赖无法满足,所以也无法执行./main
。
现在我可以得出结论,执行./main时,必须满足硬依赖DSO,因为每一个硬依赖DSO也必须加载(虽然这个DSO应该被完全替换!),否则会提示DSO可以找不到!
感谢@Darryl Miles 的帮助