拿到poc时, 分析漏洞成因,关键步骤之一就是要定位到漏洞代码.
栈溢出一般分析方法:
1.基于字符串定位
当存在漏洞的代码片段处引用了字符串时,可以在IDA直接搜索该字符串,再通过交叉引用来到相应代码段处,如果有多处就可以对他们分别下断点,看断在何处.
如cve-2010-2883 ttf字体sing表溢出 漏洞 就是因为代码在处理sing表时不当导致溢出, 而处理sing表时会应用到SING这个字符串,通过该字符串很快就能定位到漏洞代码处.
2.基于栈回溯定位分析方法
如果当对字符串进行复制时溢出并向不可写的地方进行写入而发生异常时,这种方式就很快能定位到漏洞. 通过栈回溯并对返回地址上方进行反汇编,然后在这些call
上下断,就能断在漏洞代码附近.
例如 cve-2010-3333: rtf文件格式解析栈溢出漏洞
通过windbg动态调试确定下来是哪个执行执行异常,然后栈回溯定位该指令所在的模块,然后可以通过ida静态分析指令的函数和周围指令执行情况
发给缓冲区数据过多时,虽然覆盖了返回地址和seh指针,但是也可能复制数据到了不可写的地址处导致异常.
当断在异常处,查看复制数据的寄存器值,如edi,esi ,参数的esp:
明显在mso模块中的字符串复制发生异常, 查看此时esp和esi:
0:000> db esi
11045d5c 32 45 71 33 45 71 34 45-71 35 45 71 36 45 71 37 2Eq3Eq4Eq5Eq6Eq7
11045d6c 45 71 38 45 71 39 45 72-30 45 72 31 45 72 32 45 Eq8Eq9Er0Er1Er2E
11045d7c 72 33 45 72 34 45 72 35-45 72 36 45 72 37 45 72 r3Er4Er5Er6Er7Er
11045d8c 38 45 72 39 45 73 30 45-73 31 45 73 32 45 73 33 8Er9Es0Es1Es2Es3
11045d9c 45 73 34 45 73 35 45 73-36 45 73 37 45 73 38 45 Es4Es5Es6Es7Es8E
11045dac 73 39 45 74 30 45 74 31-45 74 32 45 74 33 45 74 s9Et0Et1Et2Et3Et
11045dbc 34 45 74 35 45 74 36 45-74 37 45 74 38 45 74 39 4Et5Et6Et7Et8Et9
11045dcc 45 75 30 45 75 31 45 75-32 45 75 33 45 75 34 45 Eu0Eu1Eu2Eu3Eu4E
0:000> db esp
0012a288 e4 15 3e 01 78 a4 12 00-fb b5 f0 30 e4 15 3e 01 ..>.x......0..>.
0012a298 b0 a2 12 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
0012a2a8 00 00 00 00 00 00 00 00-41 61 30 41 61 31 41 61 ........Aa0Aa1Aa
0012a2b8 32 41 61 33 41 61 34 41-61 35 41 61 36 41 61 37 2Aa3Aa4Aa5Aa6Aa7
0012a2c8 41 61 38 41 61 39 41 62-30 41 62 31 41 62 32 41 Aa8Aa9Ab0Ab1Ab2A
0012a2d8 62 33 41 62 34 41 62 35-41 62 36 41 62 37 41 62 b3Ab4Ab5Ab6Ab7Ab
0012a2e8 38 41 62 39 41 63 30 41-63 31 41 63 32 41 63 33 8Ab9Ac0Ac1Ac2Ac3
0012a2f8 41 63 34 41 63 35 41 63-36 41 63 37 41 63 38 41 Ac4Ac5Ac6Ac7Ac8A
基于污点追踪的漏洞分析方法
同样是在断在异常处代码时查看操作的寄存器值, 向上追踪它们的值是从哪来的.这种一般是已经在漏洞代码附近了,向上追溯就能分析出漏洞成因.
如cve-2011-0104 excel 文件格式漏洞
1. 附加后加载断下:
(f70.c90): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=51455047 ebx=0013f6dc ecx=00000006 edx=31622f28 esi=00000000 edi=00000400
eip=300e06f7 esp=0013d698 ebp=0013d704 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
EXCEL!Ordinal41+0xe06f7:
300e06f7 8908 mov dword ptr [eax],ecx ds:0023:51455047=???????? ;该处只是发生异常地址,并不是复制字符串.
2.查看栈:
0:000> kb
ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
0013d704 584b4c4b 30435451 50453043 55514b4c EXCEL!Ordinal41+0xe06f7
0013d708 30435451 50453043 55514b4c 4b4c4c47 0x584b4c4b
0013d70c 50453043 55514b4c 4b4c4c47 35434c43 EXCEL!Ordinal41+0x435451
0013d710 55514b4c 4b4c4c47 35434c43 51453844 0x50453043
0013d714 4b4c4c47 35434c43 51453844 4b4c4f4a 0x55514b4c
在ida中找到崩溃函数:
.text:300E05AD push ebp
然后用od 加载对崩溃函数下断加载执行断下. 然后在该函数中的栈中多设置几个内存写入断点.执行后来到复制字符串处.
这里假设复制字符串导致溢出的代码在该函数中,如果不在,可以考虑栈帧中下一个函数对栈设置内存写入断点.
300DE82D 8BD1 MOV EDX,ECX
300DE82F C1E9 02 SHR ECX,2
300DE832 8BFD MOV EDI,EBP
300DE834 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>//溢出地方,此时ecx=bf,反向计算的复制大小为0x300 大于该函数的栈空间0x60
300DE836 8BCA MOV ECX,EDX
300DE838 83E1 03 AND ECX,3
300DE83B F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
300DE83D 8B15 442C8930 MOV EDX,DWORD PTR DS:[30892C44]
300DE843 2BD8 SUB EBX,EAX
300DE845 03D0 ADD EDX,EAX
污点追踪法:因为ecx作为复制的字节数, 逆向跟踪ecx. 根据od的调用堆栈查看调用来源:
3070DF0A 83F8 3C CMP EAX,3C
3070DF0D 8945 68 MOV DWORD PTR SS:[EBP+68],EAX
3070DF10 0F85 C80A0000 JNZ EXCEL.3070E9DE
3070DF16 E8 AA089DFF CALL EXCEL.300DE7C5
3070DF1B 8B7D 34 MOV EDI,DWORD PTR SS:[EBP+34]
3070DF1E 0FAF7D 70 IMUL EDI,DWORD PTR SS:[EBP+70]
3070DF22 8945 7C MOV DWORD PTR SS:[EBP+7C],EAX
3070DF25 8B45 6C MOV EAX,DWORD PTR SS:[EBP+6C]
3070DF28 8D7407 03 LEA ESI,DWORD PTR DS:[EDI+EAX+3]
3070DF2C E8 735B9BFF CALL EXCEL.300C3AA4
3070DF31 6A FD PUSH -3
3070DF33 59 POP ECX
3070DF34 2BCF SUB ECX,EDI
3070DF36 03C1 ADD EAX,ECX
3070DF38 50 PUSH EAX
3070DF39 FF75 7C PUSH DWORD PTR SS:[EBP+7C] ; ecx==300
3070DF3C 56 PUSH ESI
3070DF3D E8 AA089DFF CALL EXCEL.300DE7EC
找到传染源后对附近的代码进行逆向分析即可.
针对activeX控件的分析方法
activeX控件注册到系统中后,在html中通过<object>标签的classid来引用, 在ie中对应的模块是oleaut32.dll, 函数是dispcallfunc.
在dispcallfunc函数中首个call ecx 即为activex中的被html调用的函数.
可以直接在od中按 alt+e 找到模块,按ctrl+n找到函数. 然后找到call ecx跟进分析即可
堆溢出一般分析方法:
1.堆调试
!heap 查看程序用heapcreate函数创建的堆信息
!heap -p -a 地址 用于查看该地址的堆详细信息
dt _HEAP_FREE_ENTRY 地址 显示空闲堆块详细信息
dt _LIST_ENTRY 地址 显示系统链表结构信息
堆溢出调试技巧: 正常运行时没有这些机制,都是windbg加上的:
htc: 堆尾检查 在堆块末尾添加额外信息,当被覆盖时将断下
hfc: 堆释放检查 防止重复覆盖同一个堆
hpc: 堆参数检查 对传递给堆管理的参数进行检查
hpa: 启用堆页 当堆溢出发生时将立即触发异常
在windbg的安装目录可以找打gflags程序, 通过gflags -i 程序名 +某机制 :添加某机制, -则为取消某机制
详细原理可参考<<软件调试>>第23章
2.基于heapPage的分析方法
通过开启hpa后, 附加,加载poc,断下. 然后查看栈回溯,反汇编返回地址上方, 在上面找合适的地方下断点,重新运行调试断下,然后结合实际慢慢分析.
如cve-2010-2553 cvddecompress 函数堆溢出漏洞
打开player,利用windbg附加, 然后启用hpa 继续运行
用player加载poc.avi 在windbg断下:
开启hpa:
0:011> !gflag +hpa
New NtGlobalFlag contents: 0x02000000
hpa - Place heap allocations at ends of pages
0:011> g
断下:
(e40.5f0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00006000 ebx=04668f20 ecx=00000312 edx=04ecfd38 esi=04698000 edi=0469a000
eip=73b722cc esp=04ecfd04 ebp=04ecfd30 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
iccvid!CVDecompress+0x11e:
73b722cc f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
堆栈跟踪:
0:016> kb
ChildEBP RetAddr Args to Child
04ecfd30 73b7cbf3 00000004 00000000 00000068 iccvid!CVDecompress+0x11e
04ecfd60 73b766c8 04568cf8 00000000 00198188 iccvid!Decompress+0x11d //这里是断下的代码所在的函数的返回地址,所以对该地址前面
进行反汇编就能查看到触发异常的函数调用了即断下的代码所在的函数
04ecfdac 73b41938 04568cf8 00000001 0000400d iccvid!DriverProc+0x1bf
04ecfdd0 7cf8fa9e 73b5b500 0000400d 04ecfde8 MSVFW32!ICSendMessage+0x2b
04ecfe00 7cf8f9e9 73b5b500 00000000 00198188 quartz!CVFWDynLink::ICDecompress+0x3e
查看反汇编:
0:016> ub iccvid!Decompress+0x11d
iccvid!Decompress+0x102:
73b7cbd8 ffb698000000 push dword ptr [esi+98h]
73b7cbde 57 push edi
73b7cbdf ff7528 push dword ptr [ebp+28h]
73b7cbe2 ff752c push dword ptr [ebp+2Ch]
73b7cbe5 ff7530 push dword ptr [ebp+30h]
73b7cbe8 ff7514 push dword ptr [ebp+14h]
73b7cbeb ff765c push dword ptr [esi+5Ch]
73b7cbee e8bb55ffff call iccvid!CVDecompress (73b721ae) //显然是进入该函数产生异常
易得该函数位于iccvid模块中,然而该模块是在加载poc.avi时动态加载的,正常没法进行下断点. 所以
通过windbg对该模块下断点:sxe ld:模块名 即sxe ld:iccvid 当首次加载该模块后将断下,然后对该函数下断继续运行即可
bp 0x73b7cbee
然后用ida加载该模块,按g来到该函数处.
73b721e1 33c0 xor eax,eax
73b721e3 837d1020 cmp dword ptr [ebp+10h],20h ;ebp+10h== 某关键标记
73b721e7 0f8200020000 jb iccvid!CVDecompress+0x23f (73b723ed) (小于20h才跳转,触发漏洞需要大于20h)
73b721ed 8b750c mov esi,dword ptr [ebp+0Ch] ;esi==某数据
0:016> dd esi
053dd4f8 68000000 20016001 00101000 00001000
053dd508 60000000 00206001 00110000 41411000
053dd518 41414141 41414141 00114141 41411000
053dd528 41414141 41414141 00114141 41411000
053dd538 41414141 41414141 00114141 00411000
cinepak_codec_data1 = '\x00\x00\x00\x68\x01\x60\x01\x20'
73b721f0 8a6601 mov ah,byte ptr [esi+1] ;ah=0
73b721f3 0fb64e03 movzx ecx,byte ptr [esi+3] ;ecx==0x68
73b721f7 8a4602 mov al,byte ptr [esi+2] ;al=0
73b721fa c1e008 shl eax,8 ;eax=0
73b721fd 0bc1 or eax,ecx ;eax=ecx
73b721ff 394510 cmp dword ptr [ebp+10h],eax ;某关键标记和0x68比,不能跳转
73b72202 0f8cec010000 jl iccvid!CVDecompress+0x246 (73b723f4) 小于则跳转,所以应该大于0x68
73b72208 8a0e mov cl,byte ptr [esi]
73b7220a 884d13 mov byte ptr [ebp+13h],cl
73b7220d 8d4df0 lea ecx,[ebp-10h]
73b72210 51 push ecx
73b72211 6a0a push 0Ah
73b72213 50 push eax
73b72214 e86dffffff call iccvid!ULongSub (73b72186)
73b72219 85c0 test eax,eax
73b7221b 0f8cd3010000 jl iccvid!CVDecompress+0x246 (73b723f4)
73b72221 33c0 xor eax,eax
73b72223 8a6608 mov ah,byte ptr [esi+8]
73b72226 83c60a add esi,0Ah
73b72229 897dec mov dword ptr [ebp-14h],edi
73b7222c 8975e8 mov dword ptr [ebp-18h],esi
73b7222f 8975f4 mov dword ptr [ebp-0Ch],esi
然后结合文件格式,慢慢分析漏洞成因
例子:CVE-2012-1876_MSHTML_DLL_CTableLayout_CalculateMinMax 堆溢出漏洞
hpa结合污点追踪
多进程调试:.childdbg 1
异常断下后:
mshtml!IERegisterXMLNS+0x96f3e: (此时符号文件还未设置,导致的错误符号)
7054f167 890f mov dword ptr [edi],ecx ds:002b:0051a131=????????
0:005> kb
ChildEBP RetAddr Args to Child
02f3d8ac 71ed5b8e 00519159 02f3dbf0 00000001 mshtml!CTableColCalc::AdjustForCol+0x15
02f3d95c 71d40713 00000001 02f3dbf0 000003e8 mshtml!CTableLayout::CalculateMinMax+0x52f
02f3db78 71d2af19 02f3dbf0 02f3dbbc 00000001 mshtml!CTableLayout::CalculateLayout+0x276
02f3dd24 71e1cc48 02f3f398 02f3df50 00000000 mshtml!CTableLayout::CalcSizeVirtual+0x720
02f3de5c 71e0f5d0 00723778 00000000 00000000 mshtml!CLayout::CalcSize+0x2b8
02f3df20 71e0f31d 00723778 0002321c 0002321c mshtml!CFlowLayout::MeasureSite+0x312
02f3df68 71e0f664 041ae440 00000061 02f3f398 mshtml!CFlowLayout::GetSiteWidth+0x156
02f3dfa8 71e0fb40 05b55738 00723778 00000001 mshtml!CLSMeasurer::GetSiteWidth+0xce
02f3e02c 7305665d 007a0fb0 02f3e04c 02f3e110 mshtml!CEmbeddedILSObj::Fmt+0x150
02f3e0bc 73056399 05b36ed4 00000000 05a3eab8 msls31!ProcessOneRun+0x3e9
找到崩溃函数:
0:005> ub 71ed5b8e
mshtml!CTableLayout::CalculateMinMax+0x516:
71ed5b75 2bc8 sub ecx,eax
71ed5b77 894df4 mov dword ptr [ebp-0Ch],ecx
71ed5b7a ff75c4 push dword ptr [ebp-3Ch]
71ed5b7d 8b45cc mov eax,dword ptr [ebp-34h]
71ed5b80 ff750c push dword ptr [ebp+0Ch]
71ed5b83 8b75dc mov esi,dword ptr [ebp-24h]
71ed5b86 ff75f4 push dword ptr [ebp-0Ch]
71ed5b89 e8c4951800 call mshtml!CTableColCalc::AdjustForCol (7205f152) ;崩溃函数
查看模块:
0:005> lmm mshtml
start end module name
71c30000 721e2000 mshtml (pdb symbols) c:\symbol\mshtml.pdb\5B825981E9B445BBB998A27119FF0D6E2\mshtml.pdb
0:005> lmm mshtml -v
Unknown option '-'
start end module name
71c30000 721e2000 mshtml (pdb symbols) c:\symbol\mshtml.pdb\5B825981E9B445BBB998A27119FF0D6E2\mshtml.pdb
Loaded symbol image file: C:\Windows\SysWOW64\mshtml.dll ;找到地址后用ida加载
Image path: C:\Windows\SysWOW64\mshtml.dll
小技巧:当windows7这种系统有aslr时,直接对地址下断点可能有问题,所以可以直接用符号名代替,如bp mshtml!CTableLayout::CalculateMinMax
对上层函数下断:bp mshtml!CTableLayout::CalculateMinMax
查看反汇编:
mshtml!CTableLayout::CalculateMinMax:
731c018a 8bff mov edi,edi
731c018c 55 push ebp
731c018d 8bec mov ebp,esp
731c018f 81ec90000000 sub esp,90h
731c0195 53 push ebx
731c0196 8b5d08 mov ebx,dword ptr [ebp+8] //ebx = arg1
0:005> ln poi(ebx)
(730b9868) mshtml!CTableLayout::`vftable' | (730b99a8) mshtml!CTableLayoutBlock::`vftable'
Exact matches:
mshtml!CTableLayout::`vftable' = <no type information>
则第一个参数是html中的table标签对象
731c0199 56 push esi
731c019a 8b750c mov esi,dword ptr [ebp+0Ch]// esi=arg2
731c019d 8b4628 mov eax,dword ptr [esi+28h]
731c01a0 898574ffffff mov dword ptr [ebp-8Ch],eax //var1 = arg2
731c01a6 8b4354 mov eax,dword ptr [ebx+54h]
eax == 1
显然是table的span属性值
731c01a9 894508 mov dword ptr [ebp+8],eax //arg1=arg1+54; eax == 1
731c01ac 8b8328010000 mov eax,dword ptr [ebx+128h]
731c01b2 c1e802 shr eax,2
731c01b5 8945b8 mov dword ptr [ebp-48h],eax
731c01b8 57 push edi
731c01b9 33ff xor edi,edi
731c01bb 8d4594 lea eax,[ebp-6Ch]
731c01be 50 push eax
731c01bf 8bc3 mov eax,ebx
731c01c1 897ddc mov dword ptr [ebp-24h],edi
731c01c4 897de0 mov dword ptr [ebp-20h],edi
731c01c7 897df8 mov dword ptr [ebp-8],edi
731c01ca 897dcc mov dword ptr [ebp-34h],edi
单步到此处:
发现msdn写的帮助上HeapRealloc有4个参数,而这里只传了一个参数,怀疑是该模块自己实现的一个函数,跟进去看
720c8fe0 8bd8 mov ebx,eax
720c8fe2 85db test ebx,ebx
720c8fe4 7525 jne mshtml!CImplAry::EnsureSizeWorker+0xb1 (720c900b)
720c8fe6 f6470402 test byte ptr [edi+4],2
720c8fea 0f85fc2e0400 jne mshtml!CImplAry::EnsureSizeWorker+0x56 (7210beec)
720c8ff0 ff75f8 push dword ptr [ebp-8]
720c8ff3 8d770c lea esi,[edi+0Ch]
720c8ff6 e86edcfdff call mshtml!_HeapRealloc (720a6c69)
发现msdn写的帮助上HeapRealloc有4个参数,而这里只传了一个参数,怀疑是该模块自己实现的一个函数,跟进去看
720a6c69 8bff mov edi,edi
720a6c6b 55 push ebp
720a6c6c 8bec mov ebp,esp
720a6c6e 57 push edi
720a6c6f 33ff xor edi,edi
720a6c71 397d08 cmp dword ptr [ebp+8],edi
720a6c74 0f84768c0e00 je mshtml!_HeapRealloc+0xd (7218f8f0)
720a6c7a 8b06 mov eax,dword ptr [esi]
720a6c7c ff7508 push dword ptr [ebp+8]
720a6c7f 3bc7 cmp eax,edi
720a6c81 0f85afd80200 jne mshtml!_HeapRealloc+0x43 (720d4536)
720a6c87 57 push edi
720a6c88 ff3518444272 push dword ptr [mshtml!g_hProcessHeap (72424418)]
720a6c8e ff15c412ef71 call dword ptr [mshtml!_imp__HeapAlloc (71ef12c4)] ;正常的堆分配函数
720a6c94 8906 mov dword ptr [esi],eax ;返回地址传入了[esi]
因此根据720c8ff3 8d770c lea esi,[edi+0Ch] 指令可知,堆内存地址返回到了edi+0Ch中
回去看:
720002f0 8bfe mov edi,esi
720002db 8db390000000 lea esi,[ebx+90h]
因此可知分配的堆地址存放在arg1,即table对象的0x9c偏移处
继续执行后,再次断下
继续单步发现:
73335a2c 8bc7 mov eax,edi
73335a2e e8d445dfff call mshtml!CTableCol::GetAAspan (7312a007)
73335a33 3de8030000 cmp eax,3E8h ;3e8正好是1000,而span不能超过1000,GetAAspan函数就是获取span值的函数
73335a38 894510 mov dword ptr [ebp+10h],eax
73335a3b 7c07 jl mshtml!CTableLayout::CalculateMinMax+0x394 (73335a44)
73335a3d c74510e8030000 mov dword ptr [ebp+10h],3E8h
对 mshtml!CTableCol::GetAAspan 下断后继续运行,由于修改了span的值,再次读取时将为1000
eax=055d90f8 ebx=056c7fe0 ecx=00000035 edx=00000000 esi=043d44ac edi=055d90f8
eip=7312a007 esp=030bd8f4 ebp=030bd994 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
mshtml!CTableCol::GetAAspan:
7312a007 8bff mov edi,edi
0:005> gu
eax=000003e8 ebx=056c7fe0 ecx=00000002 edx=09e261b8 esi=043d44ac edi=055d90f8
eip=73335a33 esp=030bd8f8 ebp=030bd994 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
mshtml!CTableLayout::CalculateMinMax+0x383:
73335a33 3de8030000 cmp eax,3E8h ;此时eax=1000
................................
格式化字符串漏洞分析
基于输出消息漏洞定位
其实就是一种字符串定位的方法
如 cve-2012-3569 VMware OVF Tool格式化字符串漏洞
当加载poc后输出一些特征字符串,载入od后搜索该字符串即可,然后跟过去看代码.
..............
3.通过栈回溯和堆状态判断漏洞类型
如cve-2010-3974-Microsoft Windows 传真封面编辑器双重释放漏洞
附加到windbg后直接打开poc.cov文件发生异常后:
0:005> g
ModLoad: 6e4f0000 6e504000 C:\Windows\system32\FontSub.dll
(efc.f84): C++ EH exception - code e06d7363 (first chance)
Critical error detected c0000374
(efc.f84): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=772d07ed edx=0012f38d esi=00460000 edi=023f40a8
eip=7737280d esp=0012f5e0 ebp=0012f658 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
ntdll!RtlReportCriticalFailure+0x29:
7737280d cc int 3
然后查看栈回溯:
从符号名可以发现应该是在做一些内存释放,资源销毁的动作,而且是在调用free函数后进入异常流程, 说明很可能是个双重释放漏洞
此外根据free, RtlFreeHeap函数的参数,可知绿色的即为要被释放的地址
0:000> kb
ChildEBP RetAddr Args to Child
0012f658 7737376b c0000374 7738cdc8 0012f69c ntdll!RtlReportCriticalFailure+0x29
0012f668 7737384b 00000002 7786b978 00460000 ntdll!RtlpReportHeapFailure+0x21
0012f69c 77373ab4 00000003 00460000 023f40a8 ntdll!RtlpLogHeapFailure+0xa1
0012f6f4 77337ad7 00460000 023f40a8 00000000 ntdll!RtlpAnalyzeHeapFailure+0x25b
0012f7e8 77302d68 023f40a8 023f40b0 023f40b0 ntdll!RtlpFreeHeap+0xc6
0012f808 76fc98cd 00460000 00000000 023f40b0 ntdll!RtlFreeHeap+0x142
0012f854 005ef43a 023f40b0 023f40b0 0012f880 msvcrt!free+0xcd
0012f864 005eab0c 00000001 00468b50 0046eea0 FXSCOVER!CDrawRoundRect::`scalar deleting destructor'+0x1a
0012f880 005eb1d4 00000000 0046eea0 6ab98515 FXSCOVER!CDrawDoc::Remove+0x96
0012f88c 6ab98515 0046eea0 6ab984df 0046eea0 FXSCOVER!CDrawDoc::DeleteContents+0xc
0012f894 6ab984df 0046eea0 0046eea0 0012f8d8 MFC42u!CDocument::OnNewDocument+0x15
0012f8a4 005ea812 0046eea0 6ab983e8 628d08b0 MFC42u!COleDocument::OnNewDocument+0xe
0012f8ac 6ab983e8 628d08b0 00468b50 00468bcc FXSCOVER!CDrawDoc::OnNewDocument+0xa
0012f8d8 6ab98598 00000000 00000001 628d0900 MFC42u!CSingleDocTemplate::OpenDocumentFile+0x103
4.基于ROP指令地址反向追踪
例如: CVE-2014-0502-Adobe Flash Player 双重释放漏洞分析, 详情见http://www.cnblogs.com/freesec/articles/6421878.html