作者blog:
http://hi.baidu.com/yicong2007
目 的:纯属学习,请勿用于恶意用途。
系统环境:XP SP3 简体中文版,IE 7
工 具:WinDbg+IDA
感谢mj0011指正了我原先分析的错误,感谢云砉生指出了出现漏洞的实质原因。
MPEG-2 0day是一个ReadFile时的缓冲区溢出,通过覆盖SEH配合heap spray使得shellcode获得执行机会。
漏洞利用网页http://vip762.3322.org/aa/index.htm
相关畸形文件logo.gif内容:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 00 03 00 00 11 20 34 00 00 00 00 00 00 00 00 00 ..... 4.........
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 FF FF FF FF 0C 0C 0C 0C 00 ......ÿÿÿÿ.....
因为我不清楚这个编码规范,仅凭后面调试过程中看到的结果,猜测这个结构。
第0-3个字节 0x00000300h,某个属性标识,意义不详
第4-5个字节 0x2011h,这似乎又是一个属性值(代码中根据这个属性值不同去到不同的分支)
第6-9个字节 0x00000034h, 这个似乎指的是该DWORD后面的内容的长度。
第10-13个字节 与第6-9个字节一起被读入,用途不详。
第14个字节及以后:由于代码对缓冲区地址以及指针的处理有误,这部分数据被读入栈中,造成缓冲区溢出覆盖掉SEH,使shellcode获得执行机会。
触发过程:
在msvidctl.dll的ATL::AtlIPersistStreamInit_Load调用ATL::CComVariant::ReadFromStream的时候,后者通过读取文件中的这个标识内容长度的0x00000034h,并调用mshtml!FatStream::Read(是对ReadFile的封装)将内容读入内存。
ATL::CComVariant::ReadFromStream成功申请了内存,但是在调用mshtml!FatStream::Read的时候犯了一个程序员经常犯的错误(感谢云砉生指出这一点),即将保存缓冲区指针的堆栈地址当成缓冲区指针本身传入(将传入参数buff误写为&buff),使得读入的文件内容覆盖掉了属于ATL::AtlIPersistStreamInit_Load的局部变量以及其设置的SEH,其中0xFFFFFFFF与0x0C0C0C0C刚好覆盖掉SEH,0x0C0C0C0C这个地址已通过Heap spray被shellcode前面的nop占据,结果ATL::AtlIPersistStreamInit_Load在后续操作中触发了异常,就跳到shellcode中执行了。
ATL::AtlIPersistStreamInit_Load的代码如下,注意注释的标号说明顺序。
.text:59F0D3BA
.text:59F0D3BA ; *************** S U B R O U T I N E ***************************************
.text:59F0D3BA
.text:59F0D3BA
.text:59F0D3BA long __stdcall ATL::AtlIPersistStreamInit_Load(struct IStream *, struct ATL::ATL_PROPMAP_ENTRY *, void *, struct IUnknown *, bool) proc near
.text:59F0D3BA mov eax, offset loc_59FC730E
.text:59F0D3BF call __EH_prolog
.text:59F0D3BF
.text:59F0D3C4 sub esp, 18h ; (5)第三次到达这里,插入SEH后,这个SEH最后被溢出覆盖了
.text:59F0D3C7 mov eax, [ebp+8]
.text:59F0D3CA push ebx
.text:59F0D3CB push esi
.text:59F0D3CC xor esi, esi
.text:59F0D3CE cmp eax, esi
.text:59F0D3D0 push edi
.text:59F0D3D1 jz loc_59F0D603
.text:59F0D3D1
.text:59F0D3D7 mov ebx, [ebp+0Ch] ; ATL::ATL_PROPMAP_ENTRY * `public: static struct ATL::ATL_PROPMAP_ENTRY * __stdcall CMPEG2TuneRequest::GetPropertyMap(void)'::`2'::pPropMap
.text:59F0D3DA cmp ebx, esi
.text:59F0D3DC jz loc_59F0D603
.text:59F0D3DC
.text:59F0D3E2 cmp [ebp+10h], esi
.text:59F0D3E5 jz loc_59F0D603
.text:59F0D3E5
.text:59F0D3EB cmp [ebp+14h], esi
.text:59F0D3EE jz loc_59F0D603
.text:59F0D3EE
.text:59F0D3F4 cmp byte ptr [ebp+18h], 0
.text:59F0D3F8 mov [ebp+0Ch], esi
.text:59F0D3FB jz short loc_59F0D422 ; (3)第二次进入的时候这里跳走了
.text:59F0D3FB ; (6)第三次进入的时候也跳走了
.text:59F0D3FB
.text:59F0D3FD mov ecx, [eax]
.text:59F0D3FF push esi
.text:59F0D400 push 4
.text:59F0D402 lea edx, [ebp-14h] ; Buffer
.text:59F0D405 push edx
.text:59F0D406 push eax
.text:59F0D407 call dword ptr [ecx+0Ch] ; (1)mshtml!FatStream::Read,第一次读取最前面4个字节
.text:59F0D40A cmp eax, esi
.text:59F0D40C mov [ebp+0Ch], eax
.text:59F0D40F jl loc_59F0D608
.text:59F0D40F
.text:59F0D415 cmp dword ptr [ebp-14h], 300h ; [ebp-14]==0x300
.text:59F0D41C ja loc_59F0D5C7
.text:59F0D41C
.text:59F0D422
.text:59F0D422 loc_59F0D422: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+41j
.text:59F0D422 mov [ebp+18h], esi
.text:59F0D425 cmp [ebx+8], esi
.text:59F0D428 mov [ebp-4], esi
.text:59F0D42B mov [ebp-10h], esi
.text:59F0D42E jz loc_59F0D5ED
.text:59F0D42E
.text:59F0D434 mov [ebp-14h], ebx
.text:59F0D434
.text:59F0D437
.text:59F0D437 loc_59F0D437: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+1F4j
.text:59F0D437 mov eax, [ebx+0Ch]
.text:59F0D43A cmp eax, esi
.text:59F0D43C jz short loc_59F0D489 ; (7)第三次进入的时候这里跳走了
.text:59F0D43C
.text:59F0D43E push 4
.text:59F0D440 mov esi, eax
.text:59F0D442 pop ecx
.text:59F0D443 mov edi, offset __GUID_2a6e293d_2595_11d3_b64c_00c04f79498e
.text:59F0D448 xor eax, eax
.text:59F0D44A repe cmpsd
.text:59F0D44C jnz short loc_59F0D487
.text:59F0D44C
.text:59F0D44E call dword ptr [ebx+8]
.text:59F0D451 test eax, eax
.text:59F0D453 jz loc_59F0D5B6
.text:59F0D453
.text:59F0D459 mov ecx, [ebx+10h]
.text:59F0D45C add ecx, [ebp+10h]
.text:59F0D45F push 0
.text:59F0D461 push dword ptr [ebp+14h]
.text:59F0D464 push ecx
.text:59F0D465 push eax
.text:59F0D466 push dword ptr [ebp+8]
.text:59F0D469 call ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool) ; (2)重入
.text:59F0D469 ; (4)又一次重入
.text:59F0D469
.text:59F0D46E test eax, eax
.text:59F0D470 mov [ebp+0Ch], eax
.text:59F0D473 jge loc_59F0D513
.text:59F0D473
.text:59F0D479 mov eax, [ebp+18h]
.text:59F0D47C or dword ptr [ebp-4], 0FFFFFFFFh
.text:59F0D480 test eax, eax
.text:59F0D482 jmp loc_59F0D5F6
.text:59F0D482
.text:59F0D487 ; ---------------------------------------------------------------------------
.text:59F0D487
.text:59F0D487 loc_59F0D487: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+92j
.text:59F0D487 xor esi, esi
.text:59F0D487
.text:59F0D489
.text:59F0D489 loc_59F0D489: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+82j
.text:59F0D489 cmp [ebx], esi
.text:59F0D48B jz loc_59F0D5A2
.text:59F0D48B
.text:59F0D491 xor eax, eax
.text:59F0D493 lea edi, [ebp-24h] ; (8)
.text:59F0D496 stosd
.text:59F0D497 stosd
.text:59F0D498 stosd
.text:59F0D499 stosd
.text:59F0D49A mov [ebp-24h], si ; si=0
.text:59F0D49E mov edi, [ebx+10h]
.text:59F0D4A1 mov ecx, [ebx+14h]
.text:59F0D4A4 add edi, [ebp+10h]
.text:59F0D4A7 cmp ecx, esi
.text:59F0D4A9 mov byte ptr [ebp-4], 1
.text:59F0D4AD jz short loc_59F0D4CE
.text:59F0D4AD
.text:59F0D4AF movzx eax, word ptr [ebx+18h]
.text:59F0D4B3 cmp eax, 0Bh ; eax==0dh
.text:59F0D4B6 jg short loc_59F0D51A ; (9)跳走了
.text:59F0D4B6
.text:59F0D4B8 jz short loc_59F0D529
.text:59F0D4B8
.text:59F0D4BA cmp eax, 2
.text:59F0D4BD jl short loc_59F0D4CE
.text:59F0D4BD
.text:59F0D4BF cmp eax, 3
.text:59F0D4C2 jle short loc_59F0D529
.text:59F0D4C2
.text:59F0D4C4 cmp eax, 4
.text:59F0D4C7 jle short loc_59F0D4CE
.text:59F0D4C7
.text:59F0D4C9 cmp eax, 7
.text:59F0D4CC jle short loc_59F0D529
.text:59F0D4CC
.text:59F0D4CE
.text:59F0D4CE loc_59F0D4CE: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+F3j
.text:59F0D4CE ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+103j
.text:59F0D4CE ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+10Dj
.text:59F0D4CE ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+163j
.text:59F0D4CE ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+16Dj
.text:59F0D4CE push dword ptr [ebp+8] ;
.text:59F0D4D1 lea ecx, [ebp-24h]
.text:59F0D4D4 call ATL::CComVariant::ReadFromStream(IStream *); (11)这里溢出了!
.text:59F0D4D4
.text:59F0D4D9 cmp eax, esi
.text:59F0D4DB mov [ebp+0Ch], eax
.text:59F0D4DE jl loc_59F0D5D5
.text:59F0D4DE
.text:59F0D4E4 mov ecx, [ebx+14h]
.text:59F0D4E7 cmp ecx, esi
.text:59F0D4E9 jz short loc_59F0D542
.text:59F0D4E9
.text:59F0D4EB mov eax, ecx
.text:59F0D4ED shr ecx, 2
.text:59F0D4F0 lea esi, [ebp-1Ch]
.text:59F0D4F3 rep movsd
.text:59F0D4F5 mov ecx, eax
.text:59F0D4F7 and ecx, 3
.text:59F0D4FA lea eax, [ebp-24h]
.text:59F0D4FD rep movsb
.text:59F0D4FF and word ptr [ebp-24h], 0
.text:59F0D504 push eax ; pvarg
.text:59F0D505 mov byte ptr [ebp-1Ch], 0
.text:59F0D509 mov byte ptr [ebp-4], 0
.text:59F0D50D call ds:VariantClear(x)
.text:59F0D50D
.text:59F0D513
.text:59F0D513 loc_59F0D513: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+B9j
.text:59F0D513 xor esi, esi
.text:59F0D515 jmp loc_59F0D5A2
.text:59F0D515
.text:59F0D51A ; ---------------------------------------------------------------------------
.text:59F0D51A
.text:59F0D51A loc_59F0D51A: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+FCj
.text:59F0D51A cmp eax, 10h
.text:59F0D51D jl short loc_59F0D4CE ; (10)跳走了
.text:59F0D51D
.text:59F0D51F cmp eax, 17h
.text:59F0D522 jle short loc_59F0D529
.text:59F0D522
.text:59F0D524 cmp eax, 48h
.text:59F0D527 jnz short loc_59F0D4CE
.text:59F0D527
.text:59F0D529
.text:59F0D529 loc_59F0D529: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+FEj
.text:59F0D529 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+108j
.text:59F0D529 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+112j
.text:59F0D529 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+168j
.text:59F0D529 mov eax, [ebp+8]
.text:59F0D52C mov edx, [eax]
.text:59F0D52E push esi
.text:59F0D52F push ecx
.text:59F0D530 push edi
.text:59F0D531 push eax
.text:59F0D532 call dword ptr [edx+0Ch]
.text:59F0D535 cmp eax, esi
.text:59F0D537 mov [ebp+0Ch], eax
.text:59F0D53A jl loc_59F0D5D5
.text:59F0D53A
.text:59F0D540 jmp short loc_59F0D586
.text:59F0D540
.text:59F0D542 ; ---------------------------------------------------------------------------
.text:59F0D542
.text:59F0D542 loc_59F0D542: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+12Fj
.text:59F0D542 mov eax, [ebp-10h]
.text:59F0D545 cmp [ebx+0Ch], eax
.text:59F0D548 jz short loc_59F0D573
.text:59F0D548
.text:59F0D54A mov eax, [ebp+18h]
.text:59F0D54D cmp eax, esi
.text:59F0D54F jz short loc_59F0D55A
.text:59F0D54F
.text:59F0D551 mov [ebp+18h], esi
.text:59F0D554 mov ecx, [eax]
.text:59F0D556 push eax
.text:59F0D557 call dword ptr [ecx+8]
.text:59F0D557
.text:59F0D55A
.text:59F0D55A loc_59F0D55A: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+195j
.text:59F0D55A mov eax, [ebp+14h]
.text:59F0D55D mov ecx, [eax]
.text:59F0D55F lea edx, [ebp+18h]
.text:59F0D562 push edx
.text:59F0D563 push dword ptr [ebx+0Ch]
.text:59F0D566 push eax
.text:59F0D567 call dword ptr [ecx]
.text:59F0D569 test eax, eax
.text:59F0D56B jl short loc_59F0D5CE
.text:59F0D56B
.text:59F0D56D mov eax, [ebx+0Ch]
.text:59F0D570 mov [ebp-10h], eax
.text:59F0D570
.text:59F0D573
.text:59F0D573 loc_59F0D573: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+18Ej
.text:59F0D573 lea eax, [ebp-24h]
.text:59F0D576 push eax
.text:59F0D577 push dword ptr [ebx+4]
.text:59F0D57A push dword ptr [ebp+18h]
.text:59F0D57D call ATL::CComDispatchDriver::PutProperty(IDispatch *,long,tagVARIANT *)
.text:59F0D57D
.text:59F0D582 test eax, eax
.text:59F0D584 jl short loc_59F0D5CE
.text:59F0D584
.text:59F0D586
.text:59F0D586 loc_59F0D586: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+186j
.text:59F0D586 cmp word ptr [ebp-24h], 0FFFh
.text:59F0D58C mov byte ptr [ebp-4], 0
.text:59F0D590 jnz short loc_59F0D598
.text:59F0D590
.text:59F0D592 mov word ptr [ebp-24h], 8
.text:59F0D592
.text:59F0D598
.text:59F0D598 loc_59F0D598: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+1D6j
.text:59F0D598 lea eax, [ebp-24h]
.text:59F0D59B push eax ; pvarg
.text:59F0D59C call ds:VariantClear(x)
.text:59F0D59C
.text:59F0D5A2
.text:59F0D5A2 loc_59F0D5A2: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+D1j
.text:59F0D5A2 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+15Bj
.text:59F0D5A2 mov ebx, [ebp-14h] ; (18)这里由于前面的溢出,[ebp-14]被覆盖,为0
.text:59F0D5A5 add ebx, 20h
.text:59F0D5A8 cmp [ebx+8], esi ; (19)这里访问0x00000028处内存,触发了Access Violation
.text:59F0D5AB mov [ebp-14h], ebx
.text:59F0D5AE jnz loc_59F0D437
.text:59F0D5AE
.text:59F0D5B4 jmp short loc_59F0D5ED
.text:59F0D5B4
.text:59F0D5B6 ; ---------------------------------------------------------------------------
.text:59F0D5B6
.text:59F0D5B6 loc_59F0D5B6: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+99j
.text:59F0D5B6 mov eax, [ebp+18h]
.text:59F0D5B9 or dword ptr [ebp-4], 0FFFFFFFFh
.text:59F0D5BD test eax, eax
.text:59F0D5BF jz short loc_59F0D5C7
.text:59F0D5BF
.text:59F0D5C1 mov ecx, [eax]
.text:59F0D5C3 push eax
.text:59F0D5C4 call dword ptr [ecx+8]
.text:59F0D5C4
.text:59F0D5C7
.text:59F0D5C7 loc_59F0D5C7: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+62j
.text:59F0D5C7 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+205j
.text:59F0D5C7 mov eax, 80004005h
.text:59F0D5CC jmp short loc_59F0D608
.text:59F0D5CC
.text:59F0D5CE ; ---------------------------------------------------------------------------
.text:59F0D5CE
.text:59F0D5CE loc_59F0D5CE: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+1B1j
.text:59F0D5CE ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+1CAj
.text:59F0D5CE mov dword ptr [ebp+0Ch], 80004005h
.text:59F0D5CE
.text:59F0D5D5
.text:59F0D5D5 loc_59F0D5D5: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+124j
.text:59F0D5D5 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+180j
.text:59F0D5D5 cmp word ptr [ebp-24h], 0FFFh
.text:59F0D5DB jnz short loc_59F0D5E3
.text:59F0D5DB
.text:59F0D5DD mov word ptr [ebp-24h], 8
.text:59F0D5DD
.text:59F0D5E3
.text:59F0D5E3 loc_59F0D5E3: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+221j
.text:59F0D5E3 lea eax, [ebp-24h]
.text:59F0D5E6 push eax ; pvarg
.text:59F0D5E7 call ds:VariantClear(x)
.text:59F0D5E7
.text:59F0D5ED
.text:59F0D5ED loc_59F0D5ED: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+74j
.text:59F0D5ED ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+1FAj
.text:59F0D5ED mov eax, [ebp+18h]
.text:59F0D5F0 or dword ptr [ebp-4], 0FFFFFFFFh
.text:59F0D5F4 cmp eax, esi
.text:59F0D5F4
.text:59F0D5F6
.text:59F0D5F6 loc_59F0D5F6: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+C8j
.text:59F0D5F6 jz short loc_59F0D5FE
.text:59F0D5F6
.text:59F0D5F8 mov ecx, [eax]
.text:59F0D5FA push eax
.text:59F0D5FB call dword ptr [ecx+8]
.text:59F0D5FB
.text:59F0D5FE
.text:59F0D5FE loc_59F0D5FE: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool):loc_59F0D5F6j
.text:59F0D5FE mov eax, [ebp+0Ch]
.text:59F0D601 jmp short loc_59F0D608
.text:59F0D601
.text:59F0D603 ; ---------------------------------------------------------------------------
.text:59F0D603
.text:59F0D603 loc_59F0D603: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+17j
.text:59F0D603 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+22j
.text:59F0D603 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+2Bj
.text:59F0D603 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+34j
.text:59F0D603 mov eax, 80004003h
.text:59F0D603
.text:59F0D608
.text:59F0D608 loc_59F0D608: ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+55j
.text:59F0D608 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+212j
.text:59F0D608 ; ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+247j
.text:59F0D608 mov ecx, [ebp-0Ch]
.text:59F0D60B pop edi
.text:59F0D60C pop esi
.text:59F0D60D pop ebx
.text:59F0D60E mov large fs:0, ecx
.text:59F0D615 leave
.text:59F0D616 retn 14h
.text:59F0D616
.text:59F0D616 long __stdcall ATL::AtlIPersistStreamInit_Load(struct IStream *, struct ATL::ATL_PROPMAP_ENTRY *, void *, struct IUnknown *, bool) endp ; sp = 4
.text:59F0D616
.text:59F0D616 ; ---------------------------------------------------------------------------
.text:59F0D4D4 call ATL::CComVariant::ReadFromStream(IStream *);
这里call进去,代码如下,同样注意注释标号:
.text:59F0D61E
.text:59F0D61E ; *************** S U B R O U T I N E ***************************************
.text:59F0D61E
.text:59F0D61E
.text:59F0D61E public: long __thiscall ATL::CComVariant::ReadFromStream(struct IStream *) proc near
.text:59F0D61E ; CODE XREF: ATL::AtlIPersistStreamInit_Load(IStream *,ATL::ATL_PROPMAP_ENTRY *,void *,IUnknown *,bool)+11Ap
.text:59F0D61E mov eax, offset loc_59FC7325
.text:59F0D623 call __EH_prolog
.text:59F0D623
.text:59F0D628 sub esp, 1Ch
.text:59F0D62B push ebx
.text:59F0D62C push esi
.text:59F0D62D mov esi, ecx
.text:59F0D62F push esi ; pvarg
.text:59F0D630 call ds:VariantClear(x)
.text:59F0D636 xor ebx, ebx
.text:59F0D638 cmp eax, ebx
.text:59F0D63A jl loc_59F0D7BE
.text:59F0D63A
.text:59F0D640 push edi
.text:59F0D641 mov edi, [ebp+8]
.text:59F0D644 mov eax, [edi]
.text:59F0D646 push ebx
.text:59F0D647 push 2
.text:59F0D649 lea ecx, [ebp-10h] ; Buffer
.text:59F0D64C push ecx
.text:59F0D64D push edi
.text:59F0D64E call dword ptr [eax+0Ch] ; (12)mshtml!FatStream::Read,第一次(整个过程第二次)读了两个字节属性值0x2011
.text:59F0D651 cmp eax, 1
.text:59F0D654 jnz short loc_59F0D65B
.text:59F0D654
.text:59F0D656 mov eax, 80004005h
.text:59F0D656
.text:59F0D65B
.text:59F0D65B loc_59F0D65B: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+36j
.text:59F0D65B cmp eax, ebx
.text:59F0D65D jl loc_59F0D7BD
.text:59F0D65D
.text:59F0D663 mov ecx, [ebp-10h] ; 读出的属性值,这里是0x2011
.text:59F0D666 movzx eax, cx
.text:59F0D669 cmp eax, 48h
.text:59F0D66C mov [esi], cx
.text:59F0D66F jg short loc_59F0D6DC ; (13)这里跳走了
.text:59F0D66F
.text:59F0D671 jz short loc_59F0D6D7
.text:59F0D671
.text:59F0D673 dec eax
.text:59F0D674 dec eax
.text:59F0D675 cmp eax, 15h
.text:59F0D678 ja loc_59F0D76B
.text:59F0D678
.text:59F0D67E movzx eax, ds:byte_59F0D7E6[eax]
.text:59F0D685 jmp ds:off_59F0D7CE[eax*4]
.text:59F0D685
.text:59F0D68C
.text:59F0D68C loc_59F0D68C: ; DATA XREF: .text:59F0D7DAo
.text:59F0D68C lea eax, [esi+8]
.text:59F0D68F cmp cx, 0Dh
.text:59F0D693 mov [eax], ebx
.text:59F0D695 mov ecx, offset __GUID_00000000_0000_0000_c000_000000000046
.text:59F0D69A jz short loc_59F0D6A1
.text:59F0D69A
.text:59F0D69C mov ecx, offset __GUID_00020400_0000_0000_c000_000000000046
.text:59F0D69C
.text:59F0D6A1
.text:59F0D6A1 loc_59F0D6A1: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+7Cj
.text:59F0D6A1 push eax ; ppvObj
.text:59F0D6A2 push ecx ; iidInterface
.text:59F0D6A3 push edi ; pStm
.text:59F0D6A4 call ds:OleLoadFromStream(x,x,x)
.text:59F0D6AA xor eax, eax
.text:59F0D6AC jmp loc_59F0D7BD
.text:59F0D6AC
.text:59F0D6B1 ; ---------------------------------------------------------------------------
.text:59F0D6B1
.text:59F0D6B1 loc_59F0D6B1: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+67j
.text:59F0D6B1 ; DATA XREF: .text:59F0D7DEo
.text:59F0D6B1 xor eax, eax
.text:59F0D6B3 inc eax
.text:59F0D6B3
.text:59F0D6B4
.text:59F0D6B4 loc_59F0D6B4: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+BCj
.text:59F0D6B4 mov ecx, [edi]
.text:59F0D6B6 push ebx
.text:59F0D6B7 push eax
.text:59F0D6B8 add esi, 8
.text:59F0D6BB push esi
.text:59F0D6BC push edi
.text:59F0D6BD call dword ptr [ecx+0Ch]
.text:59F0D6C0 cmp eax, 1
.text:59F0D6C3 jnz loc_59F0D7BD
.text:59F0D6C3
.text:59F0D6C9 jmp short loc_59F0D701
.text:59F0D6C9
.text:59F0D6CB ; ---------------------------------------------------------------------------
.text:59F0D6CB
.text:59F0D6CB loc_59F0D6CB: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+67j
.text:59F0D6CB ; DATA XREF: .text:off_59F0D7CEo
.text:59F0D6CB push 2
.text:59F0D6CD jmp short loc_59F0D6D9
.text:59F0D6CD
.text:59F0D6CF ; ---------------------------------------------------------------------------
.text:59F0D6CF
.text:59F0D6CF loc_59F0D6CF: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+67j
.text:59F0D6CF ; DATA XREF: .text:59F0D7D2o
.text:59F0D6CF push 4
.text:59F0D6D1 jmp short loc_59F0D6D9
.text:59F0D6D1
.text:59F0D6D3 ; ---------------------------------------------------------------------------
.text:59F0D6D3
.text:59F0D6D3 loc_59F0D6D3: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+67j
.text:59F0D6D3 ; DATA XREF: .text:59F0D7D6o
.text:59F0D6D3 push 8
.text:59F0D6D5 jmp short loc_59F0D6D9
.text:59F0D6D5
.text:59F0D6D7 ; ---------------------------------------------------------------------------
.text:59F0D6D7
.text:59F0D6D7 loc_59F0D6D7: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+53j
.text:59F0D6D7 push 10h
.text:59F0D6D7
.text:59F0D6D9
.text:59F0D6D9 loc_59F0D6D9: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+AFj
.text:59F0D6D9 ; ATL::CComVariant::ReadFromStream(IStream *)+B3j
.text:59F0D6D9 ; ATL::CComVariant::ReadFromStream(IStream *)+B7j
.text:59F0D6D9 pop eax
.text:59F0D6DA jmp short loc_59F0D6B4
.text:59F0D6DA
.text:59F0D6DC ; ---------------------------------------------------------------------------
.text:59F0D6DC
.text:59F0D6DC loc_59F0D6DC: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+51j
.text:59F0D6DC cmp eax, 2011h
.text:59F0D6E1 jnz loc_59F0D76B
.text:59F0D6E1
.text:59F0D6E7 mov eax, [edi]
.text:59F0D6E9 push ebx
.text:59F0D6EA push 8
.text:59F0D6EC lea ecx, [ebp-28h] ; Buffer
.text:59F0D6EF push ecx
.text:59F0D6F0 push edi
.text:59F0D6F1 call dword ptr [eax+0Ch] ; (14)mshtml!FatStream::Read,又读了8字节,这时dword ptr [ebp-28h]=0x00000034
.text:59F0D6F4 cmp eax, ebx
.text:59F0D6F6 jl loc_59F0D7BD
.text:59F0D6F6
.text:59F0D6FC cmp eax, 1
.text:59F0D6FF jnz short loc_59F0D70B ; (15)跳走了
.text:59F0D6FF
.text:59F0D701
.text:59F0D701 loc_59F0D701: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+ABj
.text:59F0D701 ; ATL::CComVariant::ReadFromStream(IStream *)+146j
.text:59F0D701 mov eax, 80004005h
.text:59F0D706 jmp loc_59F0D7BD
.text:59F0D706
.text:59F0D70B ; ---------------------------------------------------------------------------
.text:59F0D70B
.text:59F0D70B loc_59F0D70B: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+E1j
.text:59F0D70B mov eax, [ebp-28h]
.text:59F0D70E mov [ebp-20h], eax
.text:59F0D711 lea eax, [ebp-20h]
.text:59F0D714 push eax ; rgsabound
.text:59F0D715 push 1 ; cDims
.text:59F0D717 push 11h ; vt
.text:59F0D719 mov [ebp-1Ch], ebx
.text:59F0D71C call ds:SafeArrayCreate(x,x,x)
.text:59F0D722 mov ebx, eax
.text:59F0D724 test ebx, ebx
.text:59F0D726 jnz short loc_59F0D732 ; (16)跳走了
.text:59F0D726
.text:59F0D728 mov eax, 8007000Eh
.text:59F0D72D jmp loc_59F0D7BD
.text:59F0D72D
.text:59F0D732 ; ---------------------------------------------------------------------------
.text:59F0D732
.text:59F0D732 loc_59F0D732: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+108j
.text:59F0D732 lea eax, [ebp+8]
.text:59F0D735 push eax ; ppvData
.text:59F0D736 push ebx ; psa
.text:59F0D737 call ds:SafeArrayAccessData(x,x)
.text:59F0D73D test eax, eax
.text:59F0D73F jl short loc_59F0D7BD
.text:59F0D73F
.text:59F0D741 mov eax, [edi]
.text:59F0D743 push 0
.text:59F0D745 push dword ptr [ebp-28h] ; 直接取dword ptr [ebp-28](=0x00000034)作为NumberOfBytesToRead
.text:59F0D748 lea ecx, [ebp+8] ; 27楼的云砉生说得很中肯,这里本来[ebp+8]里保存的就是已分配的0x34字节缓冲区,因此必须是mov ecx, [ebp+8]才是正确的
.text:59F0D74B push ecx
.text:59F0D74C push edi
.text:59F0D74D call dword ptr [eax+0Ch] ; (17)mshtml!FatStream::Read,直接读了,因为指针搞错,结果溢出了
.text:59F0D750 push ebx ; psa
.text:59F0D751 mov [ebp-18h], eax
.text:59F0D754 call ds:SafeArrayUnaccessData(x)
.text:59F0D75A mov eax, [ebp-18h]
.text:59F0D75D test eax, eax
.text:59F0D75F jl short loc_59F0D7BD
.text:59F0D75F
.text:59F0D761 cmp eax, 1
.text:59F0D764 jz short loc_59F0D701
.text:59F0D764
.text:59F0D766 mov [esi+8], ebx
.text:59F0D769 xor ebx, ebx
.text:59F0D769
.text:59F0D76B
.text:59F0D76B loc_59F0D76B: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+5Aj
.text:59F0D76B ; ATL::CComVariant::ReadFromStream(IStream *)+67j
.text:59F0D76B ; ATL::CComVariant::ReadFromStream(IStream *)+C3j
.text:59F0D76B ; DATA XREF: .text:59F0D7E2o
.text:59F0D76B mov [ebp-14h], ebx
.text:59F0D76E push edi
.text:59F0D76F lea ecx, [ebp-14h]
.text:59F0D772 mov [ebp-4], ebx
.text:59F0D775 call ATL::CComBSTR::ReadFromStream(IStream *)
.text:59F0D775
.text:59F0D77A mov edi, eax
.text:59F0D77C cmp edi, ebx
.text:59F0D77E jl short loc_59F0D7B2
.text:59F0D77E
.text:59F0D780 cmp word ptr [ebp-10h], 8
.text:59F0D785 mov eax, [ebp-14h]
.text:59F0D788 mov word ptr [esi], 8
.text:59F0D78D mov [ebp-14h], ebx
.text:59F0D790 mov [esi+8], eax
.text:59F0D793 jz short loc_59F0D7AB
.text:59F0D793
.text:59F0D795 cmp word ptr [ebp-10h], 0FFFh
.text:59F0D79B jz short loc_59F0D7AB
.text:59F0D79B
.text:59F0D79D push dword ptr [ebp-10h] ; vt
.text:59F0D7A0 push ebx ; wFlags
.text:59F0D7A1 push esi ; pvarSrc
.text:59F0D7A2 push esi ; pvargDest
.text:59F0D7A3 call ds:VariantChangeType(x,x,x,x)
.text:59F0D7A9 mov edi, eax
.text:59F0D7A9
.text:59F0D7AB
.text:59F0D7AB loc_59F0D7AB: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+175j
.text:59F0D7AB ; ATL::CComVariant::ReadFromStream(IStream *)+17Dj
.text:59F0D7AB mov ax, [ebp-10h]
.text:59F0D7AF mov [esi], ax
.text:59F0D7AF
.text:59F0D7B2
.text:59F0D7B2 loc_59F0D7B2: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+160j
.text:59F0D7B2 push dword ptr [ebp-14h] ; BSTR
.text:59F0D7B5 call ds:SysFreeString(x)
.text:59F0D7BB mov eax, edi
.text:59F0D7BB
.text:59F0D7BD
.text:59F0D7BD loc_59F0D7BD: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+3Fj
.text:59F0D7BD ; ATL::CComVariant::ReadFromStream(IStream *)+8Ej
.text:59F0D7BD ; ATL::CComVariant::ReadFromStream(IStream *)+A5j
.text:59F0D7BD ; ATL::CComVariant::ReadFromStream(IStream *)+D8j
.text:59F0D7BD ; ATL::CComVariant::ReadFromStream(IStream *)+E8j
.text:59F0D7BD ; ATL::CComVariant::ReadFromStream(IStream *)+10Fj ...
.text:59F0D7BD pop edi
.text:59F0D7BD
.text:59F0D7BE
.text:59F0D7BE loc_59F0D7BE: ; CODE XREF: ATL::CComVariant::ReadFromStream(IStream *)+1Cj
.text:59F0D7BE mov ecx, [ebp-0Ch]
.text:59F0D7C1 pop esi
.text:59F0D7C2 pop ebx
.text:59F0D7C3 mov large fs:0, ecx
.text:59F0D7CA leave
.text:59F0D7CB retn 4
.text:59F0D7CB
.text:59F0D7CB public: long __thiscall ATL::CComVariant::ReadFromStream(struct IStream *) endp ; sp = 4
.text:59F0D7CB
.text:59F0D7CB ; ---------------------------------------------------------------------------
mshtml!FatStream::Read代码如下:
.text:3F87C14B
.text:3F87C14B ; *************** S U B R O U T I N E ***************************************
.text:3F87C14B
.text:3F87C14B ; Attributes: bp-based frame
.text:3F87C14B
.text:3F87C14B ; int __stdcall FatStream__Read(int,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD lpNumberOfBytesRead)
.text:3F87C14B public: virtual long __stdcall FatStream::Read(void *, unsigned long, unsigned long *) proc near
.text:3F87C14B ; DATA XREF: .text:3F7F0FB8o
.text:3F87C14B
.text:3F87C14B arg_0 = dword ptr 8
.text:3F87C14B lpBuffer = dword ptr 0Ch
.text:3F87C14B nNumberOfBytesToRead= dword ptr 10h
.text:3F87C14B lpNumberOfBytesRead= dword ptr 14h
.text:3F87C14B
.text:3F87C14B ; FUNCTION CHUNK AT .text:3F8F8BCA SIZE 00000012 BYTES
.text:3F87C14B
.text:3F87C14B mov edi, edi
.text:3F87C14D push ebp
.text:3F87C14E mov ebp, esp
.text:3F87C150 mov eax, [ebp+arg_0]
.text:3F87C153 mov ecx, [eax+8] ; FileHandle
.text:3F87C156 cmp ecx, INVALID_HANDLE_VALUE
.text:3F87C159 jz loc_3F8F8BCA ; FileHandle is wrong.
.text:3F87C159
.text:3F87C15F mov eax, [ebp+lpNumberOfBytesRead]
.text:3F87C162 test eax, eax
.text:3F87C164 jz loc_3F8F8BD4
.text:3F87C164
.text:3F87C16A
.text:3F87C16A loc_3F87C16A: ; CODE XREF: FatStream::Read(void *,ulong,ulong *)+7CA8Cj
.text:3F87C16A push 0 ; lpOverlapped
.text:3F87C16C push eax ; lpNumberOfBytesRead
.text:3F87C16D push [ebp+nNumberOfBytesToRead] ; nNumberOfBytesToRead
.text:3F87C170 push [ebp+lpBuffer] ; lpBuffer
.text:3F87C173 push ecx ; hFile
.text:3F87C174 call ds:ReadFile(x,x,x,x,x)
.text:3F87C17A test eax, eax
.text:3F87C17C jz short loc_3F87C184
.text:3F87C17C
.text:3F87C17E xor eax, eax
.text:3F87C17E
.text:3F87C180
.text:3F87C180 loc_3F87C180: ; CODE XREF: FatStream::Read(void *,ulong,ulong *)+3Ej
.text:3F87C180 ; FatStream::Read(void *,ulong,ulong *)+7CA84j
.text:3F87C180 pop ebp
.text:3F87C181 retn 10h
.text:3F87C181
.text:3F87C184 ; ---------------------------------------------------------------------------
.text:3F87C184
.text:3F87C184 loc_3F87C184: ; CODE XREF: FatStream::Read(void *,ulong,ulong *)+31j
.text:3F87C184 call GetLastWin32Error(void)
.text:3F87C184
.text:3F87C189 jmp short loc_3F87C180
.text:3F87C189
.text:3F87C189 public: virtual long __stdcall FatStream::Read(void *, unsigned long, unsigned long *) endp
.text:3F87C189
.text:3F87C189 ; ---------------------------------------------------------------------------
可以看到仅仅是ReadFile而已。
[课程]Android-CTF解题方法汇总!