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.

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