我希望将一个目标文件注入现有的二进制文件中.我尝试的方法是:
gcc/ld将可重定位目标文件与要嵌入的目标文件链接起来.鉴于来源:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
puts("main");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
我host用以下代码编译它:
gcc -Wall host.c -o host
Run Code Online (Sandbox Code Playgroud)
我使用以下命令转换为可重定位目标文件:
objcopy -B i386 -I binary -O elf64-x86-64 host host.o
Run Code Online (Sandbox Code Playgroud)
然后我尝试链接:
gcc host.o -o host
Run Code Online (Sandbox Code Playgroud)
理想情况下,这会将可重定位目标文件重新链接回二进制文件.这也有机会链接任何额外的目标文件.不幸的是,该命令给出了以下错误:
/usr/lib/gcc/x86_64-linux-gnu/4.6.1/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么会出现这个错误,我将如何正确地重新连接?
我尝试的东西是在这一点链接另一个目标文件,其中包含一个虚拟主(因为我想我以后可以手动修补入口点),但是发生的事情是新的二进制文件似乎重新定位了旧的代码.奇怪的方式与符号表完全搞砸了.
readelf 在二进制文件上产生以下内容:
mike@mike-ubuntu:~/Desktop/inject-obj$ readelf -h host
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400410
Start of program headers: 64 (bytes into file)
Start of section headers: 4424 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 30
Section header string table index: 27
Run Code Online (Sandbox Code Playgroud)
在可重定位目标文件上:
mike@mike-ubuntu:~/Desktop/inject-obj$ readelf -h host.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 8480 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 5
Section header string table index: 2
Run Code Online (Sandbox Code Playgroud)
对于那些感兴趣的人,可以在这里找到理由.
非 PIE 的可执行文件无法重定位。搬迁已经进行,搬迁记录已被丢弃。也就是说,重新定位它需要找到二进制代码和数据内的对象或函数的所有地址,但无法确定字节序列是地址还是其他类型的数据或代码。
应该有一种方法可以完成您最初想做的事情(添加新代码),但您所采取的方法注定会失败。