271 lines
8.6 KiB
C
271 lines
8.6 KiB
C
|
#include <private.h>
|
||
|
#include <globals.h>
|
||
|
|
||
|
// Random debug info modification functions for imagehlp
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
IMAGEAPI
|
||
|
UpdateDebugInfoFile(
|
||
|
LPSTR ImageFileName,
|
||
|
LPSTR SymbolPath,
|
||
|
LPSTR DebugFilePath,
|
||
|
PIMAGE_NT_HEADERS32 NtHeaders
|
||
|
)
|
||
|
{
|
||
|
return UpdateDebugInfoFileEx(
|
||
|
ImageFileName,
|
||
|
SymbolPath,
|
||
|
DebugFilePath,
|
||
|
NtHeaders,
|
||
|
NtHeaders->OptionalHeader.CheckSum);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
IMAGEAPI
|
||
|
UpdateDebugInfoFileEx(
|
||
|
LPSTR ImageFileName,
|
||
|
LPSTR SymbolPath,
|
||
|
LPSTR DebugFilePath,
|
||
|
PIMAGE_NT_HEADERS32 NtHeaders,
|
||
|
DWORD OldCheckSum
|
||
|
)
|
||
|
{
|
||
|
// UnSafe...
|
||
|
|
||
|
HANDLE hDebugFile, hMappedFile;
|
||
|
PVOID MappedAddress;
|
||
|
PIMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader;
|
||
|
DWORD dwError = ERROR_SUCCESS;
|
||
|
|
||
|
#ifdef _BUILDING_UPDDBG_
|
||
|
OSVERSIONINFO OSVerInfo;
|
||
|
OSVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||
|
GetVersionEx(&OSVerInfo);
|
||
|
#endif
|
||
|
|
||
|
hDebugFile = FindDebugInfoFile(
|
||
|
ImageFileName,
|
||
|
SymbolPath,
|
||
|
DebugFilePath
|
||
|
);
|
||
|
if ( hDebugFile == NULL ) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
CloseHandle(hDebugFile);
|
||
|
|
||
|
hDebugFile = CreateFile( DebugFilePath,
|
||
|
GENERIC_READ | GENERIC_WRITE,
|
||
|
g.OSVerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT ? (FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE) : (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 ||
|
||
|
DbgFileHeader->SizeOfImage != NtHeaders->OptionalHeader.SizeOfImage
|
||
|
) {
|
||
|
DbgFileHeader->ImageBase = NtHeaders->OptionalHeader.ImageBase;
|
||
|
if (OldCheckSum != DbgFileHeader->CheckSum) {
|
||
|
DbgFileHeader->Flags |= IMAGE_SEPARATE_DEBUG_MISMATCH;
|
||
|
dwError = ERROR_INVALID_DATA;
|
||
|
}
|
||
|
DbgFileHeader->CheckSum = NtHeaders->OptionalHeader.CheckSum;
|
||
|
DbgFileHeader->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
|
||
|
DbgFileHeader->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
|
||
|
FlushViewOfFile(MappedAddress,0);
|
||
|
UnmapViewOfFile(MappedAddress);
|
||
|
TouchFileTimes(hDebugFile,NULL);
|
||
|
CloseHandle(hDebugFile);
|
||
|
SetLastError(dwError);
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
FlushViewOfFile(MappedAddress,0);
|
||
|
UnmapViewOfFile(MappedAddress);
|
||
|
CloseHandle(hDebugFile);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
#ifndef _BUILDING_UPDDBG_
|
||
|
|
||
|
BOOL
|
||
|
IMAGEAPI
|
||
|
RemovePrivateCvSymbolic(
|
||
|
PCHAR DebugData,
|
||
|
PCHAR * NewDebugData,
|
||
|
ULONG * NewDebugSize
|
||
|
)
|
||
|
{
|
||
|
BOOL rc;
|
||
|
rc = RemovePrivateCvSymbolicEx(DebugData, 0, NewDebugData, NewDebugSize);
|
||
|
if (rc && (*NewDebugSize == 0) && (*NewDebugData == DebugData)) {
|
||
|
*NewDebugData = NULL;
|
||
|
}
|
||
|
return(rc);
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
IMAGEAPI
|
||
|
RemovePrivateCvSymbolicEx(
|
||
|
PCHAR DebugData,
|
||
|
ULONG DebugSize,
|
||
|
PCHAR * NewDebugData,
|
||
|
ULONG * NewDebugSize
|
||
|
)
|
||
|
{
|
||
|
OMFSignature *CvDebugData, *NewStartCvSig, *NewEndCvSig;
|
||
|
OMFDirEntry *CvDebugDirEntry;
|
||
|
OMFDirHeader *CvDebugDirHead;
|
||
|
unsigned int i, j;
|
||
|
PCHAR NewCvData;
|
||
|
ULONG NewCvSize = 0, NewCvOffset;
|
||
|
BOOL RC = FALSE;
|
||
|
|
||
|
__try {
|
||
|
CvDebugDirHead = NULL;
|
||
|
CvDebugDirEntry = NULL;
|
||
|
CvDebugData = (OMFSignature *)DebugData;
|
||
|
|
||
|
if ((((*(PULONG)(CvDebugData->Signature)) == '90BN') ||
|
||
|
((*(PULONG)(CvDebugData->Signature)) == '80BN') ||
|
||
|
((*(PULONG)(CvDebugData->Signature)) == '11BN')) &&
|
||
|
((CvDebugDirHead = (OMFDirHeader *)((PUCHAR) CvDebugData + CvDebugData->filepos)) != NULL) &&
|
||
|
((CvDebugDirEntry = (OMFDirEntry *)((PUCHAR) CvDebugDirHead + CvDebugDirHead->cbDirHeader)) != NULL)) {
|
||
|
|
||
|
// Walk the directory. Keep what we want, zero out the rest.
|
||
|
|
||
|
for (i=0, j=0; i < CvDebugDirHead->cDir; i++) {
|
||
|
switch (CvDebugDirEntry[i].SubSection) {
|
||
|
case sstSegMap:
|
||
|
case sstSegName:
|
||
|
case sstOffsetMap16:
|
||
|
case sstOffsetMap32:
|
||
|
case sstModule:
|
||
|
case SSTMODULE:
|
||
|
case SSTPUBLIC:
|
||
|
case sstPublic:
|
||
|
case sstPublicSym:
|
||
|
case sstGlobalPub:
|
||
|
CvDebugDirEntry[j] = CvDebugDirEntry[i];
|
||
|
NewCvSize += CvDebugDirEntry[j].cb;
|
||
|
NewCvSize = (NewCvSize + 3) & ~3;
|
||
|
if (i != j++) {
|
||
|
// Clear the old entry.
|
||
|
RtlZeroMemory(&CvDebugDirEntry[i], CvDebugDirHead->cbDirEntry);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
RC = TRUE;
|
||
|
RtlZeroMemory(CvDebugDirEntry[i].lfo + (PUCHAR) CvDebugData, CvDebugDirEntry[i].cb);
|
||
|
RtlZeroMemory(&CvDebugDirEntry[i], CvDebugDirHead->cbDirEntry);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Now, allocate the new cv data.
|
||
|
|
||
|
CvDebugDirHead->cDir = j;
|
||
|
|
||
|
NewCvSize += (j * CvDebugDirHead->cbDirEntry) + // The directory itself
|
||
|
CvDebugDirHead->cbDirHeader + // The directory header
|
||
|
(sizeof(OMFSignature) * 2); // The signature/offset pairs at each end.
|
||
|
|
||
|
NewCvData = (PCHAR) MemAlloc( NewCvSize );
|
||
|
|
||
|
// And move the stuff we kept into the new section.
|
||
|
|
||
|
NewCvOffset = sizeof(OMFSignature);
|
||
|
|
||
|
RtlCopyMemory(NewCvData + NewCvOffset, CvDebugDirHead, CvDebugDirHead->cbDirHeader);
|
||
|
|
||
|
CvDebugDirHead = (OMFDirHeader *) (NewCvData + NewCvOffset);
|
||
|
|
||
|
NewCvOffset += CvDebugDirHead->cbDirHeader;
|
||
|
|
||
|
RtlCopyMemory(NewCvData + NewCvOffset,
|
||
|
CvDebugDirEntry,
|
||
|
CvDebugDirHead->cDir * CvDebugDirHead->cbDirEntry);
|
||
|
|
||
|
CvDebugDirEntry = (OMFDirEntry *)(NewCvData + NewCvOffset);
|
||
|
|
||
|
NewCvOffset += (CvDebugDirHead->cbDirEntry * CvDebugDirHead->cDir);
|
||
|
|
||
|
for (i=0; i < CvDebugDirHead->cDir; i++) {
|
||
|
RtlCopyMemory(NewCvData + NewCvOffset,
|
||
|
CvDebugDirEntry[i].lfo + (PCHAR) CvDebugData,
|
||
|
CvDebugDirEntry[i].cb);
|
||
|
CvDebugDirEntry[i].lfo = NewCvOffset;
|
||
|
NewCvOffset += (CvDebugDirEntry[i].cb + 3) & ~3;
|
||
|
}
|
||
|
|
||
|
|
||
|
// Re-do the start/end signatures
|
||
|
|
||
|
NewStartCvSig = (OMFSignature *) NewCvData;
|
||
|
NewEndCvSig = (OMFSignature *) ((PCHAR)NewCvData + NewCvOffset);
|
||
|
*(PULONG)(NewStartCvSig->Signature) = *(PULONG)(CvDebugData->Signature);
|
||
|
NewStartCvSig->filepos = (int)((PCHAR)CvDebugDirHead - (PCHAR)NewStartCvSig);
|
||
|
*(PULONG)(NewEndCvSig->Signature) = *(PULONG)(CvDebugData->Signature);
|
||
|
NewCvOffset += sizeof(OMFSignature);
|
||
|
NewEndCvSig->filepos = (LONG)NewCvOffset;
|
||
|
|
||
|
// Set the return values appropriately
|
||
|
|
||
|
*NewDebugData = NewCvData;
|
||
|
*NewDebugSize = NewCvSize;
|
||
|
|
||
|
} else {
|
||
|
if (*(PULONG)(CvDebugData->Signature) == '01BN') {
|
||
|
*NewDebugData = DebugData;
|
||
|
*NewDebugSize = DebugSize;
|
||
|
RC = TRUE;
|
||
|
} else {
|
||
|
// Not NB10, NB09 or NB08. Forget we ever heard of it.
|
||
|
*NewDebugData = DebugData;
|
||
|
*NewDebugSize = 0;
|
||
|
RC = TRUE;
|
||
|
}
|
||
|
}
|
||
|
} __except(EXCEPTION_EXECUTE_HANDLER) {
|
||
|
RC = FALSE;
|
||
|
}
|
||
|
|
||
|
return(RC);
|
||
|
}
|
||
|
|
||
|
#include <copypdb.c>
|
||
|
|
||
|
#endif
|