将依赖项添加到现有共享对象库

Add a dependency to an existing shared object library

本文关键字:共享 对象 依赖 添加      更新时间:2023-10-16

假设我有三个库:libMissingSymbol.so、libMiddle.so 和 libSymbolHaver.so。 libMissingSymbol 包含一个在 libSymbolHaver 中定义的符号,但只依赖于 libMiddle。 libMiddle 应该依赖于 libSymbolHaver,但它没有。我没有组装这些库的源代码或未链接的对象文件。我是否可以将libMiddle与libSymbolHaver链接,以便libMissingSymbol可以在加载时找到所需的符号?有什么方法可以仅使用这三个共享对象文件和任何必要的工具来解决此问题?我必须最终使用具有相同内容的库(包括 SONAME),除非依赖项更改为 libMiddle,以免在我的项目中进一步分解内容。

假设的 readelf 输出(为相关性而修剪)以阐明:

$ readelf -s libMissingSymbol.so
123: 00000000     0 OBJECT  GLOBAL DEFAULT  UND MangledSymbol
$ readelf -d libMissingSymbol.so
Dynamic section at offset 0x42434 contains 37 entries:
Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libMiddle.so]
0x0000000e (SONAME)                     Library soname: [libMissingSymbol.so]
$ readelf -d libMiddle.so 
Dynamic section at offset 0x75b28 contains 29 entries:
Tag        Type                         Name/Value
0x0000000e (SONAME)                     Library soname: [libMiddle.so]
$ readelf -s libSymbolHaver.so
35: 00064d0c     4 OBJECT  GLOBAL DEFAULT   22 MangledSymbol

我是否可以将libMiddle与libSymbolHaver链接起来,以便libMissingSymbol可以在加载时找到所需的符号?

否:除 AIX 链接器外,所有 UNIX 链接器都考虑.so最终链接产品,并且无法进行进一步修改。

更新:

以不同的方式执行此操作的可行性(例如,反编译libMiddle并使用正确的依赖项重建它)?

我也不认为这是可行的——修改一个完全链接的 ELF 文件并且不违反无数的内部一致性约束真的很难

我建议以下方法,这很可能只是工作(TM)。

  1. 放弃"仅使用这三个库"的限制。这似乎是人为的和不必要的。

  2. 复制libMiddle.so->libZiddle.so(确保在其他地方复制原始libMiddle.so,以防出现问题)。

  3. 二进制修补libZiddle.so中的SONAME以匹配新名称。字符串"libMiddle.so"位于库的.dynstr部分,并且(我相信)没有以任何方式散列,因此更改其中的一个字母不会在新库中引入任何自不一致。

    完成此操作后,比较readelf -a libMiddle.soreadelf -a libZiddle.soSONAME应该是唯一的区别。

  4. 删除libMiddle.so

  5. 链接包含some_unused_function()的新libMiddle.so并且libZiddle.solibSymbolHaver.so具有动态依赖关系。

现在,任何当前链接到libMiddle.so并失败并缺少符号的二进制文件(例如libMissingSymbol.so)会找到新的(空的)libMiddle.so,但是因为新的libMiddle.so需要libZiddle.so(大多数符号所在的位置)libSymbolHaver.so,它应该可以工作。