Windows 替换现有Win32.exe中的PE存根

Windows 替换现有Win32.exe中的PE存根,windows,stub,portable-executable,Windows,Stub,Portable Executable,我有一个现有的Win32.exe,开头有一个PE存根,另一个PE存根存储在一个单独的文件中。这个单独的PE存根长度超过20kib,原始PE存根最多为512字节。我没有源代码,因此无法重新编译或重新链接。如何替换Win32.exe中的PE存根 可能我需要一个工具来更新剖面文件偏移量。但这还不够:根据objdump-x file.exe的不同输出,这些输出还必须更新:AddressOfEntryPoint、BaseOfCode、BaseOfData、SizeOfImage、SizeOfHeaders

我有一个现有的Win32.exe,开头有一个PE存根,另一个PE存根存储在一个单独的文件中。这个单独的PE存根长度超过20kib,原始PE存根最多为512字节。我没有源代码,因此无法重新编译或重新链接。如何替换Win32.exe中的PE存根

可能我需要一个工具来更新剖面文件偏移量。但这还不够:根据
objdump-x file.exe的不同输出,这些输出还必须更新:AddressOfEntryPoint、BaseOfCode、BaseOfData、SizeOfImage、SizeOfHeaders、数据目录中的偏移量、重定位修复中的地址

TL:DR使用中的Perl脚本替换PE.exe中的DOS存根

具有大存根(甚至大于100000字节)的Win32 PE.exe文件在各种Windows版本上都可以工作,但有一个要求:每个节的VirtualAddress不得小于头大小(包括存根、PE头和PE节表)。因此,如果一个程序用一个更大的存根替换存根,该程序还必须增加每个部分的虚拟外观。这听起来像是一个非常复杂的操作,所以不太可能有现成的工具

仅供参考,在Win32上,还有一个附加要求:PE头(以最后一节头的最后一个字节结尾)必须适合0x800(2048)字节

即使有了这些要求,也可以添加一个长存根,而不必触及节的VirtualAddress或ImageBase。PE.exe将如下所示:

  • 32字节的DOS.exe头(包括结尾的几个字节的填充),从
    MZ
    开始。偏移量为8的标头字段指向DOS存根代码(#3)
  • 大约368字节的PE头(包含4个节头,每个节头40字节),从
    PE
    开始,以最后一个节头结束
  • 其余的DOS存根代码将被加载到内存并由DOS运行。它可以小到32字节,也可以大到几百KiB
  • 一些填充字节将第一部分与0x200的倍数对齐
  • 节数据,每个节数据的倍数为0x200
  • 我已经在中以Perl脚本的形式实现了这样的存根替换和拆分


    它之所以有效是因为#3的大小没有(小的)上限。

    当你说存根时,你是指在DOS模式下工作的DOS存根吗?假设是这种情况,并且您通过将所有20k的DOS存根复制到PE头并更新所有其他RVA和大小来实现目标,Windows将不会加载PE头(包括存根)不在第一页内存(4096字节)中的PE文件。这并不意味着无法完成,但需要对代码进行一些修改并重新定位其中的一部分。@byteptr:是的,我指的是DOS存根。Windows不加载带有20kib DOS存根的程序是不正确的。我刚刚在Windows1064位(以及WindowsXP和WindowsNT3.1虚拟机)上试用过,他们很高兴地运行了.exe。@byteptr:你知道有什么工具可以对.exe进行所有必要的更改,以便正确地替换存根吗?向下投票者:你有什么方法可以推荐我改进这个问题,使它更容易回答吗?DOS存根程序可以大于4096字节,只是在某个时候,存根需要跳转到EXE中的某些保留空间,才能继续。具体地说,ElfanewDOS头成员尽管是32位,但必须是偏移量,以便后面的PE头适合前4096字节。只要存根能绕过这个限制,你就很好。我听说微软链接器在当时有一些存根限制,所以最初的作者可能手工编写了存根入口点。你能把这个文件分享到某个地方让我们看看吗?太棒了!您提供的最新可执行文件在XP、Win7x64和Win10x64上运行,更不用说DOSBox了,它包含一个头文件,其中包含一个大约98k的顺序DOS存根。这是令人困惑的,因为我已经研究了一些内核代码(以及Windows Research内核),并且有头检查。我看到了你的.text部分的巨大和虚假的大小,但在这一点上,我不明白你是如何让所有版本的Windows都加载它,绕过检查的。也许你的结论确实如此?无论如何,谢谢你的宝贵信息@byteptr:我设法找到了一个技巧,用一个更大的DOS存根替换DOS存根,并实现了它。有关详细信息,请参见编辑后的答案。