Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

264 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. smashlck.c
  5. Abstract:
  6. This function smashes lock prefixes replacing them with NOPs
  7. Author:
  8. Mark Lucovsky (markl) 30-Apr-1993
  9. Revision History:
  10. --*/
  11. #include <private.h>
  12. BOOL fVerbose;
  13. BOOL fUpdate;
  14. BOOL fUsage;
  15. UCHAR LockPrefixOpcode = 0xf0;
  16. UCHAR NoOpOpcode = 0x90;
  17. LPSTR CurrentImageName;
  18. PIMAGE_OPTIONAL_HEADER32 OptionalHeader32;
  19. PIMAGE_OPTIONAL_HEADER64 OptionalHeader64;
  20. PIMAGE_FILE_HEADER FileHeader;
  21. LOADED_IMAGE CurrentImage;
  22. CHAR DebugFilePath[_MAX_PATH];
  23. LPSTR SymbolPath;
  24. PVOID
  25. ImageVaToLoadVa(
  26. PVOID ImageVa,
  27. PLOADED_IMAGE Image
  28. )
  29. {
  30. PIMAGE_SECTION_HEADER Section;
  31. ULONG i, Rva;
  32. PVOID Va;
  33. PIMAGE_OPTIONAL_HEADER32 OptionalHeader32 = NULL;
  34. PIMAGE_OPTIONAL_HEADER64 OptionalHeader64 = NULL;
  35. PIMAGE_FILE_HEADER FileHeader;
  36. FileHeader = &((PIMAGE_NT_HEADERS32)Image->FileHeader)->FileHeader;
  37. OptionalHeadersFromNtHeaders((PIMAGE_NT_HEADERS32)Image->FileHeader,
  38. &OptionalHeader32,
  39. &OptionalHeader64);
  40. if (!OptionalHeader32 && !OptionalHeader64)
  41. return NULL;
  42. Rva = (ULONG)((ULONG_PTR)((PUCHAR)ImageVa - (PUCHAR)OPTIONALHEADER(ImageBase)));
  43. Va = NULL;
  44. Section = Image->LastRvaSection;
  45. if ( Rva >= Section->VirtualAddress &&
  46. Rva < (Section->VirtualAddress + Section->SizeOfRawData) ) {
  47. Va = (PVOID)(Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress);
  48. } else {
  49. for(Section = Image->Sections,i=0; i<Image->NumberOfSections; i++,Section++) {
  50. if ( Rva >= Section->VirtualAddress &&
  51. Rva < (Section->VirtualAddress + Section->SizeOfRawData) ) {
  52. Va = (PVOID)(Rva - Section->VirtualAddress + Section->PointerToRawData + Image->MappedAddress);
  53. Image->LastRvaSection = Section;
  54. break;
  55. }
  56. }
  57. }
  58. if ( !Va ) {
  59. fprintf(stderr,"SMASHLOCK: ImageVaToLoadVa %p in image %p failed\n",ImageVa,Image);
  60. }
  61. return Va;
  62. }
  63. int __cdecl
  64. main(
  65. int argc,
  66. char *argv[],
  67. char *envp[]
  68. )
  69. {
  70. DWORD dw;
  71. LPSTR FilePart;
  72. CHAR Buffer[MAX_PATH];
  73. PIMAGE_LOAD_CONFIG_DIRECTORY ConfigInfo;
  74. ULONG whocares;
  75. char c, *p;
  76. BOOLEAN LocksSmashed;
  77. ULONG CheckSum;
  78. ULONG HeaderSum;
  79. ULONG OldChecksum;
  80. int retval = 0;
  81. fUsage = FALSE;
  82. fVerbose = FALSE;
  83. fUpdate = FALSE;
  84. _tzset();
  85. if (argc <= 1) {
  86. goto showUsage;
  87. }
  88. while (--argc) {
  89. p = *++argv;
  90. if (*p == '/' || *p == '-') {
  91. while (c = *++p)
  92. switch (toupper( c )) {
  93. case '?':
  94. fUsage = TRUE;
  95. break;
  96. case 'V':
  97. fVerbose = TRUE;
  98. break;
  99. case 'U':
  100. fUpdate = TRUE;
  101. break;
  102. case 'S':
  103. argc--, argv++;
  104. SymbolPath = *argv;
  105. break;
  106. default:
  107. fprintf( stderr, "SMASHLOCK: Invalid switch - /%c\n", c );
  108. fUsage = TRUE;
  109. break;
  110. }
  111. if ( fUsage ) {
  112. showUsage:
  113. fputs("usage: SMASHLOCK [switches] image-names... \n"
  114. " [-?] display this message\n"
  115. " [-u] update image\n"
  116. " [-v] verbose output\n"
  117. " [-s] path to symbol files\n", stderr );
  118. exit(1);
  119. }
  120. } else {
  121. LocksSmashed = FALSE;
  122. CurrentImageName = p;
  123. dw = GetFullPathName(CurrentImageName,sizeof(Buffer),Buffer,&FilePart);
  124. if ( dw == 0 || dw > sizeof(Buffer) ) {
  125. FilePart = CurrentImageName;
  126. }
  127. //
  128. // Map and load the current image
  129. //
  130. if ( MapAndLoad(CurrentImageName, NULL, &CurrentImage, FALSE, !fUpdate )) {
  131. FileHeader = &((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader)->FileHeader;
  132. OptionalHeadersFromNtHeaders((PIMAGE_NT_HEADERS32)CurrentImage.FileHeader,
  133. &OptionalHeader32,
  134. &OptionalHeader64);
  135. //
  136. // make sure the image has correct configuration information,
  137. // and that the LockPrefixTable is set up properly
  138. //
  139. ConfigInfo = (PIMAGE_LOAD_CONFIG_DIRECTORY)ImageDirectoryEntryToData(
  140. CurrentImage.MappedAddress,
  141. FALSE,
  142. IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG,
  143. &whocares
  144. );
  145. if ( ConfigInfo && ConfigInfo->LockPrefixTable ) {
  146. //
  147. // Walk through the lock prefix table
  148. //
  149. PUCHAR *LockPrefixs;
  150. PUCHAR LockPrefix;
  151. LockPrefixs = (PUCHAR *)ImageVaToLoadVa((PVOID)ConfigInfo->LockPrefixTable,&CurrentImage);
  152. while(LockPrefixs && *LockPrefixs) {
  153. LockPrefix = (PUCHAR) ImageVaToLoadVa(*LockPrefixs,&CurrentImage);
  154. if ( LockPrefix && *LockPrefix == LockPrefixOpcode ) {
  155. if (fVerbose) {
  156. printf("LockPrefix Found at 0x%p = %x\n",*LockPrefixs,*LockPrefix);
  157. }
  158. if (fUpdate) {
  159. LocksSmashed = TRUE;
  160. *LockPrefix = NoOpOpcode;
  161. }
  162. }
  163. LockPrefixs++;
  164. }
  165. }
  166. if ( fUpdate && LocksSmashed ) {
  167. //
  168. // recompute the checksum.
  169. //
  170. OldChecksum = OPTIONALHEADER(CheckSum);
  171. if ( CurrentImage.hFile != INVALID_HANDLE_VALUE ) {
  172. OPTIONALHEADER_ASSIGN(CheckSum, 0);
  173. CheckSumMappedFile(
  174. (PVOID)CurrentImage.MappedAddress,
  175. GetFileSize(CurrentImage.hFile, NULL),
  176. &HeaderSum,
  177. &CheckSum
  178. );
  179. OPTIONALHEADER_ASSIGN(CheckSum, CheckSum);
  180. }
  181. FlushViewOfFile(CurrentImage.MappedAddress,0);
  182. TouchFileTimes(CurrentImage.hFile,NULL);
  183. // And update the .dbg file (if requested)
  184. if (SymbolPath &&
  185. FileHeader->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
  186. if ( UpdateDebugInfoFileEx( CurrentImageName,
  187. SymbolPath,
  188. DebugFilePath,
  189. (PIMAGE_NT_HEADERS32) CurrentImage.FileHeader,
  190. OldChecksum) ) {
  191. if (GetLastError() == ERROR_INVALID_DATA) {
  192. printf( "Warning: Old checksum did not match for %s\n", DebugFilePath);
  193. }
  194. printf("Updated symbols for %s\n", DebugFilePath);
  195. } else {
  196. printf("Unable to update symbols: %s\n", DebugFilePath);
  197. retval=1;
  198. }
  199. }
  200. }
  201. UnmapViewOfFile(CurrentImage.MappedAddress);
  202. if ( CurrentImage.hFile != INVALID_HANDLE_VALUE ) {
  203. CloseHandle(CurrentImage.hFile);
  204. }
  205. ZeroMemory(&CurrentImage,sizeof(CurrentImage));
  206. } else {
  207. if (!CurrentImage.fSystemImage && !CurrentImage.fDOSImage) {
  208. fprintf(stderr,"SMASHLOCK: failure mapping and loading %s\n",CurrentImageName);
  209. retval=1;
  210. }
  211. }
  212. }
  213. }
  214. return retval;
  215. }