我希望将一个目标文件注入现有的二进制文件中。我正在尝试的方法是:
gcc/ld
将可重定位目标文件与要嵌入的目标文件相链接。鉴于来源:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
puts("main");
return EXIT_SUCCESS;
}
我使用以下内容将其编译为host
:
gcc -Wall host.c -o host
我使用以下命令转换为可重定位目标文件:
objcopy -B i386 -I binary -O elf64-x86-64 host host.o
然后我尝试使用以下链接:
gcc host.o -o host
理想情况下,这会将可重定位目标文件重新链接回二进制文件。这也有机会链接任何额外的目标文件。不幸的是,该命令给出了以下错误:
/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
我的问题是为什么会出现此错误以及如何正确重新连接?
我尝试的东西是在此时链接另一个目标文件,其中包含一个虚拟主(因为我想我以后可以手动修补入口点),但是发生的事情是新的二进制文件似乎重新定位旧的代码以奇怪的方式与符号表完全混乱。
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
在可重定位目标文件上:
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
对于那些感兴趣的人,可以找到基本原理here。
答案 0 :(得分:3)
非PIE的可执行文件无法进行重定位。已经进行了重新安置,并且拆除了这些重新安置的记录。也就是说,重新定位它需要在代码和二进制数据中查找对象或函数的所有地址,但是不可能确定字节序列是地址还是某种其他类型的数据或代码。 / p>
应该有办法做你原本想做的事情(添加新代码),但你采取的方法注定要失败。