强制ELF二进制文件使用另一个libc.so

时间:2016-07-26 12:58:47

标签: linux ld elf libc

我需要制作ELF二进制文件以使用其他版本的libc.so用于科学目的。我尝试使用LD_PRELOADpatchelf实用程序执行此操作,但二进制文件不会运行时出现以下错误:

./a.out: error while loading shared libraries: libc-2.15.so: cannot open shared object file: No such file or directorySegmentation fault (core dumped)

我认为这是因为我需要另一个版本的ld.so

什么是使二进制使用我的libc版本的最有效方法?

编辑:我没有二进制源代码。

编辑:已编辑错误消息。没有SELinux,没有AppArmor。

2 个答案:

答案 0 :(得分:2)

对我来说,看起来你没有花费整个路径到新的libc变体。

我做了以下事情:

ldd example

linux-vdso.so.1 (0x00007ffe9c087000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f0cef872000)
libm.so.6 => /lib64/libm.so.6 (0x00007f0cef56f000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f0cef359000)
libc.so.6 => /lib64/libc.so.6 (0x00007f0ceef98000)
/lib64/ld-linux-x86-64.so.2 (0x000055ca3cb92000)

LD_PRELOAD=/tmp/bug_libc.so ldd example

linux-vdso.so.1 (0x00007ffc2cff8000)
/tmp/bug_libc.so (0x00007f56a1358000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f56a0f9a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f56a0c98000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f56a0a82000)
/lib64/ld-linux-x86-64.so.2 (0x00005605c8a7a000)

如果我用无效的libc替换,则会收到不同的错误消息。只有当我给出错误的道路时:

LD_PRELOAD=/tmp/bug_libc.so2 ldd go

ERROR: ld.so: object '/tmp/bug_libc.so2' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/tmp/bug_libc.so2' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
linux-vdso.so.1 (0x00007ffedcde4000)
libstdc++.so.6 => /opt/linux-gnu_6.1.0/lib64/libstdc++.so.6 (0x00007f3ae2188000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3ae1e85000)
libgcc_s.so.1 => /opt/linux-gnu_6.1.0/lib64/libgcc_s.so.1 (0x00007f3ae1c6f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3ae18ae000)
/lib64/ld-linux-x86-64.so.2 (0x000055df54aae000)

通过访问替换libc文件,可能还有其他问题。 检查文件上的访问标志,并检查SELinux或AppArmor或其他保护是否停止在您的环境中加载libc。因为替换libc打开了一个安全漏洞,所以它是SELinux&合作!

您应该首先检查ldd。也许你的新libc需要一些在你的系统上找不到的其他lib的更多(旧)变体。 Normaly libc不需要其他库,但我不知道你在玩什么游戏。无论如何:ldd为你提供了一个更详细的答案来解决图书馆加载阶段正在发生的事情。

编辑:segfault

如果您遇到段错误,通常会使用不兼容的头文件编译您的应用程序。您必须使用您要使用的libc版本附带的标头进行编译。如果针对系统libc的系统头编译并运行任何不兼容的预编译libc版本,则通过访问错误的数据结构会出现任何类型的内存错误。

答案 1 :(得分:1)

This answer解释了为什么LD_PRELOAD 无法工作,并建议解决方案。

  

我尝试使用LD_PRELOAD和patchelf实用程序

目前尚不清楚您对patchelf的使用是仅触及DT_RPATH,仅触及PT_INTERP,还是两者兼而有之。你需要做到这两点。