2007年11月20日星期二

[Tips]关于call __alloca_probe中的"溢出"

by axis
2007-11-21
http://www.ph4nt0m.org

这两天在FD上有人说他发现了dxmsft里的多个溢出,他向微软报告,微软不理他,他就发到FD上了。
漏洞链接: Multiple stack-based buffer overflows in dxmsft.dll


跟了一下,发现这个“溢出”是发生在__alloca_probe里的,那么微软不理他也是正常的。
在我的机器里


这个调用是怎么一回事呢? 为什么说这里没用呢?

以前我在网上收集了一个tips,这里转贴一下,原出处已经忘了。

这个函数是在很多程序中间都能够看到的一个东西,Caller Function 调用了这个以后,堆栈结构就不再是一般的BP Frame 了,而变成Local Variable 使用 ESP 定位的方式了,一般用来在堆栈里分配大量的空间。它一般在Caller Function 构建好BP Frame 之后马上调用,EAX 中存放需要分配的字节数。函数返回之后 ESP = EBP - EAX。



.text:00458210 __alloca_probe  proc near               ; CODE XREF: .text:00414718p
.text:
00458210                                         ; sub_41487A+8p 
.text:
00458210
.text:
00458210 savedEBP        = dword ptr  8
.text:
00458210
.text:
00458210                 push    ecx
.text:
00458211                 cmp     eax, 1000h
.text:
00458216                 lea     ecx, [esp+savedEBP]
.text:0045821A                 jb      
short AllocLess1000h
.text:0045821C
.text:0045821C AllocStack1000h:                        ; CODE XREF: __alloca_probe
+1Ej
.text:0045821C                 sub     ecx, 1000h
.text:
00458222                 sub     eax, 1000h
.text:
00458227                 test    [ecx], eax      ; 看是否溢出
.text:
00458229                 cmp     eax, 1000h
.text:0045822E                 jnb     
short AllocStack1000h
.text:
00458230
.text:
00458230 AllocLess1000h:                         ; CODE XREF: __alloca_probe+Aj
.text:
00458230                 sub     ecx, eax
.text:
00458232                 mov     eax, esp        ; 记录原来的堆栈指针
.text:
00458234                 test    [ecx], eax      ; 看是否溢出
.text:
00458236                 mov     esp, ecx        ; 修改堆栈指针
.text:
00458238                 mov     ecx, [eax]      ; 相当于 pop ecx
.text:0045823A                 mov     eax, [eax
+4]    ; 这里存放的是返回地址
.text:0045823D                 push    eax             ; 构建一个假的Far Return 堆栈返回地址
.text:0045823E                 retn
.text:0045823E __alloca_probe  endp



注意: call __alloca_probe是用来分配空间的,如果溢出发生在这里,则说明是超出了栈空间,会有test [ecx], eax ; 看是否溢出 来检测, [ecx]指向字符串的指针.
所以溢出发生在这里是没有用的,是不能利用的。
比如yahoo messanger的activex 里的ywcupl.dll里的 ThrowViewer() GrantRequest()调用等...




BTW:好像这个dxmsft的我以前也fuzz出来过,不过看是发生在__alloca_probe就自动忽略了,如果去fuzz的话,应该能找出很多这种