1 // Copyright 2015 The Crashpad Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef CRASHPAD_UTIL_WIN_PROCESS_STRUCTS_H_ 16 #define CRASHPAD_UTIL_WIN_PROCESS_STRUCTS_H_ 17 18 #include <windows.h> 19 20 namespace crashpad { 21 namespace process_types { 22 23 namespace internal { 24 25 struct Traits32 { 26 using Pad = DWORD; 27 using UnsignedIntegral = DWORD; 28 using Pointer = DWORD; 29 }; 30 31 struct Traits64 { 32 using Pad = DWORD64; 33 using UnsignedIntegral = DWORD64; 34 using Pointer = DWORD64; 35 }; 36 37 } // namespace internal 38 39 //! \{ 40 41 //! \brief Selected structures from winternl.h, ntddk.h, and `dt ntdll!xxx`, 42 //! customized to have both x86 and x64 sizes available. 43 //! 44 //! The structure and field names follow the Windows names for clarity. We do, 45 //! however, use plain integral types rather than pointer types. This is both 46 //! easier to define, and avoids accidentally treating them as pointers into the 47 //! current address space. 48 //! 49 //! The templates below should be instantiated with either internal::Traits32 50 //! for structures targeting x86, or internal::Traits64 for x64. 51 52 // We set packing to 1 so that we can explicitly control the layout to make it 53 // match the OS defined structures. 54 #pragma pack(push, 1) 55 56 template <class Traits> 57 struct PROCESS_BASIC_INFORMATION { 58 union { 59 DWORD ExitStatus; 60 typename Traits::Pad padding_for_x64_0; 61 }; 62 typename Traits::Pointer PebBaseAddress; 63 typename Traits::UnsignedIntegral AffinityMask; 64 union { 65 DWORD BasePriority; 66 typename Traits::Pad padding_for_x64_1; 67 }; 68 typename Traits::UnsignedIntegral UniqueProcessId; 69 typename Traits::UnsignedIntegral InheritedFromUniqueProcessId; 70 }; 71 72 template <class Traits> 73 struct LIST_ENTRY { 74 typename Traits::Pointer Flink; 75 typename Traits::Pointer Blink; 76 }; 77 78 template <class Traits> 79 struct UNICODE_STRING { 80 union { 81 struct { 82 USHORT Length; 83 USHORT MaximumLength; 84 }; 85 typename Traits::Pad padding_for_x64; 86 }; 87 typename Traits::Pointer Buffer; 88 }; 89 90 template <class Traits> 91 struct PEB_LDR_DATA { 92 ULONG Length; 93 DWORD Initialized; 94 typename Traits::Pointer SsHandle; 95 LIST_ENTRY<Traits> InLoadOrderModuleList; 96 LIST_ENTRY<Traits> InMemoryOrderModuleList; 97 LIST_ENTRY<Traits> InInitializationOrderModuleList; 98 }; 99 100 template <class Traits> 101 struct LDR_DATA_TABLE_ENTRY { 102 LIST_ENTRY<Traits> InLoadOrderLinks; 103 LIST_ENTRY<Traits> InMemoryOrderLinks; 104 LIST_ENTRY<Traits> InInitializationOrderLinks; 105 typename Traits::Pointer DllBase; 106 typename Traits::Pointer EntryPoint; 107 union { 108 ULONG SizeOfImage; 109 typename Traits::Pad padding_for_x64; 110 }; 111 UNICODE_STRING<Traits> FullDllName; 112 UNICODE_STRING<Traits> BaseDllName; 113 ULONG Flags; 114 USHORT ObsoleteLoadCount; 115 USHORT TlsIndex; 116 LIST_ENTRY<Traits> HashLinks; 117 ULONG TimeDateStamp; 118 }; 119 120 template <class Traits> 121 struct CURDIR { 122 UNICODE_STRING<Traits> DosPath; 123 typename Traits::Pointer Handle; 124 }; 125 126 template <class Traits> 127 struct STRING { 128 union { 129 struct { 130 USHORT Length; 131 USHORT MaximumLength; 132 }; 133 typename Traits::Pad padding_for_x64; 134 }; 135 typename Traits::Pointer Buffer; 136 }; 137 138 template <class Traits> 139 struct RTL_DRIVE_LETTER_CURDIR { 140 WORD Flags; 141 WORD Length; 142 DWORD TimeStamp; 143 STRING<Traits> DosPath; 144 }; 145 146 template <class Traits> 147 struct RTL_USER_PROCESS_PARAMETERS { 148 DWORD MaximumLength; 149 DWORD Length; 150 DWORD Flags; 151 DWORD DebugFlags; 152 typename Traits::Pointer ConsoleHandle; 153 union { 154 DWORD ConsoleFlags; 155 typename Traits::Pad padding_for_x64_0; 156 }; 157 typename Traits::Pointer StandardInput; 158 typename Traits::Pointer StandardOutput; 159 typename Traits::Pointer StandardError; 160 CURDIR<Traits> CurrentDirectory; 161 UNICODE_STRING<Traits> DllPath; 162 UNICODE_STRING<Traits> ImagePathName; 163 UNICODE_STRING<Traits> CommandLine; 164 typename Traits::Pointer Environment; 165 DWORD StartingX; 166 DWORD StartingY; 167 DWORD CountX; 168 DWORD CountY; 169 DWORD CountCharsX; 170 DWORD CountCharsY; 171 DWORD FillAttribute; 172 DWORD WindowFlags; 173 union { 174 DWORD ShowWindowFlags; 175 typename Traits::Pad padding_for_x64_1; 176 }; 177 UNICODE_STRING<Traits> WindowTitle; 178 UNICODE_STRING<Traits> DesktopInfo; 179 UNICODE_STRING<Traits> ShellInfo; 180 UNICODE_STRING<Traits> RuntimeData; 181 RTL_DRIVE_LETTER_CURDIR<Traits> CurrentDirectores[32]; // sic. 182 ULONG EnvironmentSize; 183 }; 184 185 template <class T> 186 struct GdiHandleBufferCountForBitness; 187 188 template <> 189 struct GdiHandleBufferCountForBitness<internal::Traits32> { 190 enum { value = 34 }; 191 }; 192 template <> 193 struct GdiHandleBufferCountForBitness<internal::Traits64> { 194 enum { value = 60 }; 195 }; 196 197 template <class Traits> 198 struct PEB { 199 union { 200 struct { 201 BYTE InheritedAddressSpace; 202 BYTE ReadImageFileExecOptions; 203 BYTE BeingDebugged; 204 BYTE BitField; 205 }; 206 typename Traits::Pad padding_for_x64_0; 207 }; 208 typename Traits::Pointer Mutant; 209 typename Traits::Pointer ImageBaseAddress; 210 typename Traits::Pointer Ldr; 211 typename Traits::Pointer ProcessParameters; 212 typename Traits::Pointer SubSystemData; 213 typename Traits::Pointer ProcessHeap; 214 typename Traits::Pointer FastPebLock; 215 typename Traits::Pointer AtlThunkSListPtr; 216 typename Traits::Pointer IFEOKey; 217 union { 218 DWORD CrossProcessFlags; 219 typename Traits::Pad padding_for_x64_1; 220 }; 221 typename Traits::Pointer KernelCallbackTable; 222 DWORD SystemReserved; 223 DWORD AtlThunkSListPtr32; 224 typename Traits::Pointer ApiSetMap; 225 union { 226 DWORD TlsExpansionCounter; 227 typename Traits::Pad padding_for_x64_2; 228 }; 229 typename Traits::Pointer TlsBitmap; 230 DWORD TlsBitmapBits[2]; 231 typename Traits::Pointer ReadOnlySharedMemoryBase; 232 typename Traits::Pointer SparePvoid0; 233 typename Traits::Pointer ReadOnlyStaticServerData; 234 typename Traits::Pointer AnsiCodePageData; 235 typename Traits::Pointer OemCodePageData; 236 typename Traits::Pointer UnicodeCaseTableData; 237 DWORD NumberOfProcessors; 238 DWORD NtGlobalFlag; 239 DWORD alignment_for_x86; 240 LARGE_INTEGER CriticalSectionTimeout; 241 typename Traits::UnsignedIntegral HeapSegmentReserve; 242 typename Traits::UnsignedIntegral HeapSegmentCommit; 243 typename Traits::UnsignedIntegral HeapDeCommitTotalFreeThreshold; 244 typename Traits::UnsignedIntegral HeapDeCommitFreeBlockThreshold; 245 DWORD NumberOfHeaps; 246 DWORD MaximumNumberOfHeaps; 247 typename Traits::Pointer ProcessHeaps; 248 typename Traits::Pointer GdiSharedHandleTable; 249 typename Traits::Pointer ProcessStarterHelper; 250 DWORD GdiDCAttributeList; 251 typename Traits::Pointer LoaderLock; 252 DWORD OSMajorVersion; 253 DWORD OSMinorVersion; 254 WORD OSBuildNumber; 255 WORD OSCSDVersion; 256 DWORD OSPlatformId; 257 DWORD ImageSubsystem; 258 DWORD ImageSubsystemMajorVersion; 259 union { 260 DWORD ImageSubsystemMinorVersion; 261 typename Traits::Pad padding_for_x64_3; 262 }; 263 typename Traits::UnsignedIntegral ActiveProcessAffinityMask; 264 DWORD GdiHandleBuffer[GdiHandleBufferCountForBitness<Traits>::value]; 265 typename Traits::Pointer PostProcessInitRoutine; 266 typename Traits::Pointer TlsExpansionBitmap; 267 DWORD TlsExpansionBitmapBits[32]; 268 union { 269 DWORD SessionId; 270 typename Traits::Pad padding_for_x64_4; 271 }; 272 ULARGE_INTEGER AppCompatFlags; 273 ULARGE_INTEGER AppCompatFlagsUser; 274 typename Traits::Pointer pShimData; 275 typename Traits::Pointer AppCompatInfo; 276 UNICODE_STRING<Traits> CSDVersion; 277 typename Traits::Pointer ActivationContextData; 278 typename Traits::Pointer ProcessAssemblyStorageMap; 279 typename Traits::Pointer SystemDefaultActivationContextData; 280 typename Traits::Pointer SystemAssemblyStorageMap; 281 typename Traits::UnsignedIntegral MinimumStackCommit; 282 typename Traits::Pointer FlsCallback; 283 LIST_ENTRY<Traits> FlsListHead; 284 typename Traits::Pointer FlsBitmap; 285 DWORD FlsBitmapBits[4]; 286 DWORD FlsHighIndex; 287 }; 288 289 template <class Traits> 290 struct NT_TIB { 291 union { 292 // See https://msdn.microsoft.com/library/dn424783.aspx. 293 typename Traits::Pointer Wow64Teb; 294 struct { 295 typename Traits::Pointer ExceptionList; 296 typename Traits::Pointer StackBase; 297 typename Traits::Pointer StackLimit; 298 typename Traits::Pointer SubSystemTib; 299 union { 300 typename Traits::Pointer FiberData; 301 BYTE Version[4]; 302 }; 303 typename Traits::Pointer ArbitraryUserPointer; 304 typename Traits::Pointer Self; 305 }; 306 }; 307 }; 308 309 // See https://msdn.microsoft.com/library/gg750647.aspx. 310 template <class Traits> 311 struct CLIENT_ID { 312 typename Traits::Pointer UniqueProcess; 313 typename Traits::Pointer UniqueThread; 314 }; 315 316 // This is a partial definition of the TEB, as we do not currently use many 317 // fields of it. See https://nirsoft.net/kernel_struct/vista/TEB.html, and the 318 // (arch-specific) definition of _TEB in winternl.h. 319 template <class Traits> 320 struct TEB { 321 NT_TIB<Traits> NtTib; 322 typename Traits::Pointer EnvironmentPointer; 323 CLIENT_ID<Traits> ClientId; 324 typename Traits::Pointer ActiveRpcHandle; 325 typename Traits::Pointer ThreadLocalStoragePointer; 326 typename Traits::Pointer ProcessEnvironmentBlock; 327 typename Traits::Pointer RemainderOfReserved2[399]; 328 BYTE Reserved3[1952]; 329 typename Traits::Pointer TlsSlots[64]; 330 BYTE Reserved4[8]; 331 typename Traits::Pointer Reserved5[26]; 332 typename Traits::Pointer ReservedForOle; 333 typename Traits::Pointer Reserved6[4]; 334 typename Traits::Pointer TlsExpansionSlots; 335 }; 336 337 // See https://msdn.microsoft.com/library/gg750724.aspx. 338 template <class Traits> 339 struct SYSTEM_THREAD_INFORMATION { 340 union { 341 struct { 342 LARGE_INTEGER KernelTime; 343 LARGE_INTEGER UserTime; 344 LARGE_INTEGER CreateTime; 345 union { 346 ULONG WaitTime; 347 typename Traits::Pad padding_for_x64_0; 348 }; 349 typename Traits::Pointer StartAddress; 350 CLIENT_ID<Traits> ClientId; 351 LONG Priority; 352 LONG BasePriority; 353 ULONG ContextSwitches; 354 ULONG ThreadState; 355 union { 356 ULONG WaitReason; 357 typename Traits::Pad padding_for_x64_1; 358 }; 359 }; 360 LARGE_INTEGER alignment_for_x86[8]; 361 }; 362 }; 363 364 // There's an extra field in the x64 VM_COUNTERS (or maybe it's VM_COUNTERS_EX, 365 // it's not clear), so we just make separate specializations for 32/64. 366 template <class Traits> 367 struct VM_COUNTERS {}; 368 369 template <> 370 struct VM_COUNTERS<internal::Traits32> { 371 SIZE_T PeakVirtualSize; 372 SIZE_T VirtualSize; 373 ULONG PageFaultCount; 374 SIZE_T PeakWorkingSetSize; 375 SIZE_T WorkingSetSize; 376 SIZE_T QuotaPeakPagedPoolUsage; 377 SIZE_T QuotaPagedPoolUsage; 378 SIZE_T QuotaPeakNonPagedPoolUsage; 379 SIZE_T QuotaNonPagedPoolUsage; 380 SIZE_T PagefileUsage; 381 SIZE_T PeakPagefileUsage; 382 }; 383 384 template <> 385 struct VM_COUNTERS<internal::Traits64> { 386 SIZE_T PeakVirtualSize; 387 SIZE_T VirtualSize; 388 union { 389 ULONG PageFaultCount; 390 internal::Traits64::Pad padding_for_x64; 391 }; 392 SIZE_T PeakWorkingSetSize; 393 SIZE_T WorkingSetSize; 394 SIZE_T QuotaPeakPagedPoolUsage; 395 SIZE_T QuotaPagedPoolUsage; 396 SIZE_T QuotaPeakNonPagedPoolUsage; 397 SIZE_T QuotaNonPagedPoolUsage; 398 SIZE_T PagefileUsage; 399 SIZE_T PeakPagefileUsage; 400 SIZE_T PrivateUsage; 401 }; 402 403 // https://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/System%20Information/Structures/SYSTEM_PROCESS_INFORMATION.html 404 template <class Traits> 405 struct SYSTEM_PROCESS_INFORMATION { 406 ULONG NextEntryOffset; 407 ULONG NumberOfThreads; 408 LARGE_INTEGER WorkingSetPrivateSize; 409 ULONG HardFaultCount; 410 ULONG NumberOfThreadsHighWatermark; 411 ULONGLONG CycleTime; 412 LARGE_INTEGER CreateTime; 413 LARGE_INTEGER UserTime; 414 LARGE_INTEGER KernelTime; 415 UNICODE_STRING<Traits> ImageName; 416 union { 417 LONG BasePriority; 418 typename Traits::Pad padding_for_x64_0; 419 }; 420 union { 421 DWORD UniqueProcessId; 422 typename Traits::Pad padding_for_x64_1; 423 }; 424 union { 425 DWORD InheritedFromUniqueProcessId; 426 typename Traits::Pad padding_for_x64_2; 427 }; 428 ULONG HandleCount; 429 ULONG SessionId; 430 typename Traits::Pointer UniqueProcessKey; 431 union { 432 VM_COUNTERS<Traits> VirtualMemoryCounters; 433 LARGE_INTEGER alignment_for_x86[6]; 434 }; 435 IO_COUNTERS IoCounters; 436 SYSTEM_THREAD_INFORMATION<Traits> Threads[1]; 437 }; 438 439 // https://undocumented.ntinternals.net/source/usermode/structures/THREAD_BASIC_INFORMATION.html 440 template <class Traits> 441 struct THREAD_BASIC_INFORMATION { 442 union { 443 LONG ExitStatus; 444 typename Traits::Pad padding_for_x64_0; 445 }; 446 typename Traits::Pointer TebBaseAddress; 447 CLIENT_ID<Traits> ClientId; 448 typename Traits::Pointer AffinityMask; 449 ULONG Priority; 450 LONG BasePriority; 451 }; 452 453 template <class Traits> 454 struct EXCEPTION_POINTERS { 455 typename Traits::Pointer ExceptionRecord; 456 typename Traits::Pointer ContextRecord; 457 }; 458 459 using EXCEPTION_POINTERS32 = EXCEPTION_POINTERS<internal::Traits32>; 460 using EXCEPTION_POINTERS64 = EXCEPTION_POINTERS<internal::Traits64>; 461 462 // This is defined in winnt.h, but not for cross-bitness. 463 template <class Traits> 464 struct RTL_CRITICAL_SECTION { 465 typename Traits::Pointer DebugInfo; 466 LONG LockCount; 467 LONG RecursionCount; 468 typename Traits::Pointer OwningThread; 469 typename Traits::Pointer LockSemaphore; 470 typename Traits::UnsignedIntegral SpinCount; 471 }; 472 473 template <class Traits> 474 struct RTL_CRITICAL_SECTION_DEBUG { 475 union { 476 struct { 477 WORD Type; 478 WORD CreatorBackTraceIndex; 479 }; 480 typename Traits::Pad alignment_for_x64; 481 }; 482 typename Traits::Pointer CriticalSection; 483 LIST_ENTRY<Traits> ProcessLocksList; 484 DWORD EntryCount; 485 DWORD ContentionCount; 486 DWORD Flags; 487 WORD CreatorBackTraceIndexHigh; 488 WORD SpareWORD; 489 }; 490 491 struct SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX { 492 void* Object; 493 ULONG_PTR UniqueProcessId; 494 HANDLE HandleValue; 495 ULONG GrantedAccess; 496 USHORT CreatorBackTraceIndex; 497 USHORT ObjectTypeIndex; 498 ULONG HandleAttributes; 499 ULONG Reserved; 500 }; 501 502 struct SYSTEM_HANDLE_INFORMATION_EX { 503 ULONG_PTR NumberOfHandles; 504 ULONG_PTR Reserved; 505 SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX Handles[1]; 506 }; 507 508 #pragma pack(pop) 509 510 //! \} 511 512 } // namespace process_types 513 } // namespace crashpad 514 515 #endif // CRASHPAD_UTIL_WIN_PROCESS_STRUCTS_H_ 516