|
/* VC6 在Link中加入 Imagehlp.lib*/
/*
SetCSUM v1.01, (c)2000 Jeremy Collake
http://www.collakesoftware.com
mailto:collake@charter.net
--------------------------------------------------------------------------------
This simple, console mode utility will verify, and optionally set, the correct
checksum of Portable Executables (win32 EXE,DLL,OCX,SCR,etc..). This checksum
is required to be accurate for NT device drivers and some system DLLs. C++
source included.
Usage:
SetCSUM filespec [/A] [/V]
filespec = directory name, a wildcard, or a specific filename.
/A = always set correct checksum in header.
/V = do not prompt to set correct checksum, verify only.
Non-PE files can be checksummed, but obviously cannot have the
checksum in the header set, since there is no PE header.
*/
#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<winuser.h>
#include<imagehlp.h>
#include<winnt.h>
#define ERROR_USAGE 1
#define ERROR_NOFILES 2
#define ERROR_USERQUIT 3
#define CHECKSUM_SET_ERROR 5
#define CHECKSUM_NOT_PE 6
bool DoesDirectoryExist(char *pDirName) {
unsigned int nAttributes=0;
if((nAttributes=GetFileAttributes(pDirName))==-1)
return false;
if((nAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0)
return true;
else return false;
}
int SetCorrectChecksum(char *szFile)
{
HANDLE hFile;
HANDLE hMapping;
unsigned char *pView;
DWORD dwHeaderSum;
DWORD dwCorrectSum;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_DOS_HEADER pDOS;
DWORD nFileSize;
hFile=CreateFile(szFile,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
if(hFile==INVALID_HANDLE_VALUE)
{
return CHECKSUM_OPEN_FAILURE;
}
nFileSize=GetFileSize(hFile,NULL);
hMapping=CreateFileMapping(hFile,0,PAGE_READWRITE,0,0,NULL);
if(!hMapping)
{
CloseHandle(hFile);
return CHECKSUM_MAP_FAILURE;
}
pView=(unsigned char *)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
if(!pView)
{
CloseHandle(hMapping);
CloseHandle(hFile);
return CHECKSUM_MAPVIEW_FAILURE;
}
pDOS=(PIMAGE_DOS_HEADER)pView;
pNTHeader=(PIMAGE_NT_HEADERS)(pDOS->e_lfanew+(DWORD)pDOS);
if(pDOS->e_magic!=IMAGE_DOS_SIGNATURE
||
IsBadReadPtr((void *)pNTHeader,sizeof(_IMAGE_OPTIONAL_HEADER))
||
pNTHeader->Signature!=IMAGE_NT_SIGNATURE)
{
UnmapViewOfFile((LPCVOID)pView);
CloseHandle(hMapping);
CloseHandle(hFile);
return CHECKSUM_NOT_PE;
}
pNTHeader=CheckSumMappedFile((LPVOID)pView,nFileSize,&dwHeaderSum,&dwCorrectSum);
pNTHeader->OptionalHeader.CheckSum=dwCorrectSum;
pNTHeader=CheckSumMappedFile((LPVOID)pView,nFileSize,&dwHeaderSum,&dwCorrectSum);
printf("\n Recompute\n Header Checksum: %.8X\n Correct Checksum: %.8X",dwHeaderSum,dwCorrectSum);
UnmapViewOfFile((LPCVOID)pView);
CloseHandle(hMapping);
CloseHandle(hFile);
if(dwHeaderSum!=dwCorrectSum)
{
return CHECKSUM_SET_ERROR;
}
return CHECKSUM_SUCCESS;
}
int main(int argc, char **argv)
{
WIN32_FIND_DATA FindData;
HANDLE findHandle;
char szFilespec[MAX_PATH*2];
char szPath[MAX_PATH*2];
char szFile[MAX_PATH*2];
DWORD dwDesiredAccess=GENERIC_READ;
DWORD flProtect=PAGE_READONLY;
DWORD dwCorrectSum;
DWORD dwHeaderSum;
bool bAlways=false;
bool bVerifyOnly=false;
printf("\n SetCSUM v1.01, (c)2000 Jeremy Collake");
printf("\n http://www.collakesoftware.com");
printf("\n mailto:collake@charter.net");
printf("\n ----------------------------------------------------------------------");
if(argc<2)
{
showhelp:
printf("\n Usage: SetCSUM filespec [/V] [/A]");
printf("\n\n /V = Verify only, do not prompt to set new checksum.");
printf("\n /A = Always set new checksum.");
printf("\n\n Non-PE files can be checksummed, but obviously cannot have the");
printf("\n checksum in the header set, since there is no PE header.\n");
return ERROR_USAGE;
}
for(int nN=1;nN<argc;nN++)
{
if(argv[nN][0]=='/')
{
if(toupper(argv[nN][1])=='A')
{
bAlways=true;
}
else if(toupper(argv[nN][1])=='V')
{
bVerifyOnly=true;
}
else if(toupper(argv[nN][1])=='?' || toupper(argv[nN][1])=='H')
{
goto showhelp;
}
else
{
printf("\n Unrecognized switch: %s.", argv[nN]);
}
}
else
{
strcpy(szPath,argv[nN]);
strcpy(szFilespec,argv[nN]);
}
}
if(!DoesDirectoryExist(szPath))
{
if((strstr(szPath,"\\")!=NULL || strstr(szPath,"/")!=NULL) && strlen(szPath))
{
for(int nI=strlen(szPath)-1;
szPath[nI]!=0 && szPath[nI]!='\\' && szPath[nI]!='/' && nI>0;
nI--);
szPath[nI]=0;
}
else
{
strcpy((char *)&szPath,".");
}
}
else
{
if(szPath[strlen(szPath)-1]=='\\')
{
szPath[strlen(szPath)-1]=0;
}
strcpy(szFilespec,szPath);
strcat(szFilespec,"\\*.*");
}
findHandle=NULL;
while(1)
{
if(!findHandle)
{
findHandle=FindFirstFile(szFilespec,&FindData);
if(findHandle==INVALID_HANDLE_VALUE)
{
printf("\n No files found!\n");
return ERROR_NOFILES;
}
}
else
{
if(!FindNextFile(findHandle,&FindData))
{
break;
}
}
if((FindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0)
{
continue;
}
strcpy(szFile,szPath);
strcat(szFile,"\\");
strcat(szFile,FindData.cFileName);
printf("\n %s = ",szFile);
switch(MapFileAndCheckSum(szFile,&dwHeaderSum,&dwCorrectSum))
{
case CHECKSUM_SUCCESS:
printf("\n Header Checksum: %.8X\n Correct Checksum: %.8X",dwHeaderSum,dwCorrectSum);
if(dwHeaderSum!=dwCorrectSum)
{
printf("\n Checksums do not match!");
}
if(dwHeaderSum!=dwCorrectSum && !bVerifyOnly)
{
char ch=0;
if(!bAlways)
{
printf("\n Set correct checksum in file? [Y/N/Q] ");
do {
ch=getch();
ch=toupper(ch);
} while(ch!='Y' && ch!='N' && ch!='Q');
putch(ch);
}
if(bAlways || ch=='Y')
{
switch(SetCorrectChecksum(szFile))
{
case CHECKSUM_OPEN_FAILURE:
printf("\n Error opening file! (03)");
break;
case CHECKSUM_MAP_FAILURE:
printf("\n Error mapping file! (03)");
break;
case CHECKSUM_MAPVIEW_FAILURE:
printf("\n Error creating view! (03)");
break;
case CHECKSUM_SET_ERROR:
printf("\n Error setting checksum! (03)");
break;
case CHECKSUM_NOT_PE:
printf("\n File is not Portable Executable (PE), cannot set checksum! (03)");
break;
default:
printf("\n Checksum set!");
}
}
if(ch=='Q')
{
printf("\n\n User quit.");
return ERROR_USERQUIT;
}
}
break;
case CHECKSUM_OPEN_FAILURE:
printf(" Error opening file! (02)");
break;
case CHECKSUM_MAP_FAILURE:
printf(" Error mapping file! (02)");
break;
case CHECKSUM_MAPVIEW_FAILURE:
printf(" Error creating view! (02)");
break;
case CHECKSUM_UNICODE_FAILURE:
printf(" Error converting filename to Unicode (02)");
break;
default:
printf(" Unknown error!");
break;
}
}
printf("\n\n Done!");
return ERROR_SUCCESS;
} |
|