Exploit開發系列教程-Heap

wyzsk發表於2020-08-19
作者: P3nro5e · 2015/07/20 14:38

0x00 Heap


當程式開始執行時,堆管理器會建立一個新的堆,其被稱為程式的預設堆。c/c++應用程式也會建立所謂的CRT堆 (在進行與new/delete、 malloc/free有關的操作及涉及他們的變數時會使用到)。透過HeapCreate API函式也可以建立其它的堆。堆管理器分為:前端分配器(Front End Allocator)和後端分配器 (Back End Allocator)。

0x01 前端分配器


前端分配器(Front End Allocator)是後端分配器(Back End Allocator)的一種抽象最佳化層。不同的使用案例會涉及到不同型別的前端分配器。前端分配器為:

  1. 旁視列表(Look aside list,LF)前端分配器
  2. 低碎片堆(Low fragmentation ,LF)前端分配器

LAL是一個由128個連結串列組成的表.每個列表含有特定大小的空閒塊,其始於16位元組。每個塊的大小包含後設資料的8個位元組,它被使用於管理塊。在決定所給出大小的列表中,求其索引值的公式為 index = ceil((size + 8)/8) – 1,”+8”是用於後設資料的計數。索引值總為正。

從Windows Vista開始,就沒再使用LAL前端分配器,取而代之的是使用LF 前端分配器。 LF前端分配器非常複雜,主要是試圖透過分配最小的記憶體塊(具有足夠大小來容納被請求大小的資料)來減少堆碎片。

0x02 後端分配器


如果前端分配器不能滿足分配的請求,則請求會被髮送到後端分配器。

在Windows XP中,後端分配器使用一個與前端分配器相似的表。

索引0的連結串列含有空閒塊,其大小大於1016位元組並且小於或等於虛擬分配的限制大小(0x7FFF0位元組)。

塊在該列表中按大小升序排列。索引1閒置,通常索引x包含大小為8x的空閒塊。當需要一個已給出大小但是無法得到的塊時,後端分配器會試圖將更大的塊分割為所需大小的塊。相對的處理操作,也被稱作堆合併( heap coalescing):當某個塊被釋放時,堆管理器可能會檢查它以及跟它鄰近的塊。並且如果其中一個塊或兩個塊是空閒狀態時,空閒塊將可能被合併為單一的塊。這樣做將會減少堆碎片。堆管理器分配的堆塊大小大於0x7FFF0位元組時,堆管理器會將分配請求傳送到虛擬記憶體管理器並讓已分配的塊持續存在於一個被稱作虛擬分配列表(virtual allocation list)的表上。

在windows 7中,不再有特定大小的空閒列表。Windows 7使用一個單一的空閒列表,它含有所有按大小升序排列的塊和另一節點(屬於typeListHint)的列表(指向空閒列表中的節點)並且被使用來找到恰當大小的節點來滿足分配請求。

0x03 堆(記憶體)段


堆管理器從Windows 虛擬記憶體管理器中請求其使用的所有記憶體。堆管理器請求大的堆塊的虛擬記憶體,其被稱作堆(記憶體)段。堆管理器使用那些段來分配所有的塊和內部的bookkeeping結構。當新的段被建立時,只保留少部分被提交的記憶體。當需要更多的記憶體時,另一部分的記憶體會被提交。最後,在當前段中沒有足夠的未被提交的空間時,會建立新的段,其大小為前一個段的兩倍。如果沒有足夠大的記憶體,那麼將建立更小的段。如果沒有用於建立最小段的空間,那麼將會返回錯誤。

0x04 分析堆


偏移0x90的PEB中包含堆:

