Recognize all heap regions in process memory tab
@@ -239,6 +239,86 @@ PPH_MEMORY_ITEM PhpSetMemoryRegionType(
return memoryItem;
}
+void PhpUpdateHeapRegions(
+ _In_ PPH_MEMORY_ITEM_LIST List,
+ _In_ HANDLE ProcessHandle
+ )
+{
+ PRTL_DEBUG_INFORMATION debugBuffer = NULL;
+ HANDLE powerRequestHandle = NULL;
+
+ if (WindowsVersion >= WINDOWS_8)
+ {
+ // RtlQueryProcessDebugInformation can cause deadlock on some older versions when querying frozen (suspended) immersive process. (ge0rdi)
+ // A workaround was implemented using PhCreateExecutionRequiredRequest(). (ge0rdi)
+ PhCreateExecutionRequiredRequest(ProcessHandle, &powerRequestHandle);
+ }
+
+ for (ULONG i = 0x10000; ; i *= 2) // based on PhQueryProcessHeapInformation (ge0rdi)
+ {
+ if (!(debugBuffer = RtlCreateQueryDebugBuffer(i, FALSE)))
+ break;
+
+ NTSTATUS status = RtlQueryProcessDebugInformation(
+ List->ProcessId,
+ RTL_QUERY_PROCESS_HEAP_SUMMARY | RTL_QUERY_PROCESS_HEAP_ENTRIES_EX,
+ debugBuffer
+ );
+
+ if (!NT_SUCCESS(status))
+ {
+ RtlDestroyQueryDebugBuffer(debugBuffer);
+ debugBuffer = NULL;
+ }
+
+ if (NT_SUCCESS(status) || status != STATUS_NO_MEMORY)
+ break;
+
+ if (2 * i <= i)
+ break;
+ }
+
+ if (powerRequestHandle)
+ PhDestroyExecutionRequiredRequest(powerRequestHandle);
+
+ if (!debugBuffer)
+ return;
+
+ if (debugBuffer->Heaps)
+ {
+ for (ULONG i = 0; i < debugBuffer->Heaps->NumberOfHeaps; i++)
+ {
+ PRTL_HEAP_INFORMATION heapInfo = &debugBuffer->Heaps->Heaps[i];
+ PPH_MEMORY_ITEM heapMemoryItem;
+
+ if (heapMemoryItem = PhpSetMemoryRegionType(List, heapInfo->BaseAddress, TRUE, HeapRegion))
+ {
+ heapMemoryItem->u.Heap.Index = i;
+
+ for (ULONG j = 0; j < heapInfo->NumberOfEntries; j++)
+ {
+ PRTL_HEAP_ENTRY heapEntry = &heapInfo->Entries[j];
+
+ if (heapEntry->Flags & RTL_HEAP_SEGMENT)
+ {
+ PVOID blockAddress = heapEntry->u.s2.FirstBlock;
+
+ PPH_MEMORY_ITEM memoryItem = PhLookupMemoryItemList(List, blockAddress);
+
+ if (memoryItem && memoryItem->BaseAddress == blockAddress && memoryItem->RegionType == UnknownRegion)
+ {
+ memoryItem->RegionType = HeapSegmentRegion;
+ memoryItem->u.HeapSegment.HeapItem = heapMemoryItem;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ RtlDestroyQueryDebugBuffer(debugBuffer);
+}
+
NTSTATUS PhpUpdateMemoryRegionTypes(
_In_ PPH_MEMORY_ITEM_LIST List,
_In_ HANDLE ProcessHandle
@@ -312,6 +392,8 @@ NTSTATUS PhpUpdateMemoryRegionTypes(
ULONG apiSetMap32;
#endif
+ PhpUpdateHeapRegions(List, ProcessHandle);
+
if (NT_SUCCESS(PhGetProcessBasicInformation(ProcessHandle, &basicInfo)) && basicInfo.PebBaseAddress != 0)
{
// HACK: Windows 10 RS2 and above 'added TEB/PEB sub-VAD segments' and we need to tag individual sections. (dmex)
