我可以在已编译的二进制文件中更改“rpath”吗?

时间:2012-12-07 18:46:57

标签: linux linker elf

我有一个旧的可执行文件,它是为废料堆安排的,但它还没有。它依赖于从我的环境中删除的一些库,但我在某些地方工作正常。我想将此可执行文件指向这些存根库。是的,我可以设置LD_LIBRARY_PATH,但是这个可执行文件是从许多脚本调用的,很多用户和我都喜欢在一个地方修复它。

我没有这方面的来源,并且很难得到它。我在想 - 我可以使用ELF识别编辑器编辑这个文件,并在rpath中添加一个简单的PATH以使其命中新的库吗?这是可能的吗,或者一旦你创建了ELF二进制文件,你就把东西固定到位置并且它们不能移动?

4 个答案:

答案 0 :(得分:129)

有一种比名为patchelfchrpath更通用的工具。它最初是为Nix和NixOS(包装系统和GNU / Linux发行版)制作包而创建的。

如果二进制文件中没有rpath(此处称为rdsamp),chrpath将失败:

chrpath -r '$ORIGIN/../lib64' rdsamp 
rdsamp: no rpath or runpath tag found.

另一方面,

patchelf --set-rpath '$ORIGIN/../lib64' rdsamp

成功就好了。

答案 1 :(得分:66)

有一个名为chrpath的工具可以执行此操作 - 它可能在您的发行版包中提供。

答案 2 :(得分:2)

就像@ user7610所说的那样,正确的方法是使用@typeclass工具。

但是,我觉得我可以给出一个更全面的答案,涵盖一个人确切要做的所有命令。

首先,许多开发人员谈论patchelf,但实际上是指RPATH。这是两个不同的可选动态部分,加载器对它们的处理方式非常不同。您可以详细了解它们here之间的区别。

现在,请记住:

  • 如果设置了RUNPATH,则会忽略RUNPATH
  • RPATH已过时,应避免使用
  • 最好使用
  • RPATH,因为它可以被RUNPATH
  • 覆盖

查看当前的R [UN] PATH

LD_LIBRARY_PATH

清除R [UN] PATH

readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"

注意:

  • 同时删除patchelf --remove-rpath <path-to-elf> RPATH

向R [UN] PATH添加值

RUNPATH

注意:

  • patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf> 是用逗号分隔的目录列表,例如:<desired-path>
  • 如果您指定/my/libs:/my/other/libs,请设置--force-rpath,否则请设置RPATH

答案 3 :(得分:0)

这对我有用,用$ ORIGIN替换XORIGIN。

chrpath -r '\$\ORIGIN/../lib64' httpd