#!bash
0:001> dt _PEB @$peb
 ntdll!_PEB
 +0x000 InheritedAddressSpace : 0 ''
 +0x001 ReadImageFileExecOptions : 0 ''
 +0x002 BeingDebugged    : 0x1 ''
 +0x003 BitField         : 0x8 ''
 +0x003 ImageUsesLargePages : 0y0
 +0x003 IsProtectedProcess : 0y0
 +0x003 IsLegacyProcess  : 0y0
 +0x003 IsImageDynamicallyRelocated : 0y1
 +0x003 SkipPatchingUser32Forwarders : 0y0
 +0x003 SpareBits        : 0y000
 +0x004 Mutant           : 0xffffffff Void
 +0x008 ImageBaseAddress : 0x004a0000 Void
 +0x00c Ldr              : 0x77eb0200 _PEB_LDR_DATA
 +0x010 ProcessParameters : 0x002d13c8 _RTL_USER_PROCESS_PARAMETERS
 +0x014 SubSystemData    : (null)
 +0x018 ProcessHeap      : 0x002d0000 Void
 +0x01c FastPebLock      : 0x77eb2100 _RTL_CRITICAL_SECTION
 +0x020 AtlThunkSListPtr : (null)
 +0x024 IFEOKey          : (null)
 +0x028 CrossProcessFlags : 0
 +0x028 ProcessInJob     : 0y0
 +0x028 ProcessInitializing : 0y0
 +0x028 ProcessUsingVEH  : 0y0
 +0x028 ProcessUsingVCH  : 0y0
 +0x028 ProcessUsingFTH  : 0y0
 +0x028 ReservedBits0    : 0y000000000000000000000000000 (0)
 +0x02c KernelCallbackTable : 0x760eb9f0 Void
 +0x02c UserSharedInfoPtr : 0x760eb9f0 Void
 +0x030 SystemReserved   : [1] 0
 +0x034 AtlThunkSListPtr32 : 0
 +0x038 ApiSetMap        : 0x00040000 Void
 +0x03c TlsExpansionCounter : 0
 +0x040 TlsBitmap        : 0x77eb4250 Void
 +0x044 TlsBitmapBits    : [2] 0x1fffffff
 +0x04c ReadOnlySharedMemoryBase : 0x7efe0000 Void
 +0x050 HotpatchInformation : (null)
 +0x054 ReadOnlyStaticServerData : 0x7efe0a90  -> (null)
 +0x058 AnsiCodePageData : 0x7efb0000 Void
 +0x05c OemCodePageData  : 0x7efc0228 Void
 +0x060 UnicodeCaseTableData : 0x7efd0650 Void
 +0x064 NumberOfProcessors : 8
 +0x068 NtGlobalFlag     : 0x70
 +0x070 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
 +0x078 HeapSegmentReserve : 0x100000
 +0x07c HeapSegmentCommit : 0x2000
 +0x080 HeapDeCommitTotalFreeThreshold : 0x10000
 +0x084 HeapDeCommitFreeBlockThreshold : 0x1000
 +0x088 NumberOfHeaps    : 7
 +0x08c MaximumNumberOfHeaps : 0x10
 +0x090 ProcessHeaps     : 0x77eb4760  -> 0x002d0000 Void
 +0x094 GdiSharedHandleTable : (null)
 +0x098 ProcessStarterHelper : (null)
 +0x09c GdiDCAttributeList : 0
 +0x0a0 LoaderLock       : 0x77eb20c0 _RTL_CRITICAL_SECTION
 +0x0a4 OSMajorVersion   : 6
 +0x0a8 OSMinorVersion   : 1
 +0x0ac OSBuildNumber    : 0x1db1
 +0x0ae OSCSDVersion     : 0x100
 +0x0b0 OSPlatformId     : 2
 +0x0b4 ImageSubsystem   : 2
 +0x0b8 ImageSubsystemMajorVersion : 6
 +0x0bc ImageSubsystemMinorVersion : 1
 +0x0c0 ActiveProcessAffinityMask : 0xff
 +0x0c4 GdiHandleBuffer  : [34] 0
 +0x14c PostProcessInitRoutine : (null)
 +0x150 TlsExpansionBitmap : 0x77eb4248 Void
 +0x154 TlsExpansionBitmapBits : [32] 1
 +0x1d4 SessionId        : 1
 +0x1d8 AppCompatFlags   : _ULARGE_INTEGER 0x0
 +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
 +0x1e8 pShimData        : (null)
 +0x1ec AppCompatInfo    : (null)
 +0x1f0 CSDVersion       : _UNICODE_STRING "Service Pack 1"
 +0x1f8 ActivationContextData : 0x00060000 _ACTIVATION_CONTEXT_DATA
 +0x1fc ProcessAssemblyStorageMap : 0x002d4988 _ASSEMBLY_STORAGE_MAP
 +0x200 SystemDefaultActivationContextData : 0x00050000 _ACTIVATION_CONTEXT_DATA
 +0x204 SystemAssemblyStorageMap : (null)
 +0x208 MinimumStackCommit : 0
 +0x20c FlsCallback      : 0x002d5cb8 _FLS_CALLBACK_INFO
 +0x210 FlsListHead      : _LIST_ENTRY [ 0x2d5a98 - 0x2d5a98 ]
 +0x218 FlsBitmap        : 0x77eb4240 Void
 +0x21c FlsBitmapBits    : [4] 0x1f
 +0x22c FlsHighIndex     : 4
 +0x230 WerRegistrationData : (null)
 +0x234 WerShipAssertPtr : (null)
 +0x238 pContextData     : 0x00070000 Void
 +0x23c pImageHeaderHash : (null)
 +0x240 TracingFlags     : 0
 +0x240 HeapTracingEnabled : 0y0
 +0x240 CritSecTracingEnabled : 0y0
 +0x240 SpareTracingBits : 0y000000000000000000000000000000 (0)

