我需要制作 ELF 二进制文件以使用另一个版本的 libc.so
用于科学目的。我尝试使用 LD_PRELOAD
和 patchelf
实用程序来执行此操作,但二进制文件无法运行,并出现如下错误:
./a.out:加载共享库时出错:libc-2.15.so:无法打开共享对象文件:没有这样的文件或目录
或段错误(核心已转储)
.
我认为这是因为我需要另一个版本的ld.so
。
使二进制文件使用我的 libc 版本的最有效方法是什么?
编辑:我没有二进制源代码。
编辑:错误信息已编辑。没有 SELinux,没有 AppArmor。
对我来说,您似乎并没有花整个路径到新的 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 & Co 的候选对象!
并且您应该始终首先检查 ldd
。也许您的新 libc 需要更多(较旧的)其他库的变体,而这些变体在您的系统上找不到。通常 libc 不需要其他库,但我不知道你在玩什么游戏。不管怎样:ldd 为您提供有关库加载阶段发生的事情的更详细的答案。
编辑:段错误
如果出现段错误,通常是您使用不兼容的头文件编译了应用程序。您必须使用您要使用的 libc 版本附带的 header 进行编译。如果针对系统 libc 的系统头文件进行编译并运行预编译 libc 的任何不兼容版本,则会因访问错误的数据结构而导致任何类型的内存错误。