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.

498 lines
16 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. peb.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Ramon J San Andres (ramonsa) 5-Nov-1993
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include <time.h>
  16. BOOL
  17. GetTeb32FromWowTeb(ULONG64 Teb, PULONG64 pTeb32)
  18. {
  19. if (pTeb32) {
  20. return ReadPointer(Teb, pTeb32);
  21. }
  22. return FALSE;
  23. }
  24. BOOL
  25. GetPeb32FromWowTeb(ULONG64 Teb, PULONG64 pPeb32)
  26. {
  27. ULONG Peb32;
  28. ULONG64 Teb32=0;
  29. ULONG err;
  30. if (GetTeb32FromWowTeb(Teb, &Teb32) && Teb32) {
  31. if (!(err =GetFieldValue(Teb32, "nt!TEB32", "ProcessEnvironmentBlock", Peb32))) {
  32. *pPeb32 = Peb32;
  33. return TRUE;
  34. } else if (err == SYMBOL_TYPE_INFO_NOT_FOUND) {
  35. if (!(err =GetFieldValue(Teb32, "wow64!TEB32", "ProcessEnvironmentBlock", Peb32))) {
  36. *pPeb32 = Peb32;
  37. return TRUE;
  38. }
  39. }
  40. }
  41. return FALSE;
  42. }
  43. HRESULT
  44. DumpPeb(ULONG64 peb, BOOL IsWow64Peb)
  45. {
  46. ULONG64 ldr;
  47. ULONG64 err;
  48. ULONG64 ldr_Initialized;
  49. ULONG64 ldr_InInitializationOrderModuleList_Flink;
  50. ULONG64 ldr_InInitializationOrderModuleList_Blink;
  51. ULONG64 ldr_InLoadOrderModuleList_Flink;
  52. ULONG64 ldr_InLoadOrderModuleList_Blink;
  53. ULONG ldr_InMemoryOrderModuleList_Offset;
  54. ULONG64 ldr_InMemoryOrderModuleList_Flink;
  55. ULONG64 ldr_InMemoryOrderModuleList_Blink;
  56. ULONG ldr_DataTableEntry_InMemoryOrderLinks_Offset;
  57. ULONG64 peb_SubSystemData;
  58. ULONG64 peb_ProcessHeap;
  59. ULONG64 peb_ProcessParameters;
  60. PCHAR ldrdata = "nt!_PEB_LDR_DATA";
  61. PCHAR ldrEntry = "nt!_LDR_DATA_TABLE_ENTRY";
  62. PCHAR processparam = "nt!_RTL_USER_PROCESS_PARAMETERS";
  63. HRESULT hr = S_OK;
  64. if (IsWow64Peb) {
  65. // try and load types from nt
  66. if ( err = InitTypeRead( peb, nt!PEB32 ) ) {
  67. if (err == SYMBOL_TYPE_INFO_NOT_FOUND) {
  68. // try load types from wow64
  69. if ( !( err = InitTypeRead( peb, wow64!PEB32 )) ) {
  70. ldrdata = "wow64!_PEB_LDR_DATA32";
  71. ldrEntry = "wow64!_LDR_DATA_TABLE_ENTRY32";
  72. processparam = "wow64!_RTL_USER_PROCESS_PARAMETERS32";
  73. } else {
  74. dprintf( "error %d InitTypeRead( wow64!PEB32 at %p)...\n", (ULONG) err, peb);
  75. return E_INVALIDARG;
  76. }
  77. } else {
  78. dprintf( "error %d InitTypeRead( nt!PEB32 at %p)...\n", (ULONG) err, peb);
  79. return E_INVALIDARG;
  80. }
  81. } else {
  82. ldrdata = "nt!_PEB_LDR_DATA32";
  83. ldrEntry = "nt!_LDR_DATA_TABLE_ENTRY32";
  84. processparam = "nt!_RTL_USER_PROCESS_PARAMETERS32";
  85. }
  86. } else {
  87. if ( err = InitTypeRead( peb, PEB ) ) {
  88. dprintf( "error %d InitTypeRead( nt!PEB32 at %p)...\n", (ULONG) err, peb);
  89. return E_INVALIDARG;
  90. }
  91. }
  92. dprintf(
  93. " InheritedAddressSpace: %s\n"
  94. " ReadImageFileExecOptions: %s\n"
  95. " BeingDebugged: %s\n"
  96. " ImageBaseAddress: %p\n"
  97. " Ldr %p\n",
  98. ReadField( InheritedAddressSpace ) ? "Yes" : "No",
  99. ReadField( ReadImageFileExecOptions ) ? "Yes" : "No",
  100. ReadField( BeingDebugged ) ? "Yes" : "No",
  101. ReadField( ImageBaseAddress ),
  102. (ldr = ReadField( Ldr ))
  103. );
  104. peb_SubSystemData = ReadField( SubSystemData );
  105. peb_ProcessHeap = ReadField( ProcessHeap );
  106. peb_ProcessParameters = ReadField( ProcessParameters );
  107. err = GetFieldOffset( ldrdata,
  108. "InMemoryOrderModuleList",
  109. &ldr_InMemoryOrderModuleList_Offset
  110. );
  111. if ( err ) {
  112. dprintf( " *** _PEB_LDR_DATA%s was not found...\n",
  113. ( err == FIELDS_DID_NOT_MATCH ) ? ".InMemoryModuleList field" :
  114. " type"
  115. );
  116. }
  117. else {
  118. err = GetFieldOffset( ldrEntry,
  119. "InMemoryOrderLinks",
  120. &ldr_DataTableEntry_InMemoryOrderLinks_Offset
  121. );
  122. if (err ) {
  123. dprintf( " *** _LDR_DATA_TABLE_ENTRY%s was not found...\n",
  124. ( err == FIELDS_DID_NOT_MATCH ) ? ".InMemoryOrderLinks field" :
  125. " type"
  126. );
  127. }
  128. }
  129. if ( err || GetFieldValue( ldr, ldrdata, "Initialized", ldr_Initialized ) ) {
  130. dprintf( " *** unable to read Ldr table at %p\n", ldr );
  131. }
  132. else {
  133. ULONG64 next, head;
  134. BOOL First = TRUE;
  135. GetFieldValue( ldr, ldrdata, "InInitializationOrderModuleList.Flink", ldr_InInitializationOrderModuleList_Flink );
  136. GetFieldValue( ldr, ldrdata, "InInitializationOrderModuleList.Blink", ldr_InInitializationOrderModuleList_Blink );
  137. GetFieldValue( ldr, ldrdata, "InLoadOrderModuleList.Flink", ldr_InLoadOrderModuleList_Flink );
  138. GetFieldValue( ldr, ldrdata, "InLoadOrderModuleList.Blink", ldr_InLoadOrderModuleList_Blink );
  139. GetFieldValue( ldr, ldrdata, "InMemoryOrderModuleList.Flink", ldr_InMemoryOrderModuleList_Flink );
  140. GetFieldValue( ldr, ldrdata, "InMemoryOrderModuleList.Blink", ldr_InMemoryOrderModuleList_Blink );
  141. dprintf(
  142. " Ldr.Initialized: %s\n"
  143. " Ldr.InInitializationOrderModuleList: %p . %p\n"
  144. " Ldr.InLoadOrderModuleList: %p . %p\n"
  145. " Ldr.InMemoryOrderModuleList: %p . %p\n",
  146. ldr_Initialized ? "Yes" : "No",
  147. ldr_InInitializationOrderModuleList_Flink,
  148. ldr_InInitializationOrderModuleList_Blink,
  149. ldr_InLoadOrderModuleList_Flink,
  150. ldr_InLoadOrderModuleList_Blink,
  151. ldr_InMemoryOrderModuleList_Flink,
  152. ldr_InMemoryOrderModuleList_Blink
  153. );
  154. head = ldr + (ULONG64)ldr_InMemoryOrderModuleList_Offset;
  155. next = ldr_InMemoryOrderModuleList_Flink;
  156. while( next != head ) {
  157. ULONG64 entry, dllBase;
  158. UNICODE_STRING64 u;
  159. ULONG Timestamp;
  160. const char *time;
  161. entry = next - ldr_DataTableEntry_InMemoryOrderLinks_Offset;
  162. if (GetFieldValue( entry, ldrEntry, "DllBase", dllBase )) {
  163. dprintf("Cannot read %s at %p\n",ldrEntry, entry);
  164. break;
  165. }
  166. GetFieldValue( entry, ldrEntry, "TimeDateStamp", Timestamp );
  167. GetFieldValue( entry, ldrEntry, "FullDllName.Buffer", u.Buffer );
  168. GetFieldValue( entry, ldrEntry, "FullDllName.Length", u.Length );
  169. GetFieldValue( entry, ldrEntry, "FullDllName.MaximumLength", u.MaximumLength );
  170. if (First) {
  171. if (IsPtr64()) {
  172. dprintf(" Base TimeStamp / Module\n");
  173. } else {
  174. dprintf(" Base TimeStamp Module\n");
  175. }
  176. First = FALSE;
  177. }
  178. if (IsPtr64()) {
  179. dprintf(" ");
  180. }
  181. dprintf( "%16p ", dllBase );
  182. if ((time = ctime((time_t *) &Timestamp)) != NULL) {
  183. dprintf( "%08x %-20.20s ", Timestamp, time+4);
  184. }
  185. if ( u.Buffer ) {
  186. if (IsPtr64()) {
  187. dprintf("\n ");
  188. }
  189. DumpUnicode64( u );
  190. }
  191. dprintf( "\n");
  192. GetFieldValue( entry, ldrEntry, "InMemoryOrderLinks.Flink", next );
  193. if (CheckControlC()) {
  194. break;
  195. }
  196. }
  197. }
  198. dprintf(
  199. " SubSystemData: %p\n"
  200. " ProcessHeap: %p\n"
  201. " ProcessParameters: %p\n",
  202. peb_SubSystemData,
  203. peb_ProcessHeap,
  204. peb_ProcessParameters
  205. );
  206. if ( peb_ProcessParameters ) {
  207. ULONG64 peb_ProcessParameters_Environment;
  208. ULONG64 peb_ProcessParameters_Flags;
  209. UNICODE_STRING64 windowTitle;
  210. UNICODE_STRING64 imagePathName;
  211. UNICODE_STRING64 commandLine;
  212. UNICODE_STRING64 dllPath;
  213. GetFieldValue( peb_ProcessParameters, processparam, "Environment", peb_ProcessParameters_Environment );
  214. GetFieldValue( peb_ProcessParameters, processparam, "Flags", peb_ProcessParameters_Flags );
  215. GetFieldValue( peb_ProcessParameters, processparam, "WindowTitle.Buffer", windowTitle.Buffer );
  216. GetFieldValue( peb_ProcessParameters, processparam, "WindowTitle.Length", windowTitle.Length );
  217. GetFieldValue( peb_ProcessParameters, processparam, "WindowTitle.MaximumLength", windowTitle.MaximumLength );
  218. GetFieldValue( peb_ProcessParameters, processparam, "ImagePathName.Buffer", imagePathName.Buffer );
  219. GetFieldValue( peb_ProcessParameters, processparam, "ImagePathName.Length", imagePathName.Length );
  220. GetFieldValue( peb_ProcessParameters, processparam, "ImagePathName.MaximumLength", imagePathName.MaximumLength );
  221. GetFieldValue( peb_ProcessParameters, processparam, "CommandLine.Buffer", commandLine.Buffer );
  222. GetFieldValue( peb_ProcessParameters, processparam, "CommandLine.Length", commandLine.Length );
  223. GetFieldValue( peb_ProcessParameters, processparam, "CommandLine.MaximumLength", commandLine.MaximumLength );
  224. GetFieldValue( peb_ProcessParameters, processparam, "DllPath.Buffer", dllPath.Buffer );
  225. GetFieldValue( peb_ProcessParameters, processparam, "DllPath.Length", dllPath.Length );
  226. GetFieldValue( peb_ProcessParameters, processparam, "DllPath.MaximumLength", dllPath.MaximumLength );
  227. if ( !(peb_ProcessParameters_Flags & RTL_USER_PROC_PARAMS_NORMALIZED) ) {
  228. windowTitle.Buffer += peb_ProcessParameters;
  229. imagePathName.Buffer += peb_ProcessParameters;
  230. commandLine.Buffer += peb_ProcessParameters;
  231. dllPath.Buffer += peb_ProcessParameters;
  232. }
  233. dprintf(
  234. " WindowTitle: '" );
  235. DumpUnicode64( windowTitle );
  236. dprintf("'\n");
  237. dprintf(
  238. " ImageFile: '" );
  239. DumpUnicode64( imagePathName );
  240. dprintf("'\n");
  241. dprintf(
  242. " CommandLine: '" );
  243. DumpUnicode64( commandLine );
  244. dprintf("'\n");
  245. dprintf(
  246. " DllPath: '" );
  247. DumpUnicode64( dllPath );
  248. dprintf("'\n"
  249. " Environment: %p\n", peb_ProcessParameters_Environment );
  250. }
  251. else {
  252. dprintf( " *** unable to read process parameters\n" );
  253. }
  254. return S_OK;
  255. }
  256. DECLARE_API( peb )
  257. /*++
  258. Routine Description:
  259. This function is called to dump the PEB
  260. Called as:
  261. !peb
  262. Arguments:
  263. None
  264. Return Value:
  265. None
  266. --*/
  267. {
  268. ULONG64 pebAddress;
  269. ULONG64 peb;
  270. HRESULT hr = S_OK;
  271. INIT_API();
  272. if ( *args ) {
  273. pebAddress = GetExpression( args );
  274. } else {
  275. ULONG64 tebAddress;
  276. GetTebAddress( &tebAddress );
  277. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && tebAddress) {
  278. ULONG64 Peb32=0;
  279. if (GetPeb32FromWowTeb(tebAddress, &Peb32) && Peb32) {
  280. dprintf("Wow64 PEB32 at %lx\n", Peb32);
  281. DumpPeb(Peb32, TRUE);
  282. dprintf("\n\nWow64 ");
  283. }
  284. }
  285. GetPebAddress( 0, &pebAddress );
  286. }
  287. if ( pebAddress ) {
  288. dprintf( "PEB at %p\n", pebAddress );
  289. }
  290. else {
  291. dprintf( "PEB NULL...\n" );
  292. return E_INVALIDARG;
  293. }
  294. peb = IsPtr64() ? pebAddress : (ULONG64)(LONG64)(LONG)pebAddress;
  295. hr = DumpPeb(peb, FALSE);
  296. EXIT_API();
  297. return hr;
  298. } // PebExtension()
  299. HRESULT
  300. DumpTeb(ULONG64 tebAddress, BOOL IsWow64Teb)
  301. {
  302. ULONG64 teb;
  303. ULONG64 tib_ExceptionList;
  304. ULONG64 tib_StackBase;
  305. ULONG64 tib_StackLimit;
  306. ULONG64 tib_StackSusSystemTib;
  307. ULONG64 tib_FiberData;
  308. ULONG64 tib_ArbitraryUserPointer;
  309. ULONG64 tib_Self;
  310. ULONG64 tib_EnvironmentPointer;
  311. ULONG64 teb_ClientId_UniqueProcess;
  312. ULONG64 teb_ClientId_UniqueThread;
  313. ULONG64 teb_RealClientId_UniqueProcess;
  314. ULONG64 teb_RealClientId_UniqueThread;
  315. ULONG64 DeallocationBStore;
  316. HRESULT hr = S_OK;
  317. ULONG64 err;
  318. teb = tebAddress;
  319. if (!IsWow64Teb) {
  320. if ( InitTypeRead( teb, TEB ) ) {
  321. dprintf( "error InitTypeRead( TEB )...\n");
  322. return E_INVALIDARG;
  323. }
  324. } else {
  325. if ( err = InitTypeRead( teb, nt!TEB32 ) ) {
  326. if (err == SYMBOL_TYPE_INFO_NOT_FOUND) {
  327. if ( InitTypeRead( teb, wow64!TEB32 ) ) {
  328. dprintf( "error InitTypeRead( wow64!TEB32 )...\n");
  329. return E_INVALIDARG;
  330. }
  331. } else {
  332. dprintf( "error InitTypeRead( TEB32 )...\n");
  333. return E_INVALIDARG;
  334. }
  335. }
  336. }
  337. dprintf(
  338. " ExceptionList: %p\n"
  339. " StackBase: %p\n"
  340. " StackLimit: %p\n"
  341. " SubSystemTib: %p\n"
  342. " FiberData: %p\n"
  343. " ArbitraryUserPointer: %p\n"
  344. " Self: %p\n"
  345. " EnvironmentPointer: %p\n",
  346. GetShortField(0, "NtTib.ExceptionList", 0),
  347. ReadField( NtTib.StackBase ),
  348. GetShortField(0, "NtTib.StackLimit", 0),
  349. GetShortField(0, "NtTib.SubsystemTib", 0),
  350. GetShortField(0, "NtTib.FiberData", 0),
  351. GetShortField(0, "NtTib.ArbitraryUsetPointer", 0),
  352. GetShortField(0, "NtTib.Self", 0),
  353. GetShortField(0, "NtTib.EnvironmentPointer", 0)
  354. );
  355. teb_ClientId_UniqueProcess = GetShortField( 0, "ClientId.UniqueProcess", 0 );
  356. teb_ClientId_UniqueThread = GetShortField( 0, "ClientId.UniqueThread", 0 );
  357. teb_RealClientId_UniqueProcess = GetShortField( 0, "RealClientId.UniqueProcess", 0 );
  358. teb_RealClientId_UniqueThread = GetShortField( 0, "RealClientId.UniqueThread", 0 );
  359. dprintf(
  360. " ClientId: %p . %p\n", teb_ClientId_UniqueProcess, teb_ClientId_UniqueThread );
  361. if ( teb_ClientId_UniqueProcess != teb_RealClientId_UniqueProcess ||
  362. teb_ClientId_UniqueThread != teb_RealClientId_UniqueThread )
  363. {
  364. dprintf(
  365. " Real ClientId: %p . %p\n", teb_RealClientId_UniqueProcess, teb_RealClientId_UniqueThread );
  366. }
  367. dprintf(
  368. " RpcHandle: %p\n"
  369. " Tls Storage: %p\n"
  370. " PEB Address: %p\n"
  371. " LastErrorValue: %u\n"
  372. " LastStatusValue: %x\n"
  373. " Count Owned Locks: %u\n"
  374. " HardErrorsMode: %u\n",
  375. ReadField( ActiveRpcHandle ),
  376. ReadField( ThreadLocalStoragePointer ),
  377. ReadField( ProcessEnvironmentBlock ),
  378. (ULONG)ReadField( LastErrorValue ),
  379. (ULONG)ReadField( LastStatusValue ),
  380. (ULONG)ReadField( CountOfOwnedCriticalSections ),
  381. (ULONG)ReadField( HardErrorsAreDisabled )
  382. );
  383. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && !IsWow64Teb) {
  384. dprintf(
  385. " DeallocationBStore: %p\n"
  386. " BStoreLimit: %p\n",
  387. ReadField(DeallocationBStore),
  388. ReadField( BStoreLimit )
  389. );
  390. }
  391. return hr;
  392. } // DumpTeb()
  393. DECLARE_API( teb )
  394. /*++
  395. Routine Description:
  396. This function is called to dump the TEB
  397. Called as:
  398. !teb
  399. --*/
  400. {
  401. ULONG64 tebAddress;
  402. HRESULT hr = S_OK;
  403. INIT_API();
  404. if ( *args ) {
  405. tebAddress = GetExpression( args );
  406. } else {
  407. GetTebAddress( &tebAddress );
  408. }
  409. if ( tebAddress ) {
  410. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && tebAddress) {
  411. ULONG64 Teb32=0;
  412. if (GetTeb32FromWowTeb(tebAddress, &Teb32) && Teb32) {
  413. dprintf("Wow64 TEB32 at %p\n", Teb32);
  414. DumpTeb(Teb32, TRUE);
  415. dprintf("\n\nWow64 ");
  416. }
  417. }
  418. dprintf( "TEB at %p\n", tebAddress );
  419. } else {
  420. dprintf( "TEB NULL...\n" );
  421. hr = E_INVALIDARG;
  422. goto ExitTeb;
  423. }
  424. tebAddress = IsPtr64() ? tebAddress : (ULONG64)(LONG64)(LONG)tebAddress;
  425. hr = DumpTeb(tebAddress, FALSE);
  426. ExitTeb:
  427. EXIT_API();
  428. return hr;
  429. }