265 lines
8.5 KiB
C
265 lines
8.5 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1992 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
smashlck.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This function smashes lock prefixes replacing them with NOPs
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Mark Lucovsky (markl) 30-Apr-1993
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <private.h>
|
||
|
|
||
|
|
||
|
BOOL fVerbose;
|
||
|
BOOL fUpdate;
|
||
|
BOOL fUsage;
|
||
|
|
||
|
UCHAR LockPrefixOpcode = 0xf0;
|
||
|
UCHAR NoOpOpcode = 0x90;
|
||
|
|
||
|
LPSTR CurrentImageName;
|
||
|
PIMAGE_OPTIONAL_HEADER32 OptionalHeader32;
|
||
|
PIMAGE_OPTIONAL_HEADER64 OptionalHeader64;
|
||
|
PIMAGE_FILE_HEADER FileHeader;
|
||
|
LOADED_IMAGE CurrentImage;
|
||
|
CHAR DebugFilePath[_MAX_PATH];
|
||
|
LPSTR SymbolPath;
|
||
|
|
||
|
PVOID
|
||
|
ImageVaToLoadVa(
|
||
|
PVOID ImageVa,
|
||
|
PLOADED_IMAGE Image
|
||
|
)
|
||
|
{
|
||
|
PIMAGE_SECTION_HEADER Section;
|
||
|
ULONG i, Rva;
|
||
|
PVOID Va;
|
||
|
PIMAGE_OPTIONAL_HEADER32 OptionalHeader32 = NULL;
|
||
|
PIMAGE_OPTIONAL_HEADER64 OptionalHeader64 = NULL;
|
||
|
PIMAGE_FILE_HEADER FileHeader;
|
||
|
|
||
|
FileHeader = &((PIMAGE_NT_HEADERS32)Image->FileHeader)->FileHeader;
|
||
|
|
||
|
OptionalHeadersFromNtHeaders((PIMAGE_NT_HEADERS32)Image->FileHeader,
|
||
|
&OptionalHeader32,
|
||
|
&OptionalHeader64);
|
||
|
if (!OptionalHeader32 && !OptionalHeader64)
|
||
|
return NULL;
|
||
|
|
||
|
Rva = (ULONG)((ULONG_PTR)((PUCHAR)ImageVa - (PUCHAR)OPTIONALHEADER(ImageBase)));
|
||
|
Va = NULL;
|
||
|
Section = Image->LastRvaSection;
|
||
|
if ( Rva >= Section->VirtualAddress &&
|
||
|
Rva < (Section->VirtualAddress + Section->SizeOfRawData) ) {
|
||
|
Va = (PVOID)(Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress);
|
||
|
} else {
|
||
|
for(Section = Image->Sections,i=0; i<Image->NumberOfSections; i++,Section++) {
|
||
|
if ( Rva >= Section->VirtualAddress &&
|
||
|
Rva < (Section->VirtualAddress + Section->SizeOfRawData) ) {
|
||
|
Va = (PVOID)(Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress);
|
||
|
Image->LastRvaSection = Section;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ( !Va ) {
|
||
|
fprintf(stderr,"SMASHLOCK: ImageVaToLoadVa %p in image %p failed\n",ImageVa,Image);
|
||
|
}
|
||
|
return Va;
|
||
|
}
|
||
|
|
||
|
int __cdecl
|
||
|
main(
|
||
|
int argc,
|
||
|
char *argv[],
|
||
|
char *envp[]
|
||
|
)
|
||
|
{
|
||
|
|
||
|
DWORD dw;
|
||
|
LPSTR FilePart;
|
||
|
CHAR Buffer[MAX_PATH];
|
||
|
PIMAGE_LOAD_CONFIG_DIRECTORY ConfigInfo;
|
||
|
ULONG whocares;
|
||
|
char c, *p;
|
||
|
BOOLEAN LocksSmashed;
|
||
|
ULONG CheckSum;
|
||
|
ULONG HeaderSum;
|
||
|
ULONG OldChecksum;
|
||
|
int retval = 0;
|
||
|
|
||
|
fUsage = FALSE;
|
||
|
fVerbose = FALSE;
|
||
|
fUpdate = FALSE;
|
||
|
|
||
|
_tzset();
|
||
|
|
||
|
if (argc <= 1) {
|
||
|
goto showUsage;
|
||
|
}
|
||
|
|
||
|
while (--argc) {
|
||
|
p = *++argv;
|
||
|
if (*p == '/' || *p == '-') {
|
||
|
while (c = *++p)
|
||
|
switch (toupper( c )) {
|
||
|
case '?':
|
||
|
fUsage = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'V':
|
||
|
fVerbose = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'U':
|
||
|
fUpdate = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'S':
|
||
|
argc--, argv++;
|
||
|
SymbolPath = *argv;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
fprintf( stderr, "SMASHLOCK: Invalid switch - /%c\n", c );
|
||
|
fUsage = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( fUsage ) {
|
||
|
showUsage:
|
||
|
fputs("usage: SMASHLOCK [switches] image-names... \n"
|
||
|
" [-?] display this message\n"
|
||
|
" [-u] update image\n"
|
||
|
" [-v] verbose output\n"
|
||
|
" [-s] path to symbol files\n", stderr );
|
||
|
exit(1);
|
||
|
}
|
||
|
} else {
|
||
|
LocksSmashed = FALSE;
|
||
|
|
||
|
CurrentImageName = p;
|
||
|
dw = GetFullPathName(CurrentImageName,sizeof(Buffer),Buffer,&FilePart);
|
||
|
if ( dw == 0 || dw > sizeof(Buffer) ) {
|
||
|
FilePart = CurrentImageName;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Map and load the current image
|
||
|
//
|
||
|
|
||
|
if ( MapAndLoad(CurrentImageName, NULL, &CurrentImage, FALSE, !fUpdate )) {
|
||
|
|
||
|
FileHeader = &((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->FileHeader;
|
||
|
|
||
|
OptionalHeadersFromNtHeaders((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader,
|
||
|
&OptionalHeader32,
|
||
|
&OptionalHeader64);
|
||
|
//
|
||
|
// make sure the image has correct configuration information,
|
||
|
// and that the LockPrefixTable is set up properly
|
||
|
//
|
||
|
|
||
|
ConfigInfo = (PIMAGE_LOAD_CONFIG_DIRECTORY)ImageDirectoryEntryToData(
|
||
|
CurrentImage.MappedAddress,
|
||
|
FALSE,
|
||
|
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
|
||
|
&whocares
|
||
|
);
|
||
|
if ( ConfigInfo && ConfigInfo->LockPrefixTable ) {
|
||
|
|
||
|
//
|
||
|
// Walk through the lock prefix table
|
||
|
//
|
||
|
|
||
|
PUCHAR *LockPrefixs;
|
||
|
PUCHAR LockPrefix;
|
||
|
|
||
|
LockPrefixs = (PUCHAR *)ImageVaToLoadVa((PVOID)ConfigInfo->LockPrefixTable,&CurrentImage);
|
||
|
|
||
|
while(LockPrefixs && *LockPrefixs) {
|
||
|
LockPrefix = (PUCHAR) ImageVaToLoadVa(*LockPrefixs,&CurrentImage);
|
||
|
if ( LockPrefix && *LockPrefix == LockPrefixOpcode ) {
|
||
|
if (fVerbose) {
|
||
|
printf("LockPrefix Found at 0x%p = %x\n",*LockPrefixs,*LockPrefix);
|
||
|
}
|
||
|
if (fUpdate) {
|
||
|
LocksSmashed = TRUE;
|
||
|
*LockPrefix = NoOpOpcode;
|
||
|
}
|
||
|
}
|
||
|
LockPrefixs++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( fUpdate && LocksSmashed ) {
|
||
|
|
||
|
//
|
||
|
// recompute the checksum.
|
||
|
//
|
||
|
|
||
|
OldChecksum = OPTIONALHEADER(CheckSum);
|
||
|
if ( CurrentImage.hFile != INVALID_HANDLE_VALUE ) {
|
||
|
|
||
|
OPTIONALHEADER_ASSIGN(CheckSum, 0);
|
||
|
|
||
|
CheckSumMappedFile(
|
||
|
(PVOID)CurrentImage.MappedAddress,
|
||
|
GetFileSize(CurrentImage.hFile, NULL),
|
||
|
&HeaderSum,
|
||
|
&CheckSum
|
||
|
);
|
||
|
|
||
|
OPTIONALHEADER_ASSIGN(CheckSum, CheckSum);
|
||
|
}
|
||
|
|
||
|
FlushViewOfFile(CurrentImage.MappedAddress,0);
|
||
|
TouchFileTimes(CurrentImage.hFile,NULL);
|
||
|
|
||
|
// And update the .dbg file (if requested)
|
||
|
if (SymbolPath &&
|
||
|
FileHeader->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
|
||
|
if ( UpdateDebugInfoFileEx( CurrentImageName,
|
||
|
SymbolPath,
|
||
|
DebugFilePath,
|
||
|
(PIMAGE_NT_HEADERS32) CurrentImage.FileHeader,
|
||
|
OldChecksum) ) {
|
||
|
if (GetLastError() == ERROR_INVALID_DATA) {
|
||
|
printf( "Warning: Old checksum did not match for %s\n", DebugFilePath);
|
||
|
}
|
||
|
printf("Updated symbols for %s\n", DebugFilePath);
|
||
|
} else {
|
||
|
printf("Unable to update symbols: %s\n", DebugFilePath);
|
||
|
retval=1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnmapViewOfFile(CurrentImage.MappedAddress);
|
||
|
if ( CurrentImage.hFile != INVALID_HANDLE_VALUE ) {
|
||
|
CloseHandle(CurrentImage.hFile);
|
||
|
}
|
||
|
ZeroMemory(&CurrentImage,sizeof(CurrentImage));
|
||
|
} else {
|
||
|
if (!CurrentImage.fSystemImage && !CurrentImage.fDOSImage) {
|
||
|
fprintf(stderr,"SMASHLOCK: failure mapping and loading %s\n",CurrentImageName);
|
||
|
retval=1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return retval;
|
||
|
}
|