为什么在更改了校验和,或者更改了数据部分但没有新的校验和的情况下,可执行文件仍然运行?

问题描述 投票:0回答:1

我有一个用Flat Assembler编译的 "Hello World "控制台应用程序。可执行文件的大小是2048字节,校验和是0x3797。

我的问题是。

  1. 如果我对可执行文件的数据部分进行了修改,对代码部分进行了小的修改,但却保持了相同的校验和,这有什么关系吗?

并不是真的改变操作码,只是插入不同的 input.Length (数据部分的空端文本字符串的长度)

         push 0xfffffff5 // - 11
         call DWORD PTR ds:0x40304c // .idata [GetStdHandle]
         push 0x0
         push 0x401014
         push [input.Length]
         push 0x401000 // .data
         push eax
         call DWORD PTR ds:0x403050 // .idata [WriteConsole]
         push 0x0
         call DWORD PTR ds:0x0403048 // .idata [ExitProcess]
  1. 为什么即使我使用不同的校验码,它也能运行?

例如,即使我把校验和改成0x995A或0x5A99,它仍然运行。

我使用ImageHlp.dll来计算校验和,总结如下。职位.

checksum portable-executable
1个回答
0
投票

PE的校验和是有记录的 此处. 它只是PE文件格式中的一个字段,对于普通用户模式的应用程序来说是可选的。链接器通常将该字段默认为0,至少在从Microsoft Visual C++构建时是如此。在大多数应用程序中,Windows会忽略这个字段,你可以自由地对二进制文件进行修改,而不需要更新这个值。

例外的情况是,对驱动程序和关键系统进程的校验和需要匹配。 从提供的链接来看,"所有的驱动程序,任何在启动时加载的DLL,以及任何加载到关键Windows进程中的DLL",你需要一个匹配的校验和,否则Windows将无法加载该模块。

附注:Windows要求驱动程序除了需要匹配的校验和之外,还需要一个嵌入式代码签名证书,以便在XP之后的Windows版本(即Vista及以上)中加载该模块。 更多信息,请参阅 认证码规格.

你可以计算并将正确的校验和存储到你的PE文件中(许多工具也会为你做这件事),因为你可以选择在运行时编写逻辑来验证这个值,如果你想要一个基本的完整性检查来防止可执行的修改--但这是可选的。 如果你想在 PE 文件的结尾嵌入一个代码签名证书,可以通过 WinTrust APIs 访问更强大的完整性检查(见上面的 Authenticode 链接)。

© www.soinside.com 2019 - 2024. All rights reserved.