heap到底释放了吗?
C/C++本地代码调试
heap到底释放了吗?
lazyworm
2015-06-04, 02:10 上午
还记得4年前在某公司的时候,听过奎哥去给公司其他部门的人做x64 programming prestation见过您一面。当时抱着作为一名security resercher对X64 架构必须有所了解的心态去的。在奎哥精炼的讲座中的学到的知识。仍给我的日常工作提供了不少帮助。
最近在工作之余学习点东西,碰到一个问题。想请教一下各路高手。
有一个heap上的内存地址
0181788
0:008> !address 181788
00140000 : 00140000 - 00100000
Type 00020000 MEM_PRIVATE
Protect 00000004 PAGE_READWRITE
State 00001000 MEM_COMMIT
Usage RegionUsageHeap
Handle 00140000
Entry User Heap Segment Size PrevSize Unused Flags
-----------------------------------------------------------------------------
00140000 00140008 00140000 00140640 640 0 0 busy
以下是该heap 的freelist entry
FreeList[ 00 ] at 00140178: 02f18048 . 02f18048
02f18040: 00400 . 01c00 [00] - free
FreeList[ 02 ] at 00140188: 00164050 . 00180cc0
00180cb8: 00030 . 00010 [00] - free
00148238: 00040 . 00010 [00] - free
0016b828: 00028 . 00010 [00] - free
00164048: 00030 . 00010 [00] - free
FreeList[ 03 ] at 00140190: 00177e28 . 001775e0
001775d8: 00020 . 00018 [00] - free
0017d9c8: 00018 . 00018 [00] - free
0023ffe8: 00338 . 00018 [10] - free
001769c8: 00040 . 00018 [00] - free
00151248: 000b0 . 00018 [00] - free
00148150: 00028 . 00018 [00] - free
001754e8: 00518 . 00018 [20] - free
00177e20: 00010 . 00018 [00] - free
FreeList[ 04 ] at 00140198: 001784e8 . 00177ef8
00177ef0: 00028 . 00020 [00] - free
001784e0: 00020 . 00020 [20] - free
FreeList[ 05 ] at 001401a0: 0016a810 . 0014ff90
0014ff88: 00070 . 00028 [00] - free
00177dc0: 00020 . 00028 [00] - free
0016a808: 00078 . 00028 [00] - free
FreeList[ 08 ] at 001401b8: 001736e8 . 001736e8
001736e0: 00400 . 00040 [00] - free
FreeList[ 09 ] at 001401c0: 00147628 . 00181e38
00181e30: 00088 . 00048 [00] - free
0014e7c0: 00048 . 00048 [00] - free
00147620: 00028 . 00048 [00] - free
FreeList[ 0a ] at 001401c8: 00180bd0 . 00180bd0
00180bc8: 00068 . 00050 [00] - free
FreeList[ 0b ] at 001401d0: 00164080 . 00164080
00164078: 00020 . 00058 [00] - free
FreeList[ 0f ] at 001401f0: 0015e970 . 0015e970
0015e968: 00068 . 00078 [20] - free
FreeList[ 10 ] at 001401f8: 00175cd8 . 00175cd8
00175cd0: 00028 . 00080 [00] - free
FreeList[ 18 ] at 00140238: 0016a458 . 0016a458
0016a450: 00030 . 000c0 [20] - free
FreeList[ 1c ] at 00140258: 001698d0 . 00163098
00163090: 00050 . 000e0 [00] - free
001698c8: 000f0 . 000e0 [00] - free
FreeList[ 1e ] at 00140268: 001783d8 . 0014f628
0014f620: 00020 . 000f0 [00] - free
001783d0: 00400 . 000f0 [00] - free
FreeList[ 1f ] at 00140270: 00143b28 . 00143b28
00143b20: 000b8 . 000f8 [00] - free
FreeList[ 20 ] at 00140278: 00150ca0 . 00150ca0
00150c98: 00110 . 00100 [00] - free
FreeList[ 21 ] at 00140280: 0017ae68 . 0017ae68
0017ae60: 00048 . 00108 [00] - free
FreeList[ 22 ] at 00140288: 00162cf8 . 00162cf8
00162cf0: 00038 . 00110 [00] - free
FreeList[ 23 ] at 00140290: 00164a18 . 00164a18
00164a10: 00018 . 00118 [00] - free
FreeList[ 25 ] at 001402a0: 001762d0 . 00164268
00164260: 00110 . 00128 [00] - free
001762c8: 00018 . 00128 [00] - free
FreeList[ 27 ] at 001402b0: 029dfed0 . 0017ace8
0017ace0: 00028 . 00138 [00] - free
001724e8: 000e8 . 00138 [00] - free
029dfec8: 00800 . 00138 [10] - free
FreeList[ 28 ] at 001402b8: 00177460 . 00155cd0
00155cc8: 00050 . 00140 [00] - free
00177458: 00108 . 00140 [00] - free
FreeList[ 2a ] at 001402c8: 00148338 . 00148338
00148330: 000e8 . 00150 [00] - free
FreeList[ 2d ] at 001402e0: 00147e38 . 00155730
00155728: 000e0 . 00168 [00] - free
00147e30: 00180 . 00168 [20] - free
FreeList[ 34 ] at 00140318: 029d9890 . 029d9890
029d9888: 05000 . 001a0 [00] - free
FreeList[ 35 ] at 00140320: 001804b8 . 001804b8
001804b0: 00048 . 001a8 [00] - free
FreeList[ 39 ] at 00140340: 00174c38 . 00172638
00172630: 00010 . 001c8 [00] - free
00174c30: 00048 . 001c8 [00] - free
FreeList[ 3e ] at 00140368: 00162e58 . 00157fe0
00157fd8: 00058 . 001f0 [00] - free
00162e50: 00050 . 001f0 [00] - free
FreeList[ 3f ] at 00140370: 001643b8 . 001643b8
001643b0: 00028 . 001f8 [00] - free
FreeList[ 41 ] at 00140380: 0014d8d8 . 0014d8d8
0014d8d0: 03988 . 00208 [00] - free
FreeList[ 44 ] at 00140398: 0017b828 . 0017b828
0017b820: 005f0 . 00220 [20] - free
FreeList[ 45 ] at 001403a0: 00175fe0 . 001676f8
001676f0: 00048 . 00228 [00] - free
00175fd8: 00228 . 00228 [20] - free
FreeList[ 46 ] at 001403a8: 001423e0 . 001423e0
001423d8: 00058 . 00230 [20] - free
FreeList[ 47 ] at 001403b0: 0017bad8 . 0017c3a0
0017c398: 00010 . 00238 [00] - free
00147280: 00018 . 00238 [00] - free
0017bad0: 00090 . 00238 [20] - free
FreeList[ 48 ] at 001403b8: 00173048 . 00173048
00173040: 00400 . 00240 [20] - free
FreeList[ 4b ] at 001403d0: 0017afb8 . 001693b0
001693a8: 00038 . 00258 [00] - free
0017afb0: 00048 . 00258 [00] - free
FreeList[ 56 ] at 00140428: 00163348 . 00163348
00163340: 00038 . 002b0 [00] - free
FreeList[ 5a ] at 00140448: 001646b0 . 001646b0
001646a8: 00018 . 002d0 [00] - free
FreeList[ 5c ] at 00140458: 00163620 . 00163620
00163618: 00028 . 002e0 [00] - free
FreeList[ 5e ] at 00140468: 00156298 . 00156298
00156290: 00050 . 002f0 [00] - free
FreeList[ 5f ] at 00140470: 00151eb0 . 00151eb0
00151ea8: 00218 . 002f8 [00] - free
FreeList[ 70 ] at 001404f8: 0016bc20 . 0016bc20
0016bc18: 00390 . 00380 [00] - free
FreeList[ 71 ] at 00140500: 001558f8 . 001558f8
001558f0: 00010 . 00388 [00] - free
FreeList[ 72 ] at 00140508: 0016ea60 . 0016ea60
0016ea58: 00390 . 00390 [00] - free
FreeList[ 78 ] at 00140538: 0301ac48 . 0301ac48
0301ac40: 05000 . 003c0 [10] - free
FreeList[ 7f ] at 00140570: 0015e510 . 0015e510
0015e508: 00110 . 003f8 [00] - free
...........以下是该segment的列出部分entry
00180738: 000e0 . 00028 [01] - busy (20)
00180760: 00028 . 00400 [01] - busy (3f8)
00180b60: 00400 . 00068 [01] - busy (60)
00180bc8: 00068 . 00050 [00]
00180c18: 00050 . 00038 [01] - busy (2c)
00180c50: 00038 . 00038 [01] - busy (30)
00180c88: 00038 . 00030 [23] - busy (1c) - unable to read heap entry extra at 00180cb0, user flags (1)
00180cb8: 00030 . 00010 [00]
00180cc8: 00010 . 000e0 [01] - busy (d8)
00180da8: 000e0 . 01000 [01] - busy (ff8)
-这个entry 包含了181788的内存
00181da8: 01000 . 00088 [23] - busy (78) - unable to read heap entry extra at 00181e28, user flags (1)
...........
这里有个问题就是,181788这个地址明明由于在RtlFreeHeap调用时被释放了,为什么仍然在这个segment中的entry中。而且是busy状态。由于我对Windows的heap实现原理不熟悉,水平也不够去分析其代码,只能猜测是因为这个entry是没有被完全释放。所以还仍然是busy状态吗?
0:008> g
eax=00181788 ebx=00000000 ecx=02f8b48c edx=00000000 esi=020f8c24 edi=001eb760
eip=7c90ff0d esp=020f8c00 ebp=020f8c18 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
ntdll!RtlFreeHeap:
7c90ff0d 68a0000000 push offset <Unloaded_Ed20.dll>+0x9f (000000a0)
Re: heap到底释放了吗?
Bombs
2015-06-04, 11:47 上午
菜鸟也来插一句,释放的时候有可能会归到空闲链表里去,也有可能会归到旁视链表里去,若是归到旁视链表里去则其依然是占用状态!
Re: heap到底释放了吗?
lazyworm
2015-06-04, 11:57 上午
谢谢楼上的回复,我记得在debug时,进程好像是不使用lookaside表中的内存的。是这样吗?
Re: heap到底释放了吗?
Bombs
2015-06-09, 18:00 下午
有没有开启页堆或者app verifier? 我今天在调试一个问题的时候有这么一段话,maybe it can help you.
APPLICATION_VERIFIER_DOUBLE_FREE (7)
Heap block already freed.
This situation happens if the block is freed twice.
Freed blocks are marked in a
special way and are kept around for a while in a delayed free queue
. If a buggy
program tries to free the block again this will be caught assuming the block was not
dequeued from delayed free queue and its memory reused for other allocations.
The depth of the delay free queue is in the order of thousands of blocks therefore
there are good chances that most double frees will be caught.
Arguments:
Arg1: 13171000, Heap handle for the heap owning the block.
Arg2: 131749c0, Heap block being freed again.
Arg3: 00000020, Size of the heap block.
Arg4: 00000000, Not used