有没有办法直接改变二进制的SONAME?

Posted

技术标签:

【中文标题】有没有办法直接改变二进制的SONAME?【英文标题】:Is there any way to change the SONAME of a binary directly? 【发布时间】:2013-08-30 07:15:39 【问题描述】:

我的程序依赖libcurl.so.3,但是在RHEL6中没有符号链接libcurl.so.3 ⇾ libcurl.so.4(我的程序在创建这个链接时可以顺利运行)。但是,有符号链接libcurl.so ⇾ libcurl.so.4

我想将嵌入在libcurl.so.3.0.0.0 文件中的SONAMElibcurl.so.3 修改为libcurl.so,这样我就可以在不创建符号链接的情况下在RHEL 6 上运行我的程序。

我的解决方案可能不是最优的,但我认为学习如何直接修改二进制文件很有价值。

$readelf -d libcurl.so.3.0.0 

Dynamic segment at offset 0x303cc contains 25 entries:

  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libssl.so.2]
 0x0000000e (SONAME)                     Library soname: [libcurl.so.3]

我想把上面的libcurl.so.3改成libcurl.so

【问题讨论】:

您所说的是重命名文件或符号链接,而不是修改二进制文件。 您可以创建“libcurl.so.4”的副本,将其重命名为“libcurl.so.3”并使用十六进制编辑器将 SONAME 条目从“libcurl.so.4”重命名到“libcurl.so.3”。这通常不起作用,因为版本信息也存在于动态库中。 我认为最简单的方法是重建 libcurl 并修改一些构建规则以获得所需的 SONAME。对于后期构建更改,我不建议使用二进制版本。有一个关于修补 ELF 格式nixos.org/patchelf.html 的项目,它不允许更改 SONAME,但它可以提供一些关于如何实现这样的事情的想法。 【参考方案1】:

是的,你可以像这样使用patchelf(来自它的Readme):

patchelf --set-soname libnewname.so.3.4.5 path/to/libmylibrary.so.1.2.3

【讨论】:

在 so 上使用 patchelf -set-soname strip 后现在失败:strip: src/.libs/st1B6Gj2: 程序头没有足够的空间,请尝试使用 -N strip:src/.libs/ 链接st1B6Gj2[.note.gnu.build-id]:错误值【参考方案2】:

您应该避免删除 SO 对象的版本,例如当您的应用程序依赖于特定的 libc (libc.so.6) 时。

如果您想使用另一个库,正确的做法是在调用您的应用程序之前使用 LD_PRELOAD 变量

如果您将 LD_PRELOAD 设置为新文件的路径,则该文件将在任何其他库(甚至包括 C 运行时、libc.so)之前加载。

【讨论】:

以上是关于有没有办法直接改变二进制的SONAME?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法直接在 mongoDB 中存储 python 对象而不序列化它们

java的socket通信如何直接接收16进制数据

编程语言介绍

具有特殊操作的二进制搜索树

二进制数字怎么表示?

是否可以直接从文件加载镶木地板?