创建GDI位图对象-CreateBitmap函数逆向分析

分析的时windows 10 21h2

CreateBitmap 在3环会先调用gdi32.dll 同名函数接着调用 gdi32full.dll 的同名函数->再接着w32u.dll 的NtGdiCreateBitmap 让后进入内核

 

__int64 __fastcall NtGdiCreateBitmap(unsigned int a1, unsigned int a2, unsigned int a3, unsigned int a4, char *Address)
{
  __int64 Bitmap; // rbx
  HANDLE v10; // rdi
  unsigned __int64 v12; // r8
  unsigned __int64 v13; // r8
  char *v14; // rcx

  Bitmap = 1i64;
  v10 = 0i64;
  if ( Address )
  {
    v12 = ((a1 * (unsigned __int16)a3 * (unsigned __int64)(unsigned __int16)a4 + 15) >> 3) & 0x1FFFFFFFFFFFFFFEi64;
    if ( v12 <= 0xFFFFFFFF && (v13 = a2 * v12, v13 <= 0xFFFFFFFF) && (_DWORD)v13 )
    {
      v14 = &Address[(int)v13];
      if ( (unsigned __int64)v14 > MmUserProbeAddress || v14 < Address )
        *(_BYTE *)MmUserProbeAddress = 0;
      v10 = MmSecureVirtualMemory(Address, (int)v13, 2u);
      Bitmap = -(__int64)(v10 != 0i64) & 1;
    }
    else
    {
      Bitmap = 0i64;
    }
  }
  if ( Bitmap )
    Bitmap = GreCreateBitmap(a1, a2, a3, a4, Address);
  if ( v10 )
    MmUnsecureVirtualMemory(v10);
  return Bitmap;
}

 

会调用 win32kbase.sys 的
GreCreateBitmap(a1, a2, a3, a4, Address); 进行bitmap 结构申请·和变量赋值
__int64 __fastcall GreCreateBitmap(int a1, int a2, unsigned int a3, unsigned int a4, __int64 a5)
{
  __int64 v5; // rdi
  unsigned int v6; // r10d
  unsigned __int64 v7; // r14
  int v8; // ebx
  __int64 v9; // rdx
  __int64 v10; // rsi
  __int64 v11; // r14
  __int64 v12; // rbx
  __int64 v13; // r8
  __int64 v15; // [rsp+50h] [rbp-30h] BYREF
  char v16; // [rsp+58h] [rbp-28h]
  int v17[4]; // [rsp+60h] [rbp-20h] BYREF
  _QWORD v18[2]; // [rsp+70h] [rbp-10h]
  int v19; // [rsp+A0h] [rbp+20h] BYREF

  v5 = 0i64;
  v6 = a4 * a3;
  if ( a1 <= 0
    || (unsigned int)a1 > 0x7FFFFFF
    || a2 <= 0
    || a3 > 0x20
    || a4 > 0x20
    || v6 > 0x20
    || (v7 = a2 * (unsigned __int64)(((a1 * v6 + 15) >> 3) & 0x1FFFFFFE), v7 > 0xFFFFFFFF) )
  {
    EngSetLastError(0x57u);
    return 0i64;
  }
  else
  {
    v17[3] = 0;
    v18[1] = 1i64;
    v17[1] = a1;
    v17[2] = a2;
    v18[0] = 0i64;
    if ( v6 > 1 )
    {
      v8 = 4;
      if ( v6 <= 4 )
      {
        v8 = 2;
      }
      else if ( v6 <= 8 )
      {
        v8 = 3;
      }
      else if ( v6 > 0x10 )
      {
        v8 = (v6 > 0x18) + 5;
      }
    }
    else
    {
      v8 = 1;
      v18[0] = WPP_MAIN_CB.Dpc.DeferredRoutine;
    }
    v17[0] = v8;
    v15 = 0i64;
    v16 = 0;
    SURFMEM::bCreateDIB((SURFMEM *)&v15, (struct _DEVBITMAPINFO *)v17, 0i64, 0i64, 0, 0i64, 0i64, 0, 1, 0);
    v10 = v15;
    if ( v15 )
    {
      *(_DWORD *)(v15 + 112) |= 0x4000000u;
      if ( a5 )
      {
        v19 = 0;
        if ( (int)IsGreSetBitmapBitsSupported_0() >= 0 )
          GreSetBitmapBits_0(*(_QWORD *)(v10 + 32), (unsigned int)v7, a5, &v19);
      }
      if ( v8 != 1 )
        *(_DWORD *)(v10 + 112) |= 0x800200u;
      v11 = *(_QWORD *)(v10 + 32);
      LOBYTE(v9) = 5;
      v16 |= 1u;
      v12 = HmgShareLockCheck(v11, v9);
      if ( v12 )
      {
        if ( (v11 & 0x800000) == 0 )
        {
          LOBYTE(v13) = 5;
          HmgSetOwner(v11, 2147483650i64, v13);
        }
        HmgDecrementShareReferenceCount(v12);
      }
      v5 = *(_QWORD *)(v10 + 32);
    }
    SURFMEM::~SURFMEM((SURFMEM *)&v15);
    return v5;
  }
}

接着调用

SURFMEM::bCreateDIB   申请gib 对象 就结束了
这里还涉及 对象大小计算 当nPlanes*nBitCount 不同结果导致不同的计算规则。

当nPlanes*nBitCount=8时 有

