CODE:004AC138 sub_4AC138 proc near ; CODE XREF: sub_4AA590+50 p
CODE:004AC138 ; sub_4AA590+26B p
CODE:004AC138
CODE:004AC138 var_1024 = dword ptr -1024h
CODE:004AC138 var_1020 = dword ptr -1020h
CODE:004AC138 var_101C = word ptr -101Ch
CODE:004AC138 var_1018 = dword ptr -1018h
CODE:004AC138 var_1014 = dword ptr -1014h
CODE:004AC138 var_1010 = dword ptr -1010h ;读取文件内容后就是从这一局部变量开始保存的,通过这里就可以确定函数分配的栈空间大小为1010h,即4112字节,因为栈空间是由高到低分配的,所以要覆盖到返回地址就要填充4112字节才行。
CODE:004AC138
CODE:004AC138 push ebx
CODE:004AC139 push esi
CODE:004AC13A push edi
CODE:004AC13B push ebp
CODE:004AC13C add esp, 0FFFFF004h ; 分配栈空间
CODE:004AC142 push eax
CODE:004AC143 add esp, 0FFFFFFF4h ; 继续分配栈空间
CODE:004AC146 mov esi, eax
CODE:004AC148 mov byte ptr [esi+407Ch], 0
CODE:004AC14F xor edi, edi
CODE:004AC151 mov ebx, 4
CODE:004AC156 lea edx, [esp+101Ch+var_1010] ; 将edx指向局部变量,后面将用它来保存读取的文件内容,即我们构造的文件内容将会填充到栈空间
CODE:004AC15A mov ecx, 4
CODE:004AC15F mov eax, [esi+44h]
CODE:004AC162 mov ebp, [eax]
CODE:004AC164 call _ReadWavFile ;用于读取文件内容
{
0041EC54 . 8B40 04 MOV EAX,DWORD PTR DS:[EAX+4]
0041EC57 . E8 F4A7FEFF CALL <cdextrac._MyReadFile>
{
00409450 >/$ 53 PUSH EBX
00409451 |. 56 PUSH ESI
00409452 |. 57 PUSH EDI
00409453 |. 51 PUSH ECX
00409454 |. 8BF9 MOV EDI,ECX
00409456 |. 8BF2 MOV ESI,EDX
00409458 |. 8BD8 MOV EBX,EAX
0040945A |. 6A 00 PUSH 0 ;
/pOverlapped
= NULL
0040945C |. 8D4424 04 LEA EAX,DWORD PTR SS:[ESP+4] ; |
00409460 |. 50 PUSH EAX ; |pBytesRead
00409461 |. 57 PUSH EDI ; |BytesToRead
00409462 |. 56 PUSH ESI ; |Buffer
00409463 |. 53 PUSH EBX ; |hFile
00409464 |. E8 23DBFFFF CALL <JMP.&kernel32.ReadFile> ; \ReadFile,读取文件内容并将其保存在漏洞函数的局部变量中
00409469 |. 85C0 TEST EAX,EAX
0040946B |. 75 07 JNZ SHORT cdextrac.00409474
0040946D |. C70424 FFFFFF>MOV DWORD PTR SS:[ESP],-1
00409474 |> 8B0424 MOV EAX,DWORD PTR SS:[ESP]
00409477 |. 5A POP EDX
00409478 |. 5F POP EDI
00409479 |. 5E POP ESI
0040947A |. 5B POP EBX
0040947B \. C3 RETN
}
0041EC5C . 83F8 FF CMP EAX,-1
0041EC5F . 75 02 JNZ SHORT cdextrac.0041EC63
0041EC61 . 33C0 XOR EAX,EAX
0041EC63 > C3 RETN
}
CODE:004AC167
cmp
ebx, 2000h ; 作为计数器
CODE:004AC16D jge loc_4AC624 ; 跳走则函数结束
CODE:004AC173
CODE:004AC173 loc_4AC173: ; CODE XREF: sub_4AC138+4E6 j
CODE:004AC173 mov eax, edi
CODE:004AC175
cmp
eax, 4 ; switch 5 cases
CODE:004AC178 ja loc_4AC5F4 ; default
CODE:004AC17E jmp off_4AC185[eax*4] ; switch jump,判断是哪一文件部分,如RIFF,WAVE,FMT,DATA等等,然后跳至相应位置进行处理,由于文件全部用A来填充,因此文件处理均在RIFF部分中进行
CODE:004AC17E ; ---------------------------------------------------------------------------
CODE:004AC185 off_4AC185
dd
offset loc_4AC199 ; DATA XREF: sub_4AC138+46 r
CODE:004AC185
dd
offset loc_4AC1E0 ; jump table
for
switch statement
CODE:004AC185
dd
offset loc_4AC227
CODE:004AC185
dd
offset loc_4AC467
CODE:004AC185
dd
offset loc_4AC55B
CODE:004AC199 ; ---------------------------------------------------------------------------
CODE:004AC199
CODE:004AC199 loc_4AC199: ; CODE XREF: sub_4AC138+46 j
CODE:004AC199 ; DATA XREF: sub_4AC138:off_4AC185 o
CODE:004AC199 mov edx, offset aRiff_0 ; jumptable 004AC17E
case
0,资源交换文件标志(RIFF)
CODE:004AC19E lea eax, [esp+ebx+101Ch+var_1014]
CODE:004AC1A2 call sub_4AA4F4
CODE:004AC1A7
test
al, al
CODE:004AC1A9 jnz short loc_4AC1C2
CODE:004AC1AB lea edx, [esp+ebx+101Ch+var_1010] ; 局部变量,从栈顶开始向栈底填充文件内容
CODE:004AC1AF mov ecx, 1
CODE:004AC1B4 mov eax, [esi+44h]
CODE:004AC1B7 mov ebp, [eax]
CODE:004AC1B9 call _ReadWavFile ; 读取文件内容
CODE:004AC1BC inc ebx ;递增计数器
CODE:004AC1BD jmp loc_4AC5F4 ; default
……省略部分代码……
CODE:004AC5F4
CODE:004AC5F4 loc_4AC5F4: ; CODE XREF: sub_4AC138+40 j
CODE:004AC5F4 ; sub_4AC138+85 j ...
CODE:004AC5F4 mov eax, [esi+44h] ; default
CODE:004AC5F7 mov edx, [eax]
CODE:004AC5F9 call dword ptr [edx]
CODE:004AC5FB push edx
CODE:004AC5FC push eax
CODE:004AC5FD mov eax, [esi+44h]
CODE:004AC600 call @Classes@TStream@GetPosition$qqrv ; Classes::TStream::GetPosition(void)
CODE:004AC605
cmp
edx, [esp+1024h+var_1020]
CODE:004AC609 jnz short loc_4AC614
CODE:004AC60B
cmp
eax, [esp+1024h+var_1024]
CODE:004AC60E pop edx
CODE:004AC60F pop eax
CODE:004AC610 jb short loc_4AC618
CODE:004AC612 jmp short loc_4AC624
CODE:004AC614 ; ---------------------------------------------------------------------------
CODE:004AC614
CODE:004AC614 loc_4AC614: ; CODE XREF: sub_4AC138+4D1 j
CODE:004AC614 pop edx
CODE:004AC615 pop eax
CODE:004AC616 jge short loc_4AC624
CODE:004AC618
CODE:004AC618 loc_4AC618: ; CODE XREF: sub_4AC138+4D8 j
CODE:004AC618
cmp
ebx, 2000h ;计数器,循环读取文件,第一次是读取4字节,之后都是一字节一字节地读取,故共可读取2003h > 1010h,最终导致溢出!!!
CODE:004AC61E jl loc_4AC173 ;若小于2000h则跳至上方实现循环操作
CODE:004AC624
CODE:004AC624 loc_4AC624: ; CODE XREF: sub_4AC138+35 j
CODE:004AC624 ; sub_4AC138+4DA j ...
CODE:004AC624 mov byte ptr [esi+407Ch], 0
CODE:004AC62B
CODE:004AC62B loc_4AC62B: ; CODE XREF: sub_4AC138+1BE j
CODE:004AC62B ; sub_4AC138+4BA j
CODE:004AC62B add esp, 100Ch
CODE:004AC631 pop ebp
CODE:004AC632 pop edi
CODE:004AC633 pop esi
CODE:004AC634 pop ebx
CODE:004AC635 retn
CODE:004AC635 sub_4AC138 endp