Sample code:
#include <windows.h>
#include <imagehlp.h>
#pragma comment(linker, "imagehlp.lib")
#include <stdio.h>
int main(int argc, char *argv[])
{
HANDLE FileHandle, MappingHandle;
LPVOID BaseAddress;
DWORD FileLength;
DWORD CheckSum;
DWORD HeaderSum;
PIMAGE_NT_HEADERS pNThdr;
// Open the file for read access
FileHandle = CreateFileW(L"file_to_check.exe", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (FileHandle == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Error opening file!\n");
return 1;
}
// Create a file mapping
MappingHandle = CreateFileMapping(FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL);
if (!MappingHandle)
{
fprintf(stderr, "Error mapping file!\n");
CloseHandle(FileHandle);
return 1;
}
// Map a view of the file
BaseAddress = MapViewOfFile(MappingHandle, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
if (BaseAddress == NULL)
{
fprintf(stderr, "Error mapping view of file!\n");
CloseHandle(MappingHandle);
CloseHandle(FileHandle);
return 1;
}
// Get the length of the file in bytes and call ImageHlp function
FileLength = GetFileSize(FileHandle, NULL);
pNThdr = CheckSumMappedFile(BaseAddress, FileLength, &HeaderSum, &CheckSum);
int res;
if (!pNThdr)
{
//Function failed
fprintf(stderr, "Error checking file! Maybe the file isn't an executable.\n");
res = 1; //error
}
else
{
res = 0; //OK
if (HeaderSum)
{
//File has already a checksum.
//Check for correctness, print report and exit.
if (HeaderSum != CheckSum)
printf("File checksum exist and is wrong.\n"
"Value = 0x%08x, should be 0x%08x.\n", HeaderSum, CheckSum);
else
printf("File checksum exist and is OK. Value = 0x%08x.\n", HeaderSum);
}
else
{
//Set checksum
printf("Setting file checksum to value = 0x%08x.\n", CheckSum);
pNThdr->OptionalHeader.CheckSum = CheckSum;
}
}
// Cleanup and exit
UnmapViewOfFile(BaseAddress);
CloseHandle(MappingHandle);
CloseHandle(FileHandle);
return res;
}
I discourage the use of hand brew checksum code, because in case of changes made by MS it could go wrong.
It's always preferable to use the OS provided functions.