有没有办法告诉链接器在加载共享对象时忽略 DT_SONAME?

Mic*_*nez 3 c linux linker

man ld 说:

-soname=name 创建 ELF 共享对象时,将内部 DT_SONAME 字段设置为指定名称。当可执行文件与具有 DT_SONAME 字段的共享对象链接时,当可执行文件运行时,动态链接器将尝试加载由 DT_SONAME 字段指定的共享对象,而不是使用提供给链接器的文件名。

可以覆盖此语句的后半部分吗?换句话说,可以在运行可执行文件时强制链接器忽略外部共享库的 DT_SONAME 而只使用文件名吗?

Emp*_*ian 5

换句话说,可以在运行可执行文件时强制链接器忽略外部共享库的 DT_SONAME 而只使用文件名吗?

不。

首先,链接器不参与可执行文件的运行,加载器(也称为动态链接器)是。加载器是一个完全独立的程序,通常不共享代码,与链接器完全不同。

其次,链接器完成后,用于链接可执行文件的文件名不会在任何地方记录(仅DT_SONAME记录)。因此,即使加载程序想要使用原始文件名,它也无法找出它是什么。

也就是说,您可以更改.dynstr记录DT_SONAME. 如果字符串是 (say) foobar.so.1,并且您将其二进制编辑为barfoo.so,那么加载程序将查找barfoo.so(使用其通常的共享库搜索规则)而不是foobar.so.1. 这里唯一的限制是新名称不能比旧名称长(否则会损坏其他字符串)。

也可以.dynstr用更长的字符串替换该部分(并替换foobar.so.1/full/path/to/libsomething.so),但这种转换很难正确执行。