需要扩展共享 (.so) 库使用的库列表

逆向工程 linux 安卓 手臂 图书馆
2021-06-12 09:07:12

我有许多相互调用的共享库(.so,ARM,Android),仅限二进制。

我想为某些函数添加日志记录funcA(),...,funcZ()定义在libsomething.so. 这些函数是从libstuff1.so, ...,调用的libstuffN.so我可以重命名原始库中的函数(将名称保留在同一个存储桶中有点棘手,但可能)。

我想:

  1. 在调用库的依赖列表中添加一个额外的库,也就是libstuff1.so原来只引用了libsomething.so,我希望它同时引用libsomething.solibOneMoreLib.so
  2. 或者,向现有库添加一个额外的函数,例如在 中libsomething.so,我重命名funcA()funbQ()并定义(即添加)funcA()以打印日志并调用funbQ().

我该怎么做?

3个回答

所需的共享库作为DT_NEEDED条目存储在可执行文件的动态部分中。该条目又指向动态字符串表。因此,要添加另一个库,您需要执行以下操作:

  1. 解析程序头列表并找到PT_DYNAMIC条目
  2. p_vaddr使用其他PT_LOAD条目映射到文件偏移量(您可以使用条目本身p_offset字段,PT_DYNAMIC但不能保证它是正确的。)
  3. 阅读并解析动态部分条目,直到您点击DT_NULL
  4. 记住字符串表 ( DT_STRTAB/ DT_STRSZ) 的地址和大小请注意,它是一个虚拟地址,需要使用PT_LOAD条目映射回文件偏移量
  5. 使用您的图书馆名称扩展字符串表。您可能需要为它找到其他地方,因为桌子末端不太可能有足够的空间。如果是这样,您可能需要添加另一个PT_LOAD条目以确保它在进程内存中结束。这将意味着移动其他条目的所有文件偏移量。但让我们假设你已经做到了。
  6. 再次浏览动态部分,并使用新地址更新指向字符串表的所有条目。同时更新DT_STRTAB/ DT_STRSZ
  7. 现在您终于可以DT_NEEDED为您的库添加一个新条目,并DT_NULL在它之后添加另一个终止符。并希望新的DT_NULL没有覆盖任何重要的东西:)

有一个简单的方法。readelf -d libxyz.so所有依赖项列表。这些库之一可以扩展或替代。

我知道这不是对您问题的直接回答,但是诸如LD_PRELOAD机制之类的东西可以让您实现您想要的吗?

随着LD_PRELOAD您可以指定库,该库被加载并从该库函数将被用来代替那些在原有的库。这是在 Linux 系统上进行函数挂钩的一种常见且简单的方法。

下面是一个使用LD_PRELOAD钩子函数的例子