Leaked source code of windows server 2003
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.

527 lines
17 KiB

  1. /*++
  2. Copyright (c) 1992-2000 Microsoft Corporation
  3. Module Name:
  4. dlls.c
  5. Revision History:
  6. --*/
  7. #include "precomp.h"
  8. #pragma hdrstop
  9. VOID
  10. DllsExtension(
  11. PCSTR lpArgumentString,
  12. ULONG64 ProcessPeb
  13. );
  14. DECLARE_API( dlls )
  15. /*++
  16. Routine Description:
  17. Dump user mode dlls (Kernel debugging)
  18. Arguments:
  19. args - [address [detail]]
  20. Return Value:
  21. None
  22. --*/
  23. {
  24. ULONG64 Process, Peb;
  25. INIT_API();
  26. Peb = GetExpression("@$peb");
  27. DllsExtension( args, Peb );
  28. EXIT_API();
  29. return S_OK;
  30. }
  31. void
  32. ShowImageVersionInfo(
  33. ULONG64 DllBase
  34. )
  35. {
  36. VS_FIXEDFILEINFO FixedVer;
  37. ULONG SizeRead;
  38. CHAR VersionBuffer[100];
  39. CHAR FileStr[MAX_PATH]= {0};
  40. BOOL ResFileVerStrOk = FALSE;
  41. BOOL ResProdVerStrOk = FALSE;
  42. struct LANGANDCODEPAGE {
  43. WORD wLanguage;
  44. WORD wCodePage;
  45. } Translate;
  46. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  47. DllBase, "\\VarFileInfo\\Translation",
  48. (PVOID) &Translate,
  49. sizeof(Translate),
  50. &SizeRead) == S_OK) {
  51. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\CompanyName",
  52. Translate.wLanguage, Translate.wCodePage);
  53. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  54. DllBase, VersionBuffer,
  55. (PVOID) FileStr,
  56. sizeof(FileStr),
  57. &SizeRead) == S_OK) {
  58. FileStr[SizeRead] = 0;
  59. dprintf(" Company Name %s\n", FileStr);
  60. }
  61. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\ProductName",
  62. Translate.wLanguage, Translate.wCodePage);
  63. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  64. DllBase, VersionBuffer,
  65. (PVOID) FileStr,
  66. sizeof(FileStr),
  67. &SizeRead) == S_OK) {
  68. FileStr[SizeRead] = 0;
  69. dprintf(" Product Name %s\n", FileStr);
  70. }
  71. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\ProductVersion",
  72. Translate.wLanguage, Translate.wCodePage);
  73. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  74. DllBase, VersionBuffer,
  75. (PVOID) FileStr,
  76. sizeof(FileStr),
  77. &SizeRead) == S_OK) {
  78. ResProdVerStrOk = TRUE;
  79. FileStr[SizeRead] = 0;
  80. dprintf(" Product Version %s\n", FileStr);
  81. }
  82. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\OriginalFilename",
  83. Translate.wLanguage, Translate.wCodePage);
  84. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  85. DllBase, VersionBuffer,
  86. (PVOID) FileStr,
  87. sizeof(FileStr),
  88. &SizeRead) == S_OK) {
  89. FileStr[SizeRead] = 0;
  90. dprintf(" Original Filename %s\n", FileStr);
  91. }
  92. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\FileDescription",
  93. Translate.wLanguage, Translate.wCodePage);
  94. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  95. DllBase, VersionBuffer,
  96. (PVOID) FileStr,
  97. sizeof(FileStr),
  98. &SizeRead) == S_OK) {
  99. FileStr[SizeRead] = 0;
  100. dprintf(" File Description %s\n", FileStr);
  101. }
  102. sprintf(VersionBuffer, "\\StringFileInfo\\%04X%04X\\FileVersion",
  103. Translate.wLanguage, Translate.wCodePage);
  104. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  105. DllBase, VersionBuffer,
  106. (PVOID) FileStr,
  107. sizeof(FileStr),
  108. &SizeRead) == S_OK) {
  109. FileStr[SizeRead] = 0;
  110. dprintf(" File Version %s\n", FileStr);
  111. ResFileVerStrOk = TRUE;
  112. }
  113. }
  114. if (g_ExtSymbols->GetModuleVersionInformation(DEBUG_ANY_ID,
  115. DllBase, "\\",
  116. &FixedVer,
  117. sizeof(FixedVer),
  118. &SizeRead) == S_OK) {
  119. if (!ResFileVerStrOk) {
  120. dprintf(" File version %d.%d.%d.%d\n",
  121. FixedVer.dwFileVersionMS >> 16,
  122. FixedVer.dwFileVersionMS & 0xFFFF,
  123. FixedVer.dwFileVersionLS >> 16,
  124. FixedVer.dwFileVersionLS & 0xFFFF);
  125. }
  126. if (!ResProdVerStrOk) {
  127. dprintf(" Product Version %d.%d.%d.%d\n",
  128. FixedVer.dwProductVersionMS >> 16,
  129. FixedVer.dwProductVersionMS & 0xFFFF,
  130. FixedVer.dwProductVersionLS >> 16,
  131. FixedVer.dwProductVersionLS & 0xFFFF);
  132. }
  133. }
  134. }
  135. typedef enum {
  136. Memory = 1,
  137. Load = 2,
  138. Init = 3
  139. } ELOAD_ORDER;
  140. VOID
  141. DllsExtension(
  142. PCSTR lpArgumentString,
  143. ULONG64 ProcessPeb
  144. )
  145. {
  146. BOOL b;
  147. ULONG64 pLdrEntry;
  148. ULONG64 PebLdrAddress;
  149. ULONG Offset;
  150. ULONG64 Next;
  151. WCHAR StringData[MAX_PATH+1];
  152. BOOL SingleEntry;
  153. BOOL DoHeaders;
  154. BOOL DoSections;
  155. BOOL DoAll;
  156. BOOL ShowVersionInfo;
  157. PSTR lpArgs = (PSTR)lpArgumentString;
  158. PSTR p;
  159. ULONG64 addrContaining = 0;
  160. ELOAD_ORDER OrderList = Load;
  161. ULONG64 OrderModuleListStart;
  162. ULONG64 DllBase;
  163. SingleEntry = FALSE;
  164. DoAll = FALSE;
  165. DoHeaders = FALSE;
  166. DoSections = FALSE;
  167. ShowVersionInfo = FALSE;
  168. #if 0
  169. while ( lpArgumentString != NULL && *lpArgumentString ) {
  170. if (*lpArgumentString != ' ') {
  171. sscanf(lpArgumentString,"%lx",&pLdrEntry);
  172. SingleEntry = TRUE;
  173. goto dumpsingleentry;
  174. }
  175. lpArgumentString++;
  176. }
  177. #endif
  178. while (*lpArgs) {
  179. while (isspace(*lpArgs)) {
  180. lpArgs++;
  181. }
  182. if (*lpArgs == '/' || *lpArgs == '-') {
  183. // process switch
  184. switch (*++lpArgs) {
  185. case 'a': // dump everything we can
  186. case 'A':
  187. ++lpArgs;
  188. DoAll = TRUE;
  189. break;
  190. case 'c': // dump only the dll containing the specified address
  191. case 'C':
  192. lpArgs += 2; // step over the c and the space.
  193. addrContaining = GetExpression(lpArgs);
  194. while (*lpArgs && (!isspace(*lpArgs))) {
  195. lpArgs++;
  196. }
  197. if (addrContaining != 0) {
  198. dprintf("Dump dll containing 0x%p:\n", addrContaining);
  199. } else {
  200. dprintf("-c flag requires and address arguement\n");
  201. return;
  202. }
  203. break;
  204. default: // invalid switch
  205. case 'h': // help
  206. case 'H':
  207. case '?':
  208. dprintf("Usage: dlls [options] [address]\n");
  209. dprintf("\n");
  210. dprintf("Displays loader table entries. Optionally\n");
  211. dprintf("dumps image and section headers.\n");
  212. dprintf("\n");
  213. dprintf("Options:\n");
  214. dprintf("\n");
  215. dprintf(" -a Dump everything\n");
  216. dprintf(" -c nnn Dump dll containing address nnn\n");
  217. dprintf(" -f Dump file headers\n");
  218. dprintf(" -i Dump dll's in Init order\n");
  219. dprintf(" -l Dump dll's in Load order (the default)\n");
  220. dprintf(" -m Dump dll's in Memory order\n");
  221. dprintf(" -s Dump section headers\n");
  222. dprintf(" -v Dump version info from resource section\n");
  223. dprintf("\n");
  224. return;
  225. case 'f':
  226. case 'F':
  227. ++lpArgs;
  228. DoAll = FALSE;
  229. DoHeaders = TRUE;
  230. break;
  231. case 'm': // dump in memory order
  232. case 'M':
  233. ++lpArgs;
  234. OrderList = Memory;
  235. break;
  236. case 'i': // dump in init order
  237. case 'I':
  238. ++lpArgs;
  239. OrderList = Init;
  240. break;
  241. case 'l': // dump in load order
  242. case 'L':
  243. ++lpArgs;
  244. OrderList = Load;
  245. break;
  246. case 's':
  247. case 'S':
  248. ++lpArgs;
  249. DoAll = FALSE;
  250. DoSections = TRUE;
  251. break;
  252. case 'v':
  253. case 'V':
  254. ++lpArgs;
  255. ShowVersionInfo = TRUE;
  256. break;
  257. }
  258. }
  259. else if (*lpArgs) {
  260. CHAR c;
  261. if (SingleEntry) {
  262. dprintf("Invalid extra argument\n");
  263. return;
  264. }
  265. p = lpArgs;
  266. while (*p && !isspace(*p)) {
  267. p++;
  268. }
  269. c = *p;
  270. *p = 0;
  271. pLdrEntry = GetExpression(lpArgs);
  272. SingleEntry = TRUE;
  273. *p = c;
  274. lpArgs=p;
  275. }
  276. }
  277. if (SingleEntry) {
  278. goto dumpsingleentry;
  279. }
  280. //
  281. // Capture PebLdrData
  282. //
  283. GetFieldValue(ProcessPeb, "nt!_PEB", "Ldr", PebLdrAddress);
  284. if (InitTypeRead(PebLdrAddress, nt!_PEB_LDR_DATA)) {
  285. dprintf( " Unable to read nt!_PEB_LDR_DATA type at %p\n", PebLdrAddress );
  286. return;
  287. }
  288. //
  289. // Walk through the loaded module table and display all ldr data
  290. //
  291. switch (OrderList) {
  292. case Memory:
  293. GetFieldOffset("nt!_PEB_LDR_DATA","InMemoryOrderModuleList", &Offset);
  294. OrderModuleListStart = PebLdrAddress + Offset;
  295. Next = ReadField(InMemoryOrderModuleList.Flink);
  296. break;
  297. case Init:
  298. GetFieldOffset("nt!_PEB_LDR_DATA","InInitializationOrderModuleList", &Offset);
  299. OrderModuleListStart = PebLdrAddress + Offset;
  300. Next = ReadField(InInitializationOrderModuleList.Flink);
  301. break;
  302. default:
  303. case Load:
  304. GetFieldOffset("nt!_PEB_LDR_DATA","InLoadOrderModuleList", &Offset);
  305. OrderModuleListStart = PebLdrAddress + Offset;
  306. Next = ReadField(InLoadOrderModuleList.Flink);
  307. break;
  308. }
  309. while (Next != OrderModuleListStart) {
  310. ULONG Length;
  311. if (CheckControlC()) {
  312. return;
  313. }
  314. switch (OrderList) {
  315. case Memory:
  316. GetFieldOffset("nt!_LDR_DATA_TABLE_ENTRY","InMemoryOrderLinks", &Offset);
  317. pLdrEntry = Next - Offset;
  318. break;
  319. case Init:
  320. GetFieldOffset("nt!_LDR_DATA_TABLE_ENTRY","InInitializationOrderLinks", &Offset);
  321. pLdrEntry = Next - Offset;
  322. break;
  323. default:
  324. case Load:
  325. GetFieldOffset("nt!_LDR_DATA_TABLE_ENTRY","InLoadOrderLinks", &Offset);
  326. pLdrEntry = Next - Offset;
  327. break;
  328. }
  329. //
  330. // Capture LdrEntry
  331. //
  332. dumpsingleentry:
  333. if (InitTypeRead(pLdrEntry, nt!_LDR_DATA_TABLE_ENTRY)) {
  334. dprintf( " Unable to read Ldr Entry at %p\n", pLdrEntry );
  335. return;
  336. }
  337. Length = (ULONG) ReadField(FullDllName.Length);
  338. if (Length >= sizeof(StringData))
  339. {
  340. Length = sizeof(StringData) -1;
  341. }
  342. ZeroMemory( StringData, sizeof( StringData ) );
  343. b = ReadMemory( ReadField(FullDllName.Buffer),
  344. StringData,
  345. Length,
  346. NULL
  347. );
  348. if (!b) {
  349. dprintf( " Unable to read Module Name\n" );
  350. ZeroMemory( StringData, sizeof( StringData ) );
  351. }
  352. //
  353. // Dump the ldr entry data
  354. // (dump all the entries if no containing address specified)
  355. //
  356. if ((addrContaining == 0) ||
  357. ((ReadField(DllBase) <= addrContaining) &&
  358. (addrContaining <= (ReadField(DllBase) + ReadField(SizeOfImage)))
  359. )
  360. ) {
  361. ULONG Flags;
  362. dprintf( "\n" );
  363. dprintf( "0x%08p: %ws\n", pLdrEntry, StringData[0] ? StringData : L"Unknown Module" );
  364. dprintf( " Base 0x%08p EntryPoint 0x%08p Size 0x%08p\n",
  365. DllBase = ReadField(DllBase),
  366. ReadField(EntryPoint),
  367. ReadField(SizeOfImage)
  368. );
  369. dprintf( " Flags 0x%08x LoadCount 0x%08x TlsIndex 0x%08x\n",
  370. Flags = (ULONG) ReadField(Flags),
  371. (ULONG) ReadField(LoadCount),
  372. (ULONG) ReadField(TlsIndex)
  373. );
  374. if (Flags & LDRP_STATIC_LINK) {
  375. dprintf( " LDRP_STATIC_LINK\n" );
  376. }
  377. if (Flags & LDRP_IMAGE_DLL) {
  378. dprintf( " LDRP_IMAGE_DLL\n" );
  379. }
  380. if (Flags & LDRP_LOAD_IN_PROGRESS) {
  381. dprintf( " LDRP_LOAD_IN_PROGRESS\n" );
  382. }
  383. if (Flags & LDRP_UNLOAD_IN_PROGRESS) {
  384. dprintf( " LDRP_UNLOAD_IN_PROGRESS\n" );
  385. }
  386. if (Flags & LDRP_ENTRY_PROCESSED) {
  387. dprintf( " LDRP_ENTRY_PROCESSED\n" );
  388. }
  389. if (Flags & LDRP_ENTRY_INSERTED) {
  390. dprintf( " LDRP_ENTRY_INSERTED\n" );
  391. }
  392. if (Flags & LDRP_CURRENT_LOAD) {
  393. dprintf( " LDRP_CURRENT_LOAD\n" );
  394. }
  395. if (Flags & LDRP_FAILED_BUILTIN_LOAD) {
  396. dprintf( " LDRP_FAILED_BUILTIN_LOAD\n" );
  397. }
  398. if (Flags & LDRP_DONT_CALL_FOR_THREADS) {
  399. dprintf( " LDRP_DONT_CALL_FOR_THREADS\n" );
  400. }
  401. if (Flags & LDRP_PROCESS_ATTACH_CALLED) {
  402. dprintf( " LDRP_PROCESS_ATTACH_CALLED\n" );
  403. }
  404. if (Flags & LDRP_DEBUG_SYMBOLS_LOADED) {
  405. dprintf( " LDRP_DEBUG_SYMBOLS_LOADED\n" );
  406. }
  407. if (Flags & LDRP_IMAGE_NOT_AT_BASE) {
  408. dprintf( " LDRP_IMAGE_NOT_AT_BASE\n" );
  409. }
  410. if (Flags & LDRP_COR_IMAGE) {
  411. dprintf( " LDRP_COR_IMAGE\n" );
  412. }
  413. if (Flags & LDRP_COR_OWNS_UNMAP) {
  414. dprintf( " LDR_COR_OWNS_UNMAP\n" );
  415. }
  416. if (ShowVersionInfo) {
  417. ShowImageVersionInfo(DllBase);
  418. }
  419. }
  420. switch (OrderList) {
  421. case Memory:
  422. Next = ReadField(InMemoryOrderLinks.Flink);
  423. break;
  424. case Init:
  425. Next = ReadField(InInitializationOrderLinks.Flink);
  426. break;
  427. default:
  428. case Load:
  429. Next = ReadField(InLoadOrderLinks.Flink);
  430. break;
  431. }
  432. if (DoAll || DoHeaders || DoSections) {
  433. DumpImage( ReadField(DllBase),
  434. DoAll || DoHeaders,
  435. DoAll || DoSections );
  436. }
  437. if (SingleEntry) {
  438. return;
  439. }
  440. }
  441. }