-
Notifications
You must be signed in to change notification settings - Fork 1
/
heap.html
474 lines (446 loc) · 35.8 KB
/
heap.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
<!DOCTYPE html>
<html>
<head>
<title>Heap</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="inner-content"><header class="page-header"><h1 class="page-title">Heap</h1></header><div class="page-content"><p>When a process starts, the <span style="color: #00ccff;">heap manager</span> creates a new <span style="color: #00ccff;">heap</span> called the <span style="color: #00ccff;">default process heap</span>. <span style="color: #00ccff;">C/C++</span> applications also creates the so-called <span style="color: #00ccff;">CRT heap</span> (used by <span style="color: #00ccff;">new</span>/<span style="color: #00ccff;">delete</span>, <span style="color: #00ccff;">malloc</span>/<span style="color: #00ccff;">free</span> and their variants). It is also possible to create other heaps via the <span style="color: #00ccff;">HeapCreate</span> API function. The <span style="color: #00ccff;">Windows heap manager</span> can be broken down into two components: the <span style="color: #00ccff;">Front End Allocator</span> and the <span style="color: #00ccff;">Back End Allocator</span>.</p><h2>Front End Allocator</h2><p>The <span style="color: #00ccff;">front end allocator</span> is an abstract optimization layer for the <span style="color: #00ccff;">back end allocator</span>. There are different types of <span style="color: #00ccff;">front end allocators</span> which are optimized for different use cases. The <span style="color: #00ccff;">front end allocators</span> are:</p><ol><li><span style="color: #00ccff;">Look aside list</span> (<span style="color: #00ccff;">LAL</span>) <span style="color: #00ccff;">front end allocator</span></li><li><span style="color: #00ccff;">Low fragmentation</span> (<span style="color: #00ccff;">LF</span>) <span style="color: #00ccff;">front end allocator</span></li></ol><p>The <span style="color: #00ccff;">LAL</span> is a table of 128 <span style="color: #00ccff;">singly-linked lists</span>. Each list contains <span style="color: #00ccff;">free blocks</span> of a specific size, starting at 16 bytes. The size of each block includes 8 bytes of <span style="color: #00ccff;">metadata</span> used to manage the block. The formula for determining the index into the table given the size is <span style="color: #00ff00;">index = ceil((size + 8)/8) – 1</span> where the “<span style="color: #00ff00;">+8</span>” accounts for the metadata. Note that <span style="color: #00ff00;">index</span> is always positive.</p><p>Starting with <span style="color: #00ccff;">Windows Vista</span>, the <span style="color: #00ccff;">LAL front end allocator</span> isn’t present anymore and the <span style="color: #00ccff;">LFH front end allocator</span> is used instead. The <span style="color: #00ccff;">LFH front end allocator</span> is very complex, but the main idea is that it tries to reduce the heap fragmentation by allocating the smallest block of memory that is large enough to contain data of the requested size.</p><h2>Back End Allocator</h2><p>If the <span style="color: #00ccff;">front end allocator</span> is unable to satisfy an allocation request, the request is sent to the <span style="color: #00ccff;">back end allocator</span>.</p><p>In <span style="color: #00ccff;">Windows XP</span>, the <span style="color: #00ccff;">back end allocator</span> uses a table similar to that used in the <span style="color: #00ccff;">front end allocator</span>. The list at index 0 of the table contains free blocks whose size is greater than 1016 bytes and less than or equal to the <span style="color: #00ccff;">virtual allocation limit</span> (<span style="color: #00ff00;">0x7FFF0</span> bytes). The blocks in this list are sorted by size in ascending order. The index 1 is unused and, in general, index <span style="color: #00ff00;">x</span> contains free blocks of size <span style="color: #00ff00;">8x</span>. When a block of a given size is needed but isn’t available, the <span style="color: #00ccff;">back end allocator</span> tries to split bigger blocks into blocks of the needed size. The opposite process, called <span style="color: #00ccff;">heap coalescing</span> is also possible: when a block is freed, the heap manager checks the two adjacent blocks and if one or both of them are free, the free blocks may be coalesced into a single block. This reduces <span style="color: #00ccff;">heap fragmentation</span>. For allocations of size greater than <span style="color: #00ff00;">0x7FFF0</span> bytes the heap manager sends an explicit allocation request to the <span style="color: #00ccff;">virtual memory manager</span> and keeps the allocated blocks on a list called the <span style="color: #00ccff;">virtual allocation list</span>.</p><p>In <span style="color: #00ccff;">Windows 7</span>, there aren’t any longer dedicated <span style="color: #00ccff;">free lists</span> for specific sizes. <span style="color: #00ccff;">Windows 7</span> uses a single <span style="color: #00ccff;">free list</span> which holds blocks of all sizes sorted by size in ascending order, and another list of nodes (of type <span style="color: #00ccff;">ListHint</span>) which point to nodes in the free list and are used to find the nodes of the appropriate size to satisfy the allocation request.</p><h2>Heap segments</h2><p>All the memory used by the <span style="color: #00ccff;">heap manager</span> is requested from the <span style="color: #00ccff;">Windows virtual memory manager</span>. The <span style="color: #00ccff;">heap manager</span> requests big chunks of virtual memory called <span style="color: #00ccff;">segments</span>. Those <span style="color: #00ccff;">segments</span> are then used by the <span style="color: #00ccff;">heap manager</span> to allocate all the blocks and the internal bookkeeping structures. When a new <span style="color: #00ccff;">segment</span> is created, its memory is just reserved and only a small portion of it is committed. When more memory is needed, another portion is committed. Finally, when there isn’t enough uncommitted space in the current <span style="color: #00ccff;">segment</span>, a new <span style="color: #00ccff;">segment</span> is created which is twice as big as the previous <span style="color: #00ccff;">segment</span>. If this isn’t possible because there isn’t enough memory, a smaller <span style="color: #00ccff;">segment</span> is created. If the available space is insufficient even for the smallest possible <span style="color: #00ccff;">segment</span>, an error is returned.</p><h2>Analyzing the Heap</h2><p>The list of heaps is contained in the <span style="color: #00ccff;">PEB</span> (<span style="color: #00ccff;">P</span>rocess <span style="color: #00ccff;">E</span>nvironment <span style="color: #00ccff;">B</span>lock) at offset 0x90:</p><pre class="ignore:true">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)</pre><p>The interesting part is this:</p><pre class="ignore:true">+0x088 NumberOfHeaps : 7
.
+0x090 ProcessHeaps : 0x77eb4760 -> 0x002d0000 Void</pre><p><span style="color: #00ff00;">ProcessHeaps</span> points to an array of pointers to <span style="color: #00ff00;">HEAP</span> structures (one pointer per heap).<br> Let’s see the array:</p><pre class="ignore:true">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</pre><p>We can display the <span style="color: #00ff00;">HEAP</span> structure of the first heap like this:</p><pre class="ignore:true">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</pre><p>We can get useful information by using <span style="color: #00ccff;">mona.py</span>. Let’s start with some general information:</p><pre class="ignore:true">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</pre><p>As we can see there are 7 heaps and <span style="color: #00ccff;">mona</span> also shows the <span style="color: #00ccff;">segments</span> for each heap.</p><p>We can also use<span style="color: #00ff00;"> !heap</span>:</p><pre class="ignore:true">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)</pre><p>The option “<span style="color: #00ff00;">-m</span>” shows also the segments.</p><p>To see the segments for a specific heap (0x5a0000), we can use:</p><pre class="ignore:true">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</pre><p>Note that <span style="color: #00ccff;">mona</span> shows a summary of all the heaps followed by the specific information we asked. We can also omit “<span style="color: #00ff00;">-h 5a0000</span>” to get a list of the <span style="color: #00ccff;">segments</span> of all the heaps:</p><pre class="ignore:true">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</pre><p><span style="color: #00ccff;">mona.py</span> calls the allocated block of memory <span style="color: #00ccff;">chunks</span>. To see the <span style="color: #00ccff;">chunks</span> in the segments for a heap use:</p><pre class="ignore:true">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)
<span style="color: #00ff00;"><snip></span>
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</pre><p>You can also use <span style="color: #00ff00;">!heap</span>:</p><pre class="ignore:true">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
<span style="color: #00ff00;"><snip></span>
005ec530: 00038 . 00048 [107] - busy (2c), tail fill
005ec578: 00048 . 12a68 [104] free fill
005fefe0: 12a68 . 00020 [111] - busy (1d)
005ff000: 000a1000 - uncommitted bytes.</pre><p>To display some statistics, add the option “<span style="color: #00ff00;">-stat</span>“:</p><pre class="ignore:true">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 %)
<span style="color: #00ff00;"><snip></span>
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 %)
<span style="color: #00ff00;"><snip></span>
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</pre><p><span style="color: #00ccff;">mona.py</span> is able to discover <span style="color: #00ccff;">strings</span>, <span style="color: #00ccff;">BSTRING</span>s and <span style="color: #00ccff;">vtable objects</span> in the blocks/chunks of the <span style="color: #00ccff;">segments</span>. To see this information, use “<span style="color: #00ff00;">-t layout</span>“. This function writes the data to the file <span style="color: #00ff00;">heaplayout.txt</span>.<br> You can use the following additional options:</p><ul><li><span style="color: #00ff00;">-v</span>: write the data also in the log window</li><li><span style="color: #00ff00;">-fast</span>: skip the discovery of object sizes</li><li><span style="color: #00ff00;">-size <sz></span>: skip strings that are smaller than <span style="color: #00ff00;"><sz></span></li><li><span style="color: #00ff00;">-after <val></span>: ignore entries inside a chunk until either a <span style="color: #00ccff;">string</span> or <span style="color: #00ccff;">vtable</span> reference is found that contains the value <span style="color: #00ff00;"><val></span>; then, output everything for the current chunk.</li></ul><p>Example:</p><pre class="ignore:true">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 : 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 'heaplayout.txt'
- (Re)setting logfile heaplayout.txt
[+] Generating module info table, hang on...
- Processing modules
- Done. Let's rock 'n roll.
[+] Processing heap 0x005a0000
----- Heap 0x005a0000, Segment 0x005a0588 - 0x006a0000 (1/1) -----
Chunk 0x005a0588 (Usersize 0x24f, ChunkSize 0x250) : Fill pattern,Extra present,Busy
Chunk 0x005a07d8 (Usersize 0x18, ChunkSize 0x30) : Fill pattern,Extra present,Busy
Chunk 0x005a0808 (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 Kits\8.1\Debuggers\x86\winext\arcade;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:\Windows\system32\WindowsPowerShell\v1.0\Modules\
+0234 @ 005a1305->005a1387 : Unicode (0x80/128 bytes, 0x40/64 chars) : WINDBG_DIR=C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86
Chunk 0x005a13c0 (Usersize 0x135c, ChunkSize 0x1378) : Fill pattern,Extra present,Busy
+04a7 @ 005a1867->005a1ab5 : Unicode (0x24c/588 bytes, 0x126/294 chars) : C:\Windows\System32;;C:\Windows\system32;C:\Windows\system;C:\Windows;.;C:\Program Files (x86)\Windo...
+046c @ 005a1f21->005a20e9 : Unicode (0x1c6/454 bytes, 0xe3/227 chars) : Path=C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86\winext\arcade;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:\Windows\system32\WindowsPowerShell\v1.0\Modules\
+0234 @ 005a267b->005a26fd : Unicode (0x80/128 bytes, 0x40/64 chars) : WINDBG_DIR=C:\Program Files (x86)\Windows Kits\8.1\Debuggers\x86
Chunk 0x005a2738 (Usersize 0x3c, ChunkSize 0x58) : Fill pattern,Extra present,Busy
Chunk 0x005a2790 (Usersize 0x30, ChunkSize 0x48) : Fill pattern,Extra present,Busy
<span style="color: #00ff00;"><snip></span>
Chunk 0x005ec4b0 (Usersize 0x30, ChunkSize 0x48) : Fill pattern,Extra present,Busy
Chunk 0x005ec4f8 (Usersize 0x20, ChunkSize 0x38) : Fill pattern,Extra present,Busy
Chunk 0x005ec530 (Usersize 0x2c, ChunkSize 0x48) : Fill pattern,Extra present,Busy
Chunk 0x005ec578 (Usersize 0x12a68, ChunkSize 0x12a68) : Fill pattern
Chunk 0x005fefe0 (Usersize 0x1d, ChunkSize 0x20) : Busy</pre><p>Consider the following two lines extracted from the output above:</p><pre class="ignore:true">Chunk 0x005a0808 (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 Kits\8.1\Debuggers\x86\winext\arcade;C:\Program Files (x86)\NVID...</pre><p>The second line tells us that:</p><ol><li>the entry is at 3a3 bytes from the beginning of the <span style="color: #00ccff;">chunk</span>;</li><li>the entry goes from 5a0bab to 5a0d73;</li><li>the entry is a <span style="color: #00ccff;">Unicode string</span> of 454 bytes or 227 chars;</li><li>the string is “<span style="color: #00ff00;">Path=C:\Program Files (x86)\Windows Kits\…</span>” (snipped).</li></ol> </div></div>
</body>
</html>