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

Linux 插入静态链接的二进制文件,linux,elf,static-linking,ld-preload,Linux,Elf,Static Linking,Ld Preload,插入动态链接的二进制文件有一种众所周知的技术:创建共享库并使用变量。但它不适用于静态链接的二进制文件 一种方法是编写一个静态库,插入函数并在编译时将其与应用程序链接。但这并不实用,因为重新编译并不总是可能的(想想第三方二进制文件、库等) 因此,我想知道是否有一种方法可以将静态链接的二进制文件插入动态链接的二进制文件的相同LD_预加载工作中,即不更改代码或重新编译现有的二进制文件 我只对Linux操作系统感兴趣。因此,如果一个潜在的解决方案不是“可移植”的,这就不是问题了。我假设您想在主可执行文件

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

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

因此,我想知道是否有一种方法可以将静态链接的二进制文件插入动态链接的二进制文件的相同LD_预加载工作中,即不更改代码或重新编译现有的二进制文件


我只对Linux操作系统感兴趣。因此,如果一个潜在的解决方案不是“可移植”的,这就不是问题了。

我假设您想在主可执行文件中插入符号,它来自一个静态库,相当于插入一个在可执行文件中定义的符号。因此,问题归结为是否有可能截获在可执行文件中定义的函数

这是不可能的(编辑:至少在没有大量工作的情况下是不可能的-请参阅对此答案的评论),原因有二:

  • 默认情况下,可执行文件中定义的符号不会导出,因此动态链接器无法访问(您可以通过
    -export dynamic
    或导出列表更改此符号,但这会对性能或维护产生不愉快的副作用)
  • 即使导出必要的符号,ELF也要求在符号解析期间始终首先搜索可执行文件的动态符号选项卡(请参阅中的第1.5.4节“查找范围”);
    LD_PRELOAD
    -ed库的符号选项卡将始终跟随可执行文件的符号选项卡,因此没有机会截取符号
一种方法是编写一个静态库,插入函数并在编译时将其与应用程序链接

这种插入器的一个困难是它无法轻松调用原始函数(因为它具有相同的名称)

链接器
--wrap=
可以在这里提供帮助

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

这里不需要重新编译,只需要重新链接

并不总是可能的(想想第三方二进制文件、库等)

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


使用这种技术仍然是可能的,但实现起来相当棘手。

您正在寻找的是所谓的二进制指令插入(例如,使用or)。其思想是编写一个mutator程序,附加(或静态重写)原始程序(称为mutatee),并在mutatee中的特定点插入您选择的代码。主要的挑战通常围绕使用检测引擎提供的API查找这些插入点。在您的情况下,由于您主要寻找静态符号,因此这可能是相当具有挑战性的,并且如果mutatee没有非动态符号,则可能需要进行启发式操作。

“‘假设您希望在主可执行文件中插入符号,它来自静态库,相当于插入在可执行文件中定义的符号。”-Yes(例如,
intmain(void){puts(“hello”);}
编译为
gcc-static hello.c
;我想插入
puts
)。对不起,如果不清楚的话。我知道第二期公告。我只是想知道是否有一个机制,即使它很粗糙。感谢您的回答。“这是不可能的”——这是非常可能的,但不使用类似于
LD_PRELOAD
的机制。这也是不容易的。@ SeaDrWorkOrthTrar,我不认为手工修改GET或修补函数PROLUGUES是实用的。@ EdWorkDrof你介意把这个机制概括为一个答案吗?