阅读:2174回复:0
Exploit开发系列教程-Heap
◆0 Heap
当进程开始运行时,堆管理器会创建一个新的堆,其被称为进程的默认堆。c/c++应用程序也会创建所谓的CRT堆 (在进行与new/delete、 malloc/free有关的操作及涉及他们的变量时会使用到)。通过HeapCreate API函数也可以创建其它的堆。堆管理器分为:前端分配器(Front End Allocator)和后端分配器 (Back End Allocator)。 ◆1 前端分配器 前端分配器(Front End Allocator)是后端分配器(Back End Allocator)的一种抽象优化层。不同的使用案例会涉及到不同类型的前端分配器。前端分配器为: [*]旁视列表(Look aside list,LF)前端分配器 [*]低碎片堆(Low fragmentation ,LF)前端分配器 LAL是一个由128个链表组成的表.每个列表含有特定大小的空闲块,其始于16字节。每个块的大小包含元数据的8个字节,它被使用于管理块。在决定所给出大小的列表中,求其索引值的公式为 index = ceil((size + 8)/8) – 1,”+8”是用于元数据的计数。索引值总为正。 从Windows Vista开始,就没再使用LAL前端分配器,取而代之的是使用LF 前端分配器。 LF前端分配器非常复杂,主要是试图通过分配最小的内存块(具有足够大小来容纳被请求大小的数据)来减少堆碎片。 ◆2 后端分配器 如果前端分配器不能满足分配的请求,则请求会被发送到后端分配器。 在Windows XP中,后端分配器使用一个与前端分配器相似的表。 索引0的链表含有空闲块,其大小大于1016字节并且小于或等于虚拟分配的限制大小(0x7FFF0字节)。 块在该列表中按大小升序排列。索引1闲置,通常索引x包含大小为8x的空闲块。当需要一个已给出大小但是无法得到的块时,后端分配器会试图将更大的块分割为所需大小的块。相对的处理操作,也被称作堆合并( heap coalescing):当某个块被释放时,堆管理器可能会检查它以及跟它邻近的块。并且如果其中一个块或两个块是空闲状态时,空闲块将可能被合并为单一的块。这样做将会减少堆碎片。堆管理器分配的堆块大小大于0x7FFF0字节时,堆管理器会将分配请求发送到虚拟内存管理器并让已分配的块持续存在于一个被称作虚拟分配列表(virtual allocation list)的表上。 在windows 7中,不再有特定大小的空闲列表。Windows 7使用一个单一的空闲列表,它含有所有按大小升序排列的块和另一节点(属于typeListHint)的列表(指向空闲列表中的节点)并且被使用来找到恰当大小的节点来满足分配请求。 ◆3 堆(内存)段 堆管理器从Windows 虚拟内存管理器中请求其使用的所有内存。堆管理器请求大的堆块的虚拟内存,其被称作堆(内存)段。堆管理器使用那些段来分配所有的块和内部的bookkeeping结构。当新的段被创建时,只保留少部分被提交的内存。当需要更多的内存时,另一部分的内存会被提交。最后,在当前段中没有足够的未被提交的空间时,会创建新的段,其大小为前一个段的两倍。如果没有足够大的内存,那么将创建更小的段。如果没有用于创建最小段的空间,那么将会返回错误。 ◆4 分析堆 偏移0x90的PEB中包含堆: #!bash 0:001> dt _PEB @$peb ntdll!_PEB +◆00 InheritedAddressSpace : 0 '' +◆01 ReadImageFileExecOptions : 0 '' +◆02 BeingDebugged : 0x1 '' +◆03 BitField : 0x8 '' +◆03 ImageUsesLargePages : 0y0 +◆03 IsProtectedProcess : 0y0 +◆03 IsLegacyProcess : 0y0 +◆03 IsImageDynamicallyRelocated : 0y1 +◆03 SkipPatchingUser32Forwarders : 0y0 +◆03 SpareBits : 0y000 +◆04 Mutant : 0xffffffff Void +◆08 ImageBaseAddress : ◆04a0000 Void +◆0c Ldr : 0x77eb0200 _PEB_LDR_DATA +◆10 ProcessParameters : ◆02d13c8 _RTL_USER_PROCESS_PARAMETERS +◆14 SubSystemData : (null) +◆18 ProcessHeap : ◆02d0000 Void +◆1c FastPebLock : 0x77eb2100 _RTL_CRITICAL_SECTION +◆20 AtlThunkSListPtr : (null) +◆24 IFEOKey : (null) +◆28 CrossProcessFlags : 0 +◆28 ProcessInJob : 0y0 +◆28 ProcessInitializing : 0y0 +◆28 ProcessUsingVEH : 0y0 +◆28 ProcessUsingVCH : 0y0 +◆28 ProcessUsingFTH : 0y0 +◆28 ReservedBits0 : 0y000000000000000000000000000 (0) +◆2c KernelCallbackTable : 0x760eb9f0 Void +◆2c UserSharedInfoPtr : 0x760eb9f0 Void +◆30 SystemReserved : [1] 0 +◆34 AtlThunkSListPtr32 : 0 +◆38 ApiSetMap : ◆0040000 Void +◆3c TlsExpansionCounter : 0 +◆40 TlsBitmap : 0x77eb4250 Void +◆44 TlsBitmapBits : [2] 0x1fffffff +◆4c ReadOnlySharedMemoryBase : 0x7efe0000 Void +◆50 HotpatchInformation : (null) +◆54 ReadOnlyStaticServerData : 0x7efe0a90 -> (null) +◆58 AnsiCodePageData : 0x7efb0000 Void +◆5c OemCodePageData : 0x7efc0228 Void +◆60 UnicodeCaseTableData : 0x7efd0650 Void +◆64 NumberOfProcessors : 8 +◆68 NtGlobalFlag : 0x70 +◆70 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000 +◆78 HeapSegmentReserve : 0x100000 +◆7c HeapSegmentCommit : 0x2000 +◆80 HeapDeCommitTotalFreeThreshold : 0x10000 +◆84 HeapDeCommitFreeBlockThreshold : 0x1000 +◆88 NumberOfHeaps : 7 +◆8c MaximumNumberOfHeaps : 0x10 +◆90 ProcessHeaps : 0x77eb4760 -> ◆02d0000 Void +◆94 GdiSharedHandleTable : (null) +◆98 ProcessStarterHelper : (null) +◆9c GdiDCAttributeList : 0 +◆a0 LoaderLock : 0x77eb20c0 _RTL_CRITICAL_SECTION +◆a4 OSMajorVersion : 6 +◆a8 OSMinorVersion : 1 +◆ac OSBuildNumber : 0x1db1 +◆ae OSCSDVersion : 0x100 +◆b0 OSPlatformId : 2 +◆b4 ImageSubsystem : 2 +◆b8 ImageSubsystemMajorVersion : 6 +◆bc ImageSubsystemMinorVersion : 1 +◆c0 ActiveProcessAffinityMask : 0xff +◆c4 GdiHandleBuffer : [34] 0 +0x14c PostProcessInitRoutine : (null) +0x150 TlsExpansionBitmap : 0x77eb4248 Void +0x154 TlsExpansionBitmapBits : [32] 1 +0x1d4 SessionId : 1 +0x1d8 AppCompatFlags : _ULARGE_INTEGER ◆ +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER ◆ +0x1e8 pShimData : (null) +0x1ec AppCompatInfo : (null) +0x1f0 CSDVersion : _UNICODE_STRING "Service Pack 1" +0x1f8 ActivationContextData : ◆0060000 _ACTIVATION_CONTEXT_DATA +0x1fc ProcessAssemblyStorageMap : ◆02d4988 _ASSEMBLY_STORAGE_MAP +0x200 SystemDefaultActivationContextData : ◆0050000 _ACTIVATION_CONTEXT_DATA +0x204 SystemAssemblyStorageMap : (null) +0x208 MinimumStackCommit : 0 +0x20c FlsCallback : ◆02d5cb8 _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 : ◆0070000 Void +0x23c pImageHeaderHash : (null) +0x240 TracingFlags : 0 +0x240 HeapTracingEnabled : 0y0 +0x240 CritSecTracingEnabled : 0y0 +0x240 SpareTracingBits : 0y000000000000000000000000000000 (0) 有意思的部分如下: #!bash +◆88 NumberOfHeaps : 7 . +◆90 ProcessHeaps : 0x77eb4760 -> ◆02d0000 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 +◆00 Entry : _HEAP_ENTRY +◆08 SegmentSignature : 0xffeeffee +◆0c SegmentFlags : 0 +◆10 SegmentListEntry : _LIST_ENTRY [ 0x2d00a8 - 0x2d00a8 ] +◆18 Heap : ◆02d0000 _HEAP +◆1c BaseAddress : ◆02d0000 Void +◆20 NumberOfPages : 0x100 +◆24 FirstEntry : ◆02d0588 _HEAP_ENTRY +◆28 LastValidEntry : ◆03d0000 _HEAP_ENTRY +◆2c NumberOfUnCommittedPages : 0xd0 +◆30 NumberOfUnCommittedRanges : 1 +◆34 SegmentAllocatorBackTraceIndex : 0 +◆36 Reserved : 0 +◆38 UCRSegmentList : _LIST_ENTRY [ 0x2ffff0 - 0x2ffff0 ] +◆40 Flags : 0x40000062 +◆44 ForceFlags : 0x40000060 +◆48 CompatibilityFlags : 0 +◆4c EncodeFlagMask : 0x100000 +◆50 Encoding : _HEAP_ENTRY +◆58 PointerKey : 0x7d37bf2e +◆5c Interceptor : 0 +◆60 VirtualMemoryThreshold : 0xfe00 +◆64 Signature : 0xeeffeeff +◆68 SegmentReserve : 0x100000 +◆6c SegmentCommit : 0x2000 +◆70 DeCommitFreeBlockThreshold : 0x200 +◆74 DeCommitTotalFreeThreshold : 0x2000 +◆78 TotalFreeSize : 0x1b01 +◆7c MaximumAllocationSize : 0x7ffdefff +◆80 ProcessHeapsListIndex : 1 +◆82 HeaderValidateLength : 0x138 +◆84 HeaderValidateCopy : (null) +◆88 NextAvailableTagIndex : 0 +◆8a MaximumTagIndex : 0 +◆8c TagEntries : (null) +◆90 UCRList : _LIST_ENTRY [ 0x2fffe8 - 0x2fffe8 ] +◆98 AlignRound : 0x17 +◆9c AlignMask : 0xfffffff8 +◆a0 VirtualAllocdBlocks : _LIST_ENTRY [ 0x2d00a0 - 0x2d00a0 ] +◆a8 SegmentList : _LIST_ENTRY [ 0x2d0010 - 0x2d0010 ] +◆b0 AllocatorBackTraceIndex : 0 +◆b4 NonDedicatedListLength : 0 +◆b8 BlocksIndex : ◆02d0150 Void +◆bc UCRIndex : ◆02d0590 Void +◆c0 PseudoTagEntries : (null) +◆c4 FreeLists : _LIST_ENTRY [ 0x2f0a60 - 0x2f28a0 ] +◆cc LockVariable : ◆02d0138 _HEAP_LOCK +◆d0 CommitRoutine : 0x7d37bf2e long +7d37bf2e +◆d4 FrontEndHeap : (null) +◆d8 FrontHeapLockCount : 0 +◆da FrontEndHeapType : 0 '' +◆dc 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 : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) 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 : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) Encoding key: 0x757121ce [+] Processing heap ◆05a0000 Segment List for heap ◆05a0000: --------------------------------- Segment ◆05a0588 - ◆06a0000 (FirstEntry: ◆05a0588 - LastValidEntry: ◆06a0000): ◆00ffa78 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 : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) Encoding key: 0x757121ce [+] Processing heap ◆05a0000 Segment List for heap ◆05a0000: --------------------------------- Segment ◆05a0588 - ◆06a0000 (FirstEntry: ◆05a0588 - LastValidEntry: ◆06a0000): ◆00ffa78 bytes [+] Processing heap ◆0170000 Segment List for heap ◆0170000: --------------------------------- Segment ◆0170588 - ◆0180000 (FirstEntry: ◆0170588 - LastValidEntry: ◆0180000): ◆000fa78 bytes Segment ◆45a0000 - ◆46a0000 (FirstEntry: ◆45a0040 - LastValidEntry: ◆46a0000): ◆0100000 bytes [+] Processing heap ◆0330000 Segment List for heap ◆0330000: --------------------------------- Segment ◆0330588 - ◆0370000 (FirstEntry: ◆0330588 - LastValidEntry: ◆0370000): ◆003fa78 bytes [+] Processing heap ◆01d0000 Segment List for heap ◆01d0000: --------------------------------- Segment ◆01d0588 - ◆01e0000 (FirstEntry: ◆01d0588 - LastValidEntry: ◆01e0000): ◆000fa78 bytes Segment ◆06a0000 - ◆07a0000 (FirstEntry: ◆06a0040 - LastValidEntry: ◆07a0000): ◆0100000 bytes [+] Processing heap ◆20c0000 Segment List for heap ◆20c0000: --------------------------------- Segment ◆20c0588 - ◆2100000 (FirstEntry: ◆20c0588 - LastValidEntry: ◆2100000): ◆003fa78 bytes [+] Processing heap ◆2c50000 Segment List for heap ◆2c50000: --------------------------------- Segment ◆2c50588 - ◆2c90000 (FirstEntry: ◆2c50588 - LastValidEntry: ◆2c90000): ◆003fa78 bytes [+] Processing heap ◆2b10000 Segment List for heap ◆2b10000: --------------------------------- Segment ◆2b10588 - ◆2b20000 (FirstEntry: ◆2b10588 - LastValidEntry: ◆2b20000): ◆000fa78 bytes Segment ◆4450000 - ◆4550000 (FirstEntry: ◆4450040 - LastValidEntry: ◆4550000): ◆0100000 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 : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) 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 ◆05a0000 Segment List for heap ◆05a0000: --------------------------------- Segment ◆05a0588 - ◆06a0000 (FirstEntry: ◆05a0588 - LastValidEntry: ◆06a0000): ◆00ffa78 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) 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) ◆05feff8 - ◆06a0000 (end of segment) : 0xa1008 (659464) uncommitted bytes Heap : ◆05a0000 : 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 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 : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) 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 ◆05a0000 Segment List for heap ◆05a0000: --------------------------------- Segment ◆05a0588 - ◆06a0000 (FirstEntry: ◆05a0588 - LastValidEntry: ◆06a0000): ◆00ffa78 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 %) 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 : ◆05a0000 : 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 %) 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 : skip strings that are smaller than • -after : ignore entries inside a chunk until either 可以发现一个字符串或vtable引用含有的值为;然后,输出当前堆块的相关信息。 范例: #!bash 0:003> !py mona heap -h 5a0000 -t layout -v Hold on... [+] Command used: !py mona.py heap -h 5a0000 -t layout -v Peb : 0x7efde000, NtGlobalFlag : ◆0000070 Heaps: ------ ◆05a0000 (1 segment(s) : ◆05a0000) * Default process heap Encoding key: 0x171f4fc1 ◆0170000 (2 segment(s) : ◆0170000,◆45a0000) Encoding key: 0x21f9a301 ◆0330000 (1 segment(s) : ◆0330000) Encoding key: 0x1913b812 ◆01d0000 (2 segment(s) : ◆01d0000,◆06a0000) Encoding key: 0x547202aa ◆20c0000 (1 segment(s) : ◆20c0000) Encoding key: ◆896f86d ◆2c50000 (1 segment(s) : ◆2c50000) Encoding key: 0x21f9a301 ◆2b10000 (2 segment(s) : ◆2b10000,◆4450000) Encoding key: 0x757121ce [+] Preparing output file 'heaplayout.txt' - (Re)setting logfile heaplayout.txt [+] Generating module info table, hang on... - Processing modules - Done. Let's rock 'n roll. [+] Processing heap ◆05a0000 ----- Heap ◆05a0000, Segment ◆05a0588 - ◆06a0000 (1/1) ----- Chunk ◆05a0588 (Usersize 0x24f, ChunkSize 0x250) : Fill pattern,Extra present,Busy Chunk ◆05a07d8 (Usersize 0x18, ChunkSize 0x30) : Fill pattern,Extra present,Busy Chunk ◆05a0808 (Usersize 0xb9e, ChunkSize 0xbb8) : Fill pattern,Extra present,Busy +03a3 @ 005a0bab->005a0d73 : Unicode (0x1c6/454 bytes, 0xe3/227 chars) : Path=C:Program Files (x86)Windows Kits8.1Debuggersx86winextarcade;C:Program Files (x86)NVID... +00ec @ 005a0e5f->005a0eef : Unicode (0x8e/142 bytes, 0x47/71 chars) : PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 60 Stepping 3, GenuineIntel +0160 @ 005a104f->005a10d1 : Unicode (0x80/128 bytes, 0x40/64 chars) : PSModulePath=C:Windowssystem32WindowsPowerShellv1.0Modules +0234 @ 005a1305->005a1387 : Unicode (0x80/128 bytes, 0x40/64 chars) : WINDBG_DIR=C:Program Files (x86)Windows Kits8.1Debuggersx86 Chunk ◆05a13c0 (Usersize 0x135c, ChunkSize 0x1378) : Fill pattern,Extra present,Busy +04a7 @ 005a1867->005a1ab5 : Unicode (0x24c/588 bytes, 0x126/294 chars) : C:WindowsSystem32;;C:Windowssystem32;C:Windowssystem;C:Windows;.;C:Program Files (x86)Windo... +046c @ 005a1f21->005a20e9 : Unicode (0x1c6/454 bytes, 0xe3/227 chars) : Path=C:Program Files (x86)Windows Kits8.1Debuggersx86winextarcade;C:Program Files (x86)NVID... +00ec @ 005a21d5->005a2265 : Unicode (0x8e/142 bytes, 0x47/71 chars) : PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 60 Stepping 3, GenuineIntel +0160 @ 005a23c5->005a2447 : Unicode (0x80/128 bytes, 0x40/64 chars) : PSModulePath=C:Windowssystem32WindowsPowerShellv1.0Modules +0234 @ 005a267b->005a26fd : Unicode (0x80/128 bytes, 0x40/64 chars) : WINDBG_DIR=C:Program Files (x86)Windows Kits8.1Debuggersx86 Chunk ◆05a2738 (Usersize 0x3c, ChunkSize 0x58) : Fill pattern,Extra present,Busy Chunk ◆05a2790 (Usersize 0x30, ChunkSize 0x48) : Fill pattern,Extra present,Busy Chunk ◆05ec4b0 (Usersize 0x30, ChunkSize 0x48) : Fill pattern,Extra present,Busy Chunk ◆05ec4f8 (Usersize 0x20, ChunkSize 0x38) : Fill pattern,Extra present,Busy Chunk ◆05ec530 (Usersize 0x2c, ChunkSize 0x48) : Fill pattern,Extra present,Busy Chunk ◆05ec578 (Usersize 0x12a68, ChunkSize 0x12a68) : Fill pattern Chunk ◆05fefe0 (Usersize 0x1d, ChunkSize 0x20) : Busy 分析以上输出内容中提取的两行信息: #!bash Chunk ◆05a0808 (Usersize 0xb9e, ChunkSize 0xbb8) : Fill pattern,Extra present,Busy +03a3 @ 005a0bab->005a0d73 : Unicode (0x1c6/454 bytes, 0xe3/227 chars) : Path=C:Program Files (x86)Windows Kits8.1Debuggersx86winextarcade;C:Program Files (x86)NVID... 其中的第二行内容告诉我们: 入口在起始的堆块地址+3a3字节的位置。 入口地址范围:005a0bab到005a0d73; 入口是454 字节或227个字符的Unicode字符串; 字符串为Path=C:Program Files (x86)Windows Kits... 收藏 分享 新浪微博 图片:avatar_4587.jpeg 旁视列表(Look aside list,LF)前端分配器 --> 旁视列表(Look aside list, LAL)前端分配器 回复 图片:avatar_50_50.png |
|