有意思的部分如下:

#!bash
+0x088 NumberOfHeaps    : 7
.
+0x090 ProcessHeaps     : 0x77eb4760  -> 0x002d0000 Void

ProcessHeaps是儲存指向HEAP 結構指標的陣列。 我們來觀察該陣列:

#!bash
0:001> dd 0x77eb4760
 77eb4760  002d0000 005b0000 01e30000 01f90000
 77eb4770  02160000 02650000 02860000 00000000
 77eb4780  00000000 00000000 00000000 00000000
 77eb4790  00000000 00000000 00000000 00000000
 77eb47a0  00000000 00000000 00000000 00000000
 77eb47b0  00000000 00000000 00000000 00000000
 77eb47c0  00000000 00000000 00000000 00000000
 77eb47d0  00000000 00000000 00000000 00000000

我們可以展示出第一個堆的結構資訊如下:

#!bash
0:001> dt _HEAP 2d0000
 ntdll!_HEAP
 +0x000 Entry            : _HEAP_ENTRY
 +0x008 SegmentSignature : 0xffeeffee
 +0x00c SegmentFlags     : 0
 +0x010 SegmentListEntry : _LIST_ENTRY [ 0x2d00a8 - 0x2d00a8 ]
 +0x018 Heap             : 0x002d0000 _HEAP
 +0x01c BaseAddress      : 0x002d0000 Void
 +0x020 NumberOfPages    : 0x100
 +0x024 FirstEntry       : 0x002d0588 _HEAP_ENTRY
 +0x028 LastValidEntry   : 0x003d0000 _HEAP_ENTRY
 +0x02c NumberOfUnCommittedPages : 0xd0
 +0x030 NumberOfUnCommittedRanges : 1
 +0x034 SegmentAllocatorBackTraceIndex : 0
 +0x036 Reserved         : 0
 +0x038 UCRSegmentList   : _LIST_ENTRY [ 0x2ffff0 - 0x2ffff0 ]
 +0x040 Flags            : 0x40000062
 +0x044 ForceFlags       : 0x40000060
 +0x048 CompatibilityFlags : 0
 +0x04c EncodeFlagMask   : 0x100000
 +0x050 Encoding         : _HEAP_ENTRY
 +0x058 PointerKey       : 0x7d37bf2e
 +0x05c Interceptor      : 0
 +0x060 VirtualMemoryThreshold : 0xfe00
 +0x064 Signature        : 0xeeffeeff
 +0x068 SegmentReserve   : 0x100000
 +0x06c SegmentCommit    : 0x2000
 +0x070 DeCommitFreeBlockThreshold : 0x200
 +0x074 DeCommitTotalFreeThreshold : 0x2000
 +0x078 TotalFreeSize    : 0x1b01
 +0x07c MaximumAllocationSize : 0x7ffdefff
 +0x080 ProcessHeapsListIndex : 1
 +0x082 HeaderValidateLength : 0x138
 +0x084 HeaderValidateCopy : (null)
 +0x088 NextAvailableTagIndex : 0
 +0x08a MaximumTagIndex  : 0
 +0x08c TagEntries       : (null)
 +0x090 UCRList          : _LIST_ENTRY [ 0x2fffe8 - 0x2fffe8 ]
 +0x098 AlignRound       : 0x17
 +0x09c AlignMask        : 0xfffffff8
 +0x0a0 VirtualAllocdBlocks : _LIST_ENTRY [ 0x2d00a0 - 0x2d00a0 ]
 +0x0a8 SegmentList      : _LIST_ENTRY [ 0x2d0010 - 0x2d0010 ]
 +0x0b0 AllocatorBackTraceIndex : 0
 +0x0b4 NonDedicatedListLength : 0
 +0x0b8 BlocksIndex      : 0x002d0150 Void
 +0x0bc UCRIndex         : 0x002d0590 Void
 +0x0c0 PseudoTagEntries : (null)
 +0x0c4 FreeLists        : _LIST_ENTRY [ 0x2f0a60 - 0x2f28a0 ]
 +0x0cc LockVariable     : 0x002d0138 _HEAP_LOCK
 +0x0d0 CommitRoutine    : 0x7d37bf2e     long  +7d37bf2e
 +0x0d4 FrontEndHeap     : (null)
 +0x0d8 FrontHeapLockCount : 0
 +0x0da FrontEndHeapType : 0 ''
 +0x0dc Counters         : _HEAP_COUNTERS
 +0x130 TuningParameters : _HEAP_TUNING_PARAMETERS

