如何在Windows PE 32位可执行文件中为我的代码洞穴腾出空间

所以我想在minesweeper.exe(典型的Windows XP扫雷游戏,链接Minesweeper)中为我的代码洞穴腾出空间.所以我通过CFF Explorer修改文件的PE头,以增加.text部分的大小.

我尝试将.text段的原始大小增加1000h(新大小为3B58),但Windows无法找到入口点,游戏无法启动.然后我尝试增加.rsrc部分的大小,添加一个新的部分,增加图像大小,但这些尝试都没有成功,Windows说“这不是x32可执行文件”.

所以这就是问题:如何为我的代码洞穴腾出空间?我不想搜索编译器留下的空白空间,我想为我的代码提供漂亮而干净的1000h字节.这个教程以及如何在不破坏游戏的情况下做到这一点的详细解释将是伟大的! (是的,我实际上正在攻击扫雷)

如果不使以下部分无效,则无法增加部分的大小(通常是因为它使这些部分中的偏移和地址无效).这仍然是可能的,但它非常容易出错,当你有一个更简单的解决方案时,不值得麻烦.

通常,您需要在PE的末尾添加一个部分,然后从代码部分跳转到那里.在代码部分(代码洞穴)的末尾通常有一点空间,因此您可以将JMP(或一些代码存根)放在那里以重定向到新部分.您还可以为数据或新资源或任何您想要的内容添加其他新部分.

注意:我使用两个工具:CFF explorer作为PE浏览器;十六进制编辑器.

这个文件非常特别,所以添加新的部分比平常更难.

开始吧!

下面是IMAGE_SECTION_HEADER数组的十六进制视图:

通常有一些空间可以添加一个新的部分,但在这种特殊情况下,没有…最后一个部分标题后面紧跟一些东西.

根据内容判断,这可能是一个绑定的导入目录,在CFF资源管理器中确认(绑定目录的偏移量为0x248):

绑定导入目录今天没用,特别是ASLR,所以我们可以将整个目录归零:

您也可以将数据目录中的绑定导入目录RVA归零,尽管这不是严格要求的:

现在,是时候添加新的部分了.

添加新部分

minesweeper认带有3个部分,因此将部分数从3增加到4:

转到节标题添加一个新节(您可以直接在CFF资源管理器中执行此操作):

您需要选择两个数字:

>新部分的原始大小(我选择了0x400);它必须是FileAlignment的倍数(在这种情况下为0x200).
>新部分的虚拟大小(我选择了0x1000);它必须是SectionAlignement的倍数(对于这个二进制文件,它是0x1000).

现在我们“需要计算另外两个成员,虚拟地址和原始地址.

虚拟地址

让我们以第一和第二部分为例.

第一部分从0x1000开始,虚拟大小为0x3A56.下一节虚拟地址必须在SectionAlignement(0x1000)上对齐,所以计算是(在这里使用python):

>>> def round_up_multiple_of(number,multiple):
    num = number + (multiple - 1)
    return num - (num % multiple)

>>> hex(round_up_multiple_of(0x1000 + 0x3a56,0x1000))
'0x5000'

这给出了正确的0x5000(.data部分从0x5000开始).

现在,我们的最后一节应该从哪里开始?

.rsrc部分从0x6000开始,大小为0x19160:

>>> hex(round_up_multiple_of(0x6000 + 0x19160,0x1000))
'0x20000'

所以它必须从0x20000开始.将该号码放在虚拟地址中.

原始地址

(通常不需要这样,因为所有部分已经对齐,最后一部分必须从文件末尾开始,但我们会这样做).

让我们从一个例子开始(第一和第二部分):

第一部分原始地址是0x400,原始地址是0x3c00. FileAlignement是0x200,因此:

>>> hex(round_up_multiple_of(0x400 + 0x3c00,0x200))
'0x4000'

第二部分应该从0x4000处的文件(其原始地址)开始,这是正确的.

因此,对于我们的新部分,计算是:

> .rsrc部分从文件0x4200开始
> .rsrc文件的节大小为0x19200
> FileAligment是0x200

计算如下:

>>> hex(round_up_multiple_of(0x4200 + 0x19200,0x200))
 '0x1d400'

我们的最后一节从文件中的0x1d400开始,用十六进制编辑器确认:

最后的步骤

最后一步是必需的,计算Optional头中的SizeOfImage字段.根据PE规范,该领域是:

The size (in bytes) of the image,including all headers,as the image
is loaded in memory. It must be a multiple of SectionAlignment.

因此,计算结果为:最后一节的VirtualAddress VirtualSize,在SectionAlignment(0x1000)上对齐:

>>> hex(round_up_multiple_of(0x20000 + 0x1000,0x1000))
'0x21000'

现在,将所有修改保存在CFF资源管理器中并退出.

为新部分增加空间

最后一步是为最后一节添加所需的字节.当我选择原始大小0x400时,我使用十六进制编辑器在原始地址(0x1d400)处插入0x400字节.

保存文件.如果您按照所有步骤进行操作(在Win 10上测试),则可以启动修改后的可执行文件.

如果0x400不够,请尝试使用不同原始大小的新部分.

现在你有了一个新的空白部分,其余部分取决于你修改代码:)

相关文章

Windows2012R2备用域控搭建 前置操作 域控主域控的主dns:自...
主域控角色迁移和夺取(转载) 转载自:http://yupeizhi.blo...
Windows2012R2 NTP时间同步 Windows2012R2里没有了internet时...
Windows注册表操作基础代码 Windows下对注册表进行操作使用的...
黑客常用WinAPI函数整理之前的博客写了很多关于Windows编程的...
一个简单的Windows Socket可复用框架说起网络编程,无非是建...