如何解决有没有办法创建一个具有正确偏移量的剥离二进制文件?
我正在尝试将程序集文件转换为 C++,以用作另一个库的小型且易于插入的“蹦床”加载程序。它在运行时被注入到另一个程序中,然后加载一个库,在其中运行一个函数,然后释放它。这只是为了避免需要多次对 WriteProccessMemory
进行冗长的调用,并在需要时允许进行某些运行时检查。
最初,我用汇编编写代码,因为它让我可以高度控制文件的结构。我最终得到了一个 ~128 字节的文件,结构如下:
<Relocation Header> // Table of function pointers filled in by the loading code
<Code>
<Static Data>
头的大小/结构在编译时是已知的,也允许计算入口点,因此加载它所需的代码很少。
问题是在我的汇编器 (NASM) 和编译器 (GCC) 之间共享头文件的结构非常困难,因此需要重写。
g++ -c -O3 -fpic Loader.cpp
g++ -O3 -shared -nostdlib Loader.o
运行 objcopy -O binary -j .text a.exe
然后给出一个只有大约 95 字节大小的二进制文件(我在程序集版本中手动插入了一些填充,以便在调试“节”的位置时清楚)。
只有一个问题(至少对于这个问题),变量偏移量没有被重新定位(显然)。查看二进制文件,我可以看到类似 mov rcx,QWORD PTR [rip+0x4fc9]
的行。显然,这在 95 字节文件中无效。有没有办法(最好使用 GCC 或 Binutils 中的程序)我可以获得具有正确偏移量的剥离二进制文件?解决方案不必是像 objcopy
这样的后期处理,它可以在构建过程的任何部分发生。
我真的很想避免文件中出现任何不需要的信息,这不一定是有害的,但这意味着超轻量级。该文件不需要可以直接运行(入口点不必为 0)。
还要明确一点,我不是要求对所有指针进行简单的加法/减法,GCC 生成的地址分布在内存中,它们应该与代码背道而驰。
解决方法
虽然不完整并且需要一些更改,但我想我现在已经想出了一个有效的解决方案。
我像以前一样编译,但使用稍微不同的命令链接:g++ -T lnkscrpt.txt -O3 -nostdlib Loader.o
(-shared
只是让链接器抱怨缺少 DllMain)。
lnkscrpt.txt
是一个 ld
链接描述文件 (https://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_5.html#SEC5),如下所示:
SECTIONS
{
. = 0x00;
.bss : { *(.bss) }
.text : { *(.text) }
.data : { *(.rdata) *(.data) }
/DISCARD/ : {*(*)}
}
这会保留我想要的顺序并丢弃任何其他默认部分。
最后我运行 objcopy -O binary -j .* --set-section-flags .bss=alloc,load,contents a.exe
将其余部分复制到平面二进制文件中。 --set-section-flags
选项只是确保二进制文件包含为 .bss
部分分配的空间。
这会生成一个 128 字节的二进制文件,其布局方式与我的自定义程序集版本完全相同,使用正确的偏移量,并且不包含任何不需要的数据。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。