透過使用mona.py來獲取關於堆的資訊:

#!bash
0:003> !py mona heap
Hold on...
[+] Command used:
!py mona.py heap
Peb : 0x7efde000, NtGlobalFlag : 0x00000070
Heaps:
------
0x005a0000 (1 segment(s) : 0x005a0000) * Default process heap  Encoding key: 0x171f4fc1
0x00170000 (2 segment(s) : 0x00170000,0x045a0000)   Encoding key: 0x21f9a301
0x00330000 (1 segment(s) : 0x00330000)   Encoding key: 0x1913b812
0x001d0000 (2 segment(s) : 0x001d0000,0x006a0000)   Encoding key: 0x547202aa
0x020c0000 (1 segment(s) : 0x020c0000)   Encoding key: 0x0896f86d
0x02c50000 (1 segment(s) : 0x02c50000)   Encoding key: 0x21f9a301
0x02b10000 (2 segment(s) : 0x02b10000,0x04450000)   Encoding key: 0x757121ce

Please specify a valid searchtype -t
Valid values are :
   lal
   lfh
   all
   segments
   chunks
   layout
   fea
   bea

[+] This mona.py action took 0:00:00.012000

我們可以看到7個堆和使用mona指令碼展示出的每個堆段。

我們也可以使用!heap來觀察堆段:

#!bash
0:003> !heap -m
 Index   Address  Name      Debugging options enabled
 1:   005a0000
 Segment at 005a0000 to 006a0000 (0005f000 bytes committed)
 2:   00170000
 Segment at 00170000 to 00180000 (00010000 bytes committed)
 Segment at 045a0000 to 046a0000 (0000b000 bytes committed)
 3:   00330000
 Segment at 00330000 to 00370000 (00006000 bytes committed)
 4:   001d0000
 Segment at 001d0000 to 001e0000 (0000b000 bytes committed)
 Segment at 006a0000 to 007a0000 (0002e000 bytes committed)
 5:   020c0000
 Segment at 020c0000 to 02100000 (00001000 bytes committed)
 6:   02c50000
 Segment at 02c50000 to 02c90000 (00025000 bytes committed)
 7:   02b10000
 Segment at 02b10000 to 02b20000 (0000e000 bytes committed)
 Segment at 04450000 to 04550000 (00033000 bytes committed)

“-m”選項也被用於展示段資訊。

觀察特定堆(0x5a0000)段,我們可以使用:

#!bash
0:003> !py mona heap -h 5a0000 -t segments
Hold on...
[+] Command used:
!py mona.py heap -h 5a0000 -t segments
Peb : 0x7efde000, NtGlobalFlag : 0x00000070
Heaps:
------
0x005a0000 (1 segment(s) : 0x005a0000) * Default process heap  Encoding key: 0x171f4fc1
0x00170000 (2 segment(s) : 0x00170000,0x045a0000)   Encoding key: 0x21f9a301
0x00330000 (1 segment(s) : 0x00330000)   Encoding key: 0x1913b812
0x001d0000 (2 segment(s) : 0x001d0000,0x006a0000)   Encoding key: 0x547202aa
0x020c0000 (1 segment(s) : 0x020c0000)   Encoding key: 0x0896f86d
0x02c50000 (1 segment(s) : 0x02c50000)   Encoding key: 0x21f9a301
0x02b10000 (2 segment(s) : 0x02b10000,0x04450000)   Encoding key: 0x757121ce


