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.

540 lines
18 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, nt!_PEB ) ) {
  88. dprintf( "error %d InitTypeRead( nt!_PEB 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. time_t Timestamp=0;
  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. WCHAR EnvBuf[0x4000];
  252. WCHAR *Env = EnvBuf;
  253. ULONG cb;
  254. if (ReadMemory(peb_ProcessParameters_Environment, Env,
  255. sizeof(EnvBuf)-4, &cb))
  256. {
  257. EnvBuf[cb /2] = 0;
  258. EnvBuf[(cb /2)+ 1] = 0;
  259. //
  260. // Go until we reach a double NULL unicode
  261. //
  262. while(*(Env+1) != 0)
  263. {
  264. dprintf(" %ws\n", Env);
  265. while(*Env++ != 0);
  266. }
  267. if ((PUCHAR) Env >= (PUCHAR)EnvBuf + (sizeof(EnvBuf)-4))
  268. {
  269. dprintf("\n use 'db %p' to see remaining "
  270. "environment variables\n",
  271. peb_ProcessParameters_Environment + sizeof(EnvBuf));
  272. }
  273. }
  274. }
  275. }
  276. else {
  277. dprintf( " *** unable to read process parameters\n" );
  278. }
  279. return S_OK;
  280. }
  281. DECLARE_API( peb )
  282. /*++
  283. Routine Description:
  284. This function is called to dump the PEB
  285. Called as:
  286. !peb
  287. Arguments:
  288. None
  289. Return Value:
  290. None
  291. --*/
  292. {
  293. ULONG64 pebAddress;
  294. ULONG64 peb;
  295. HRESULT hr = S_OK;
  296. INIT_API();
  297. if ( *args ) {
  298. pebAddress = GetExpression( args );
  299. } else {
  300. ULONG64 tebAddress;
  301. tebAddress = GetExpression("@$teb");
  302. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && tebAddress) {
  303. ULONG64 Peb32=0;
  304. if (GetPeb32FromWowTeb(tebAddress, &Peb32) && Peb32) {
  305. dprintf("Wow64 PEB32 at %lx\n", Peb32);
  306. DumpPeb(Peb32, TRUE);
  307. dprintf("\n\nWow64 ");
  308. }
  309. }
  310. pebAddress = GetExpression("@$peb");
  311. //GetPebAddress( 0, &pebAddress );
  312. }
  313. if ( pebAddress ) {
  314. dprintf( "PEB at %p\n", pebAddress );
  315. }
  316. else {
  317. dprintf( "PEB NULL...\n" );
  318. return E_INVALIDARG;
  319. }
  320. peb = IsPtr64() ? pebAddress : (ULONG64)(LONG64)(LONG)pebAddress;
  321. hr = DumpPeb(peb, FALSE);
  322. EXIT_API();
  323. return hr;
  324. } // PebExtension()
  325. HRESULT
  326. DumpTeb(ULONG64 tebAddress, BOOL IsWow64Teb)
  327. {
  328. ULONG64 teb;
  329. ULONG64 tib_ExceptionList;
  330. ULONG64 tib_StackBase;
  331. ULONG64 tib_StackLimit;
  332. ULONG64 tib_StackSusSystemTib;
  333. ULONG64 tib_FiberData;
  334. ULONG64 tib_ArbitraryUserPointer;
  335. ULONG64 tib_Self;
  336. ULONG64 tib_EnvironmentPointer;
  337. ULONG64 teb_ClientId_UniqueProcess;
  338. ULONG64 teb_ClientId_UniqueThread;
  339. ULONG64 teb_RealClientId_UniqueProcess;
  340. ULONG64 teb_RealClientId_UniqueThread;
  341. ULONG64 DeallocationBStore;
  342. HRESULT hr = S_OK;
  343. ULONG64 err;
  344. ULONG64 UseHardErrorsAreDisabled;
  345. ULONG HardErrorModeOffset;
  346. PCHAR TebType;
  347. teb = tebAddress;
  348. if (!IsWow64Teb) {
  349. TebType = "nt!_TEB";
  350. if ( InitTypeRead( teb, nt!_TEB ) ) {
  351. dprintf( "error InitTypeRead( TEB )...\n");
  352. return E_INVALIDARG;
  353. }
  354. } else {
  355. TebType = "nt!TEB32";
  356. if ( err = InitTypeRead( teb, nt!TEB32 ) ) {
  357. if (err == SYMBOL_TYPE_INFO_NOT_FOUND) {
  358. TebType = "wow64!TEB32";
  359. if ( InitTypeRead( teb, wow64!TEB32 ) ) {
  360. dprintf( "error InitTypeRead( wow64!TEB32 )...\n");
  361. return E_INVALIDARG;
  362. }
  363. } else {
  364. dprintf( "error InitTypeRead( TEB32 )...\n");
  365. return E_INVALIDARG;
  366. }
  367. }
  368. }
  369. dprintf(
  370. " ExceptionList: %p\n"
  371. " StackBase: %p\n"
  372. " StackLimit: %p\n"
  373. " SubSystemTib: %p\n"
  374. " FiberData: %p\n"
  375. " ArbitraryUserPointer: %p\n"
  376. " Self: %p\n"
  377. " EnvironmentPointer: %p\n",
  378. GetShortField(0, "NtTib.ExceptionList", 0),
  379. ReadField( NtTib.StackBase ),
  380. GetShortField(0, "NtTib.StackLimit", 0),
  381. GetShortField(0, "NtTib.SubsystemTib", 0),
  382. GetShortField(0, "NtTib.FiberData", 0),
  383. GetShortField(0, "NtTib.ArbitraryUsetPointer", 0),
  384. GetShortField(0, "NtTib.Self", 0),
  385. GetShortField(0, "NtTib.EnvironmentPointer", 0)
  386. );
  387. teb_ClientId_UniqueProcess = GetShortField( 0, "ClientId.UniqueProcess", 0 );
  388. teb_ClientId_UniqueThread = GetShortField( 0, "ClientId.UniqueThread", 0 );
  389. teb_RealClientId_UniqueProcess = GetShortField( 0, "RealClientId.UniqueProcess", 0 );
  390. teb_RealClientId_UniqueThread = GetShortField( 0, "RealClientId.UniqueThread", 0 );
  391. dprintf(
  392. " ClientId: %p . %p\n", teb_ClientId_UniqueProcess, teb_ClientId_UniqueThread );
  393. if ( teb_ClientId_UniqueProcess != teb_RealClientId_UniqueProcess ||
  394. teb_ClientId_UniqueThread != teb_RealClientId_UniqueThread )
  395. {
  396. dprintf(
  397. " Real ClientId: %p . %p\n", teb_RealClientId_UniqueProcess, teb_RealClientId_UniqueThread );
  398. }
  399. UseHardErrorsAreDisabled = GetFieldOffset(TebType,
  400. "HardErrorMode",
  401. &HardErrorModeOffset);
  402. dprintf(
  403. " RpcHandle: %p\n"
  404. " Tls Storage: %p\n"
  405. " PEB Address: %p\n"
  406. " LastErrorValue: %u\n"
  407. " LastStatusValue: %x\n"
  408. " Count Owned Locks: %u\n"
  409. " HardErrorMode: %x\n",
  410. ReadField( ActiveRpcHandle ),
  411. ReadField( ThreadLocalStoragePointer ),
  412. ReadField( ProcessEnvironmentBlock ),
  413. (ULONG)ReadField( LastErrorValue ),
  414. (ULONG)ReadField( LastStatusValue ),
  415. (ULONG)ReadField( CountOfOwnedCriticalSections ),
  416. (ULONG) (UseHardErrorsAreDisabled
  417. ? ReadField( HardErrorsAreDisabled )
  418. : ReadField( HardErrorMode ))
  419. );
  420. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && !IsWow64Teb) {
  421. dprintf(
  422. " DeallocationBStore: %p\n"
  423. " BStoreLimit: %p\n",
  424. ReadField(DeallocationBStore),
  425. ReadField( BStoreLimit )
  426. );
  427. }
  428. return hr;
  429. } // DumpTeb()
  430. DECLARE_API( teb )
  431. /*++
  432. Routine Description:
  433. This function is called to dump the TEB
  434. Called as:
  435. !teb
  436. --*/
  437. {
  438. ULONG64 tebAddress;
  439. HRESULT hr = S_OK;
  440. INIT_API();
  441. if ( *args ) {
  442. tebAddress = GetExpression( args );
  443. } else {
  444. tebAddress = GetExpression("@$teb");
  445. }
  446. if ( tebAddress ) {
  447. if (TargetMachine == IMAGE_FILE_MACHINE_IA64 && tebAddress) {
  448. ULONG64 Teb32=0;
  449. if (GetTeb32FromWowTeb(tebAddress, &Teb32) && Teb32) {
  450. dprintf("Wow64 TEB32 at %p\n", Teb32);
  451. DumpTeb(Teb32, TRUE);
  452. dprintf("\n\nWow64 ");
  453. }
  454. }
  455. dprintf( "TEB at %p\n", tebAddress );
  456. } else {
  457. dprintf( "TEB NULL...\n" );
  458. hr = E_INVALIDARG;
  459. goto ExitTeb;
  460. }
  461. // tebAddress = IsPtr64() ? tebAddress : (ULONG64)(LONG64)(LONG)tebAddress;
  462. hr = DumpTeb(tebAddress, FALSE);
  463. ExitTeb:
  464. EXIT_API();
  465. return hr;
  466. }