如何在Windows PE 32位可执行文件中为代码洞穴腾出空间 [英] How do I make space for my code cave in a Windows PE 32bit executable

查看:100
本文介绍了如何在Windows PE 32位可执行文件中为代码洞穴腾出空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想在minesweeper.exe(典型的Windows XP minesweeper游戏,链接:扫雷).因此,我通过CFF Explorer修改了文件的PE标头,以增加.text部分的大小.

So I want to make a space for my code caves in minesweeper.exe (typical Windows XP minesweeper game, link: Minesweeper). So I modified the PE header of the file via CFF Explorer to increase size of the .text section.

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

I tried increasing raw size of .text segment by 1000h (new size was 3B58), but Windows was unable to locate the entry point and the game failed to launch. Then I tried increasing the size of the .rsrc section, adding a new section, increasing the image size, but none of those attempts were successful, Windows was saying that "This is not x32 executable".

所以这是一个问题:如何为我的代码留出空间?我不想搜索编译器留下的空白空间,我想为我的代码保留整洁的1000h字节.很好的教程以及如何在不破坏游戏的情况下做到这一点的详细解释将非常棒! (是的,我实际上是在扫雷)

So here is the question: how do I make space for my code cave? I don't want to search for empty space left by the compiler, I want to have nice and clean 1000h bytes for my code. A tutorial for that and a detailed explanation for how to do that without corrupting a game would be GREAT! (And yes, I am actually hacking a minesweeper)

推荐答案

您不能在不使以下部分无效的情况下增加部分的大小(通常是因为这会使那些部分中的偏移量和地址无效).这仍然可以实现,但是它极易出错,如果您有一个更简单的解决方案,那么这也不值得麻烦.

You can't increase the size of a section without invalidating the following ones (typically because it invalidates offsets and addresses in those sections). This remains possible but it's extremely error prone and doesn't worth the hassle when you have a simpler solution.

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

Typically, you juste need to add a section at the end of the PE and jump there from the code section. There is usually a little bit of space at the end of the code section (code cave) so you can place your JMPs (or a little code stub) there to redirect to the new section. You can also add other new sections for data or new resources or whatever you want.

注意:我正在使用两种工具:CFF资源管理器作为PE浏览器;十六进制编辑器.

Note: I'm using two tools: CFF explorer as a PE browser; an hex editor.

此文件非常特殊,因此添加新部分比平时要难一些.

This file is quite particular so it is a little bit harder than usual to add a new section.

开始吧!

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

Below is an hex view of the array of IMAGE_SECTION_HEADER:

通常有一定的空间可以添加新的节,但是在这种情况下,就没有了...最后一个节的标题后面紧跟着一些东西.

Usually there is some room to add a new section but in this particular case, there's none... The last section header is immediately followed by something.

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

Judging by the content, this is probably a bound import directory, which is confirmed in CFF explorer (offset of the bound directory is 0x248):

绑定的导入目录如今已无用,尤其是对于ASLR,因此我们可以将整个目录归零(如上一个屏幕快照所示,其大小为0xA8字节):

Bound import directory are of no use today, especially with ASLR, so we can zero out the whole directory (its size is 0xA8 bytes as indicated in the previous screenshot):

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

You can also zero out the Bound Import directory RVA in the Data Directories although this is not strictly required:

现在,该添加新部分了.

Now, it's time to add the new section.

添加新部分

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

Minesweeper comes with 3 sections by default, so increment the Number of sections from 3 to 4:

转到各节标题并添加一个新节(您可以直接在CFF资源管理器中进行操作;我将其命名为.foobar,请注意,节名最多为 8个字符,不要输入不需要以NULL字节结尾):

