1 #ifndef WINDOWS_HEAP_H 2 #define WINDOWS_HEAP_H 3 4 #include <windows.h> 5 #include <winternl.h> 6 7 /* 8 Defines most of heap related structures on Windows (some still missing) 9 Tested only on Windows 10 1809 x64 10 TODO: 11 Clean/organize this: Order and Style 12 -Can this be useful in unix? does mdmp even have a heap? remote dbg session? 13 x86 vs x64 Struct Differences: 14 -Structs definetly unaligned, check pdb 15 -Do something like the the linux_heap that includes itself but with another bitness 16 -Define macros to prefix structs to W32 or W64 17 18 Some structs are different based on the Windows version (XP, Vista, 7, Server, 8, 8.1, 10) 19 and updates (Service Packs, Windows 10 Seasonal Updates) 20 -Maybe use offsets instead of depending on structs 21 -Create structs for each windows version (ie post-fix XP_SP2, 7, 10_1703)? (Oh god) 22 -What about the parsing functions? Alter its behaviour depending on version or create 23 one function for each version 24 */ 25 #define EXTRA_FLAG (1ULL << (sizeof (size_t) * 8 - 1)) 26 27 #define SHIFT 16 28 #define LFH_BLOCK (1 << (SHIFT)) 29 #define LARGE_BLOCK (1 << (SHIFT + 1)) 30 #define NT_BLOCK (1 << (SHIFT + 2)) 31 #define SEGMENT_HEAP_BLOCK (1 << (SHIFT + 3)) 32 #define VS_BLOCK (1 << (SHIFT + 4)) 33 #define BACKEND_BLOCK (1 << (SHIFT + 5)) 34 35 typedef struct _HEAP_LOCAL_DATA *PHEAP_LOCAL_DATA; 36 typedef struct _HEAP_SUBSEGMENT *PHEAP_SUBSEGMENT; 37 typedef struct _LFH_HEAP *PLFH_HEAP; 38 typedef struct _HEAP *PHEAP; 39 40 typedef struct _RTL_BALANCED_NODE *PRTL_BALANCED_NODE; 41 typedef struct _RTL_BALANCED_NODE { 42 union { 43 PRTL_BALANCED_NODE Children[2]; 44 struct { 45 PRTL_BALANCED_NODE Left; 46 PRTL_BALANCED_NODE Right; 47 }; 48 }; 49 union { 50 BYTE Red : 1; 51 BYTE Balance : 2; 52 WPARAM ParentValue; 53 }; 54 } RTL_BALANCED_NODE, *PRTL_BALANCED_NODE; 55 56 typedef struct _RTL_RB_TREE { 57 PRTL_BALANCED_NODE Root; 58 union { 59 BOOL Encoded : 1; 60 PRTL_BALANCED_NODE Min; 61 }; 62 } RTL_RB_TREE, *PRTL_RB_TREE; 63 64 typedef struct _HEAP_COUNTERS { 65 WPARAM TotalMemoryReserved; 66 WPARAM TotalMemoryCommitted; 67 WPARAM TotalMemoryLargeUCR; 68 WPARAM TotalSizeInVirtualBlocks; 69 ULONG32 TotalSegments; 70 ULONG32 TotalUCRs; 71 ULONG32 CommittOps; 72 ULONG32 DeCommitOps; 73 ULONG32 LockAcquires; 74 ULONG32 LockCollisions; 75 ULONG32 CommitRate; 76 ULONG32 DecommittRate; 77 ULONG32 CommitFailures; 78 ULONG32 InBlockCommitFailures; 79 ULONG32 PollIntervalCounter; 80 ULONG32 DecommitsSinceLastCheck; 81 ULONG32 HeapPollInterval; 82 ULONG32 AllocAndFreeOps; 83 ULONG32 AllocationIndicesActive; 84 ULONG32 InBlockDeccommits; 85 WPARAM InBlockDeccomitSize; 86 WPARAM HighWatermarkSize; 87 WPARAM LastPolledSize; 88 } HEAP_COUNTERS, *PHEAP_COUNTERS; 89 90 typedef struct _HEAP_BUCKET_COUNTERS { 91 union { 92 struct { 93 ULONG TotalBlocks; 94 ULONG SubSegmentCounts; 95 }; 96 UINT64 Aggregate64; 97 }; 98 } HEAP_BUCKET_COUNTERS, *PHEAP_BUCKET_COUNTERS; 99 100 typedef struct _INTERLOCK_SEQ { // Is this right? NO! 101 union { 102 WORD Depth; 103 union { 104 union { 105 WORD Hint : 15; 106 WORD Lock : 1; 107 }; 108 WORD Hint16; 109 }; 110 INT32 Exchg; 111 }; 112 } INTERLOCK_SEQ, *PINTERLOCK_SEQ; 113 114 typedef struct _HEAP_UNPACKED_ENTRY { 115 #if defined(_M_X64) 116 PVOID PreviousBlockPrivateData; 117 #endif 118 union { 119 struct { 120 UINT16 Size; 121 UINT8 Flags; 122 UINT8 SmallTagIndex; 123 }; 124 #if defined(_M_X64) 125 struct { 126 ULONG32 SubSegmentCode; 127 UINT16 PreviousSize; 128 union { 129 UINT8 SegmentOffset; 130 UINT8 LFHFlags; 131 }; 132 UINT8 UnusedBytes; 133 }; 134 UINT64 CompactHeader; 135 #else 136 ULONG32 SubSegmentCode; 137 #endif 138 }; 139 #if !defined(_M_X64) 140 UINT16 PreviousSize; 141 union { 142 UINT8 SegmentOffset; 143 UINT8 LFHFlags; 144 }; 145 UINT8 UnusedBytes; 146 #endif 147 } HEAP_UNPACKED_ENTRY, *PHEAP_UNPACKED_ENTRY; 148 149 typedef struct _HEAP_EXTENDED_ENTRY { 150 #if defined(_M_X64) 151 PVOID Reserved; 152 #endif 153 union { 154 struct { 155 UINT16 FunctionIndex; 156 UINT16 ContextValue; 157 }; 158 ULONG32 InterceptorValue; 159 }; 160 UINT16 UnusedBytesLength; 161 UINT8 EntryOffset; 162 UINT8 ExtendedBlockSignature; 163 } HEAP_EXTENDED_ENTRY, *PHEAP_EXTENDED_ENTRY; 164 165 typedef struct _HEAP_ENTRY { 166 union { 167 HEAP_UNPACKED_ENTRY UnpackedEntry; 168 struct { 169 #if defined(_M_X64) 170 PVOID PreviousBlockPrivateData; 171 union { 172 struct { 173 UINT16 Size; 174 UINT8 Flags; 175 UINT8 SmallTagIndex; 176 }; 177 struct { 178 ULONG32 SubSegmentCode; 179 UINT16 PreviousSize; 180 union { 181 UINT8 SegmentOffset; 182 UINT8 LFHFlags; 183 }; 184 UINT8 UnusedBytes; 185 }; 186 UINT64 CompactHeader; 187 }; 188 #else 189 UINT16 Size; 190 UINT8 Flags; 191 UINT8 SmallTagIndex; 192 #endif 193 }; 194 #if !defined(_M_X64) 195 struct { 196 ULONG32 SubSegmentCode; 197 UINT16 PreviousSize; 198 union { 199 UINT8 SegmentOffset; 200 UINT8 LFHFlags; 201 }; 202 UINT8 UnusedBytes; 203 }; 204 #endif 205 HEAP_EXTENDED_ENTRY ExtendedEntry; 206 struct { 207 #if defined(_M_X64) 208 PVOID Reserved; 209 union { 210 struct { 211 UINT16 FunctionIndex; 212 UINT16 ContextValue; 213 }; 214 ULONG32 InterceptorValue; 215 }; 216 UINT16 UnusedBytesLength; 217 UINT8 EntryOffset; 218 UINT8 ExtendedBlockSignature; 219 #else 220 UINT16 FunctionIndex; 221 UINT16 ContextValue; 222 #endif 223 }; 224 struct { 225 #if defined(_M_X64) 226 PVOID ReservedForAlignment; 227 union { 228 struct { 229 ULONG32 Code1; 230 union { 231 struct { 232 UINT16 Code2; 233 UINT8 Code3; 234 UINT8 Code4; 235 }; 236 ULONG32 Code234; 237 }; 238 }; 239 UINT64 AgregateCode; 240 }; 241 #else 242 ULONG32 InterceptorValue; 243 UINT16 UnusedBytesLength; 244 UINT8 EntryOffset; 245 UINT8 ExtendedBlockSignature; 246 #endif 247 }; 248 #if !defined(_M_X64) 249 struct { 250 ULONG32 Code1; 251 union { 252 struct { 253 UINT16 Code2; 254 UINT8 Code3; 255 UINT8 Code4; 256 }; 257 ULONG32 Code234; 258 }; 259 }; 260 UINT64 AgregateCode; 261 #endif 262 }; 263 } HEAP_ENTRY, *PHEAP_ENTRY; 264 265 typedef struct _HEAP_LOCK { 266 union { 267 RTL_CRITICAL_SECTION CriticalSection; 268 PVOID /*(ERESOURCE)*/ Resource; 269 } Lock; 270 } HEAP_LOCK, *PHEAP_LOCK; 271 272 typedef struct _HEAP_TAG_ENTRY { 273 ULONG32 Allocs; 274 ULONG32 Frees; 275 WPARAM Size; 276 UINT16 TagIndex; 277 UINT16 CreatorBackTraceIndex; 278 WCHAR TagName[24]; 279 #if defined(_M_X64) 280 UINT8 _PADDING0_[4]; 281 #endif 282 } HEAP_TAG_ENTRY, *PHEAP_TAG_ENTRY; 283 284 typedef struct _HEAP_PSEUDO_TAG_ENTRY { 285 ULONG32 Allocs; 286 ULONG32 Frees; 287 WPARAM Size; 288 } HEAP_PSEUDO_TAG_ENTRY, *PHEAP_PSEUDO_TAG_ENTRY; 289 290 typedef struct _HEAP_TUNING_PARAMETERS { 291 ULONG32 CommittThresholdShift; 292 #if defined(_M_X64) 293 UINT8 _PADDING0_[4]; 294 #endif 295 WPARAM MaxPreCommittThreshold; 296 } HEAP_TUNING_PARAMETERS, *PHEAP_TUNING_PARAMETERS; 297 298 typedef struct _RTL_HEAP_MEMORY_LIMIT_DATA { 299 WPARAM CommitLimitBytes; 300 WPARAM CommitLimitFailureCode; 301 WPARAM MaxAllocationSizeBytes; 302 WPARAM AllocationLimitFailureCode; 303 } RTL_HEAP_MEMORY_LIMIT_DATA, *PRTL_HEAP_MEMORY_LIMIT_DATA; 304 305 typedef struct _RTL_HP_ENV_HANDLE { 306 PVOID h[2]; 307 } RTL_HP_ENV_HANDLE, *PRTL_HP_ENV_HANDLE; 308 309 typedef struct _RTL_HP_SEG_ALLOC_POLICY { 310 WPARAM MinLargePages; 311 WPARAM MaxLargePages; 312 UINT8 MinUtilization; 313 } RTL_HP_SEG_ALLOC_POLICY, *PRTL_HP_SEG_ALLOC_POLICY; 314 315 typedef enum _RTLP_HP_LOCK_TYPE { 316 HeapLockPaged, 317 HeapLockNonPaged, 318 HeapLockTypeMax 319 } RTLP_HP_LOCK_TYPE; 320 321 typedef struct _HEAP_SUBALLOCATOR_CALLBACKS { 322 PVOID Allocate; 323 PVOID Free; 324 PVOID Commit; 325 PVOID Decommit; 326 PVOID ExtendContext; 327 } HEAP_SUBALLOCATOR_CALLBACKS, *PHEAP_SUBALLOCATOR_CALLBACKS; 328 329 typedef struct _RTL_HP_VS_CONFIG { 330 struct { 331 ULONG PageAlignLargeAllocs : 1; 332 ULONG FullDecommit : 1; 333 } Flags; 334 } RTL_HP_VS_CONFIG, *PRTL_HP_VS_CONFIG; 335 336 typedef struct _HEAP_VS_SUBSEGMENT { 337 LIST_ENTRY ListEntry; 338 WPARAM CommitBitmap; 339 WPARAM CommitLock; 340 UINT16 Size; 341 UINT16 Signature : 15; 342 bool FullCommit : 1; 343 WPARAM Spare; 344 } HEAP_VS_SUBSEGMENT, *PHEAP_VS_SUBSEGMENT; 345 346 typedef struct _HEAP_VS_CONTEXT { 347 RTL_SRWLOCK Lock; 348 WPARAM /*RTLP_HP_LOCK_TYPE*/ LockType; 349 RTL_RB_TREE FreeChunkTree; 350 LIST_ENTRY SubsegmentList; 351 WPARAM TotalCommittedUnits; 352 WPARAM FreeCommittedUnits; 353 WPARAM /*HEAP_VS_DELAY_FREE_CONTEXT*/ DelayFreeContext[8]; // 0x40 Bytes 354 PVOID BackendCtx; 355 HEAP_SUBALLOCATOR_CALLBACKS Callbacks; 356 RTL_HP_VS_CONFIG Config; 357 UINT Flags; 358 WPARAM Padding; 359 } HEAP_VS_CONTEXT, *PHEAP_VS_CONTEXT; 360 361 typedef struct _HEAP_VS_CHUNK_HEADER_SIZE { 362 union { 363 WPARAM HeaderBits; 364 USHORT KeyUShort; 365 ULONG KeyULong; 366 struct { 367 USHORT MemoryCost; 368 USHORT UnsafeSize; 369 USHORT UnsafePrevSize; 370 UINT8 Allocated; 371 }; 372 }; 373 } HEAP_VS_CHUNK_HEADER_SIZE, *PHEAP_VS_CHUNK_HEADER_SIZE; 374 375 typedef struct _HEAP_VS_CHUNK_HEADER { 376 HEAP_VS_CHUNK_HEADER_SIZE Sizes; 377 union { 378 ULONG EncodedSegmentPageOffset : 8; 379 ULONG UnusedBytes : 1; 380 ULONG SkipDuringWalk : 1; 381 ULONG Spare : 22; 382 ULONG AllocatedChunkBits; 383 }; 384 } HEAP_VS_CHUNK_HEADER, *PHEAP_VS_CHUNK_HEADER; 385 386 enum { 387 PAGE_RANGE_FLAGS_LFH_SUBSEGMENT = 0x01, 388 PAGE_RANGE_FLAGS_COMMITED = 0x02, 389 PAGE_RANGE_FLAGS_ALLOCATED = 0x04, 390 PAGE_RANGE_FLAGS_FIRST = 0x08, 391 PAGE_RANGE_FLAGS_VS_SUBSEGMENT = 0x20 // LIES 392 }; 393 394 typedef struct _HEAP_PAGE_RANGE_DESCRIPTOR { 395 union { 396 RTL_BALANCED_NODE TreeNode; 397 struct { 398 ULONG TreeSignature; 399 ULONG UnusedBytes; 400 }; 401 union { 402 bool ExtraPresent; 403 UINT16 Spare0 : 15; 404 }; 405 }; 406 UCHAR RangeFlags; 407 UCHAR CommittedPageCount; 408 USHORT Spare; 409 union { 410 //_HEAP_DESCRIPTOR_KEY Key; 411 UCHAR Align[3]; 412 }; 413 union { 414 UCHAR UnitOffset; 415 UCHAR UnitSize; 416 }; 417 } HEAP_PAGE_RANGE_DESCRIPTOR, *PHEAP_PAGE_RANGE_DESCRIPTOR; 418 419 typedef struct _HEAP_PAGE_SEGMENT { 420 union { 421 struct { 422 LIST_ENTRY ListEntry; 423 WPARAM Signature; 424 PVOID SegmentCommitState; 425 UCHAR UnusedWatermark; 426 }; 427 HEAP_PAGE_RANGE_DESCRIPTOR DescArray[256]; 428 }; 429 } HEAP_PAGE_SEGMENT, *PHEAP_PAGE_SEGMENT; 430 431 typedef struct _RTL_HP_LFH_CONFIG { 432 USHORT MaxBlockSize; 433 BYTE WitholdPageCrossingBlocks : 1; 434 } RTL_HP_LFH_CONFIG, *PRTL_HP_LFH_CONFIG; 435 436 typedef struct _HEAP_LFH_SUBSEGMENT_STAT { 437 BYTE Index; 438 BYTE Count; 439 } HEAP_LFH_SUBSEGMENT_STAT, *PHEAP_LFH_SUBSEGMENT_STAT; 440 441 typedef struct _HEAP_LFH_SUBSEGMENT_STATS { 442 union { 443 HEAP_LFH_SUBSEGMENT_STAT Buckets[4]; 444 UINT64 Stats; 445 }; 446 } HEAP_LFH_SUBSEGMENT_STATS, *PHEAP_LFH_SUBSEGMENT_STATS; 447 448 typedef struct _HEAP_LFH_SUBSEGMENT_OWNER { 449 struct { 450 BYTE IsBucket : 1; 451 BYTE Spare0 : 7; 452 }; 453 BYTE BucketIndex; 454 union { 455 BYTE SlotCount; 456 BYTE SlotIndex; 457 }; 458 BYTE Spare1; 459 WPARAM AvailableSubsegmentCount; 460 RTL_SRWLOCK Lock; 461 LIST_ENTRY AvailableSubsegmentList; 462 LIST_ENTRY FullSubsegmentList; 463 } HEAP_LFH_SUBSEGMENT_OWNER, *PHEAP_LFH_SUBSEGMENT_OWNER; 464 465 typedef struct _HEAP_LFH_FAST_REF { 466 union { 467 PVOID Target; 468 WPARAM Value; 469 UINT16 RefCount : 12; 470 }; 471 } HEAP_LFH_FAST_REF, *PHEAP_LFH_FAST_REF; 472 473 typedef struct _HEAP_LFH_AFFINITY_SLOT { 474 HEAP_LFH_SUBSEGMENT_OWNER State; 475 HEAP_LFH_FAST_REF ActiveSubsegment; 476 } HEAP_LFH_AFFINITY_SLOT, *PHEAP_LFH_AFFINITY_SLOT; 477 478 typedef struct _HEAP_LFH_BUCKET { 479 HEAP_LFH_SUBSEGMENT_OWNER State; 480 WPARAM TotalBlockCount; 481 WPARAM TotalSubsegmentCount; 482 UINT ReciprocalBlockSize; 483 UINT8 Shift; 484 UINT8 ContentionCount; 485 WPARAM AffinityMappingLock; 486 PUINT8 ProcAffinityMapping; 487 PHEAP_LFH_AFFINITY_SLOT *AffinitySlots; 488 } HEAP_LFH_BUCKET, *PHEAP_LFH_BUCKET; 489 490 typedef struct _HEAP_LFH_CONTEXT { 491 PVOID BackendCtx; 492 HEAP_SUBALLOCATOR_CALLBACKS Callbacks; 493 PUINT8 AffinityModArray; 494 UINT8 MaxAffinity; 495 UINT8 LockType; 496 USHORT MemStatsOffset; 497 RTL_HP_LFH_CONFIG Config; 498 HEAP_LFH_SUBSEGMENT_STATS BucketStats; 499 WPARAM SubsegmentCreationLock; 500 WPARAM Padding[6]; 501 PHEAP_LFH_BUCKET Buckets[129]; 502 } HEAP_LFH_CONTEXT, *PHEAP_LFH_CONTEXT; 503 504 typedef struct _HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS { 505 union { 506 UINT32 EncodedData; 507 struct { 508 UINT16 BlockSize; 509 UINT16 FirstBlockOffset; 510 }; 511 }; 512 } HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS, *PHEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS; 513 514 typedef struct _HEAP_LFH_SUBSEGMENT { 515 LIST_ENTRY ListEntry; 516 union { 517 PHEAP_LFH_SUBSEGMENT_OWNER Owner; 518 WPARAM /*HEAP_LFH_SUBSEGMENT_DELAY_FREE*/ DelayFree; 519 }; 520 WPARAM CommitLock; 521 union { 522 struct { 523 UINT16 FreeCount; 524 UINT16 BlockCount; 525 }; 526 union { 527 SHORT InterlockedShort; 528 LONG InterlockedLong; 529 }; 530 }; 531 UINT16 FreeHint; 532 BYTE Location; 533 BYTE WitheldBlockCount; 534 HEAP_LFH_SUBSEGMENT_ENCODED_OFFSETS BlockOffsets; 535 BYTE CommitUnitShift; 536 BYTE CommitUnitCount; 537 UINT16 CommitStateOffset; 538 WPARAM BlockBitmap[1]; 539 } HEAP_LFH_SUBSEGMENT, *PHEAP_LFH_SUBSEGMENT; 540 541 typedef struct _HEAP_LARGE_ALLOC_DATA { 542 RTL_BALANCED_NODE TreeNode; 543 union { 544 WPARAM VirtualAddess; 545 UINT16 UnusedBytes; 546 }; 547 union { 548 UINT64 BitMask; 549 union { 550 bool ExtraPresent : 1; 551 bool GuardPageCount : 1; 552 UINT8 GuardPageAlignment : 6; 553 UINT8 Spare : 4; 554 UINT64 AllocatedPages : 52; 555 }; 556 }; 557 } HEAP_LARGE_ALLOC_DATA, *PHEAP_LARGE_ALLOC_DATA; 558 559 typedef struct _HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS { 560 WPARAM SmallPagesInUseWithinLarge; 561 WPARAM OpportunisticLargePageCount; 562 } HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS, *PHEAP_OPPORTUNISTIC_LARGE_PAGE_STATS; 563 564 typedef struct _HEAP_RUNTIME_MEMORY_STATS { 565 WPARAM TotalReservedPages; 566 WPARAM TotalCommittedPages; 567 WPARAM FreeCommittedPages; 568 WPARAM LfhFreeCommittedPages; 569 HEAP_OPPORTUNISTIC_LARGE_PAGE_STATS LargePageStats[2]; 570 RTL_HP_SEG_ALLOC_POLICY LargePageUtilizationPolicy; 571 } HEAP_RUNTIME_MEMORY_STATS, *PHEAP_RUNTIME_MEMORY_STATS; 572 573 typedef struct _HEAP_SEG_CONTEXT { 574 UINT64 SegmentMask; 575 BYTE UnitShift; 576 BYTE PagesPerUnitShift; 577 BYTE FirstDescriptorIndex; 578 BYTE CachedCommitSoftShift; 579 BYTE CachedCommitHighShift; 580 UINT16 Flags; 581 UINT MaxAllocationSize; 582 UINT16 OlpStatsOffset; 583 UINT16 MemStatsOffset; 584 PVOID LfhContext; 585 PVOID VsContext; 586 RTL_HP_ENV_HANDLE EnvHandle; 587 PVOID Heap; 588 WPARAM SegmentLock; 589 LIST_ENTRY SegmentListHead; 590 WPARAM SegmentCount; 591 RTL_RB_TREE FreePageRanges; 592 WPARAM FreeSegmentListLock; 593 SINGLE_LIST_ENTRY FreeSegmentList[2]; 594 WPARAM Padding[7]; 595 } HEAP_SEG_CONTEXT, *PHEAP_SEG_CONTEXT; 596 597 typedef struct _SEGMENT_HEAP { 598 RTL_HP_ENV_HANDLE EnvHandle; 599 ULONG Signature; 600 ULONG GlobalFlags; 601 ULONG Interceptor; 602 USHORT ProcessHeapListIndex; 603 USHORT AllocatedFromMetadata : 1; 604 union { 605 RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData; 606 struct { 607 UINT64 ReservedMustBeZero1; 608 PVOID UserContext; 609 PVOID ReservedMustBeZero2; 610 PVOID Spare; 611 }; 612 }; 613 RTL_SRWLOCK LargeMetadataLock; 614 RTL_RB_TREE LargeAllocMetadata; // Tree of HEAP_LARGE_ALLOC_DATA 615 WPARAM LargeReservedPages; 616 WPARAM LargeCommittedPages; 617 RTL_RUN_ONCE StackTraceInitVar; 618 WPARAM Padding[2]; 619 HEAP_RUNTIME_MEMORY_STATS MemStats; 620 UINT16 GlobalLockCount; 621 ULONG GlobalLockOwner; 622 RTL_SRWLOCK ContextExtendLock; 623 PUINT8 AllocatedBase; 624 PUINT8 UncommittedBase; 625 PUINT8 ReservedLimit; 626 HEAP_SEG_CONTEXT SegContexts[2]; 627 HEAP_VS_CONTEXT VsContext; 628 HEAP_LFH_CONTEXT LfhContext; 629 } SEGMENT_HEAP, *PSEGMENT_HEAP; 630 631 typedef struct _HEAP_SEGMENT { 632 HEAP_ENTRY Entry; 633 ULONG32 SegmentSignature; 634 ULONG32 SegmentFlags; 635 LIST_ENTRY SegmentListEntry; 636 PHEAP Heap; 637 PVOID BaseAddress; 638 ULONG32 NumberOfPages; 639 #if defined(_M_X64) 640 UINT8 _PADDING0_[4]; 641 #endif 642 PHEAP_ENTRY FirstEntry; 643 PHEAP_ENTRY LastValidEntry; 644 ULONG32 NumberOfUnCommittedPages; 645 ULONG32 NumberOfUnCommittedRanges; 646 UINT16 SegmentAllocatorBackTraceIndex; 647 UINT16 Reserved; 648 #if defined(_M_X64) 649 UINT8 _PADDING1_[4]; 650 #endif 651 LIST_ENTRY UCRSegmentList; 652 } HEAP_SEGMENT, *PHEAP_SEGMENT; 653 654 typedef struct _HEAP { 655 union { 656 HEAP_SEGMENT Segment; 657 struct { 658 HEAP_ENTRY Entry; 659 ULONG32 SegmentSignature; 660 ULONG32 SegmentFlags; 661 LIST_ENTRY SegmentListEntry; 662 PHEAP Heap; 663 PVOID BaseAddress; 664 ULONG32 NumberOfPages; 665 PHEAP_ENTRY FirstEntry; 666 PHEAP_ENTRY LastValidEntry; 667 ULONG32 NumberOfUnCommittedPages; 668 ULONG32 NumberOfUnCommittedRanges; 669 UINT16 SegmentAllocatorBackTraceIndex; 670 UINT16 Reserved; 671 LIST_ENTRY UCRSegmentList; 672 }; 673 }; 674 ULONG32 Flags; 675 ULONG32 ForceFlags; 676 ULONG32 CompatibilityFlags; 677 ULONG32 EncodeFlagMask; 678 HEAP_ENTRY Encoding; 679 ULONG32 Interceptor; 680 ULONG32 VirtualMemoryThreshold; 681 ULONG32 Signature; 682 #if defined(_M_X64) 683 UINT8 _PADDING0_[4]; 684 #endif 685 WPARAM SegmentReserve; 686 WPARAM SegmentCommit; 687 WPARAM DeCommitFreeBlockThreshold; 688 WPARAM DeCommitTotalFreeThreshold; 689 WPARAM TotalFreeSize; 690 WPARAM MaximumAllocationSize; 691 UINT16 ProcessHeapsListIndex; 692 UINT16 HeaderValidateLength; 693 #if defined(_M_X64) 694 UINT8 _PADDING1_[4]; 695 #endif 696 PVOID HeaderValidateCopy; 697 UINT16 NextAvailableTagIndex; 698 UINT16 MaximumTagIndex; 699 #if defined(_M_X64) 700 UINT8 _PADDING2_[4]; 701 #endif 702 PHEAP_TAG_ENTRY TagEntries; 703 LIST_ENTRY UCRList; 704 WPARAM AlignRound; 705 WPARAM AlignMask; 706 LIST_ENTRY VirtualAllocdBlocks; 707 LIST_ENTRY SegmentList; 708 UINT16 AllocatorBackTraceIndex; 709 UINT8 _PADDING03_[2]; 710 ULONG32 NonDedicatedListLength; 711 PVOID BlocksIndex; 712 PVOID UCRIndex; 713 PHEAP_PSEUDO_TAG_ENTRY PseudoTagEntries; 714 LIST_ENTRY FreeLists; 715 PHEAP_LOCK LockVariable; 716 LONG32 (WINAPI * CommitRoutine) (PVOID, PVOID *, WPARAM *); 717 RTL_RUN_ONCE StackTraceInitVar; 718 RTL_HEAP_MEMORY_LIMIT_DATA CommitLimitData; 719 PVOID FrontEndHeap; 720 UINT16 FrontHeapLockCount; 721 UINT8 FrontEndHeapType; 722 UINT8 RequestedFrontEndHeapType; 723 #if defined(_M_X64) 724 UINT8 _PADDING4_[4]; 725 #endif 726 PUINT16 FrontEndHeapUsageData; 727 UINT16 FrontEndHeapMaximumIndex; 728 #if defined(_M_X64) 729 UINT8 FrontEndHeapStatusBitmap[129]; 730 #else 731 UINT8 FrontEndHeapStatusBitmap[257]; 732 #endif 733 #if defined(_M_X64) 734 UINT8 _PADDING5_[5]; 735 #else 736 UINT8 _PADDING1_[1]; 737 #endif 738 HEAP_COUNTERS Counters; 739 HEAP_TUNING_PARAMETERS TuningParameters; 740 } HEAP, *PHEAP; 741 742 typedef struct _HEAP_ENTRY_EXTRA { 743 union { 744 struct { 745 UINT16 AllocatorBackTraceIndex; 746 UINT16 TagIndex; 747 #if defined(_M_X64) 748 UINT8 _PADDING0_[4]; 749 #endif 750 WPARAM Settable; 751 }; 752 #if defined(_M_X64) 753 struct { 754 UINT64 ZeroInit; 755 UINT64 ZeroInit1; 756 }; 757 #else 758 UINT64 ZeroInit; 759 #endif 760 }; 761 } HEAP_ENTRY_EXTRA, *PHEAP_ENTRY_EXTRA; 762 763 typedef struct _HEAP_VIRTUAL_ALLOC_ENTRY { 764 LIST_ENTRY Entry; 765 HEAP_ENTRY_EXTRA ExtraStuff; 766 WPARAM CommitSize; 767 WPARAM ReserveSize; 768 HEAP_ENTRY BusyBlock; 769 } HEAP_VIRTUAL_ALLOC_ENTRY, *PHEAP_VIRTUAL_ALLOC_ENTRY; 770 771 typedef struct _LFH_BLOCK_ZONE { 772 LIST_ENTRY ListEntry; 773 LONG NextIndex; 774 /* // Win 7 775 PVOID FreePointer; 776 PVOID Limit; 777 */ 778 } LFH_BLOCK_ZONE, *PLFH_BLOCK_ZONE; 779 780 typedef struct _HEAP_USERDATA_OFFSETS { 781 union { 782 UINT32 StrideAndOffset; 783 struct { 784 UINT16 FirstAllocationOffset; 785 UINT16 BlockStride; 786 }; 787 }; 788 } HEAP_USERDATA_OFFSETS, *PHEAP_USERDATA_OFFSETS; 789 790 typedef struct _RTL_BITMAP_EX { 791 WPARAM SizeOfBitMap; 792 WPARAM *Buffer; 793 } RTL_BITMAP_EX, *PRTL_BITMAP_EX; 794 795 typedef struct _HEAP_USERDATA_HEADER { 796 union { 797 SINGLE_LIST_ENTRY SFreeListEntry; 798 PHEAP_SUBSEGMENT SubSegment; 799 }; 800 PVOID Reserved; 801 union { 802 UINT32 SizeIndexAndPadding; 803 struct { 804 UCHAR SizeIndex; 805 UCHAR GuardPagePresent; 806 UINT16 PaddingBytes; 807 }; 808 }; 809 ULONG Signature; 810 HEAP_USERDATA_OFFSETS EncodedOffsets; 811 RTL_BITMAP_EX BusyBitmap; 812 WPARAM BitmapData; 813 } HEAP_USERDATA_HEADER, *PHEAP_USERDATA_HEADER; 814 815 816 typedef struct _HEAP_SUBSEGMENT *PHEAP_SUBSEGMENT; 817 typedef struct _HEAP_LOCAL_SEGMENT_INFO { 818 PHEAP_LOCAL_DATA LocalData; 819 PHEAP_SUBSEGMENT ActiveSubsegment; 820 PHEAP_SUBSEGMENT CachedItems[16]; 821 SLIST_HEADER SListHeader; 822 HEAP_BUCKET_COUNTERS Counters; 823 ULONG LastOpSequence; 824 UINT16 BucketIndex; 825 UINT16 LastUsed; 826 UINT16 NoThrashCount; 827 } HEAP_LOCAL_SEGMENT_INFO, *PHEAP_LOCAL_SEGMENT_INFO; 828 829 typedef struct _HEAP_SUBSEGMENT { 830 PHEAP_LOCAL_SEGMENT_INFO LocalInfo; 831 PHEAP_USERDATA_HEADER UserBlocks; 832 SLIST_HEADER DelayFreeList; 833 INTERLOCK_SEQ AggregateExchg; 834 union { 835 struct { 836 WORD BlockSize; 837 WORD Flags; 838 WORD BlockCount; 839 UINT8 SizeIndex; 840 UINT8 AffinityIndex; 841 }; 842 ULONG Alignment[2]; 843 }; 844 ULONG Lock; 845 SINGLE_LIST_ENTRY SFreeListEntry; 846 } HEAP_SUBSEGMENT, *PHEAP_SUBSEGMENT; 847 848 typedef struct _HEAP_LFH_MEM_POLICIES { 849 union { 850 ULONG AllPolicies; 851 union { 852 UINT8 DisableAffinity : 1; 853 UINT8 SlowSubsegmentGrowth : 1; 854 ULONG Spare : 30; 855 }; 856 }; 857 } HEAP_LFH_MEM_POLICIES, *PHEAP_LFH_MEM_POLICIES; 858 859 typedef struct _HEAP_LOCAL_DATA { 860 SLIST_HEADER DeletedSubSegments; 861 PLFH_BLOCK_ZONE CrtZone; 862 PLFH_HEAP LowFragHeap; 863 ULONG Sequence; 864 //HEAP_LOCAL_SEGMENT_INFO SegmentInfo[128]; // Only on Win7 865 } HEAP_LOCAL_DATA, *PHEAP_LOCAL_DATA; 866 867 typedef struct _HEAP_BUCKET { 868 WORD BlockUnits; 869 UINT8 SizeIndex; 870 union { 871 BYTE Flags; 872 union { 873 BYTE UseAffinity : 1; 874 BYTE DebugFlags : 2; 875 }; 876 }; 877 } HEAP_BUCKET, *PHEAP_BUCKET; 878 879 typedef struct _HEAP_BUCKET_RUN_INFO { 880 union { 881 struct { 882 ULONG Bucket; 883 ULONG RunLength; 884 }; 885 UINT64 Aggregate64; 886 }; 887 } HEAP_BUCKET_RUN_INFO, *PHEAP_BUCKET_RUN_INFO; 888 889 typedef struct _USER_MEMORY_CACHE_ENTRY { 890 SLIST_HEADER UserBlocks; 891 ULONG AvailableBlocks; 892 ULONG MinimumDepth; 893 ULONG CacheShiftThreshold; 894 USHORT Allocations; 895 USHORT Frees; 896 USHORT CacheHits; 897 } USER_MEMORY_CACHE_ENTRY, *PUSER_MEMORY_CACHE_ENTRY; 898 899 typedef struct _LFH_HEAP { 900 RTL_SRWLOCK Lock; 901 LIST_ENTRY SubSegmentZones; 902 PVOID Heap; 903 PVOID NextSegmentInfoArrayAddress; 904 PVOID FirstUncommittedAddress; 905 PVOID ReservedAddressLimit; 906 ULONG SegmentCreate; 907 ULONG SegmentDelete; 908 ULONG MinimumCacheDepth; 909 ULONG CacheShiftThreshold; 910 WPARAM SizeInCache; 911 HEAP_BUCKET_RUN_INFO RunInfo; 912 USER_MEMORY_CACHE_ENTRY UserBlockCache[12]; 913 HEAP_LFH_MEM_POLICIES MemoryPolicies; 914 HEAP_BUCKET Buckets[129]; 915 PHEAP_LOCAL_SEGMENT_INFO SegmentInfoArrays[129]; 916 PHEAP_LOCAL_SEGMENT_INFO AffinitizedInfoArrays[129]; 917 PSEGMENT_HEAP SegmentAllocator; 918 HEAP_LOCAL_DATA LocalData[1]; 919 } LFH_HEAP, *PLFH_HEAP; 920 921 typedef struct _HeapBlockBasicInfo { 922 WPARAM size; 923 WPARAM flags; 924 WPARAM extra; 925 WPARAM address; 926 } HeapBlockBasicInfo, *PHeapBlockBasicInfo; 927 928 typedef struct _HeapBlockExtraInfo { // think of extra stuff to put here 929 WPARAM heap; 930 WPARAM segment; 931 WPARAM unusedBytes; 932 USHORT granularity; 933 } HeapBlockExtraInfo, *PHeapBlockExtraInfo; 934 935 typedef struct _HeapBlock { 936 ULONG_PTR dwAddress; 937 SIZE_T dwSize; 938 DWORD dwFlags; 939 SIZE_T index; 940 PHeapBlockExtraInfo extraInfo; 941 } HeapBlock, *PHeapBlock; 942 943 typedef struct _DEBUG_BUFFER { 944 HANDLE SectionHandle; 945 PVOID SectionBase; 946 PVOID RemoteSectionBase; 947 WPARAM SectionBaseDelta; 948 HANDLE EventPairHandle; 949 HANDLE RemoteEventPairHandle; 950 HANDLE RemoteProcessId; 951 HANDLE RemoteThreadHandle; 952 ULONG InfoClassMask; 953 SIZE_T SizeOfInfo; 954 SIZE_T AllocatedSize; 955 SIZE_T SectionSize; 956 PVOID ModuleInformation; 957 PVOID BackTraceInformation; 958 PVOID HeapInformation; 959 PVOID LockInformation; 960 PVOID SpecificHeap; 961 HANDLE RemoteProcessHandle; 962 PVOID VerifierOptions; 963 PVOID ProcessHeap; 964 HANDLE CriticalSectionHandle; 965 HANDLE CriticalSectionOwnerThread; 966 PVOID Reserved[4]; 967 } DEBUG_BUFFER, *PDEBUG_BUFFER; 968 969 970 typedef struct _DEBUG_HEAP_INFORMATION { 971 PVOID Base; 972 DWORD Flags; 973 USHORT Granularity; 974 USHORT CreatorBackTraceIndex; 975 SIZE_T Allocated; 976 SIZE_T Committed; 977 DWORD TagCount; 978 DWORD BlockCount; 979 DWORD PseudoTagCount; 980 DWORD PseudoTagGranularity; 981 DWORD Reserved[5]; 982 PVOID Tags; 983 PVOID Blocks; 984 } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; 985 986 typedef struct _HeapInformation { 987 DWORD count; 988 DEBUG_HEAP_INFORMATION heaps[/* count */]; 989 } HeapInformation, *PHeapInformation; 990 991 PDEBUG_BUFFER (NTAPI *RtlCreateQueryDebugBuffer)( 992 IN DWORD Size, 993 IN BOOLEAN EventPair 994 ); 995 996 NTSTATUS (NTAPI *RtlQueryProcessDebugInformation)( 997 IN DWORD ProcessId, 998 IN DWORD DebugInfoClassMask, 999 IN OUT PDEBUG_BUFFER DebugBuffer 1000 ); 1001 1002 NTSTATUS (NTAPI *RtlDestroyQueryDebugBuffer)( 1003 IN PDEBUG_BUFFER DebugBuffer 1004 ); 1005 1006 __kernel_entry NTSTATUS (NTAPI *w32_NtQueryInformationProcess)( 1007 IN HANDLE ProcessHandle, 1008 IN PROCESSINFOCLASS ProcessInformationClass, 1009 OUT PVOID ProcessInformation, 1010 IN ULONG ProcessInformationLength, 1011 OUT PULONG ReturnLength 1012 ); 1013 #endif