这是一个32位控制台程序,使用AppVerifier启用了Heaps(即Full Page Heap),主要看pszBuffer1和pszBuffer2,pszBuffer1申请0xe个字节,即14字节,而pszBuffer2比pszBuffer1多申请1个字节,但是通过调试发现,其实系统是会多分配蛮多字节的,具体为什么。。我也搞不懂。。。
#include "stdafx.h" #include <string> int _tmain(int argc, _TCHAR* argv[]) { char* pszBuffer1 = new char[0xe]; memset(pszBuffer1, 1, 0xe); char* pszBuffer2 = new char[0xF]; memset(pszBuffer2, 2, 0xF); char* pszBuffer3 = new char[0x3]; memset(pszBuffer3, 3, 0x3); char* pszBuffer4 = new char[0x6]; memset(pszBuffer4, 4, 0x6); char* pszBuffer5 = new char[0x7]; memset(pszBuffer5, 5, 0x7); __debugbreak(); return 0; }
开始调试
Opened log file 'c: estlog.txt'
0:000> .symfix c:mss
0:000> .reload
Reloading current modules
.........
0:000> g
(1cc4.1220): Break instruction exception - code 80000003 (first chance)
*** WARNING: Unable to verify checksum for ConsoleApplication2.exe
eax=0630cff0 ebx=7efde000 ecx=00000000 edx=00000000 esi=00000000 edi=003cf880
eip=012f449b esp=003cf73c ebp=003cf880 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
ConsoleApplication2!wmain+0xeb:
012f449b cc int 3
#好,断点触发,那么看下ebp寄存器的值
0:000> r ebp
ebp=003cf880
#再把所有局部变量的地址啊、类型啊、值啊全部按照顺序列出来,
#可以看到,参数的地址比ebp大,局部变量的地址比ebp小,
#验证了堆栈是从大到小分配的,而且还验证了参数从右到左压栈,
0:000> dv /i/t/A/v
prv param 003cf88c wchar_t ** argv = 0x062aaf20
prv param 003cf888 int argc = 0n1
prv local 003cf878 char * pszBuffer1 =0x00c4efe8 "???"
prv local 003cf86c char * pszBuffer2 = 0x06306fe8 "???"
prv local 003cf860 char * pszBuffer3 = 0x06308ff8 "???"
prv local 003cf854 char * pszBuffer4 = 0x0630aff0 "???"
prv local 003cf848 char * pszBuffer5 = 0x0630cff0 "???"
#好,我们查到了pszBuffer1的值,它指向某个堆上分配的空间
#那么,我们用!heap -p命令来看一下Page Heap的信息
#要注意UserAddr和UserSize,可以看出,该对象返回地址
#是c4efc8,而申请了0x32字节的空间
0:000> !heap -p -a 0x00c4efe8
address 00c4efe8 found in
_DPH_HEAP_ROOT @ 551000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
553dd0: c4efc8 32 - c4e000 2000
70cf8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77120d96 ntdll!RtlDebugAllocateHeap+0x00000030
770daf0d ntdll!RtlpAllocateHeap+0x000000c4
77083cfe ntdll!RtlAllocateHeap+0x0000023a
70dba65d vrfcore!VfCoreRtlAllocateHeap+0x00000016
0f619441 MSVCR110D!_heap_alloc_base+0x00000051
0f62a22f MSVCR110D!_free_dbg_nolock+0x000006ff
0f62a6cd MSVCR110D!_nh_malloc_dbg+0x0000007d
0f62a67a MSVCR110D!_nh_malloc_dbg+0x0000002a
0f62b099 MSVCR110D!malloc+0x00000019
0f618fdf MSVCR110D!operator new+0x0000000f
012f450c ConsoleApplication2!operator new[]+0x0000000c [f:ddvctoolscrt_bldself_x86crtsrc
ewaop.cpp @ 6]
012f43d5 ConsoleApplication2!wmain+0x00000025 [c:userspunchadocumentsvisual studio 2012projectsconsoleapplication2consoleapplication2consoleapplication2.cpp @ 9]
012f4dd9 ConsoleApplication2!__tmainCRTStartup+0x00000199 [f:ddvctoolscrt_bldself_x86crtsrccrtexe.c @ 533]
012f4fcd ConsoleApplication2!wmainCRTStartup+0x0000000d [f:ddvctoolscrt_bldself_x86crtsrccrtexe.c @ 377]
74b1336a KERNEL32!BaseThreadInitThunk+0x0000000e
77089f72 ntdll!__RtlUserThreadStart+0x00000070
77089f45 ntdll!_RtlUserThreadStart+0x0000001b
#好,看看申请的0x32字节空间里面放了点什么
#其实只有接近最后的的010101才是我们真正需要的
#那其他到底是些什么???
0:000> db
c4efc8 L32
00c4efc8 50 4f 30 06 c8 6f 30 06-00 00 00 00 00 00 00 00 PO0..o0.........
00c4efd8 0e 00 00 00 01 00 00 00-b7 00 00 00 fd fd fd fd ................
00c4efe8 01 01 01 01 01 01 01 01-01 01 01 01 01 01fd fd ................
00c4eff8 fd fd
#再往前推0x20字节(32为程序)看看分配单元的Block Header结构
#证实,分配了0x32字节,申请了4k的内存(一页是4k)
0:000> dt ntdll!_DPH_BLOCK_INFORMATION c4efc8-20
+0x000 StartStamp : 0xabcdbbbb
+0x004 Heap : 0x00551000 Void
+0x008 RequestedSize : 0x32
+0x00c ActualSize : 0x1000
+0x010 FreeQueue : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 FreePushList : _SINGLE_LIST_ENTRY
+0x010 TraceIndex : 0
+0x018 StackTrace : 0x04b2d114 Void
+0x01c EndStamp : 0xdcbabbbb
#再看看第二个局部变量
0:000> dv /i/t/A/vprv param 003cf88c wchar_t ** argv = 0x062aaf20
prv param 003cf888 int argc = 0n1
prv local 003cf878 char * pszBuffer1 = 0x00c4efe8 "???"
prv local 003cf86c char * pszBuffer2 =0x06306fe8 "???"
prv local 003cf860 char * pszBuffer3 = 0x06308ff8 "???"
prv local 003cf854 char * pszBuffer4 = 0x0630aff0 "???"
prv local 003cf848 char * pszBuffer5 = 0x0630cff0 "???"
#申请了0x33字节,确实pszBuffer2是比pszBuffer1多需要一个字节的空间,
#但是0x33-0xF,那中间的差值到底是干什么用的呢?!
0:000> !heap -p -a 0x06306fe8
address 06306fe8 found in
_DPH_HEAP_ROOT @ 551000
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
6251208: 6306fc8 33 - 6306000 2000
70cf8e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77120d96 ntdll!RtlDebugAllocateHeap+0x00000030
770daf0d ntdll!RtlpAllocateHeap+0x000000c4
77083cfe ntdll!RtlAllocateHeap+0x0000023a
70dba65d vrfcore!VfCoreRtlAllocateHeap+0x00000016
0f619441 MSVCR110D!_heap_alloc_base+0x00000051
0f62a22f MSVCR110D!_free_dbg_nolock+0x000006ff
0f62a6cd MSVCR110D!_nh_malloc_dbg+0x0000007d
0f62a67a MSVCR110D!_nh_malloc_dbg+0x0000002a
0f62b099 MSVCR110D!malloc+0x00000019
0f618fdf MSVCR110D!operator new+0x0000000f
012f450c ConsoleApplication2!operator new[]+0x0000000c [f:ddvctoolscrt_bldself_x86crtsrc
ewaop.cpp @ 6]
012f43fe ConsoleApplication2!wmain+0x0000004e [c:userspunchadocumentsvisual studio 2012projectsconsoleapplication2consoleapplication2consoleapplication2.cpp @ 12]
012f4dd9 ConsoleApplication2!__tmainCRTStartup+0x00000199 [f:ddvctoolscrt_bldself_x86crtsrccrtexe.c @ 533]
012f4fcd ConsoleApplication2!wmainCRTStartup+0x0000000d [f:ddvctoolscrt_bldself_x86crtsrccrtexe.c @ 377]
74b1336a KERNEL32!BaseThreadInitThunk+0x0000000e
77089f72 ntdll!__RtlUserThreadStart+0x00000070
77089f45 ntdll!_RtlUserThreadStart+0x0000001b
0:000> dt ntdll!_DPH_BLOCK_INFORMATION 6306fc8-20
+0x000 StartStamp : 0xabcdbbbb
+0x004 Heap : 0x00551000 Void
+0x008 RequestedSize : 0x33
+0x00c ActualSize : 0x1000
+0x010 FreeQueue : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x010 FreePushList : _SINGLE_LIST_ENTRY
+0x010 TraceIndex : 0
+0x018 StackTrace : 0x04b2d16c Void
+0x01c EndStamp : 0xdcbabbbb
0:000> db 6306fc8 L+33
06306fc8 c8 ef c4 00 d8 8f 30 06-00 00 00 00 00 00 00 00 ......0.........
06306fd8 0f 00 00 00 01 00 00 00-b8 00 00 00 fd fd fd fd ................
06306fe8 02 02 02 02 02 02 02 02-02 02 02 02 02 02 02fd ................
06306ff8 fd fd fd ...
0:000> .logclose
Closing open log file c: estlog.txt