HeapEntry解码过程
来源:互联网 发布:mac word 转pdf 不成功 编辑:程序博客网 时间:2024/04/18 14:08
在调试堆时对HeapEntry解码的过程,记录下来以便以后学习用到。
在Win7上调试堆时,会发现_HEAP 增加了两个标志,一个是EncodeFlagMask,另一个是Encoding,其中EncodeFlagMask标明了堆头部是否经过了编码,这个字段的初值为0x100000,由RtlpCreateHeapEncoding()函数设置。而Encoding是一个_HEAP_ENTRY结构体的指针。
举一个例子来说:
0:005>!heap -a 1
Index Address Name Debugging options enabled
1: 003d0000
Segment at 003d0000 to 004d0000 (00100000 bytes committed)
Segment at 02c70000 to 02d70000 (00020000 bytes committed)
Flags: 00000002
ForceFlags: 00000000
Granularity: 8 bytes
Segment Reserve: 00200000
Segment Commit: 00002000
DeCommit Block Thres: 00000800
DeCommit Total Thres: 00002000
Total Free Size: 00002433
Max. Allocation Size: 7ffdefff
Lock Variable at: 003d0138
Next TagIndex: 0000
Maximum TagIndex: 0000
Tag Entries: 00000000
PsuedoTag Entries: 00000000
Virtual Alloc List: 003d00a0
Uncommitted ranges: 003d0090
02c90000: 000e0000 (917504 bytes)
FreeList[ 00 ] at 003d00c4: 02c81fe8 . 004537a8
004537a0: 00108 . 00010 [100] - free
004a7fc0: 00190 . 00010 [100] - free
00453678: 00098 . 00010 [100] - free
0044b0e8: 000c8 . 00010 [100] - free
00418bd8: 00068 . 00010 [100] - free
00413230: 00040 . 00010 [100] - free
00403b48: 00040 . 00010 [100] - free
0046f620: 00130 . 00018 [100] - free
00440e50: 000f0 . 00018 [100] - free
0044bb50: 001c8 . 00018 [100] - free
0043dc10: 00140 . 00018 [120] - free
0043ca78: 00128 . 00018 [100] - free
00474be0: 000e8 . 00018 [100] - free
00452358: 00070 . 00018 [100] - free
0042ebc8: 00090 . 00018 [100] - free
004178c0: 00070 . 00018 [100] - free
00414e40: 00040 . 00018 [100] - free
004323e0: 00088 . 00020 [120] - free
0041a608: 00040 . 00020 [100] - free
004158a8: 00070 . 00020 [100] - free
0040ff50: 00128 . 00020 [100] - free
004a2280: 00160 . 00028 [100] - free
00415ef0: 00068 . 00028 [100] - free
0047b748: 00678 . 00030 [100] - free
可以看到-a列出了所有的Heap Entries,这里只截取了其中的一部分,接下来以第一个Entry为例进行说明,先看下_heap_entry的结构:
ntdll!_HEAP_ENTRY
+0x000 Size : Uint2B
+0x002 Flags : UChar
+0x003 SmallTagIndex : UChar
+0x000 SubSegmentCode : Ptr32 Void
+0x004 PreviousSize : Uint2B
+0x006 SegmentOffset : UChar
+0x006 LFHFlags : UChar
+0x007 UnusedBytes : UChar
+0x000 FunctionIndex : Uint2B
+0x002 ContextValue : Uint2B
+0x000 InterceptorValue : Uint4B
+0x004 UnusedBytesLength : Uint2B
+0x006 EntryOffset : UChar
+0x007 ExtendedBlockSignature : UChar
+0x000 Code1 : Uint4B
+0x004 Code2 : Uint2B
+0x006 Code3 : UChar
+0x007 Code4 : UChar
+0x000 AgregateCode : Uint8B
再来看下实际数据:
0:005> dd 004537a0
004537a0 61329aa1 00007314 004a7fc8 003d00c4
004537b0 7e339abf 08007337 7606479c 76064b78
004537c0 00000002 760647ec 00000001 00000000
004537d0 00449890 ffffffff 00000000 00000000
004537e0 00000000 00000000 00000000 00000000
004537f0 760647e0 00000001 00000002 004498b8
00453800 ffffffff 00000000 00000000 00000000
00453810 00000000 0046e848 00000000 00452420
接下来定位到Encoding处,进行解码操作:
ntdll!_HEAP
+0x000 Entry : _HEAP_ENTRY
+0x008 SegmentSignature : 0xffeeffee
+0x00c SegmentFlags : 0
+0x010 SegmentListEntry : _LIST_ENTRY [ 0x2c70010 - 0x3d00a8 ]
+0x018 Heap : 0x003d0000 _HEAP
+0x01c BaseAddress : 0x003d0000
+0x020 NumberOfPages : 0x100
+0x024 FirstEntry : 0x003d0588 _HEAP_ENTRY
+0x028 LastValidEntry : 0x004d0000 _HEAP_ENTRY
+0x02c NumberOfUnCommittedPages : 0
+0x030 NumberOfUnCommittedRanges : 1
+0x034 SegmentAllocatorBackTraceIndex : 0
+0x036 Reserved : 0
+0x038 UCRSegmentList : _LIST_ENTRY [ 0x4cfff0 - 0x4cfff0 ]
+0x040 Flags : 2
+0x044 ForceFlags : 0
+0x048 CompatibilityFlags : 0
+0x04c EncodeFlagMask : 0x100000
+0x050 Encoding : _HEAP_ENTRY
+0x058 PointerKey : 0x1ff34c7d
+0x05c Interceptor : 0
+0x060 VirtualMemoryThreshold : 0xfe00
+0x064 Signature : 0xeeffeeff
+0x068 SegmentReserve : 0x200000
+0x06c SegmentCommit : 0x2000
+0x070 DeCommitFreeBlockThreshold : 0x800
+0x074 DeCommitTotalFreeThreshold : 0x2000
+0x078 TotalFreeSize : 0x2433
+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 [ 0x2c8ffe8 - 0x2c8ffe8 ]
+0x098 AlignRound : 0xf
+0x09c AlignMask : 0xfffffff8
+0x0a0 VirtualAllocdBlocks : _LIST_ENTRY [ 0x3d00a0 - 0x3d00a0 ]
+0x0a8 SegmentList : _LIST_ENTRY [ 0x3d0010 - 0x2c70010 ]
+0x0b0 AllocatorBackTraceIndex : 0
+0x0b4 NonDedicatedListLength : 0
+0x0b8 BlocksIndex : 0x003d0150
+0x0bc UCRIndex : 0x003d0590
+0x0c0 PseudoTagEntries : (null)
+0x0c4 FreeLists : _LIST_ENTRY [ 0x4537a8 - 0x2c81fe8 ]
+0x0cc LockVariable : 0x003d0138 _HEAP_LOCK
+0x0d0 CommitRoutine : 0x1ff34c7d long +1ff34c7d
+0x0d4 FrontEndHeap : 0x003d66b0
+0x0d8 FrontHeapLockCount : 0
+0x0da FrontEndHeapType : 0x2 ''
+0x0dc Counters : _HEAP_COUNTERS
+0x130 TuningParameters : _HEAP_TUNING_PARAMETERS
0:005> dd 003d0000+50
003d0050 63329aa3 00007335 1ff34c7d 00000000
003d0060 0000fe00 eeffeeff 00200000 00002000
003d0070 00000800 00002000 00002433 7ffdefff
003d0080 01380001 00000000 00000000 00000000
003d0090 02c8ffe8 02c8ffe8 0000000f fffffff8
003d00a0 003d00a0 003d00a0 003d0010 02c70010
003d00b0 00000000 00000000 003d0150 003d0590
003d00c0 00000000 004537a8 02c81fe8 003d0138
堆块入口:
0:005> dd 004537a0
004537a0 61329aa1 00007314 004a7fc8 003d00c4
004537b0 7e339abf 08007337 7606479c 76064b78
004537c0 00000002 760647ec 00000001 00000000
004537d0 00449890 ffffffff 00000000 00000000
004537e0 00000000 00000000 00000000 00000000
004537f0 760647e0 00000001 00000002 004498b8
00453800 ffffffff 00000000 00000000 00000000
00453810 00000000 0046e848 00000000 00452420
进行异或操作:
0:005> ? 9aa1^9aa3
Evaluate expression: 2 = 00000002
将结果乘以粒度大小(8字节):
0:005> ?2*8
Evaluate expression: 16 = 00000010
最终得到正确的Size大小,这与!heap -a 1中显示的一致了。- HeapEntry解码过程
- 解码过程
- mpeg2peter: 解码过程概述
- TS 流解码过程
- FFmpeg - 视频解码过程
- TS 流解码过程
- FFMPEG解码过程
- ffmpeg 解码过程
- TS 流解码过程:
- mp3解码详细过程
- JMVC 编码解码过程
- FFmpeg - 音频解码过程
- TS 流解码过程
- 视频播放解码过程
- Mp3解码过程
- java编码解码过程
- Protobuf 解码过程
- 语音识别-解码过程
- WPF图形之:Path详解
- 2013 CocoaChina开发者大会 资料
- 关于java正则表达式非捕获型括号和捕获型括号的研究
- cocos2d-X 节点(CCNode.h)API
- OCP-1Z0-053-V12.02-210题
- HeapEntry解码过程
- AndroidUI库 -SlidingMenu
- free store 和 heap
- matlab中冒号的用法
- LDD3源码学习日记<五>
- Java封装
- Codeforces_358A_Dima and Continuous Line(排序+暴力)
- 详细讲解二叉树三种遍历方式的递归与非递归实现
- poj 1318 Word Amalgamation