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

Replace the PE stub in an existing Win32 .exe

我有一个现有的 Win32 .exe,开头有一个 PE 存根,我有另一个 PE 存根存储在一个单独的文件中。这个单独的 PE stub 超过 20 KiB,原来的 PE stub 最多 512 字节。我没有源代码,所以无法重新编译或重新链接。如何替换 Win32 .exe 中的 PE 存根?

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

TL:DR Use the Perl script in pe-setstub to replace the DOS stub in a PE .exe.

具有大存根(甚至大于 100 000 字节)的 Win32 PE .exe 文件可以在各种 Windows 版本上运行,但有一个要求:每个部分的 VirtualAddress 不得小于 header 大小(包括存根、PE header 和 PE 部分 table)。因此,如果一个程序用一个更大的存根替换存根,该程序还必须增加每个部分的 VirtualAddress。这听起来像是一个非常复杂的操作,因此不太可能有一些工具 ready-made 可以做到这一点。

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

即使有这些要求,也可以添加长存根,而无需触及部分的 VirtualAddress 或 ImageBase。 PE .exe 看起来像这样:

  1. 32 个字节的 DOS .exe header(包括末尾的几个字节填充),从 MZ 开始。偏移量 8 处的 header 字段指向 DOS 存根代码 (#3)。
  2. 大约 368 字节的 PE header(包含 4 节 header,每节 40 字节),从 PE 开始,到最后一节 header 结束.
  3. 其余的 DOS 存根代码,将被 DOS 加载到内存和 运行。这可以小到 32 字节,也可以大到几百 KiB。
  4. 一些填充字节将第一部分与 0x200 的倍数对齐。
  5. 节数据,每个对齐到 0x200 的倍数。

我已经在 pe-setstub.

中实现了这样一个存根替换和拆分作为 Perl 脚本

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