[+] Processing heap 0x005a0000
Segment List for heap 0x005a0000:
---------------------------------
Segment 0x005a0588 - 0x006a0000 (FirstEntry: 0x005a0588 - LastValidEntry: 0x006a0000): 0x000ffa78 bytes

[+] This mona.py action took 0:00:00.014000

以下是我們要了解到的特定資訊以及透過使用mona來展示的所有堆塊的概要。我們也可以省略掉“-h 5a0000”選項的使用來得到所有堆段:

#!bash
0:003> !py mona heap -t segments
Hold on...
[+] Command used:
!py mona.py heap -t segments
Peb : 0x7efde000, NtGlobalFlag : 0x00000070
Heaps:
------
0x005a0000 (1 segment(s) : 0x005a0000) * Default process heap  Encoding key: 0x171f4fc1
0x00170000 (2 segment(s) : 0x00170000,0x045a0000)   Encoding key: 0x21f9a301
0x00330000 (1 segment(s) : 0x00330000)   Encoding key: 0x1913b812
0x001d0000 (2 segment(s) : 0x001d0000,0x006a0000)   Encoding key: 0x547202aa
0x020c0000 (1 segment(s) : 0x020c0000)   Encoding key: 0x0896f86d
0x02c50000 (1 segment(s) : 0x02c50000)   Encoding key: 0x21f9a301
0x02b10000 (2 segment(s) : 0x02b10000,0x04450000)   Encoding key: 0x757121ce


[+] Processing heap 0x005a0000
Segment List for heap 0x005a0000:
---------------------------------
Segment 0x005a0588 - 0x006a0000 (FirstEntry: 0x005a0588 - LastValidEntry: 0x006a0000): 0x000ffa78 bytes

[+] Processing heap 0x00170000
Segment List for heap 0x00170000:
---------------------------------
Segment 0x00170588 - 0x00180000 (FirstEntry: 0x00170588 - LastValidEntry: 0x00180000): 0x0000fa78 bytes
Segment 0x045a0000 - 0x046a0000 (FirstEntry: 0x045a0040 - LastValidEntry: 0x046a0000): 0x00100000 bytes

[+] Processing heap 0x00330000
Segment List for heap 0x00330000:
---------------------------------
Segment 0x00330588 - 0x00370000 (FirstEntry: 0x00330588 - LastValidEntry: 0x00370000): 0x0003fa78 bytes

[+] Processing heap 0x001d0000
Segment List for heap 0x001d0000:
---------------------------------
Segment 0x001d0588 - 0x001e0000 (FirstEntry: 0x001d0588 - LastValidEntry: 0x001e0000): 0x0000fa78 bytes
Segment 0x006a0000 - 0x007a0000 (FirstEntry: 0x006a0040 - LastValidEntry: 0x007a0000): 0x00100000 bytes

[+] Processing heap 0x020c0000
Segment List for heap 0x020c0000:
---------------------------------
Segment 0x020c0588 - 0x02100000 (FirstEntry: 0x020c0588 - LastValidEntry: 0x02100000): 0x0003fa78 bytes

[+] Processing heap 0x02c50000
Segment List for heap 0x02c50000:
---------------------------------
Segment 0x02c50588 - 0x02c90000 (FirstEntry: 0x02c50588 - LastValidEntry: 0x02c90000): 0x0003fa78 bytes

[+] Processing heap 0x02b10000
Segment List for heap 0x02b10000:
---------------------------------
Segment 0x02b10588 - 0x02b20000 (FirstEntry: 0x02b10588 - LastValidEntry: 0x02b20000): 0x0000fa78 bytes
Segment 0x04450000 - 0x04550000 (FirstEntry: 0x04450040 - LastValidEntry: 0x04550000): 0x00100000 bytes

[+] This mona.py action took 0:00:00.017000

mona.py呼叫記憶體堆塊中的已分配塊。在段中觀察堆塊:

