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.

863 lines
28 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. driver.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Wesley Witt (wesw) 15-Aug-1993
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include <time.h>
  16. VOID
  17. DumpImage(
  18. ULONG Base,
  19. BOOL DoHeaders,
  20. BOOL DoSections
  21. );
  22. PUCHAR DispatchRoutineTable[]=
  23. {
  24. "IRP_MJ_CREATE",
  25. "IRP_MJ_CREATE_NAMED_PIPE",
  26. "IRP_MJ_CLOSE",
  27. "IRP_MJ_READ",
  28. "IRP_MJ_WRITE",
  29. "IRP_MJ_QUERY_INFORMATION",
  30. "IRP_MJ_SET_INFORMATION",
  31. "IRP_MJ_QUERY_EA",
  32. "IRP_MJ_SET_EA",
  33. "IRP_MJ_FLUSH_BUFFERS",
  34. "IRP_MJ_QUERY_VOLUME_INFORMATION",
  35. "IRP_MJ_SET_VOLUME_INFORMATION",
  36. "IRP_MJ_DIRECTORY_CONTROL",
  37. "IRP_MJ_FILE_SYSTEM_CONTROL",
  38. "IRP_MJ_DEVICE_CONTROL",
  39. "IRP_MJ_INTERNAL_DEVICE_CONTROL",
  40. "IRP_MJ_SHUTDOWN",
  41. "IRP_MJ_LOCK_CONTROL",
  42. "IRP_MJ_CLEANUP",
  43. "IRP_MJ_CREATE_MAILSLOT",
  44. "IRP_MJ_QUERY_SECURITY",
  45. "IRP_MJ_SET_SECURITY",
  46. "IRP_MJ_POWER",
  47. "IRP_MJ_SYSTEM_CONTROL",
  48. "IRP_MJ_DEVICE_CHANGE",
  49. "IRP_MJ_QUERY_QUOTA",
  50. "IRP_MJ_SET_QUOTA",
  51. "IRP_MJ_PNP",
  52. NULL
  53. } ;
  54. PUCHAR FastIoDispatchTable[]=
  55. {
  56. "FastIoCheckIfPossible",
  57. "FastIoRead",
  58. "FastIoWrite",
  59. "FastIoQueryBasicInfo",
  60. "FastIoQueryStandardInfo",
  61. "FastIoLock",
  62. "FastIoUnlockSingle",
  63. "FastIoUnlockAll",
  64. "FastIoUnlockAllByKey",
  65. "FastIoDeviceControl",
  66. "AcquireFileForNtCreateSection",
  67. "ReleaseFileForNtCreateSection",
  68. "FastIoDetachDevice",
  69. "FastIoQueryNetworkOpenInfo",
  70. "AcquireForModWrite",
  71. "MdlRead",
  72. "MdlReadComplete",
  73. "PrepareMdlWrite",
  74. "MdlWriteComplete",
  75. "FastIoReadCompressed",
  76. "FastIoWriteCompressed",
  77. "MdlReadCompleteCompressed",
  78. "MdlWriteCompleteCompressed",
  79. "FastIoQueryOpen",
  80. "ReleaseForModWrite",
  81. "AcquireForCcFlush",
  82. "ReleaseForCcFlush",
  83. NULL
  84. } ;
  85. //
  86. // Change this value and update the above table if IRP_MJ_MAXIMUM_FUNCTION
  87. // is increased.
  88. //
  89. #define IRP_MJ_MAXIMUM_FUNCTION_HANDLED 0x1b
  90. DECLARE_API( drvobj )
  91. /*++
  92. Routine Description:
  93. Dump a driver object.
  94. Arguments:
  95. args - the location of the driver object to dump.
  96. Return Value:
  97. None
  98. --*/
  99. {
  100. ULONG64 driverToDump;
  101. ULONG Flags;
  102. char driverExprBuf[256] ;
  103. char *driverExpr ;
  104. //
  105. // !drvobj DriverAddress DumpLevel
  106. // where DriverAddress can be an expression or driver name
  107. // and DumpLevel is a hex mask
  108. //
  109. strcpy(driverExprBuf, "\\Driver\\") ;
  110. driverExpr = driverExprBuf+strlen(driverExprBuf) ;
  111. Flags = 1;
  112. driverToDump = 0 ;
  113. if (!sscanf(args, "%230s %lx", driverExpr, &Flags)) {
  114. driverExpr[0] = 0;
  115. }
  116. //
  117. // The debugger will treat C0000000 as a symbol first, then a number if
  118. // no match comes up.
  119. //
  120. if (driverExpr[0] == '\\') {
  121. driverToDump = FindObjectByName( driverExpr, 0);
  122. } else {
  123. driverToDump = FindObjectByName((PUCHAR) driverExprBuf, 0);
  124. if (driverToDump == 0)
  125. {
  126. driverToDump = GetExpression(driverExpr);
  127. }
  128. }
  129. if(driverToDump == 0) {
  130. dprintf("Driver object %s not found\n", args);
  131. return E_INVALIDARG;
  132. }
  133. dprintf("Driver object (%08p) is for:\n", driverToDump);
  134. DumpDriver( driverToDump, 0, Flags);
  135. if (!Flags)
  136. {
  137. dprintf("\n");
  138. }
  139. return S_OK;
  140. }
  141. VOID
  142. DumpDriver(
  143. ULONG64 DriverAddress,
  144. ULONG FieldWidth,
  145. ULONG Flags
  146. )
  147. /*++
  148. Routine Description:
  149. Displays the driver name and the list of device objects created by
  150. the driver.
  151. Arguments:
  152. DriverAddress - addres of the driver object to dump.
  153. FieldWidth - Width of printf field (eg %11s) for driver name.
  154. Use 0 for full display.
  155. Flags - Bit 0, Dump out device objects owned by driver
  156. Bit 1, Dump out dispatch routines for driver
  157. Return Value:
  158. None
  159. --*/
  160. {
  161. // DRIVER_OBJECT driverObject;
  162. ULONG result;
  163. ULONG i,j;
  164. PUCHAR buffer;
  165. ULONG64 deviceAddress;
  166. // DEVICE_OBJECT deviceObject;
  167. UNICODE_STRING unicodeString;
  168. ULONG64 displacement;
  169. UCHAR component[512];
  170. PUCHAR *dispatchTableText ;
  171. // FAST_IO_DISPATCH FastIoDispatch;
  172. ULONG64 *p;
  173. ULONG Type=0, Name_MaxLen=0, Name_Len=0, LongAddr, IoD_SizeOfFastIoDispatch=0;
  174. ULONG64 MajorFunction[IRP_MJ_MAXIMUM_FUNCTION_HANDLED+1]= {0}, IoD[27] = {0};
  175. ULONG64 Name_Buf=0, DriverExtension=0, Ext_ClientDriverExtension=0, DeviceObject=0,
  176. FastIoDispatch=0, IoD_FastIoCheckIfPossible=0;
  177. ULONG64 DriverEntry=0, DriverUnload=0, DriverStartIo=0;
  178. FIELD_INFO DriverFields[] = {
  179. {"DriverExtension", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA |
  180. ((Flags & 1) ? DBG_DUMP_FIELD_RECUR_ON_THIS : 0), 0, (PVOID) &DriverExtension},
  181. {"DriverName", "", 0, DBG_DUMP_FIELD_RECUR_ON_THIS, 0, NULL},
  182. {"DriverName.MaximumLength", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &Name_MaxLen},
  183. {"DriverName.Length", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &Name_Len},
  184. {"DriverName.Buffer", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &Name_Buf},
  185. {"DriverExtension.ClientDriverExtension", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &Ext_ClientDriverExtension},
  186. {"DeviceObject", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &DeviceObject},
  187. {"DriverInit", "DriverEntry", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &DriverEntry},
  188. {"DriverStartIo", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &DriverStartIo},
  189. {"DriverUnload", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &DriverUnload},
  190. {"MajorFunction", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &MajorFunction[0]},
  191. {"FastIoDispatch","", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA |
  192. DBG_DUMP_FIELD_RECUR_ON_THIS, 0, (PVOID) &FastIoDispatch},
  193. {"FastIoDispatch.SizeOfFastIoDispatch", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD_SizeOfFastIoDispatch},
  194. {"FastIoDispatch.FastIoCheckIfPossible", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[0]},
  195. {"FastIoDispatch.FastIoRead", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[1]},
  196. {"FastIoDispatch.FastIoWrite", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[2]},
  197. {"FastIoDispatch.FastIoQueryBasicInfo", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[3]},
  198. {"FastIoDispatch.FastIoQueryStandardInfo", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[4]},
  199. {"FastIoDispatch.FastIoLock", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[5]},
  200. {"FastIoDispatch.FastIoUnlockSingle", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[6]},
  201. {"FastIoDispatch.FastIoUnlockAll", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[7]},
  202. {"FastIoDispatch.FastIoUnlockAllByKey", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[8]},
  203. {"FastIoDispatch.FastIoDeviceControl", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[9]},
  204. {"FastIoDispatch.AcquireFileForNtCreateSection", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[10]},
  205. {"FastIoDispatch.ReleaseFileForNtCreateSection", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[11]},
  206. {"FastIoDispatch.FastIoDetachDevice", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[12]},
  207. {"FastIoDispatch.FastIoQueryNetworkOpenInfo", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[13]},
  208. {"FastIoDispatch.AcquireForModWrite", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[14]},
  209. {"FastIoDispatch.MdlRead", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[15]},
  210. {"FastIoDispatch.MdlReadComplete", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[16]},
  211. {"FastIoDispatch.PrepareMdlWrite", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[17]},
  212. {"FastIoDispatch.MdlWriteComplete", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[18]},
  213. {"FastIoDispatch.FastIoReadCompressed", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[19]},
  214. {"FastIoDispatch.FastIoWriteCompressed", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[20]},
  215. {"FastIoDispatch.MdlReadCompleteCompressed", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[21]},
  216. {"FastIoDispatch.MdlWriteCompleteCompressed", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[22]},
  217. {"FastIoDispatch.FastIoQueryOpen", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[23]},
  218. {"FastIoDispatch.ReleaseForModWrite", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[24]},
  219. {"FastIoDispatch.AcquireForCcFlush", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[25]},
  220. {"FastIoDispatch.ReleaseForCcFlush", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &IoD[26]},
  221. };
  222. SYM_DUMP_PARAM DriverSym = {
  223. sizeof (SYM_DUMP_PARAM), "nt!_DRIVER_OBJECT", DBG_DUMP_NO_PRINT, (ULONG64) DriverAddress,
  224. NULL, NULL, NULL, sizeof (DriverFields) / sizeof(FIELD_INFO), &DriverFields[0]
  225. };
  226. if (GetFieldValue(DriverAddress, "nt!_DRIVER_OBJECT",
  227. "Type", Type)) {
  228. dprintf("Cannot read _DRIVER_OBJECT at %p\n", DriverAddress);
  229. return;
  230. }
  231. LongAddr = IsPtr64();
  232. if (Type != IO_TYPE_DRIVER) {
  233. dprintf("%08p: is not a driver object\n", DriverAddress);
  234. return;
  235. }
  236. Ioctl(IG_DUMP_SYMBOL_INFO, &DriverSym, DriverSym.size);
  237. if (Name_MaxLen > 1024) // sanity sheck
  238. {
  239. Name_MaxLen = 1024;
  240. }
  241. buffer = LocalAlloc(LPTR, Name_MaxLen);
  242. if (buffer == NULL) {
  243. dprintf("Could not allocate %d bytes\n",
  244. Name_MaxLen);
  245. return;
  246. }
  247. //
  248. // This memory may be paged out.
  249. //
  250. unicodeString.Buffer = (PWSTR)buffer;
  251. unicodeString.Length = (USHORT) Name_Len;
  252. unicodeString.MaximumLength = (USHORT) Name_MaxLen;
  253. if (!ReadMemory( Name_Buf,
  254. buffer,
  255. Name_MaxLen,
  256. &result)) {
  257. dprintf(" Name paged out");
  258. } else {
  259. sprintf(component, " %wZ", &unicodeString);
  260. dprintf("%s", component) ;
  261. for(i = strlen(component); i<FieldWidth; i++) {
  262. dprintf(" ") ;
  263. }
  264. }
  265. LocalFree(buffer);
  266. if (Flags&1) {
  267. dprintf("\n");
  268. //
  269. // Dump the list of client extensions
  270. //
  271. if(DriverExtension) {
  272. ULONG sz = GetTypeSize("nt!_IO_CLIENT_EXTENSION");
  273. ULONG64 clientExtension = Ext_ClientDriverExtension;
  274. dprintf("Driver Extension List: (id , addr)\n");
  275. //
  276. // Check to see if there are any extensions.
  277. //
  278. while(clientExtension != 0) {
  279. ULONG64 ClientIdentificationAddress=0, NextExtension=0;
  280. FIELD_INFO IoCltFields[] = {
  281. {"ClientIdentificationAddress", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA,
  282. 0, (PVOID) &ClientIdentificationAddress},
  283. {"NextExtension", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA,
  284. 0, (PVOID) &NextExtension},
  285. };
  286. // IO_CLIENT_EXTENSION buffer;
  287. DriverSym.sName = "_IO_CLIENT_EXTENSION"; DriverSym.addr = clientExtension;
  288. DriverSym.nFields = 2; DriverSym.Fields = &IoCltFields[0];
  289. if (!Ioctl(IG_DUMP_SYMBOL_INFO, &DriverSym, DriverSym.size)) {
  290. dprintf("(%08p %08p) ",
  291. ClientIdentificationAddress,
  292. clientExtension + sz);
  293. clientExtension = NextExtension;
  294. } else {
  295. dprintf("\nCouldn't read extension at %#08p\n", clientExtension);
  296. clientExtension = 0;
  297. }
  298. }
  299. dprintf("\n");
  300. }
  301. dprintf("Device Object list:\n");
  302. deviceAddress = DeviceObject;
  303. for (i= 0; deviceAddress != 0; i++) {
  304. ULONG64 NextDevice=0;
  305. FIELD_INFO DevFields = {"NextDevice", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &NextDevice};
  306. DriverSym.sName = "_DEVICE_OBJECT"; DriverSym.addr = deviceAddress;
  307. DriverSym.nFields = 1; DriverSym.Fields = &DevFields;
  308. if (Ioctl(IG_DUMP_SYMBOL_INFO, &DriverSym, DriverSym.size)) {
  309. dprintf("%08p: Could not read device object\n", deviceAddress);
  310. break;
  311. }
  312. dprintf("%08p%s", deviceAddress, ((i & 0x03) == 0x03) ? "\n" : " ");
  313. deviceAddress = NextDevice;
  314. }
  315. dprintf("\n");
  316. }
  317. if (Flags&0x2) {
  318. GetSymbol(DriverEntry, component, &displacement);
  319. dprintf("\nDriverEntry: %8.8p\t%s\n", DriverEntry, component);
  320. GetSymbol(DriverStartIo, component, &displacement);
  321. dprintf("DriverStartIo: %8.8p\t%s\n", DriverStartIo, component);
  322. GetSymbol(DriverUnload, component, &displacement);
  323. dprintf("DriverUnload: %8.8p\t%s\n", DriverUnload, component);
  324. dprintf ("\nDispatch routines:\n");
  325. dispatchTableText = DispatchRoutineTable ;
  326. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION_HANDLED; i++) {
  327. //
  328. // Get the read pointer values depending on 32 or 64 bit addresses
  329. //
  330. if (LongAddr) {
  331. GetSymbol(MajorFunction[i], component, &displacement);
  332. } else {
  333. GetSymbol((ULONG64) (LONG64) (LONG) (((PULONG) &MajorFunction[0])[i]), component, &displacement);
  334. }
  335. //
  336. // Forms are:
  337. // [1b] IRP_MJ_PNP C0000000 DispatchHandler+30
  338. // [1b] IRP_MJ_PNP C0000000 DispatchHandler
  339. // [1b] ??? C0000000 <either of above>
  340. //
  341. if (*dispatchTableText) {
  342. dprintf("[%02x] %s", i, *dispatchTableText) ;
  343. j=strlen(*dispatchTableText) ;
  344. } else {
  345. dprintf("[%02x] ???", i) ;
  346. j=3 ;
  347. }
  348. while(j++<35) dprintf(" ") ;
  349. if (LongAddr) {
  350. dprintf("%8.8p\t%s", MajorFunction[i], component);
  351. } else {
  352. dprintf("%8.8x\t%s", (((PULONG) &MajorFunction[0])[i]), component);
  353. }
  354. // dprintf("%8.8x\t%s", driverObject.MajorFunction[i], component) ;
  355. if (displacement) {
  356. dprintf("+0x%1p\n", displacement) ;
  357. } else {
  358. dprintf("\n") ;
  359. }
  360. if (*dispatchTableText) {
  361. dispatchTableText++ ;
  362. }
  363. }
  364. if (FastIoDispatch) {
  365. dprintf("\nFast I/O routines:\n");
  366. dispatchTableText = FastIoDispatchTable ;
  367. for (i=0;i < ((IoD_SizeOfFastIoDispatch - 4)/ (LongAddr ? 8 : 4)); i++) {
  368. if (IoD[i]) {
  369. GetSymbol(IoD[i], component, &displacement);
  370. if (*dispatchTableText) {
  371. dprintf("%s", *dispatchTableText) ;
  372. j=strlen(*dispatchTableText) ;
  373. } else {
  374. dprintf("???") ;
  375. j=3 ;
  376. }
  377. while(j++<40) dprintf(" ") ;
  378. dprintf("%8.8p\t%s", IoD[i], component) ;
  379. if (displacement) {
  380. dprintf("+0x%1p", displacement) ;
  381. }
  382. dprintf("\n") ;
  383. }
  384. if (*dispatchTableText) {
  385. dispatchTableText++ ;
  386. }
  387. }
  388. }
  389. dprintf("\n");
  390. }
  391. }
  392. UCHAR *PagedOut = {"Header Paged Out"};
  393. DECLARE_API( drivers )
  394. /*++
  395. Routine Description:
  396. Displays physical memory usage by driver.
  397. Arguments:
  398. None.
  399. Return Value:
  400. None.
  401. --*/
  402. {
  403. while (*args && *args != '-' && *args != '/') ++args;
  404. ++args;
  405. if (*args == 'h' || *args == '?')
  406. {
  407. dprintf("!drivers is now replaced by \".reload -l\"\n"
  408. "Also lmv will give verbose info about loaded drivers\n");
  409. return S_OK;
  410. }
  411. return ExecuteCommand(Client, ".reload -l");
  412. #if 0
  413. LIST_ENTRY64 List;
  414. ULONG64 Next;
  415. ULONG64 ListHead;
  416. NTSTATUS Status = 0;
  417. ULONG Result;
  418. ULONG64 DataTable;
  419. LDR_DATA_TABLE_ENTRY DataTableBuffer;
  420. WCHAR UnicodeBuffer[128];
  421. UNICODE_STRING BaseName;
  422. ULONG64 NtHeader;
  423. ULONG64 DosHeader;
  424. ULONG SizeOfData;
  425. ULONG SizeOfCode;
  426. ULONG SizeOfLocked;
  427. ULONG TotalCode = 0;
  428. ULONG TotalData = 0;
  429. ULONG TotalValid = 0;
  430. ULONG TotalTransition = 0;
  431. ULONG DosHeaderSize;
  432. ULONG TimeDateStamp;
  433. LONG_PTR TDStamp;
  434. ULONG InLoadOrderLinksOff;
  435. PUCHAR time;
  436. ULONG64 Flags;
  437. UCHAR LdrName[] = "_LDR_DATA_TABLE_ENTRY";
  438. Flags = GetExpression(args);
  439. ListHead = GetNtDebuggerData( PsLoadedModuleList );
  440. if (!ListHead) {
  441. dprintf("Unable to get value of PsLoadedModuleListHead\n");
  442. return E_INVALIDARG;
  443. }
  444. if (GetFieldValue(ListHead, "_LIST_ENTRY", "Flink", List.Flink)) {
  445. dprintf("Couldn't read _LIST_ENTRY @ %p\n", ListHead);
  446. return E_INVALIDARG;
  447. }
  448. Next = List.Flink;
  449. if (Next == 0) {
  450. dprintf("PsLoadedModuleList is NULL, trying loader block instead\n");
  451. ListHead = GetUlongValue ("KeLoaderBlock");
  452. if (ListHead == 0) {
  453. dprintf ("KeLoaderBlock is NULL\n");
  454. return E_INVALIDARG;
  455. }
  456. if (GetFieldValue(ListHead, "_LIST_ENTRY", "Flink", List.Flink)) {
  457. dprintf("Couldn't read _LIST_ENTRY1 @ %p\n", ListHead);
  458. return E_INVALIDARG;
  459. }
  460. if (GetFieldValue(List.Flink, "_LIST_ENTRY", "Flink", List.Flink)) {
  461. dprintf("Couldn't read _LIST_ENTRY2 @ %p\n", ListHead);
  462. return E_INVALIDARG;
  463. }
  464. if (!IsPtr64()) {
  465. ListHead = (ULONG64)(LONG64)(LONG)ListHead;
  466. }
  467. Next = List.Flink;
  468. }
  469. dprintf("Loaded System Driver Summary\n\n");
  470. if (Flags & 1) {
  471. dprintf("Base Code Size Data Size Resident Standby Driver Name\n");
  472. } else if (Flags & 2) {
  473. dprintf("Base Code Data Locked Resident Standby Loader Entry Driver Name\n");
  474. } else {
  475. dprintf("Base Code Size Data Size Driver Name Creation Time\n");
  476. }
  477. // Get The offset of InLoadOrderLinks
  478. if (GetFieldOffset("_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks", &InLoadOrderLinksOff)){
  479. dprintf("Cannot find _LDR_DATA_TABLE_ENTRY type\n");
  480. return E_INVALIDARG;
  481. }
  482. while (Next != ListHead) {
  483. ULONG64 BaseDllBuffer=0, DllBase=0;
  484. ULONG BaseDllNameLen=0, SizeOfImage=0;
  485. if (CheckControlC()) {
  486. return E_INVALIDARG;
  487. }
  488. DataTable = Next - InLoadOrderLinksOff;
  489. if (GetFieldValue(DataTable, LdrName, "BaseDllName.Buffer", BaseDllBuffer)) {
  490. dprintf("Unable to read LDR_DATA_TABLE_ENTRY at %08lx - status %08p\n",
  491. DataTable,
  492. Status);
  493. return E_INVALIDARG;
  494. }
  495. GetFieldValue(DataTable, LdrName, "BaseDllName.Length", BaseDllNameLen);
  496. if (BaseDllNameLen >= sizeof(UnicodeBuffer)) {
  497. BaseDllNameLen = sizeof(UnicodeBuffer);
  498. }
  499. //
  500. // Get the base DLL name.
  501. //
  502. if ((!ReadMemory(BaseDllBuffer,
  503. UnicodeBuffer,
  504. BaseDllNameLen,
  505. &Result)) || (Result < BaseDllNameLen)) {
  506. dprintf("Unable to read name string at %08p - status %08lx\n",
  507. DataTable,
  508. Status);
  509. return E_INVALIDARG;
  510. }
  511. BaseName.Buffer = UnicodeBuffer;
  512. BaseName.Length = BaseName.MaximumLength = (USHORT)Result;
  513. GetFieldValue(DataTable, LdrName, "DllBase", DllBase);
  514. DosHeader = DllBase;
  515. DosHeaderSize=0;
  516. if (GetFieldValue(DosHeader, "_IMAGE_DOS_HEADER", "e_lfanew", DosHeaderSize)) {
  517. //dprintf("Unable to read DosHeader at %08lx - status %08lx\n",
  518. // &DosHeader->e_lfanew,
  519. // Status);
  520. SizeOfCode = 0;
  521. SizeOfData = 0;
  522. SizeOfLocked = -1;
  523. time = PagedOut;
  524. } else {
  525. NtHeader = DosHeader + DosHeaderSize;
  526. if (GetFieldValue(NtHeader, "_IMAGE_NT_HEADERS", "OptionalHeader.SizeOfCode", SizeOfCode)) {
  527. dprintf("Unable to read DosHeader at %08p - status %08lx\n",
  528. NtHeader,
  529. Status);
  530. goto getnext;
  531. }
  532. GetFieldValue(NtHeader, "_IMAGE_NT_HEADERS", "OptionalHeader.SizeOfInitializedData", SizeOfData);
  533. GetFieldValue(NtHeader, "_IMAGE_NT_HEADERS", "FileHeader.TimeDateStamp", TimeDateStamp);
  534. // TimeDateStamp is always a 32 bit quantity on the target, and we
  535. // need to sign extend for 64 bit host
  536. TDStamp = (LONG_PTR)(LONG)TimeDateStamp;
  537. time = ctime((time_t *)&TDStamp);
  538. if (time) {
  539. time[strlen(time)-1] = 0; // ctime always returns 26 char ending win \n\0
  540. }
  541. }
  542. GetFieldValue(DataTable, LdrName, "SizeOfImage", SizeOfImage);
  543. if (Flags & 1) {
  544. ULONG64 Va;
  545. ULONG64 EndVa;
  546. ULONG States[3] = {0,0,0};
  547. Va = DllBase;
  548. EndVa = Va + SizeOfImage;
  549. // PLATFORM SPECIFIC
  550. while (Va < EndVa) {
  551. States[GetAddressState(Va)] += _KB;
  552. Va += PageSize;
  553. }
  554. dprintf("%08p %6lx (%4ld kb) %6lx (%4ld kb) (%5ld kb %5ld kb) %12wZ\n",
  555. DllBase,
  556. SizeOfCode,
  557. SizeOfCode / 1024,
  558. SizeOfData,
  559. SizeOfData / 1024,
  560. States[ADDRESS_VALID],
  561. States[ADDRESS_TRANSITION],
  562. &BaseName);
  563. TotalValid += States[ADDRESS_VALID];
  564. TotalTransition += States[ADDRESS_TRANSITION];
  565. } else if (Flags & 2) {
  566. ULONG i;
  567. ULONG SizeToLock;
  568. ULONG64 PointerPte;
  569. ULONG64 LastPte;
  570. ULONG64 BaseAddress;
  571. ULONG64 Va;
  572. ULONG64 EndVa;
  573. ULONG States[3] = {0,0,0};
  574. ULONG64 NtSection;
  575. ULONG SizeOfOptionalHeader=0, NumberOfSections=0;
  576. Va = DllBase;
  577. EndVa = Va + SizeOfImage;
  578. while (Va < EndVa) {
  579. States[GetAddressState(Va)] += _KB;
  580. Va += PageSize;
  581. }
  582. SizeOfLocked = 0;
  583. //
  584. // Read the sections in the executable header to see which are
  585. // locked. Don't bother looking for refcounted PFNs.
  586. //
  587. NtHeader = DosHeader + DosHeaderSize;
  588. if (GetFieldValue(NtHeader, "_IMAGE_NT_HEADERS", "FileHeader.SizeOfOptionalHeader", SizeOfOptionalHeader)) {
  589. dprintf("Unable to read FileHeader at %08lx - status %08lx\n",
  590. NtHeader,
  591. Status);
  592. goto getnext;
  593. }
  594. GetFieldValue(NtHeader, "_IMAGE_NT_HEADERS", "FileHeader.NumberOfSections", NumberOfSections);
  595. NtSection = NtHeader +
  596. GetTypeSize("ULONG") +
  597. GetTypeSize("_IMAGE_FILE_HEADER") +
  598. SizeOfOptionalHeader;
  599. for (i = 0; i < NumberOfSections; i += 1) {
  600. ULONG NumberOfLinenumbers=0, PointerToRelocations=0, SizeOfRawData=0;
  601. if (GetFieldValue(NtSection, "_IMAGE_SECTION_HEADER", "NumberOfLinenumbers", NumberOfLinenumbers)) {
  602. dprintf("Unable to read NtSectionData at %08lx - status %08p\n",
  603. NtSection,
  604. Status);
  605. goto getnext;
  606. }
  607. GetFieldValue(NtSection, "_IMAGE_SECTION_HEADER", "SizeOfRawData", SizeOfRawData);
  608. GetFieldValue(NtSection, "_IMAGE_SECTION_HEADER", "PointerToRelocations", PointerToRelocations);
  609. if ((NumberOfLinenumbers == 1) ||
  610. (NumberOfLinenumbers == 2)) {
  611. BaseAddress = PointerToRelocations;
  612. SizeToLock = SizeOfRawData;
  613. PointerPte = DbgGetPteAddress( BaseAddress);
  614. LastPte = DbgGetPteAddress(BaseAddress + SizeToLock - 1);
  615. SizeOfLocked += (ULONG) (LastPte - PointerPte + 1);
  616. }
  617. NtSection += 1;
  618. }
  619. #if 0
  620. dprintf("Base Code Data Locked Resident Standby Loader Entry Driver Name\n");
  621. #endif
  622. dprintf("%08p %6lx %6lx %6lx %6lx %6lx %8lp %12wZ\n",
  623. DllBase,
  624. SizeOfCode,
  625. SizeOfData,
  626. SizeOfLocked,
  627. States[ADDRESS_VALID],
  628. States[ADDRESS_TRANSITION],
  629. DataTable,
  630. &BaseName);
  631. TotalValid += States[ADDRESS_VALID];
  632. TotalTransition += States[ADDRESS_TRANSITION];
  633. } else {
  634. dprintf("%08p %6lx (%4ld kb) %5lx (%3ld kb) %12wZ %s\n",
  635. DllBase,
  636. SizeOfCode,
  637. SizeOfCode / 1024,
  638. SizeOfData,
  639. SizeOfData / 1024,
  640. &BaseName,
  641. time);
  642. }
  643. if (Flags & 4) {
  644. dprintf("Cannot dump Image.\n");
  645. /*DumpImage(DllBase,
  646. (Flags & 2) == 2,
  647. (Flags & 4) == 4
  648. );*/
  649. }
  650. TotalCode += SizeOfCode;
  651. TotalData += SizeOfData;
  652. getnext:
  653. GetFieldValue(DataTable, LdrName, "InLoadOrderLinks.Flink", Next);
  654. }
  655. dprintf("TOTAL: %6lx (%4ld kb) %6lx (%4ld kb) (%5ld kb %5ld kb)\n",
  656. TotalCode,
  657. TotalCode / 1024,
  658. TotalData,
  659. TotalData / 1024,
  660. TotalValid,
  661. TotalTransition);
  662. return S_OK;
  663. #endif
  664. }
  665. HRESULT
  666. GetDrvObjInfo(
  667. IN ULONG64 DriverObject,
  668. OUT PDEBUG_DRIVER_OBJECT_INFO pDrvObjInfo)
  669. {
  670. ZeroMemory(pDrvObjInfo, sizeof(DEBUG_DRIVER_OBJECT_INFO));
  671. pDrvObjInfo->SizeOfStruct = sizeof(DEBUG_DRIVER_OBJECT_INFO);
  672. pDrvObjInfo->DriverObjAddress = DriverObject;
  673. if (InitTypeRead(DriverObject, nt!_DRIVER_OBJECT)) {
  674. return E_INVALIDARG;
  675. }
  676. pDrvObjInfo->DeviceObject = ReadField(DeviceObject);
  677. pDrvObjInfo->DriverExtension = ReadField(DriverExtension);
  678. pDrvObjInfo->DriverSize = (ULONG) ReadField(DriverSize);
  679. pDrvObjInfo->DriverStart = ReadField(DriverStart);
  680. pDrvObjInfo->DriverName.MaximumLength = (USHORT) ReadField(DriverName.MaximumLength);
  681. pDrvObjInfo->DriverName.Length = (USHORT) ReadField(DriverName.Length);
  682. pDrvObjInfo->DriverName.Buffer = ReadField(DriverName.Buffer);
  683. return S_OK;
  684. }
  685. EXTENSION_API( GetDrvObjInfo )(
  686. IN PDEBUG_CLIENT Client,
  687. IN ULONG64 DriverObject,
  688. OUT PDEBUG_DRIVER_OBJECT_INFO pDrvObjInfo)
  689. {
  690. HRESULT Hr = E_FAIL;
  691. INIT_API();
  692. if (pDrvObjInfo && (pDrvObjInfo->SizeOfStruct == sizeof(DEBUG_DRIVER_OBJECT_INFO))) {
  693. Hr = GetDrvObjInfo(DriverObject, pDrvObjInfo);
  694. }
  695. EXIT_API();
  696. return Hr;
  697. }