使用备用 libc 和 ld-linux.so hacks;清洁方法?

dat*_*ess 18 dynamic-linking glibc patchelf

我有一个带有非常旧 glibc 的遗留系统,如果不进行大量的测试/验证工作,我们就无法升级它。

我现在需要在该系统上多次运行较新的程序(例如 Java 1.7)。我选择了 chroot 解决方案,在那里我打包了所有需要的库,并在 chroot 中运行服务。

虽然 chroot 非常有限,我宁愿尝试用 LD_LIBRARY_PATH 解决这个问题。不幸的是,我libc.so.6: cannot handle TLS data在尝试时遇到错误。

事实证明,我也需要/lib/ld-linux.so.2来自 chroot 的 。这有效:

LD_LIBRARY_PATH=/home/chroot/lib /home/chroot/lib/ld-linux.so.2 /home/chroot/bin/program
Run Code Online (Sandbox Code Playgroud)

但是,java通过检查/proc/self/cmdline确定从何处加载其库来挫败我的伎俩,如果二进制文件未命名为“bin/java”,则失败。java 在启动期间也执行自身,使问题进一步复杂化。

在最后努力,使这项工作,我打开了Java二进制,十六进制编辑器和替换字符串/lib/ld-linux.so.2/home/chroot/ld.so(并作出一个符号链接ld-linux.so.2),和它的工作!

但我认为每个人都会同意将每个新二进制文件的路径重写为嵌套系统的绝对路径是一个巨大的麻烦。

有谁知道使用自定义库路径(包括自定义 ld-linux.so)的更简洁方法?

小智 16

正如您使用十六进制编辑器发现的那样,加载程序的路径被编译成二进制文件。实际上,你很幸运,在编辑二进制直接合作,因为这两个/lib/ld-linux.so.2/home/chroot/ld.so长度相同。这些字符串的长度也在二进制中,如果直接修改字符串,可能会导致一些微妙的问题。

如果你最终走这条路线,你应该看看像patchelf这样的东西来更新解释器。这将使您可以快速、安全地永久更改口译员。