所以我想在minesweeper.exe(典型的Windows XP扫雷游戏,链接: 扫雷 )中为我的代码洞穴腾出空间。 所以我通过CFF资源pipe理器修改了文件的PE头,增加了.text
部分的大小。
我尝试增加.text
段的原始大小1000h(新大小是3B58),但Windows无法find入口点,游戏无法启动。 然后我尝试增加.rsrc
部分的大小,添加一个新的部分,增加图像大小,但是这些尝试都没有成功,Windows说“这不是x32可执行文件”。
所以这里是一个问题:我如何为我的代码洞穴腾出空间? 我不想search编译器留下的空白空间,我想为我的代码打印1000h字节。 一个教程,以及如何做到这一点,而不破坏游戏的详细解释将是伟大的! (是的,我其实是黑客扫雷)
您不能增加一个部分的大小,而不会使以下部分失效(通常是因为它使这些部分中的偏移量和地址无效)。 这仍然是可能的,但它是非常容易出错的,当你有一个更简单的解决方案时不值得麻烦。
通常情况下,您需要在PE 的末尾添加一个部分,然后从代码部分跳转到此部分。 在代码段(代码洞)的末尾通常会有一些空间,所以你可以把你的JMP(或者一些代码片段)重定向到新的部分。 您也可以添加其他新的部分数据或新的资源或任何你想要的。
注意:我使用两个工具:CFF浏览器作为PE浏览器; 十六进制编辑器。
这个文件非常特别,所以添加一个新的部分比通常要困难一些。
开始吧!
以下是IMAGE_SECTION_HEADER
数组的十六进制视图:
通常有一些空间来添加一个新的部分,但在这种情况下,没有…最后一节标题紧接着是一些东西。
根据内容判断,这可能是一个绑定的导入目录,这在CFF浏览器(绑定目录的偏移量为0x248)中得到确认:
绑定的导入目录是没有用的,尤其是在ASLR中,所以我们可以将整个目录清零:
您也可以将数据目录中的绑定导入目录RVA清零,但这不是严格要求:
现在是时候添加新的部分了。
添加一个新的部分
扫雷器默认有3个部分,所以将部分的数量从3增加到4:
转到部分标题并添加一个新的部分(您可以直接在CFF资源管理器中):
你需要选择两个数字:
新节的原始大小(我选了0x400); 它必须是FileAlignment
(在这种情况下是0x200)。
新部分的虚拟大小(我选择了0x1000); 它必须是SectionAlignement
的倍数(对于这个二进制数是0x1000)。
现在我们需要计算另外两个成员, Virtual Address
和Raw Address
。
虚拟地址
我们以第一部分和第二部分为例。
第一部分从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开始。 把这个号码放在Virtual Address
。
原始地址
(通常这是不需要的,因为所有的部分已经对齐了,最后一部分必须从文件末尾开始,但是我们会这样做)。
我们从一个例子开始(第一和第二部分):
第一部分的原始地址是0x400,原始大小是0x3c00。 FileAlignement
是0x200,因此:
>>> hex(round_up_multiple_of(0x400 + 0x3c00, 0x200)) '0x4000'
第二部分应该在0x4000的文件(其Raw address
)上开始,这是正确的。
因此,对于我们的新部分,计算是:
FileAligment
是0x200 计算如下:
>>> hex(round_up_multiple_of(0x4200 + 0x19200, 0x200)) '0x1d400'
我们的最后一节从用十六进制编辑器确认的文件中的0x1d400开始:
最后的步骤
最后一步是必需的,计算可选标题中的SizeOfImage
字段。 根据PE规范这个领域是:
图像的大小(以字节为单位)包括所有标题,并将图像加载到内存中。 它必须是SectionAlignment的倍数。
因此,计算是:最后一节的VirtualAddress
+ VirtualSize
,在SectionAlignment
(0x1000)上对齐:
>>> hex(round_up_multiple_of(0x20000 + 0x1000, 0x1000)) '0x21000'
现在,将所有修改保存在CFF资源管理器中并退出。
为新的部分增加空间
最后一步是为最后一部分添加所需的字节。 当我选择Raw size
0x400时,我用十六进制编辑器在Raw Address
(0x1d400)处插入0x400字节。
保存你的文件。 如果您按照所有步骤进行操作(在Win 10上进行测试),则可以启动修改后的可执行文件。
如果0x400是不够的尝试体验与新的部分不同的原始大小。
现在你有一个新的空白部分,其余的是由你来修改代码:)