我有一个用Flat Assembler编译的 "Hello World "控制台应用程序。可执行文件的大小是2048字节,校验和是0x3797。
我的问题是。
并不是真的改变操作码,只是插入不同的 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]
例如,即使我把校验和改成0x995A或0x5A99,它仍然运行。
我使用ImageHlp.dll来计算校验和,总结如下。职位.
PE的校验和是有记录的 此处. 它只是PE文件格式中的一个字段,对于普通用户模式的应用程序来说是可选的。链接器通常将该字段默认为0,至少在从Microsoft Visual C++构建时是如此。在大多数应用程序中,Windows会忽略这个字段,你可以自由地对二进制文件进行修改,而不需要更新这个值。
例外的情况是,对驱动程序和关键系统进程的校验和需要匹配。 从提供的链接来看,"所有的驱动程序,任何在启动时加载的DLL,以及任何加载到关键Windows进程中的DLL",你需要一个匹配的校验和,否则Windows将无法加载该模块。
附注:Windows要求驱动程序除了需要匹配的校验和之外,还需要一个嵌入式代码签名证书,以便在XP之后的Windows版本(即Vista及以上)中加载该模块。 更多信息,请参阅 认证码规格.
你可以计算并将正确的校验和存储到你的PE文件中(许多工具也会为你做这件事),因为你可以选择在运行时编写逻辑来验证这个值,如果你想要一个基本的完整性检查来防止可执行的修改--但这是可选的。 如果你想在 PE 文件的结尾嵌入一个代码签名证书,可以通过 WinTrust APIs 访问更强大的完整性检查(见上面的 Authenticode 链接)。