(nWidth+3)*nHeight+(对齐字节满足8字节对齐)+handle(0x10)+0x2b8 就是CreateBitmap 在内存的真正大小

假定创建代码
  HGDIOBJ bitmap = CreateBitmap(1024, 2, 1, 8, NULL);

这里我们用windbg 看是否是按这样计算的

1: kd> !process 0 0 cs.exe
PROCESS ffffbd0f9aacb300
    SessionId: 1  Cid: 1938    Peb: 0039d000  ParentCid: 0db0
    DirBase: 03f45000  ObjectTable: ffffe5030f923300  HandleCount:  51.
    Image: cs.exe
1: kd> r $peb
$peb=000000000039d000

找GdiSharedHandleTable

1: kd> dt nt!_peb 000000000039d000 GdiSharedHandleTable
   +0x0f8 GdiSharedHandleTable : 0x00000000`009d0000 Void
1: kd> dq 0x00000000`009d0000+c02*18 L3
00000000`009e2030 ffffffff`ff250c02 00052505`00001938
00000000`009e2040 00000000`00000000
GdiSharedHandleTable+ (返回句柄&0xffff)*18
!pool ffffffff`ff250c02
0xac8



bCreateDIB  
 
__int64 __fastcall SURFMEM::bCreateDIB(
        SURFMEM *this,
        struct _DEVBITMAPINFO *a2,
        void *a3,
        __int64 a4,
        unsigned int a5,
        void *a6,
        unsigned __int64 a7,
        int a8,
        int a9,
        int a10)
{
  struct _DEVBITMAPINFO *v10; // r13
  int v11; // eax
  int v13; // r10d
  unsigned int v14; // edi
  unsigned int v15; // edi
  unsigned int v17; // edi
  unsigned int v18; // edi
  unsigned int v19; // edi
  unsigned int v20; // eax
  unsigned int v21; // edi
  bool v22; // cf
  unsigned int v23; // esi
  int v24; // r15d
  unsigned __int64 v25; // rcx
  __int64 v26; // rbx
  int v27; // eax
  int v28; // eax
  int v29; // eax
  PVOID v30; // rcx
  PVOID v31; // rax
  int v32; // r8d
  unsigned __int64 v33; // rcx
  int v34; // r15d
  int v35; // r12d
  __int64 v36; // rbx
  _QWORD *v37; // rax
  __int64 v38; // rbx
  void *v39; // rax
  __int64 v40; // r15
  __int64 v41; // r13
  __int64 v42; // r12
  __int64 v43; // rbx
  __int64 *CurrentThreadWin32ThreadAndEnterCriticalRegion; // rax
  __int64 v45; // rax
  signed __int32 v46; // eax
  unsigned int v47; // edx
  void *v48; // r12
  int v49; // r13d
  __int64 *ThreadWin32Thread; // rax
  __int64 v51; // rax
  _QWORD *v52; // rax
  __int64 CurrentProcess; // rax
  int v54; // edx
  __int64 v55; // r8
  __int64 v56; // r15
  __int64 v57; // rsi
  __int64 ProcessWin32Process; // rax
  __int64 v59; // rbx
  struct _ERESOURCE *v60; // rbx
  _QWORD *v61; // rax
  __int64 v62; // rax
  __int64 v63; // rax
  __int64 v64; // rax
  __int64 v65; // rax
  char v66; // si
  unsigned __int64 v67; // r12
  unsigned __int64 v68; // rbx
  __int64 *v69; // rax
  int v70; // edx
  __int64 v71; // rcx
  __int64 v72; // r8
  __int64 v73; // rax
  __int64 v74; // rax
  struct _ERESOURCE *v75; // rdi
  int v76; // r15d
  int v77; // esi
  struct _ERESOURCE *v78; // rdi
  __int64 CurrentProcessWin32Process; // rax
  __int64 v80; // rcx
  __int64 v81; // rdx
  unsigned int v82; // eax
  __int64 v83; // rax
  __int64 v84; // rdx
  int v85; // ecx
  unsigned int v86; // ecx
  unsigned int v87; // eax
  __int64 v88; // rdx
  int v89; // eax
  __int64 v90; // rdi
  __int64 *v91; // rax
  char v92; // r15
  __int64 v93; // rax
  __int64 v94; // r13
  unsigned int v95; // ebx
  bool v96; // zf
  signed __int32 v97; // eax
  struct _BASEOBJECT *v98; // rax
  __int64 v99; // r15
  struct _BASEOBJECT *v100; // rdx
  unsigned int v101; // r8d
  int v102; // ebx
  unsigned int v103; // ebx
  unsigned int CurrentProcessId; // eax
  struct _KTHREAD *CurrentThread; // rax
  __int128 v106; // xmm0
  __int64 v107; // rax
  __int128 v108; // xmm1
  __int128 v109; // xmm0
  PVOID v110; // rcx
  int v111; // eax
  __int64 v112; // rdi
  PVOID v113; // rbx
  __int64 v114; // rax
  PVOID v115; // rcx
  PVOID Object; // [rsp+50h] [rbp-B0h] BYREF
  int v117; // [rsp+58h] [rbp-A8h]
  int v118; // [rsp+5Ch] [rbp-A4h]
  int v119; // [rsp+60h] [rbp-A0h]
  unsigned int v120; // [rsp+64h] [rbp-9Ch]
  struct _BASEOBJECT *v121; // [rsp+68h] [rbp-98h]
  void *v122; // [rsp+70h] [rbp-90h] BYREF
  int v123[2]; // [rsp+78h] [rbp-88h] BYREF
  PEPROCESS v124; // [rsp+80h] [rbp-80h] BYREF
  PEPROCESS Process; // [rsp+88h] [rbp-78h] BYREF
  __int32 v126; // [rsp+9Ch] [rbp-64h]
  int v127; // [rsp+A0h] [rbp-60h]
  unsigned int v128; // [rsp+A4h] [rbp-5Ch]
  _OWORD v129[3]; // [rsp+A8h] [rbp-58h] BYREF
  __int64 v130; // [rsp+D8h] [rbp-28h] BYREF
  int v131[5]; // [rsp+E0h] [rbp-20h] BYREF
  __int32 v132; // [rsp+F4h] [rbp-Ch]
  int v133; // [rsp+F8h] [rbp-8h]
  char v134[24]; // [rsp+100h] [rbp+0h] BYREF
  __int32 v135; // [rsp+160h] [rbp+60h]
  unsigned int v136; // [rsp+160h] [rbp+60h]
  PVOID pv; // [rsp+170h] [rbp+70h] BYREF
  __int64 v139; // [rsp+178h] [rbp+78h]

  v139 = a4;
  pv = a3;
  *((_BYTE *)this + 8) = 8;
  *(_QWORD *)this = 0i64;
  v10 = a2;
  v11 = *(_DWORD *)a2 - 1;
  v120 = 1;
  v118 = 0;
  v13 = 0;
  v14 = 0;
  switch ( v11 )
  {
    case 0:
      v15 = *((_DWORD *)a2 + 1);
      if ( v15 >= 0xFFFFFFE0 )
        return 0i64;
      v14 = ((v15 + 31) >> 3) & 0x1FFFFFFC;
      goto LABEL_17;
    case 1:
      v17 = *((_DWORD *)a2 + 1);
      if ( v17 >= 0xFFFFFFF8 )
        return 0i64;
      v14 = ((v17 + 7) >> 1) & 0x7FFFFFFC;
      goto LABEL_17;
    case 2:
      v18 = *((_DWORD *)a2 + 1);
      if ( v18 >= 0xFFFFFFFC )
        return 0i64;
      v14 = (v18 + 3) & 0xFFFFFFFC;
      goto LABEL_17;
    case 3:
      v19 = *((_DWORD *)a2 + 1);
      if ( v19 >= 0xFFFFFFFE || v19 + 1 >= 0x7FFFFFFF )
        return 0i64;
      v14 = (2 * v19 + 2) & 0xFFFFFFFC;
      goto LABEL_17;
    case 4:
      v20 = *((_DWORD *)a2 + 1);
      if ( v20 >= 0x55555554 )
        return 0i64;
      v14 = (3 * (v20 + 1)) & 0xFFFFFFFC;
      goto LABEL_17;
    case 5:
      v21 = *((_DWORD *)a2 + 1);
      if ( v21 >= 0x3FFFFFFF )
        return 0i64;
      v14 = 4 * v21;
LABEL_17:
      v22 = a8 != 0;
      a8 = -a8;
      v23 = SURFACE::tSize;
      Object = 0i64;
      memset(v129, 0, sizeof(v129));
      v24 = (v22 ? 8 : 0) | 6;
      v117 = v24;
      v119 = 0;
      v122 = 0i64;
      if ( a3 )
      {
        if ( !a9
          || (!v13 ? (v33 = v14 * (unsigned __int64)*((unsigned int *)a2 + 2)) : (v33 = *((unsigned int *)a2 + 3)),
              v33 <= 0x7FFFFFFF) )
        {
          if ( (*((_DWORD *)a2 + 6) & 0x800) == 0 )
            goto LABEL_54;
          W32PIDLOCK::vInit((W32PIDLOCK *)v129);
          if ( *((_QWORD *)&v129[2] + 1) )
          {
            v118 = 2048;
            v119 = 1;
            goto LABEL_54;
          }
        }
        return 0i64;
      }
      if ( v13 )
        v25 = *((unsigned int *)a2 + 3);
      else
        v25 = v14 * (unsigned __int64)*((unsigned int *)a2 + 2);
      v26 = v25 + (unsigned int)SURFACE::tSize;
      if ( v26 < v25 || (unsigned __int64)v26 > 0x7FFFFFFF )
        return 0i64;
      v27 = *((_DWORD *)a2 + 6);
      if ( (v27 & 0x40000) != 0 && v26 > 4096 )
        *((_DWORD *)a2 + 6) = v27 | 8;
      v28 = *((_DWORD *)a2 + 6);
      if ( (v28 & 8) != 0 )
      {
        if ( (v28 & 0x80u) == 0 )
          v29 = EngAllocUserMemEx((int)v26, 0x1C0000000ui64, &pv);
        else
          v29 = AllocateSharedSection(v26, 0xC0000000, &Object, &v122, &pv);
        if ( v29 >= 0 )
        {
          v30 = pv;
          v31 = Object;
LABEL_42:
          if ( v30 || v31 )
            goto LABEL_54;
          goto LABEL_44;
        }
        return 0i64;
      }
      if ( (v28 & 0x810) != 0 )
      {
        if ( (v28 & 0x800) != 0 )
        {
          W32PIDLOCK::vInit((W32PIDLOCK *)v129);
          if ( !*((_QWORD *)&v129[2] + 1) )
            return 0i64;
          Object = 0i64;
          v123[1] = 0;
          v123[0] = v26 - v23;
          Win32CreateSection((unsigned int)&Object, 6, v32, (unsigned int)v123);
          v31 = Object;
          if ( !Object )
          {
            W32PIDLOCK::vCleanUp((W32PIDLOCK *)v129);
            return 0i64;
          }
        }
        else
        {
          AllocateKernelSection(v26, 0xC0000000, &pv);
          v31 = Object;
        }
        v30 = pv;
        if ( pv || v31 )
        {
          v118 = *((_DWORD *)v10 + 6) & 0x800 | 0x10;
          goto LABEL_42;
        }
      }
LABEL_44:
      v23 = v26;
      if ( (*((_DWORD *)v10 + 6) & 2) == 0 )
      {
        LOWORD(v24) = v24 & 0xFFFB;
        v117 = v24;
      }
LABEL_54:
      v34 = ((unsigned __int8)~(_BYTE)v24 >> 2) & 1;
      if ( gulGdiHmgrTraceObjectType == 5 )
      {
        v35 = 1;
        v23 += 160;
      }
      else
      {
        v35 = 0;
      }
      if ( dword_1C0104624 >= v23 )
      {
        v36 = qword_1C01046E8;
        if ( (int)IsWin32AllocateFromPagedLookasideListImplSupported_0() >= 0 )
        {
          v37 = (_QWORD *)Win32AllocateFromPagedLookasideListImpl_0(v36);
          v38 = (__int64)v37;
          if ( v37 )
          {
            if ( v34 )
            {
              memset(v37, 0, v23);
            }
            else
            {
              *v37 = 0i64;
              v37[1] = 0i64;
              v37[2] = 0i64;
            }
            if ( v35 )
              RtlCaptureStackBackTrace(0, 0x14u, (PVOID *)(v23 + v38 - 160), 0i64);
            LOWORD(v135) = *(_WORD *)(v38 + 12);
            HIWORD(v135) = *(_WORD *)(v38 + 14) | 0x8000;
            _InterlockedExchange((volatile __int32 *)(v38 + 12), v135);
            goto LABEL_76;
          }
        }
      }
      if ( v34 )
      {
        v38 = 0i64;
        if ( v23 )
        {
          if ( (int)IsWin32AllocPoolImplSupported_0() >= 0 )
          {
            v39 = (void *)Win32AllocPoolImpl_0(33i64, v23, 892364871i64);
            v38 = (__int64)v39;
            if ( v39 )
              memset(v39, 0, v23);
          }
        }
      }
      else
      {
        v38 = PALLOCMEM2(v23);
        if ( !v38 )
        {
LABEL_236:
          EngSetLastError(8u);
          goto LABEL_237;
        }
        *(_QWORD *)v38 = 0i64;
        *(_QWORD *)(v38 + 8) = 0i64;
        *(_QWORD *)(v38 + 16) = 0i64;
      }
      if ( !v38 )
        goto LABEL_236;
      if ( v35 )
        RtlCaptureStackBackTrace(0, 0x14u, (PVOID *)(v23 + v38 - 160), 0i64);
LABEL_76:
      *(_QWORD *)this = v38;
      v40 = 0i64;
      *(_QWORD *)(v38 + 56) = *(_QWORD *)((char *)v10 + 4);
      *(_WORD *)(*(_QWORD *)this + 100i64) = 0;
      *(_QWORD *)(*(_QWORD *)this + 136i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 216i64) = 0i64;
      v41 = *((_QWORD *)v10 + 2);
      if ( !v41 )
        goto LABEL_101;
      v42 = 0i64;
      if ( (unsigned __int16)v41 >= (unsigned int)gcMaxHmgr )
        goto LABEL_101;
      v43 = gpentHmgr + 24i64 * (unsigned __int16)v41;
      CurrentThreadWin32ThreadAndEnterCriticalRegion = (__int64 *)PsGetCurrentThreadWin32ThreadAndEnterCriticalRegion(v131);
      if ( CurrentThreadWin32ThreadAndEnterCriticalRegion )
      {
        v45 = *CurrentThreadWin32ThreadAndEnterCriticalRegion;
        if ( v45 )
          v40 = *(_QWORD *)(v45 + 72);
      }
LABEL_81:
      _m_prefetchw((const void *)(v43 + 8));
      v46 = *(_DWORD *)(v43 + 8);
      v47 = v46 & 0xFFFFFFFE;
      v132 = v46;
      if ( (v46 & 0xFFFFFFFE) != (v131[0] & 0xFFFFFFFC) && v47 && (!v40 || v47 != *(_DWORD *)(v40 + 8))
        || (*(_BYTE *)(v43 + 15) & 0x20) != 0 )
      {
        KeLeaveCriticalRegion();
LABEL_101:
        *(_QWORD *)(*(_QWORD *)this + 120i64) = 0i64;
        goto LABEL_102;
      }
      while ( (*(_BYTE *)(v43 + 15) & 0x40) == 0 )
      {
        if ( (v46 & 1) != 0 )
        {
          KeDelayExecutionThread(0, 0, gpLockShortDelay);
          goto LABEL_81;
        }
        v133 = v46 | 1;
        if ( v46 != _InterlockedCompareExchange((volatile signed __int32 *)(v43 + 8), v46 | 1, v46)
          || (*(_BYTE *)(v43 + 15) & 0x40) != 0 )
        {
          goto LABEL_81;
        }
        *((_QWORD *)gpentPushLock + (unsigned __int16)v41) = 0i64;
        *(_BYTE *)(v43 + 15) |= 0x40u;
        _m_prefetchw((const void *)(v43 + 8));
        v132 = *(_DWORD *)(v43 + 8) & 0xFFFFFFFE;
        _InterlockedExchange((volatile __int32 *)(v43 + 8), v132);
        v46 = v132;
      }
      ExAcquirePushLockExclusiveEx((char *)gpentPushLock + 8 * (unsigned __int16)v41, 0i64);
      if ( *(_BYTE *)(v43 + 14) == 8 && *(_WORD *)(v43 + 12) == WORD1(v41) )
      {
        v42 = *(_QWORD *)v43;
        ++*(_DWORD *)(*(_QWORD *)v43 + 8i64);
      }
      if ( (*(_BYTE *)(v43 + 15) & 0x40) != 0 )
      {
        ExReleasePushLockExclusiveEx((char *)gpentPushLock + 8 * (unsigned __int16)v41, 0i64);
      }
      else
      {
        _m_prefetchw((const void *)(v43 + 8));
        v132 = *(_DWORD *)(v43 + 8) & 0xFFFFFFFE;
        _InterlockedExchange((volatile __int32 *)(v43 + 8), v132);
      }
      KeLeaveCriticalRegion();
      if ( !v42 )
        goto LABEL_101;
      *(_QWORD *)(*(_QWORD *)this + 120i64) = v42;
LABEL_102:
      v48 = a6;
      v49 = a10;
      *(_DWORD *)(*(_QWORD *)this + 96i64) = *(_DWORD *)a2;
      *(_WORD *)(*(_QWORD *)this + 102i64) = v118 | *((_WORD *)a2 + 12) & 0x89;
      *(_QWORD *)(*(_QWORD *)this + 176i64) = v139;
      *(_DWORD *)(*(_QWORD *)this + 192i64) = a5;
      *(_QWORD *)(*(_QWORD *)this + 184i64) = v48;
      *(_QWORD *)(*(_QWORD *)this + 200i64) = a7;
      *(_DWORD *)(*(_QWORD *)this + 208i64) = v49;
      *(_QWORD *)(*(_QWORD *)this + 24i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 40i64) = 0i64;
      *(_DWORD *)(*(_QWORD *)this + 112i64) = *((_DWORD *)a2 + 6) & 0x40000;
      *(_QWORD *)(*(_QWORD *)this + 128i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 144i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 152i64) = 0i64;
      *(_DWORD *)(*(_QWORD *)this + 160i64) = 0;
      *(_QWORD *)(*(_QWORD *)this + 168i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 48i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 104i64) = 0i64;
      ThreadWin32Thread = (__int64 *)PsGetThreadWin32Thread(KeGetCurrentThread());
      if ( ThreadWin32Thread )
      {
        v51 = *ThreadWin32Thread;
        if ( v51 )
          *(_QWORD *)(v51 + 304) = 0i64;
      }
      *(_QWORD *)(*(_QWORD *)this + 240i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 248i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 256i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 584i64) = 0i64;
      *(_DWORD *)(*(_QWORD *)this + 592i64) = 0;
      *(_DWORD *)(*(_QWORD *)this + 116i64) = 0;
      *(_QWORD *)(*(_QWORD *)this + 496i64) = 0i64;
      *(_QWORD *)(*(_QWORD *)this + 488i64) = 0i64;
      v52 = (_QWORD *)(*(_QWORD *)this + 224i64);
      v52[1] = v52;
      *v52 = v52;
      *(_DWORD *)(*(_QWORD *)this + 312i64) = 0;
      *(_DWORD *)(*(_QWORD *)this + 316i64) = 0;
      *(_QWORD *)(*(_QWORD *)this + 568i64) = 0i64;
      CurrentProcess = PsGetCurrentProcess();
      v56 = *(_QWORD *)this;
      v57 = CurrentProcess;
      if ( CurrentProcess )
      {
        ProcessWin32Process = PsGetProcessWin32Process(CurrentProcess);
        v59 = ProcessWin32Process;
        if ( !ProcessWin32Process
          || !*(_DWORD *)(ProcessWin32Process + 836)
          || !(unsigned int)IsImmersiveAppRestricted(ProcessWin32Process)
          || (*(_DWORD *)(v59 + 776) & 0x200) != 0 )
        {
          v57 = 0i64;
        }
      }
      v60 = ghsemHmgr;
      if ( ghsemHmgr )
      {
        PsEnterPriorityRegion();
        ExEnterCriticalRegionAndAcquireResourceExclusive(v60);
        LODWORD(v60) = (_DWORD)ghsemHmgr;
      }
      if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
        Template_pqz((unsigned int)L"ghsemHmgr", v54, v55, (_DWORD)v60, 16, (__int64)L"ghsemHmgr");
      *(_QWORD *)(v56 + 576) = v57;
      if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
        Template_pz(L"ghsemHmgr", &LockRelease, v55, ghsemHmgr, L"ghsemHmgr");
      if ( ghsemHmgr )
      {
        ExReleaseResourceAndLeaveCriticalRegion(ghsemHmgr);
        PsLeavePriorityRegion();
      }
      v61 = (_QWORD *)(*(_QWORD *)this + 440i64);
      v61[1] = v61;
      *v61 = v61;
      *(_QWORD *)(*(_QWORD *)this + 560i64) = 0i64;
      if ( v119 )
        *(_DWORD *)(*(_QWORD *)this + 116i64) |= 1u;
      if ( v48 && !v49 )
        *(_WORD *)(*(_QWORD *)this + 102i64) |= 4u;
      if ( pv || Object )
        *(_QWORD *)(*(_QWORD *)this + 72i64) = pv;
      else
        *(_QWORD *)(*(_QWORD *)this + 72i64) = *(_QWORD *)this + SURFACE::tSize;
      v10 = a2;
      v62 = *(_QWORD *)this;
      if ( (unsigned int)(*(_DWORD *)a2 - 7) <= 3 )
      {
        *(_WORD *)(v62 + 102) &= ~0x800u;
        *(_DWORD *)(*(_QWORD *)this + 88i64) = 0;
        *(_DWORD *)(*(_QWORD *)this + 64i64) = *((_DWORD *)a2 + 3);
        if ( (unsigned int)(*(_DWORD *)a2 - 9) <= 1 )
          *(_QWORD *)(*(_QWORD *)this + 80i64) = 0i64;
        else
          *(_QWORD *)(*(_QWORD *)this + 80i64) = *(_QWORD *)(*(_QWORD *)this + 72i64);
      }
      else
      {
        *(_DWORD *)(v62 + 64) = v14 * *((_DWORD *)a2 + 2);
        v63 = *(_QWORD *)this;
        if ( (*((_DWORD *)a2 + 6) & 1) != 0 )
        {
          *(_DWORD *)(v63 + 88) = v14;
          *(_QWORD *)(*(_QWORD *)this + 80i64) = *(_QWORD *)(*(_QWORD *)this + 72i64);
        }
        else
        {
          *(_DWORD *)(v63 + 88) = -v14;
          *(_QWORD *)(*(_QWORD *)this + 80i64) = *(_QWORD *)(*(_QWORD *)this + 72i64)
                                               + *(_DWORD *)(*(_QWORD *)this + 64i64)
                                               - v14;
        }
      }
      if ( *(char *)(*(_QWORD *)this + 102i64) < 0 )
      {
        *(_QWORD *)(*(_QWORD *)this + 520i64) = Object;
        *(_QWORD *)(*(_QWORD *)this + 528i64) = v122;
        *(_QWORD *)(*(_QWORD *)this + 536i64) = (char *)v122
                                              + *(_QWORD *)(*(_QWORD *)this + 80i64)
                                              - *(_QWORD *)(*(_QWORD *)this + 72i64);
        *(_DWORD *)(*(_QWORD *)this + 544i64) = 1;
        v64 = W32GetThreadWin32Thread(KeGetCurrentThread());
        if ( v64 && (v65 = *(_QWORD *)(v64 + 72)) != 0 )
        {
          *(_DWORD *)(*(_QWORD *)this + 548i64) = *(_DWORD *)(v65 + 8);
          *(_DWORD *)(*(_QWORD *)this + 552i64) = 1;
        }
        else
        {
          *(_DWORD *)(*(_QWORD *)this + 548i64) = 0;
          *(_DWORD *)(*(_QWORD *)this + 552i64) = 0;
        }
      }
      v66 = v117;
      v67 = 0i64;
      v136 = (unsigned __int16)v117;
      *(_DWORD *)(*(_QWORD *)this + 92i64) = _InterlockedIncrement((volatile signed __int32 *)&_ulGlobalSurfaceUnique);
      v121 = *(struct _BASEOBJECT **)this;
      v68 = (unsigned __int64)PsGetCurrentProcessId() & 0xFFFFFFFC;
      v69 = (__int64 *)PsGetThreadWin32Thread(KeGetCurrentThread());
      if ( v69 )
      {
        v73 = *v69;
        if ( v73 )
        {
          v74 = *(_QWORD *)(v73 + 72);
          if ( v74 )
            LODWORD(v68) = *(_DWORD *)(v74 + 8);
        }
      }
      v75 = ghsemHmgr;
      if ( ghsemHmgr )
      {
        PsEnterPriorityRegion();
        ExEnterCriticalRegionAndAcquireResourceExclusive(v75);
      }
      if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
        Template_pqz(v71, v70, v72, (_DWORD)ghsemHmgr, 16, (__int64)L"ghsemHmgr");
      v76 = v66 & 8;
      if ( (v66 & 8) == 0 )
      {
        v77 = v76 + 1;
        if ( (_DWORD)v68 )
        {
          if ( (_DWORD)v68 != -2147483630 )
          {
            v78 = ghsemHmgr;
            if ( ghsemHmgr )
            {
              PsEnterPriorityRegion();
              ExEnterCriticalRegionAndAcquireResourceExclusive(v78);
            }
            if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
              Template_pqz(v71, v70, v72, (_DWORD)ghsemHmgr, 16, (__int64)L"ghsemHmgr");
            if ( (_DWORD)v68 == ((unsigned int)PsGetCurrentProcessId() & 0xFFFFFFFC) )
            {
              CurrentProcessWin32Process = PsGetCurrentProcessWin32Process();
              v81 = CurrentProcessWin32Process;
              if ( CurrentProcessWin32Process )
              {
                v80 = *(unsigned int *)(CurrentProcessWin32Process + 60);
                if ( (int)v80 < gProcessHandleQuota )
                {
                  v80 = (unsigned int)(v80 + 1);
                  *(_DWORD *)(CurrentProcessWin32Process + 60) = v80;
                  v82 = *(_DWORD *)(CurrentProcessWin32Process + 64);
                  if ( (unsigned int)v80 > v82 )
                    v82 = v80;
                  *(_DWORD *)(v81 + 64) = v82;
                }
                else
                {
                  v77 = 0;
                }
              }
            }
            else if ( PsLookupProcessByProcessId((HANDLE)(int)v68, &Process) >= 0 )
            {
              v83 = PsGetProcessWin32Process(Process);
              v84 = v83;
              if ( v83 )
              {
                v85 = *(_DWORD *)(v83 + 60);
                if ( v85 < gProcessHandleQuota )
                {
                  v86 = v85 + 1;
                  *(_DWORD *)(v83 + 60) = v86;
                  v87 = *(_DWORD *)(v83 + 64);
                  if ( v86 > v87 )
                    v87 = v86;
                  *(_DWORD *)(v84 + 64) = v87;
                }
                else
                {
                  v77 = 0;
                }
              }
              ObfDereferenceObject(Process);
            }
            if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
              Template_pz(v80, &LockRelease, v72, ghsemHmgr, L"ghsemHmgr");
            v71 = (__int64)ghsemHmgr;
            if ( ghsemHmgr )
            {
              ExReleaseResourceAndLeaveCriticalRegion(ghsemHmgr);
              PsLeavePriorityRegion();
            }
            if ( !v77 )
              goto LABEL_185;
          }
        }
      }
      if ( ghFreeHmgr )
      {
        v72 = (unsigned __int16)ghFreeHmgr;
        v88 = gpentHmgr + 24i64 * (unsigned __int16)ghFreeHmgr;
        v71 = 65285i64;
        ghFreeHmgr = *(_QWORD *)v88;
        v89 = *(_WORD *)(v88 + 12) & 0xFF00 | 5;
        *(_WORD *)(v88 + 12) = v89;
        v67 = (int)v72 | (unsigned __int64)(v89 << 16);
      }
      else
      {
        if ( gcMaxHmgr >= (unsigned int)gMaxGdiHandleCount )
          goto LABEL_183;
        v71 = 3i64 * (unsigned int)gcMaxHmgr;
        *(_WORD *)(gpentHmgr + 24i64 * (unsigned int)gcMaxHmgr + 12) = 261;
        v67 = gcMaxHmgr++ | 0x1050000i64;
      }
      if ( !v67 )
      {
LABEL_183:
        if ( !v76 )
          HmgDecProcessHandleCount((unsigned int)v68);
        goto LABEL_185;
      }
      v90 = gpentHmgr;
      v91 = (__int64 *)PsGetThreadWin32Thread(KeGetCurrentThread());
      v92 = v136;
      if ( v91 && (v93 = *v91) != 0 && (v136 & 0x10) == 0 )
        v94 = *(_QWORD *)(v93 + 72);
      else
        v94 = 0i64;
      PsGetCurrentThreadWin32ThreadAndEnterCriticalRegion(v134);
      v95 = (unsigned __int16)v67;
      v117 = (unsigned __int16)v67;
      v128 = (unsigned __int16)v67;
      _m_prefetchw((const void *)(v90 + 24i64 * (unsigned __int16)v67 + 8));
      v96 = (*(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) & 0x20) == 0;
      v97 = *(_DWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 8);
      v126 = v97;
      if ( !v96 )
      {
LABEL_209:
        KeLeaveCriticalRegion();
        goto LABEL_210;
      }
      while ( (*(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) & 0x40) == 0 )
      {
        if ( (v97 & 1) != 0 )
        {
          KeDelayExecutionThread(0, 0, gpLockShortDelay);
LABEL_208:
          _m_prefetchw((const void *)(v90 + 24i64 * (unsigned __int16)v67 + 8));
          v96 = (*(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) & 0x20) == 0;
          v97 = *(_DWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 8);
          v126 = v97;
          if ( !v96 )
            goto LABEL_209;
        }
        else
        {
          v127 = v97 | 1;
          if ( v97 != _InterlockedCompareExchange(
                        (volatile signed __int32 *)(v90 + 24i64 * (unsigned __int16)v67 + 8),
                        v97 | 1,
                        v97)
            || (*(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) & 0x40) != 0 )
          {
            goto LABEL_208;
          }
          *((_QWORD *)gpentPushLock + v128) = 0i64;
          *(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) |= 0x40u;
          _m_prefetchw((const void *)(v90 + 24i64 * (unsigned __int16)v67 + 8));
          v126 = *(_DWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 8) & 0xFFFFFFFE;
          _InterlockedExchange((volatile __int32 *)(v90 + 24i64 * (unsigned __int16)v67 + 8), v126);
          v97 = v126;
        }
      }
      v99 = 8i64 * v128;
      ExAcquirePushLockExclusiveEx((char *)gpentPushLock + v99, 0i64);
      *(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) &= 0x40u;
      v100 = v121;
      v101 = v136;
      v102 = *(_DWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 8);
      *(_QWORD *)(v90 + 24i64 * (unsigned __int16)v67) = v121;
      *(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 14) = 5;
      *(_QWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 16) = 0i64;
      if ( (v136 & 8) != 0 )
      {
        v103 = v102 & 1;
      }
      else if ( v94 )
      {
        v103 = *(_DWORD *)(v94 + 8) ^ (*(_DWORD *)(v94 + 8) ^ v102) & 1;
      }
      else
      {
        CurrentProcessId = (unsigned int)PsGetCurrentProcessId();
        v100 = v121;
        v101 = v136;
        v103 = v102 & 1 | CurrentProcessId & 0xFFFFFFFC;
      }
      if ( (v101 & 1) != 0 )
      {
        if ( v94 )
          CurrentThread = *(struct _KTHREAD **)v94;
        else
          CurrentThread = KeGetCurrentThread();
        *((_QWORD *)v100 + 2) = CurrentThread;
      }
      ++gcCurHmgr;
      *((_WORD *)v100 + 6) = v101 & 1;
      *((_DWORD *)v100 + 2) = (v101 >> 1) & 1;
      *(_QWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 16) = 0i64;
      *(_DWORD *)(v90 + 24i64 * (unsigned __int16)v67 + 8) = v103;
      if ( (*(_BYTE *)(v90 + 24i64 * (unsigned __int16)v67 + 15) & 0x40) != 0 )
      {
        ExReleasePushLockExclusiveEx((char *)gpentPushLock + v99, 0i64);
      }
      else
      {
        _m_prefetchw((const void *)(v90 + 24i64 * (unsigned __int16)v67 + 8));
        v126 = v103 & 0xFFFFFFFE;
        _InterlockedExchange((volatile __int32 *)(v90 + 24i64 * (unsigned __int16)v67 + 8), v103 & 0xFFFFFFFE);
      }
      KeLeaveCriticalRegion();
      v95 = v117;
      v92 = v136;
LABEL_210:
      v96 = gbGdiHmgrStacks == 0;
      v98 = v121;
      *(_QWORD *)v121 = v67;
      if ( !v96 && gpentHmgrStacks )
      {
        RECSTACKBACKTRACE(v95);
        v98 = v121;
      }
      if ( (v92 & 2) != 0 && gbGdiHmgrAltStacks && gpentHmgrAltStacks )
        RECALTLOCKSTACKBACKTRACE(v95, v98);
      v10 = a2;
LABEL_185:
      if ( gbLockEtw && (Microsoft_Windows_Win32kEnableBits & 0x10) != 0 )
        Template_pz(v71, &LockRelease, v72, ghsemHmgr, L"ghsemHmgr");
      if ( ghsemHmgr )
      {
        ExReleaseResourceAndLeaveCriticalRegion(ghsemHmgr);
        PsLeavePriorityRegion();
      }
      if ( v67 )
      {
        *(_QWORD *)(*(_QWORD *)this + 32i64) = **(_QWORD **)this;
        if ( (*(_WORD *)(*(_QWORD *)this + 102i64) & 0x800) != 0 && *((_QWORD *)&v129[2] + 1) )
        {
          v106 = v129[0];
          *(_QWORD *)(*(_QWORD *)this + 240i64) = Object;
          v107 = *(_QWORD *)this;
          v108 = v129[1];
          *(_OWORD *)(v107 + 264) = v106;
          v109 = v129[2];
          *(_OWORD *)(v107 + 280) = v108;
          *(_OWORD *)(v107 + 296) = v109;
          *(_QWORD *)(*(_QWORD *)this + 72i64) = 0i64;
          *(_QWORD *)(*(_QWORD *)this + 80i64) = 0i64;
          *(_DWORD *)(*(_QWORD *)this + 112i64) |= 0x200u;
        }
      }
      else
      {
        if ( *(_QWORD *)(*(_QWORD *)this + 120i64) )
        {
          v130 = *(_QWORD *)(*(_QWORD *)this + 120i64);
          XEPALOBJ::vUnrefPalette((XEPALOBJ *)&v130, 1);
          *(_QWORD *)(*(_QWORD *)this + 120i64) = 0i64;
        }
        FreeObject(*(_QWORD *)this, 5i64);
LABEL_237:
        v110 = pv;
        v120 = 0;
        *(_QWORD *)this = 0i64;
        if ( v110 || Object )
        {
          v111 = *((_DWORD *)v10 + 6);
          if ( (v111 & 8) != 0 )
          {
            if ( (v111 & 0x80u) == 0 )
            {
              EngFreeUserMem(v110);
            }
            else
            {
              v112 = W32GetThreadWin32Thread(KeGetCurrentThread());
              if ( *(_QWORD *)(v112 + 72) )
              {
                v113 = pv;
                v114 = PsGetCurrentProcess();
                MmUnmapViewOfSection(v114, v113);
                if ( PsLookupProcessByProcessId((HANDLE)*(int *)(*(_QWORD *)(v112 + 72) + 8i64), &v124) >= 0 )
                {
                  MmUnmapViewOfSection(v124, v122);
                  ObfDereferenceObject(v124);
                }
                v115 = Object;
                if ( !Object )
                  KeBugCheckEx(0x50u, 0i64, 0i64, 0x6D626B47ui64, 0i64);
                goto LABEL_251;
              }
            }
          }
          else if ( (v118 & 0x800) != 0 )
          {
            W32PIDLOCK::vCleanUp((W32PIDLOCK *)v129);
            if ( !v119 )
            {
              v115 = Object;
              if ( !Object )
                KeBugCheckEx(0x50u, 0i64, 0i64, 0x6D626B47ui64, 0i64);
LABEL_251:
              ObfDereferenceObject(v115);
            }
          }
          else if ( (v118 & 0x10) != 0 )
          {
            vFreeKernelSection(v110);
          }
        }
      }
      return v120;
    case 6:
    case 7:
    case 8:
    case 9:
      v13 = 1;
      goto LABEL_17;
    default:
      return 0i64;
  }
}

 




posted @ 2022-04-07 22:07  紅人  阅读(308)  评论(0编辑  收藏  举报