#!bash
0:003> !py mona heap -h 5a0000 -t chunks
Hold on...
[+] Command used:
!py mona.py heap -h 5a0000 -t chunks
Peb : 0x7efde000, NtGlobalFlag : 0x00000070
Heaps:
------
0x005a0000 (1 segment(s) : 0x005a0000) * Default process heap  Encoding key: 0x171f4fc1
0x00170000 (2 segment(s) : 0x00170000,0x045a0000)   Encoding key: 0x21f9a301
0x00330000 (1 segment(s) : 0x00330000)   Encoding key: 0x1913b812
0x001d0000 (2 segment(s) : 0x001d0000,0x006a0000)   Encoding key: 0x547202aa
0x020c0000 (1 segment(s) : 0x020c0000)   Encoding key: 0x0896f86d
0x02c50000 (1 segment(s) : 0x02c50000)   Encoding key: 0x21f9a301
0x02b10000 (2 segment(s) : 0x02b10000,0x04450000)   Encoding key: 0x757121ce

[+] Preparing output file 'heapchunks.txt'
    - (Re)setting logfile heapchunks.txt
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.

[+] Processing heap 0x005a0000
Segment List for heap 0x005a0000:
---------------------------------
Segment 0x005a0588 - 0x006a0000 (FirstEntry: 0x005a0588 - LastValidEntry: 0x006a0000): 0x000ffa78 bytes
    Nr of chunks : 2237 
    _HEAP_ENTRY  psize   size  unused  UserPtr   UserSize
       005a0588  00000  00250   00001  005a0590  0000024f (591) (Fill pattern,Extra present,Busy) 
       005a07d8  00250  00030   00018  005a07e0  00000018 (24) (Fill pattern,Extra present,Busy) 
       005a0808  00030  00bb8   0001a  005a0810  00000b9e (2974) (Fill pattern,Extra present,Busy) 
       005a13c0  00bb8  01378   0001c  005a13c8  0000135c (4956) (Fill pattern,Extra present,Busy) 
       005a2738  01378  00058   0001c  005a2740  0000003c (60) (Fill pattern,Extra present,Busy) 
       005a2790  00058  00048   00018  005a2798  00000030 (48) (Fill pattern,Extra present,Busy) 
       005a27d8  00048  00090   00018  005a27e0  00000078 (120) (Fill pattern,Extra present,Busy) 
       005a2868  00090  00090   00018  005a2870  00000078 (120) (Fill pattern,Extra present,Busy) 
       005a28f8  00090  00058   0001c  005a2900  0000003c (60) (Fill pattern,Extra present,Busy) 
       005a2950  00058  00238   00018  005a2958  00000220 (544) (Fill pattern,Extra present,Busy) 
       005a2b88  00238  00060   0001e  005a2b90  00000042 (66) (Fill pattern,Extra present,Busy) 
       <snip>
       005ec530  00038  00048   0001c  005ec538  0000002c (44) (Fill pattern,Extra present,Busy) 
       005ec578  00048  12a68   00000  005ec580  00012a68 (76392) (Fill pattern) 
       005fefe0  12a68  00020   00003  005fefe8  0000001d (29) (Busy) 
       0x005feff8 - 0x006a0000 (end of segment) : 0xa1008 (659464) uncommitted bytes

Heap : 0x005a0000 : VirtualAllocdBlocks : 0 
    Nr of chunks : 0 

[+] This mona.py action took 0:00:02.804000

你也可以使用 !heap來觀察:

#!bash
0:003> !heap -h 5a0000
Index   Address  Name      Debugging options enabled
1:   005a0000
Segment at 005a0000 to 006a0000 (0005f000 bytes committed)
Flags:                40000062
ForceFlags:           40000060
Granularity:          8 bytes
Segment Reserve:      00100000
Segment Commit:       00002000
DeCommit Block Thres: 00000200
DeCommit Total Thres: 00002000
Total Free Size:      00002578
Max. Allocation Size: 7ffdefff
Lock Variable at:     005a0138
Next TagIndex:        0000
Maximum TagIndex:     0000
Tag Entries:          00000000
PsuedoTag Entries:    00000000
Virtual Alloc List:   005a00a0
Uncommitted ranges:   005a0090
FreeList[ 00 ] at 005a00c4: 005ec580 . 005e4f28   (18 blocks)

