windows-nt/Source/XPSP1/NT/sdktools/restools/rlt32/rw/win32/checkfix.cpp
2020-09-26 16:20:57 +08:00

265 lines
7.5 KiB
C++

#include <afxwin.h>
#include "imagehlp.h"
#include "iodll.h"
//... PROTOTYPES
static PIMAGE_NT_HEADERS MyRtlImageNtHeader(
PVOID pBaseAddress);
static BOOL MyUpdateDebugInfoFileEx(
LPSTR ImageFileName,
LPSTR SymbolPath,
LPSTR DebugFilePath,
PIMAGE_NT_HEADERS NtHeaders,
DWORD OldCheckSum
);
//...........................................................................
DWORD QuitA( DWORD err, LPCSTR, LPSTR )
{
return err;
}
DWORD FixCheckSum( LPCSTR ImageName, LPCSTR OrigFileName, LPCSTR SymbolPath)
{
HANDLE FileHandle;
HANDLE MappingHandle;
PIMAGE_NT_HEADERS NtHeaders;
PVOID BaseAddress;
ULONG CheckSum;
ULONG FileLength;
ULONG HeaderSum;
ULONG OldCheckSum;
DWORD iErr = ERROR_NO_ERROR;
FileHandle = CreateFileA( ImageName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if ( FileHandle == INVALID_HANDLE_VALUE )
{
QuitA( 1, ImageName, NULL);
}
MappingHandle = CreateFileMapping( FileHandle,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
if ( MappingHandle == NULL )
{
CloseHandle( FileHandle );
QuitA( 22, ImageName, NULL);
}
else
{
BaseAddress = MapViewOfFile( MappingHandle,
FILE_MAP_READ | FILE_MAP_WRITE,
0,
0,
0);
CloseHandle( MappingHandle );
if ( BaseAddress == NULL )
{
CloseHandle( FileHandle );
QuitA( 23, ImageName, NULL);
}
else
{
//
// Get the length of the file in bytes and compute the checksum.
//
FileLength = GetFileSize( FileHandle, NULL );
//
// Obtain a pointer to the header information.
//
NtHeaders = MyRtlImageNtHeader( BaseAddress);
if ( NtHeaders == NULL )
{
CloseHandle( FileHandle );
UnmapViewOfFile( BaseAddress );
QuitA( 17, ImageName, NULL);
}
else
{
//
// Recompute and reset the checksum of the modified file.
//
OldCheckSum = NtHeaders->OptionalHeader.CheckSum;
(VOID) CheckSumMappedFile( BaseAddress,
FileLength,
&HeaderSum,
&CheckSum);
NtHeaders->OptionalHeader.CheckSum = CheckSum;
if (SymbolPath && *SymbolPath)
{
TCHAR DebugFilePath[MAX_PATH];
SetLastError(0);
MyUpdateDebugInfoFileEx((LPSTR)OrigFileName,
(LPSTR)SymbolPath,
DebugFilePath,
NtHeaders,
OldCheckSum);
iErr = GetLastError();
switch(iErr)
{
case ERROR_INVALID_DATA:
iErr = ERROR_IO_CHECKSUM_MISMATCH;
break;
case ERROR_FILE_NOT_FOUND:
iErr = ERROR_IO_SYMBOLFILE_NOT_FOUND;
break;
case ERROR_NO_ERROR:
break;
default:
iErr += LAST_ERROR;
}
}
if ( ! FlushViewOfFile( BaseAddress, FileLength) )
{
QuitA( 24, ImageName, NULL);
}
if ( NtHeaders->OptionalHeader.CheckSum != OldCheckSum )
{
if ( ! TouchFileTimes( FileHandle, NULL) )
{
QuitA( 25, ImageName, NULL);
}
}
UnmapViewOfFile( BaseAddress );
CloseHandle( FileHandle );
}
}
}
return( iErr);
}
//.........................................................................
static PIMAGE_NT_HEADERS MyRtlImageNtHeader( PVOID pBaseAddress)
{
IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pBaseAddress;
return( pDosHeader->e_magic == IMAGE_DOS_SIGNATURE
? (PIMAGE_NT_HEADERS)(((PBYTE)pBaseAddress) + pDosHeader->e_lfanew)
: NULL);
}
BOOL
MyUpdateDebugInfoFileEx(
LPSTR ImageFileName,
LPSTR SymbolPath,
LPSTR DebugFilePath,
PIMAGE_NT_HEADERS NtHeaders,
DWORD OldCheckSum
)
{
// UnSafe...
HANDLE hDebugFile, hMappedFile;
PVOID MappedAddress;
PIMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader;
BOOL bRet;
hDebugFile = FindDebugInfoFile(
ImageFileName,
SymbolPath,
DebugFilePath
);
if ( hDebugFile == NULL ) {
return FALSE;
}
CloseHandle(hDebugFile);
hDebugFile = CreateFile( DebugFilePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_DELETE | FILE_SHARE_READ
| FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if ( hDebugFile == INVALID_HANDLE_VALUE ) {
return FALSE;
}
hMappedFile = CreateFileMapping(
hDebugFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL
);
if ( !hMappedFile ) {
CloseHandle(hDebugFile);
return FALSE;
}
MappedAddress = MapViewOfFile(hMappedFile,
FILE_MAP_WRITE,
0,
0,
0
);
CloseHandle(hMappedFile);
if ( !MappedAddress ) {
CloseHandle(hDebugFile);
return FALSE;
}
DbgFileHeader = (PIMAGE_SEPARATE_DEBUG_HEADER)MappedAddress;
if (DbgFileHeader->ImageBase != NtHeaders->OptionalHeader.ImageBase ||
DbgFileHeader->CheckSum != NtHeaders->OptionalHeader.CheckSum
) {
if (OldCheckSum != DbgFileHeader->CheckSum) {
DbgFileHeader->Flags |= IMAGE_SEPARATE_DEBUG_MISMATCH;
SetLastError(ERROR_INVALID_DATA);
} else {
SetLastError(ERROR_SUCCESS);
}
DbgFileHeader->ImageBase = (DWORD) NtHeaders->OptionalHeader.ImageBase;
DbgFileHeader->CheckSum = NtHeaders->OptionalHeader.CheckSum;
DbgFileHeader->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
bRet = TRUE;
}
else
{
bRet = FALSE;
}
if (bRet)
TouchFileTimes(hDebugFile,NULL);
UnmapViewOfFile(MappedAddress);
CloseHandle(hDebugFile);
return bRet;
}