Go to the sections headers and add a new section (you can do it directly in CFF explorer; I named mine, .foobar, be wary that section names are at most 8 characters and don't need to end with a NULL byte):

您需要选择两个数字:

  • 新部分的原始大小(我选择了0x400); 必须FileAlignment的倍数(在这种情况下为0x200).

  • The raw size of the new section (I picked 0x400) ; it must be a multiple of FileAlignment (which is 0x200 in this case).

新部分的虚拟大小(我选择了0x1000); 必须SectionAlignement的倍数(此二进制文件为0x1000).

The virtual size of the new section (I picked 0x1000); it must be a multiple of SectionAlignement (which is 0x1000 for this binary).

现在,我们"需要计算另外两个成员Virtual AddressRaw Address.

Now we" need to calculate the two other members, Virtual Address and Raw Address.

虚拟地址

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

Let's take an example with the first and second section.

第一部分从虚拟地址0x1000开始,虚拟大小为0x3A56.下一节的虚拟地址必须SectionAlignement(0x1000)上对齐,因此计算方式为(在此处使用python):

The first section starts at virtual address 0x1000 and has a virtual Size of 0x3A56. The next section virtual address must be aligned on SectionAlignement (0x1000) so the calculation is (using python here):

>>> 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开始).

Which gives 0x5000 which is right (.data section starts at virtual address 0x5000).

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

Now, where our last section should start?

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

.rsrc section starts at 0x6000 and has a size of 0x19160:

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

因此,它必须从虚拟地址0x20000开始.将该号码放入Virtual Address.

So it must start at virtual address 0x20000. Put that number in Virtual Address.

原始地址

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

(Typically this is not needed as all sections are already aligned the last section must start right at the end of the file, but we'll do it).

提醒一下,原始地址是文件中的地址(而不是内存中的地址).

As a reminder, the raw address is an address in the file (not in memory).

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

Let's start with an example (first and second section):

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

The first section raw address is 0x400 and its raw size 0x3c00. FileAlignement is 0x200, thus:

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

第二部分应从文件(其Raw address)的0x4000开始,这是正确的.

The second section should start on the file (its Raw address) at 0x4000 which is right.

因此,对于我们的新部分,计算公式为:

Thus for our new section, the calculation is:

  • .rsrc节从文件0x4200开始
  • 文件上的
  • .rsrc节大小为0x19200
  • FileAligment是0x200
  • .rsrc section starts in the file at 0x4200
  • .rsrc section size on file is 0x19200
  • FileAligment is 0x200

计算如下:

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

我们的最后一部分从文件的原始地址0x1d400开始,该地址已通过十六进制编辑器确认:

Our last section starts at the raw address 0x1d400 in the file which is confirmed with an hex editor:

最终步骤

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

One last step is required, the calculation of the SizeOfImage field in the Optional header. According to the PE specification the field is:

图像的大小(以字节为单位),包括所有标头 已加载到内存中.它必须是SectionAlignment的倍数.

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)对齐:

Hence the calculation can be simplified as: VirtualAddress + VirtualSize of the last section, aligned on SectionAlignment (0x1000):

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

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

Now, save all your modifications in CFF explorer and exit.

为新部分添加空间

最后一步是为最后一节添加所需的字节.当我选择Raw size为0x400时,我使用十六进制编辑器在Raw Address(0x1d400)处插入了0x400字节.

The last step is to add the required bytes for the last section. As I choose a Raw size of 0x400, I insert 0x400 bytes at Raw Address (0x1d400) with an hex editor.

保存文件.如果按照所有步骤操作,它必须能够正常运行(在Win 10上进行了测试),并且可以启动已修改的可执行文件,而不会出现任何错误.

Save you file. If you followed all the steps it must work (tested on Win 10) as is and you can start the modified executable without any errors.

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

Try to experience with a different raw size for the new section if 0x400 is not enough.

现在您有一个新的空白部分,其余部分由您决定修改代码:)

Now you have a new empty section, the rest is up to you for modifying the code :)

这篇关于如何在Windows PE 32位可执行文件中为代码洞穴腾出空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