.so
,ARM,Android)。 从
funcA()
,...,funcZ()
中调用这些函数。我可以在原始库中重命名一个函数(将名称保留在同一存储桶中有些棘手,但可以)。 >
我要:
在调用库的依赖项列表中添加一个额外的库,即最初仅引用
libsomething.so
的libstuff1.so
,我希望它引用libstuffN.so
和libstuff1.so
都可以。或者,向现有库中添加一个额外的功能,例如在
libsomething.so
中,我将libsomething.so
重命名为libOneMoreLib.so
并定义(即添加)libsomething.so
以打印日志并调用funcA()
。我该怎么做?
#1 楼
所需的共享库作为DT_NEEDED
条目存储在可执行文件的动态部分中。该条目又指向动态字符串表。因此,要添加另一个库,您将需要执行以下操作:解析程序头列表并找到
PT_DYNAMIC
条目将其
p_vaddr
映射回文件使用其他PT_LOAD
条目补偿。 (您可以使用p_offset
条目本身的PT_DYNAMIC
字段,但不能保证它是正确的。)读取并解析动态节条目,直到您单击
DT_NULL
为止。 DT_STRTAB
/ DT_STRSZ
)。请注意,这是一个虚拟地址,需要使用PT_LOAD
条目将其映射回文件偏移。用您的库名称扩展字符串表。您可能需要为它找到一些其他位置,因为表的末尾不可能有足够的空间。如果是这样,您可能需要添加另一个
PT_LOAD
条目,以确保它最终出现在过程存储器中。这将意味着移动其他条目的所有文件偏移。但是,假设您已完成操作。再次遍历动态部分,并使用新地址更新指向字符串表的所有条目。同时更新
DT_STRTAB
/ DT_STRSZ
。现在,您终于可以为lib添加一个新的
DT_NEEDED
条目,并在其后添加另一个DT_NULL
终止符。并希望新的DT_NULL
不会覆盖任何重要的内容:) #2 楼
有一个简单的方法。readelf -d libxyz.so
所有依赖项列表。这些库之一可以扩展或替代。#3 楼
我知道这不是您问题的直接答案,但是类似LD_PRELOAD
的机制可以使您实现所需的功能吗?将代替原始库中的库。这是在Linux系统上执行功能挂接的常见且简单的方法。 以下是使用
LD_PRELOAD
钩函数的示例。
评论
是否有一个库可以将.so读取到内存中,然后将其转换为某些数据结构(例如DOM解析器读取XML),以便可以向列表中添加一个元素并将其写回?
– 18446744073709551615
2014年4月21日在10:04
还没看过
–伊戈尔·斯科钦斯基♦
2014年4月21日在12:48
更新:PatchELF似乎至少实现了一些必要的功能,因此您可以尝试扩展它或提交功能请求。
–伊戈尔·斯科钦斯基♦
2014年4月23日下午13:42