.text:77EFB0C0 call _cjBitmapBitsSize@4 ; cjBitmapBitsSize(x)
.text:77EFB0C5 mov [ebp+allocsize], eax
.text:77EFB0C8
.text:77EFB0C8 loc_77EFB0C8: ; CODE XREF: StretchDIBits
(x,x,x,x,x,x,x,x,x,x,x,x,x)+1162Cj
.text:77EFB0C8 mov eax, large fs:18h
.text:77EFB0CE test byte ptr [ebp+lpBits], 3 ; lpBits不能按4字节对齐
.text:77EFB0D2 mov [eax+6D0h], edi
.text:77EFB0D8 jnz AllocHeap ; 这里要跳走
.text:77EFB0D8 ;
.text:77F0C624 AllocHeap: ; CODE XREF: StretchDIBits
(x,x,x,x,x,x,x,x,x,x,x,x,x)+71j
.text:77F0C624 mov eax, large fs:18h
.text:77F0C62A push [ebp+allocsize]
.text:77F0C62D mov eax, [eax+30h]
.text:77F0C630 push edi
.text:77F0C631 push dword ptr [eax+18h]
.text:77F0C634 call ds:__imp__RtlAllocateHeap@12 ; RtlAllocateHeap(x,x,x)
.text:77F0C63A cmp eax, edi
.text:77F0C63C mov [ebp+var_3C], eax
.text:77F0C63F jz loc_77EFB0DE
.text:77F0C645 mov ecx, [ebp+allocsize]
.text:77F0C648 mov esi, [ebp+lpBits]
.text:77F0C64B mov edx, ecx
.text:77F0C64D shr ecx, 2
.text:77F0C650 mov edi, eax
.text:77F0C652 rep movsd ; copy内存
.text:77F0C652 ;
.text:77F0C654 mov ecx, edx
.text:77F0C656 and ecx, 3
.text:77F0C659 rep movsb
.text:77F0C65B mov esi, [ebp+var_10]
.text:77F0C65E mov [ebp+lpBits], eax
.text:77F0C661 xor edi, edi
上面计算了allocsize,下面进行分配内存,紧接着copymem,这样的话,如果allocsize比较大,原始的
lpBits内存空间比较小,会发生内存访问异常,而崩溃
要触发这个BUG,关键条件就是计算出来的size比较大,但不能太大,然后就是lpBits不按照4对齐
OD调试一下tc,发现,重绘PE文件的ICO是在CreateIconFromResourceEx-ConvertDIBIcon-BitmapFromDIB-SmartStretchDIBits-StretchDIBits
这里传递的过程是这样的,lpBits就是资源里面的数据,如果资源里面的ICO按4对齐,那么这里就是按4对齐
的,lpBitsInfo是重新分配的内存,从原始资源里面copy出来的
所以,要做出异常的PE,首先编译一个图标进exe,然后把图标的偏移改成不按4字节对齐,这里我把它向后
移了一个字节
然后lpBitsInfo+8处是计算图标大小的,改得大小正好超过整个文件的ImageSize即可
这样就会触发那个BUG,使explorer查看文件夹的时候 引起崩溃了
将附件的后缀名改成.exe即可看到效果
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!