有没有直接更改二进制文件的SONAME的方法?

20

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

我想修改libcurl.so.3.0.0.0文件中嵌入的SONAME,将其从libcurl.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


你所说的是重命名文件或符号链接,而不是修改二进制文件。 - devnull
1
你可以创建一个“libcurl.so.4”的副本,将其重命名为“libcurl.so.3”,并使用十六进制编辑器将SONAME条目从“libcurl.so.4”重命名为“libcurl.so.3”。通常这种方法不起作用,因为版本信息也存在于动态库中。 - Martin Rosenau
我认为最简单的方法是重新构建libcurl并稍微修改构建规则以获得所需的SONAME。对于后期构建更改,我不建议进行二进制编辑。有一个关于修补ELF格式的项目http://nixos.org/patchelf.html,它不能更改SONAME,但可以提供一些实现此类事情的想法。 - joetde
2个回答

28

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

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

使用patchelf -set-soname对so进行strip后,现在出现了错误:strip: src/.libs/st1B6Gj2: Not enough room for program headers, try linking with -N strip:src/.libs/st1B6Gj2[.note.gnu.build-id]: Bad value - Tom

1
你应该避免移除SO对象的版本,例如当你的应用程序依赖于特定的libc(libc.so.6)时。
如果你想使用另一个库,正确的方法是在调用应用程序之前使用LD_PRELOAD变量。
如果你将LD_PRELOAD设置为新文件的路径,则该文件将在任何其他库(包括C运行时库libc.so)之前加载。

这不是关于源代码(库)的问题,而是关于目标可执行文件的问题,其中需要指定SONAME。如果您没有所需的库,LD_PRELOAD如何帮助? - uvsmtid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接