插入静态链接的二进制文件

时间:2018-06-08 09:34:43

标签: linux elf static-linking ld-preload

有一种众所周知的技术可以插入动态链接的二进制文件:创建共享库并使用LD_PRELOAD变量。但它对于静态链接的二进制文件并不起作用。

一种方法是编写一个静态库,用于插入函数并在编译时将其与应用程序链接。但这并不实用,因为重新编译并不总是可行的(想想第三方二进制文件,库等)。

所以我想知道是否有一种方法可以在相同的LD_PRELOAD中为动态链接二进制文件设置静态链接二进制文件,即不更改代码或重新编译现有二进制文件。

我只对Linux上的ELF感兴趣。因此,如果潜在的解决方案不是“便携式”,那么这不是问题。

3 个答案:

答案 0 :(得分:1)

我假设您想在主要可执行文件中插入来自静态库的符号,这相当于插入可执行文件中定义的符号。因此,问题在于是否可以拦截可执行文件中定义的函数。

这是不可能的(编辑:至少没有很多工作 - 请参阅此答案的评论)有两个原因:

  • 默认情况下,可执行文件中定义的符号不会被导出,因此动态链接器无法访问(您可以通过-export-dynamic或导出列表进行更改,但这会产生令人不快的性能或维护副作用)
  • 即使您导出必要的符号,ELF也要求在符号解析期间始终首先搜索可执行文件的动态symtab(请参阅dsohowto中的第1.5.4节“查找范围”); LD_PRELOAD - ed库的symtab将始终遵循可执行文件的symtab,因此没有机会拦截符号

答案 1 :(得分:1)

  

一种方法是编写一个静态库来插入函数,并在编译时将它与应用程序链接。

这种插​​入器的一个难点是它不能轻易调用原始函数(因为它具有相同的名称)。

链接器--wrap=<symbol> option可以提供帮助。

  

但这不实用,因为重新编译

此处不需要重新编译,只需重新链接

  

并非总是可行(想想第三方二进制文件,库等)。

第三方库工作正常(重新链接),但二进制文件比较棘手。

仍然可以使用displaced execution技术,但实现起来非常棘手。

答案 2 :(得分:0)

您要查找的内容称为二进制检测(例如,使用Dyninstptrace)。这个想法是您编写一个mutator程序,该程序附加到(或静态重写)您的原始程序(称为mutatee),并将您选择的代码插入mutatee中的特定点。主要挑战通常围绕着使用仪器引擎提供的API查找那些插入点。在您的情况下,由于您主要是在寻找静态符号,所以如果变异对象被去除了非动态符号,这可能会非常具有挑战性,并且可能需要启发式搜索。