问题
我希望将一个目标文件注入到现有的二进制文件中。举个具体的例子,考虑一个源码文件 Hello.c
:
#include <stdlib.h>
int main(void)
{
return EXIT_SUCCESS;
}
这段代码可以通过 gcc -std=gnu99 -Wall Hello.c -o Hello
编译成一个可执行文件,文件名为 Hello
。此外,现在考虑一下 Embed.c
:
func1(void)
{
}
一个目标文件
Embed.o
可以通过gcc -c Embed.c
创建。我的问题是如何将Embed.o
通用地插入到Hello
中,以便执行必要的重定位,并正确修补适当的ELF内部表(例如符号表、PLT等)?
假设
可以假设要嵌入的对象文件已经静态链接了其依赖项。任何动态依赖项,如C运行时,也可以认为存在于目标可执行文件中。
目前的尝试/想法
- 使用
libbfd
将节从对象文件复制到二进制文件中。我已经取得的进展是,我可以创建一个新的对象,其中包含原始二进制文件和对象文件的节。问题在于,由于对象文件是可重定位的,因此必须先执行重定位,才能将其节正确地复制到输出中。 - 将二进制文件转换回对象文件,并重新链接
ld
。到目前为止,我尝试使用objcopy
执行转换objcopy --input elf64-x86-64 --output elf64-x86-64 Hello Hello.o
。显然,这样并不能按照我预期的工作,因为ld -o Hello2 Embed.o Hello.o
将导致ld: error: Hello.o: unsupported ELF file type 2
。不过,我认为这应该是可以预料的,因为Hello
不是一个对象文件。 - 查找已经存在的执行此类插入的工具?
原理 (可选阅读)
我正在制作一个静态可执行文件编辑器,其中的设想是允许将任意用户定义的程序插入到现有二进制文件中。这将分两步完成:
- 将一个包含用户定义程序的对象文件注入到二进制文件中。这是一项强制性步骤,不能通过其他替代方案(例如注入共享对象)来解决。
- 对新二进制文件进行静态分析,并使用此方法从原始代码静态重定向到新添加的代码。
在大多数情况下,我已经完成了步骤2所需的工作,但是我在注入对象文件方面遇到了问题。鉴于其他工具使用相同的对象注入方法(例如EEL),因此这个问题肯定是可以解决的。
.so
文件的原因之一是,诸如LD_PRELOAD
之类的注入技巧可能会被应用程序破解。不仅如此,它还需要分发一个额外的库,以形成新环境。静态拦截具有各种其他优点(特别是对于这个项目的目的),但正如我在问题和回答评论中已经说过的那样,这不是我可以更改的设计决策 :) - Mike Kwan