Saturday, April 30, 2005

image checksums

When modifying images, it is a good idea to change the checksum as well. There is an API in imagehlp.dll for calculating the checksum from the image bytes.

If you change the image bytes, you should re-calculate the checksum and store in in the image header.

Since I couldn't find a command line tool that could show the original checksum in the header as well as the computed checksum, I wrote this little tool.

Complile this with cl /Zi checksum.cpp /link imagehlp.lib
Usage checksum.exe image_name

ex:
D:\temp>checksum c:\WINDOWS\system32\kerberos.dll
checksum orig 0x00051f00 computed 0x00051f00

D:\temp>

#include <windows.h>
#include <imagehlp.h>
#include <stdio.h>


int __cdecl main(int argc, char** argv){
argc; argv;
if (argc < 2){
printf("Usage: checksum filename\n");
return 1;
}

const char* fn = argv[1];
HANDLE hFile = CreateFile(fn, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("culdn't find %s\n", fn);
return 1;
}

DWORD fileSize = GetFileSize(hFile, 0);
if (INVALID_FILE_SIZE == fileSize)
{
printf("couldn't find size of %s\n", fn);
return 1;
}

HANDLE hFileMap = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
if (hFileMap == 0)
{
printf("culdn't create mapping for %s\n", fn);
return 1;
}
PVOID hBaseFile = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
if (hBaseFile == 0)
{
printf("culdn't map %s\n", fn);
return 1;
}

DWORD hdr_checksum;
DWORD checksum;
PIMAGE_NT_HEADERS ntHeaders = CheckSumMappedFile(hBaseFile, fileSize, &hdr_checksum, &checksum);
if (!ntHeaders)
{
printf("checksum api failed\n");
return 1;
}

printf("checksum orig 0x%08x computed 0x%08x\n", hdr_checksum, checksum);
return 0;
}

No comments: