/*++ 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; LOADED_IMAGE CurrentImage; CHAR DebugFilePath[_MAX_PATH]; LPSTR SymbolPath; PVOID RvaToVa( PVOID Rva, PLOADED_IMAGE Image ) { PIMAGE_SECTION_HEADER Section; ULONG i; PVOID Va; Rva = (PVOID)((PUCHAR)Rva-(PUCHAR)Image->FileHeader->OptionalHeader.ImageBase); Va = NULL; Section = Image->LastRvaSection; if ( (ULONG)Rva >= Section->VirtualAddress && (ULONG)Rva < Section->VirtualAddress + Section->SizeOfRawData ) { Va = (PVOID)((ULONG)Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress); } else { for(Section = Image->Sections,i=0; i<Image->NumberOfSections; i++,Section++) { if ( (ULONG)Rva >= Section->VirtualAddress && (ULONG)Rva < Section->VirtualAddress + Section->SizeOfRawData ) { Va = (PVOID)((ULONG)Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress); Image->LastRvaSection = Section; break; } } } if ( !Va ) { fprintf(stderr,"SMASHLOCK: RvaToVa %lx in image %lx failed\n",Rva,Image); } return Va; } int _CRTAPI1 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; 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 )) { // // 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 *)RvaToVa(ConfigInfo->LockPrefixTable,&CurrentImage); while(LockPrefixs && *LockPrefixs) { LockPrefix = (PUCHAR) RvaToVa(*LockPrefixs,&CurrentImage); if ( LockPrefix && *LockPrefix == LockPrefixOpcode ) { if (fVerbose) { printf("LockPrefix Found at 0x%08x = %x\n",*LockPrefixs,*LockPrefix); } if (fUpdate) { LocksSmashed = TRUE; *LockPrefix = NoOpOpcode; } } LockPrefixs++; } } if ( fUpdate && LocksSmashed ) { // // recompute the checksum. // OldChecksum = CurrentImage.FileHeader->OptionalHeader.CheckSum; if ( CurrentImage.hFile != INVALID_HANDLE_VALUE ) { CurrentImage.FileHeader->OptionalHeader.CheckSum = 0; CheckSumMappedFile( (PVOID)CurrentImage.MappedAddress, GetFileSize(CurrentImage.hFile, NULL), &HeaderSum, &CheckSum ); CurrentImage.FileHeader->OptionalHeader.CheckSum = CheckSum; } FlushViewOfFile(CurrentImage.MappedAddress,0); TouchFileTimes(CurrentImage.hFile,NULL); // And update the .dbg file (if requested) if (SymbolPath && CurrentImage.FileHeader->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) { if ( UpdateDebugInfoFileEx( CurrentImageName, SymbolPath, DebugFilePath, 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); } } } 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); } } } } exit(1); return 1; }