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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13769141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:59:22  来源:igfitidea点击:

Can I change 'rpath' in an already compiled binary?

linuxlinkerelf

提问by Rich Homolka

I have an old executable that's scheduled for the scrap heap, but it's not there yet. It relies on some libs that have been removed from my environment, but I have some stub libs someplace where it works fine. Id like to point this executable to these stub libs. Yes, i could set LD_LIBRARY_PATH, but this executable is called from many scripts, and many users and I'd love to fix it in one spot.

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

I don't have source for this, and would be hard to get it. I was thinking - can I edit this file, using an ELF aware editor, and add a simple PATH to rpath to have it hit the new libs? Is this possible, or once you create an ELF binary, you fix things to locations and they can't be moved?

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

采纳答案by TomH

There is a tool called chrpathwhich can do this - it's probably available in your distribution's packages.

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

回答by user7610

There is a more universal tool than chrpathcalled patchelf. It was originally created for use in making packages for Nix and NixOS (packaging system and a GNU/Linux distribution).

有一种比chrpath所谓的更通用的工具patchelf。它最初创建用于为 Nix 和 NixOS(打包系统和 GNU/Linux 发行版)制作软件包。

In case there is no rpath in a binary (here called rdsamp), chrpathfails:

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

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

On the other hand,

另一方面,

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

succeeds just fine.

成功就好了。

回答by vikram kedlaya

This worked for me, replacing XORIGIN with $ORIGIN.

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

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

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

回答by Daniel Trugman

Just like @user7610 said, the right way to go is the patchelftool.

正如@user7610 所说,正确的方法是使用patchelf工具。

But, I feel that I can give a more comprehensive answer, covering all the commands one needs to do exactly that.

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

For a comprehensive article on the subject, click here

有关该主题的综合文章,请单击此处

First of all, many developers talk about RPATH, but they actually mean RUNPATH. These are two different optional dynamic sections, and the loader handles them very differently. You can read more about the difference between them in the link I mentioned before.

首先,很多开发者都在谈论RPATH,但实际上他们的意思是RUNPATH。这是两个不同的可选动态部分,加载程序处理它们的方式非常不同。您可以在我之前提到的链接中阅读有关它们之间差异的更多信息。

For now, just remember:

现在,请记住:

  • If RUNPATHis set, RPATHis ignored
  • RPATHis deprecated and should be avoided
  • RUNPATHis preferred because it can be overridden by LD_LIBRARY_PATH
  • 如果RUNPATH设置,RPATH则忽略
  • RPATH已弃用,应避免
  • RUNPATH是首选,因为它可以被覆盖 LD_LIBRARY_PATH

See the current R[UN]PATH

查看当前的 R[UN]PATH

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

Clear the R[UN]PATH

清除 R[UN]PATH

patchelf --remove-rpath <path-to-elf>

Notes:

笔记:

  • Removes both RPATHand RUNPATH
  • 删除RPATHRUNPATH

Add values to R[UN]PATH

将值添加到 R[UN]PATH

patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>

Notes:

笔记:

  • <desired-path>is a comma separated directories list, e.g: /my/libs:/my/other/libs
  • If you specify --force-rpath, sets RPATH, otherwise sets RUNPATH
  • <desired-path>是逗号分隔的目录列表,例如: /my/libs:/my/other/libs
  • 如果指定--force-rpath,则设置RPATH,否则设置RUNPATH