PE文件的校验和(CheckSum)

xiaoxiao2021-02-28  73

IMAGE_OPTIONAL_HEADER.CheckSum 为一个DWORD(64位下也是DWORD)型的校验值,用于检查PE文件的完整性,在一些内核模式驱动及DLL中,该值必须是存在且正确的

校验值的计算很简单:

将IMAGE_OPTIONAL_HEADER.CheckSum请0(因为这部分在文件中也是有值的,计算时得去掉)以WORD为单位对数据块进行累加,记住要用adc指令而不是add将累加和加上文件的长度(还是用adc)

将计算结果与IMAGE_OPTIONAL_HEADER.CheckSum进行比较,不相等则说明文件被修改过或不完整


方法一

可利用ImageHlp.DLL 库里的MapFileAndCheckSum函数对PE文件进行求校验和操作

#include <windows.h> #include<ImageHlp.h> #pragma comment(lib,"ImageHlp.lib") void main() { DWORD HeaderCheckSum = 0; //PE头里的校验值 DWORD CheckSum = 0; //计算下来的校验值 MapFileAndCheckSum(L"C:\\Users\\q4692\\Desktop\\ObjectHook.sys", &HeaderCheckSum, &CheckSum); if (CheckSum == HeaderCheckSum) { MessageBox(NULL, L"相等", NULL, 0); } }

方法二

当然可以自己实现一下该函数,其实很简单:

#include <windows.h> BOOL PECheckSum(LPCWSTR lpFileName); void main() { if (PECheckSum(L"G:\\Cheat Engine 6.6\\Cheat Engine.exe")) { MessageBox(NULL, L"相等", NULL, 0); } } BOOL PECheckSum(LPCWSTR lpFileName)//若校验成功,将返回TRUE { BOOL bRet = FALSE; DWORD FileSizeHigh = 0; DWORD FileSize = 0; PVOID FileBuffer = NULL; DWORD HeaderCheckSum = 0; //PE头里的校验值 DWORD CheckSum0 = 0; //计算后的校验值 HANDLE hFile = CreateFile(lpFileName, //文件完整路径 GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile==INVALID_HANDLE_VALUE) { return bRet ; } FileSize = GetFileSize(hFile, &FileSizeHigh); if (FileSize > 0 && FileSizeHigh == 0) { FileBuffer = malloc(FileSize); } else { //文件太大 return bRet; } if (!ReadFile(hFile, FileBuffer, FileSize, &FileSize, NULL)) { CloseHandle(hFile); return bRet; } //获得IMAGE_OPTIONAL_HEADER里的CheckSum值 PIMAGE_DOS_HEADER pIDH = (PIMAGE_DOS_HEADER)FileBuffer; PIMAGE_NT_HEADERS pINH = (PIMAGE_NT_HEADERS)((PCHAR)pIDH + pIDH->e_lfanew); HeaderCheckSum = pINH->OptionalHeader.CheckSum; pINH->OptionalHeader.CheckSum = 0;//对原先的CheckSum进行清空,否则计算将出错 _asm { pushad xor eax, eax xor ebx, ebx mov esi, FileBuffer mov ecx, FileSize inc ecx shr ecx, 1; 循环次数 = (FileSize+1)/sizeof(WORD) clc loop_entry : lodsw; 读入一个WORD adc bx, ax; 累加 loop loop_entry mov eax, FileSize adc eax, ebx;加上文件大小 mov CheckSum0, eax popad } if (CheckSum0 == HeaderCheckSum)//相等 { bRet = TRUE; } CloseHandle(hFile); free(FileBuffer); return bRet; }
转载请注明原文地址: https://www.6miu.com/read-2628458.html

最新回复(0)