Heap entries for Segment00 in Heap 005a0000
address: psize . size  flags   state (requested size)
005a0000: 00000 . 00588 [101] - busy (587)
005a0588: 00588 . 00250 [107] - busy (24f), tail fill
005a07d8: 00250 . 00030 [107] - busy (18), tail fill
005a0808: 00030 . 00bb8 [107] - busy (b9e), tail fill
005a13c0: 00bb8 . 01378 [107] - busy (135c), tail fill
005a2738: 01378 . 00058 [107] - busy (3c), tail fill
005a2790: 00058 . 00048 [107] - busy (30), tail fill
005a27d8: 00048 . 00090 [107] - busy (78), tail fill
005a2868: 00090 . 00090 [107] - busy (78), tail fill
005a28f8: 00090 . 00058 [107] - busy (3c), tail fill
005a2950: 00058 . 00238 [107] - busy (220), tail fill
005a2b88: 00238 . 00060 [107] - busy (42), tail fill
<snip>
005ec530: 00038 . 00048 [107] - busy (2c), tail fill
005ec578: 00048 . 12a68 [104] free fill
005fefe0: 12a68 . 00020 [111] - busy (1d)
005ff000:      000a1000      - uncommitted bytes.

新增”stat”選項來展示一些統計資料

#!bash
0:003> !py mona heap -h 5a0000 -t chunks -stat
Hold on...
[+] Command used:
!py mona.py heap -h 5a0000 -t chunks -stat
Peb : 0x7efde000, NtGlobalFlag : 0x00000070
Heaps:
------
0x005a0000 (1 segment(s) : 0x005a0000) * Default process heap  Encoding key: 0x171f4fc1
0x00170000 (2 segment(s) : 0x00170000,0x045a0000)   Encoding key: 0x21f9a301
0x00330000 (1 segment(s) : 0x00330000)   Encoding key: 0x1913b812
0x001d0000 (2 segment(s) : 0x001d0000,0x006a0000)   Encoding key: 0x547202aa
0x020c0000 (1 segment(s) : 0x020c0000)   Encoding key: 0x0896f86d
0x02c50000 (1 segment(s) : 0x02c50000)   Encoding key: 0x21f9a301
0x02b10000 (2 segment(s) : 0x02b10000,0x04450000)   Encoding key: 0x757121ce

[+] Preparing output file 'heapchunks.txt'
    - (Re)setting logfile heapchunks.txt
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.

[+] Processing heap 0x005a0000
Segment List for heap 0x005a0000:
---------------------------------
Segment 0x005a0588 - 0x006a0000 (FirstEntry: 0x005a0588 - LastValidEntry: 0x006a0000): 0x000ffa78 bytes
    Nr of chunks : 2237 
    _HEAP_ENTRY  psize   size  unused  UserPtr   UserSize
    Segment Statistics:
    Size : 0x12a68 (76392) : 1 chunks (0.04 %)
    Size : 0x3980 (14720) : 1 chunks (0.04 %)
    Size : 0x135c (4956) : 1 chunks (0.04 %)
    Size : 0x11f8 (4600) : 1 chunks (0.04 %)
    Size : 0xb9e (2974) : 1 chunks (0.04 %)
    Size : 0xa28 (2600) : 1 chunks (0.04 %)
    <snip>
    Size : 0x6 (6) : 1 chunks (0.04 %)
    Size : 0x4 (4) : 15 chunks (0.67 %)
    Size : 0x1 (1) : 1 chunks (0.04 %)
    Total chunks : 2237


Heap : 0x005a0000 : VirtualAllocdBlocks : 0 
    Nr of chunks : 0 
Global statistics
  Size : 0x12a68 (76392) : 1 chunks (0.04 %)
  Size : 0x3980 (14720) : 1 chunks (0.04 %)
  Size : 0x135c (4956) : 1 chunks (0.04 %)
  Size : 0x11f8 (4600) : 1 chunks (0.04 %)
  Size : 0xb9e (2974) : 1 chunks (0.04 %)
  Size : 0xa28 (2600) : 1 chunks (0.04 %)
  <snip>
  Size : 0x6 (6) : 1 chunks (0.04 %)
  Size : 0x4 (4) : 15 chunks (0.67 %)
  Size : 0x1 (1) : 1 chunks (0.04 %)
  Total chunks : 2237

[+] This mona.py action took 0:00:02.415000

使用mona.py可以觀察到段的塊/堆塊中的字串, BSTRINGs 和 vtable物件。使用“-t layout”選項來了解佈局情況。該功能將資料寫入到檔案heaplayout.txt中。

你可以使用如下額外的選項:

• -v: write the data also in the log window • -fast: skip the discovery of object sizes • -size

相關文章