PsCreateVsmEnclave

INT64 __fastcall PsCreateVsmEnclave(INT64 a1, INT64 a2, INT64 a3, INT64 a4, CHAR a5, INT64 a6, UINT64 a7, INT64 a8){
  INT64 v8; 
  INT64 v10; 
  _ETHREAD *CurrentThread; 
  volatile INT64 *v13; 
  char *PoolWithQuotaTag; 
  unsigned __int64 v15; 
  __int64 v16; 
  char *v17; 
  char *v18; 
  NTSTATUS Enclave; 
  unsigned int v21; 
  signed __int64 v22; 
  _ETHREAD *v23; 
  volatile INT64 *v24; 
  __int64 v25; 
  __int64 v26; 
  char *v27; 
  char v28; 
  unsigned __int64 v29; 
  __int64 v30; 
  __int64 v31; 
  _QWORD *v32; 
  __int64 v33; 
  void *v34; 
  int v35; 
  __int64 v36; 
  unsigned int v37; 
  __int64 v38; 
  __int64 v39; 
  UINT64 v40; 
  __int64 v41; 
  __int64 v42; 
  v8 = a4;
  v10 = a2;
  if( !a5 && !*(_QWORD *)(a1 + 2248) )
  {
    CurrentThread = (_ETHREAD *)KeGetCurrentThread();
    --*((_WORD *)CurrentThread + 242);
    v13 = (volatile INT64 *)(a1 + 2264);
    ExAcquirePushLockExclusiveEx(a1 + 2264, 0i64);
    if( !*(_QWORD *)(a1 + 2248) )
    {
      PoolWithQuotaTag = (char *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x20ui64, 0x48457350ui64);
      if( PoolWithQuotaTag )
      {
        v15 = (unsigned __int64)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x10ui64, 0x48457350ui64);
        *(_QWORD *)(a1 + 2248) = v15;
        if( v15 )
        {
          *(_DWORD *)v15 = 0;
          *(_QWORD *)(v15 + 8) = PoolWithQuotaTag;
          *(_DWORD *)(v15 + 4) = 128;
          v16 = v15 | 1;
          if( (PoolWithQuotaTag + 32 >= PoolWithQuotaTag ? 4 : 0) != 0 )
            memset64(PoolWithQuotaTag, v16, PoolWithQuotaTag + 32 >= PoolWithQuotaTag ? 4 : 0);
        }
        else
        {
          ExFreePoolWithTag(PoolWithQuotaTag, 0);
        }
      }
      v8 = a4;
    }
    if( (_InterlockedExchangeAdd64(v13, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
      ExfTryToWakePushLock(v13);
    KeAbPostRelease((PVOID)v13);
    KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
    if( !*(_QWORD *)(a1 + 2248) )
      return 3221225626i64;
    v10 = a2;
  }
  v17 = (char *)ExAllocatePoolWithQuotaTag((POOL_TYPE)9, 0x88ui64, 0x65567350ui64);
  v18 = v17;
  if( !v17 )
    return 3221225626i64;
  memset((INT64)v17, 0i64);
  LODWORD(v40) = a7;
  Enclave = VslCreateEnclave((INT64)v18, a1, v10, a3, v8, a6, v40, a5, (INT64)(v18 + 24));
  if( Enclave >= 0 )
  {
    v21 = 0;
    v18[76] = a5;
    *((_QWORD *)v18 + 14) = 0i64;
    *((_QWORD *)v18 + 2) = 1i64;
    *((_QWORD *)v18 + 13) = 0i64;
    *((_QWORD *)v18 + 6) = 0i64;
    *((_QWORD *)v18 + 4) = a3;
    KeInitializeEvent((_KEVENT *)(v18 + 80), NotificationEvent, 0);
    if( !a5 )
    {
      if( !*((_QWORD *)v18 + 1) )
      {
        do
        {
          v22 = _InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 2256), 1ui64);
          *((_QWORD *)v18 + 1) = v22 + 1;
        }
        while( v22 == -1 );
      }
      v23 = (_ETHREAD *)KeGetCurrentThread();
      --*((_WORD *)v23 + 242);
      v24 = (volatile INT64 *)(a1 + 2264);
      ExAcquirePushLockExclusiveEx(a1 + 2264, 0i64);
      v25 = *(_QWORD *)(a1 + 2248);
      if( *(_DWORD *)v25 >= (unsigned int)(4 * (*(_DWORD *)(v25 + 4) >> 5)) )
      {
        v26 = (unsigned int)(2 * (*(_DWORD *)(v25 + 4) >> 5));
        if( (unsigned int)v26 < 4 )
          v26 = 4i64;
        v27 = (char *)PspVsmEnclaveHashAllocator(8i64 * (unsigned int)v26);
        if( v27 )
        {
          if( (((_DWORD)v26 - 1) & (unsigned int)v26) != 0 )
          {
            v28 = -1;
            do
            {
              ++v28;
              LODWORD(v26) = (unsigned int)v26 >> 1;
            }
            while( (_DWORD)v26 );
            v26 = (unsigned int)(1 << v28);
          }
          if( (unsigned int)v26 > 0x4000000 )
            v26 = 0x4000000i64;
          v29 = (unsigned int)v26;
          if( v27 > &v27[8 * v26] )
            v29 = 0i64;
          if( v29 )
          {
            memset64(v27, v25 | 1, v29);
            v21 = 0;
          }
          v30 = -1i64 << (*(_BYTE *)(v25 + 4) & 0x1F);
          if( (*(_DWORD *)(v25 + 4) & 0xFFFFFFE0) != 0 )
          {
            do
            {
              v31 = *(_QWORD *)(v25 + 8);
              while( 1 )
              {
                v32 = *(_QWORD **)(v31 + 8i64 * v21);
                if( ((unsigned __int8)v32 & 1) != 0 )
                  break;
                *(_QWORD *)(v31 + 8i64 * v21) = *v32;
                v41 = v30 & v32[1];
                v33 = (37
                     * (BYTE6(v41)
                      + 37
                      * (BYTE5(v41)
                       + 37
                       * (BYTE4(v41)
                        + 37
                        * (BYTE3(v41) + 37 * (BYTE2(v41) + 37 * (BYTE1(v41) + 37 * ((unsigned __int8)v41 + 11623883)))))))
                     + HIBYTE(v41)) & (unsigned int)(v26 - 1);
                *v32 = *(_QWORD *)&v27[8 * v33];
                *(_QWORD *)&v27[8 * v33] = v32;
              }
              ++v21;
            }
            while( v21 < *(_DWORD *)(v25 + 4) >> 5 );
            v24 = (volatile INT64 *)(a1 + 2264);
          }
          v34 = *(void **)(v25 + 8);
          v35 = *(_DWORD *)(v25 + 4) & 0x1F | (32 * v26);
          *(_QWORD *)(v25 + 8) = v27;
          *(_DWORD *)(v25 + 4) = v35;
          if( v34 )
            SC_ENV::Free(v34);
        }
      }
      v36 = *(_QWORD *)(a1 + 2248);
      v37 = *(_DWORD *)(v36 + 4);
      v42 = *((_QWORD *)v18 + 1) & (-1i64 << (v37 & 0x1F));
      v38 = *(_QWORD *)(v36 + 8);
      v39 = (37
           * (BYTE6(v42)
            + 37
            * (BYTE5(v42)
             + 37
             * (BYTE4(v42)
              + 37 * (BYTE3(v42) + 37 * (BYTE2(v42) + 37 * (BYTE1(v42) + 37 * ((unsigned __int8)v42 + 11623883)))))))
           + HIBYTE(v42)) & ((v37 >> 5) - 1);
      *(_QWORD *)v18 = *(_QWORD *)(v38 + 8 * v39);
      *(_QWORD *)(v38 + 8 * v39) = v18;
      ++*(_DWORD *)v36;
      if( (_InterlockedExchangeAdd64(v24, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
        ExfTryToWakePushLock(v24);
      KeAbPostRelease((PVOID)v24);
      KeLeaveCriticalRegionThread((__int64)KeGetCurrentThread());
    }
    *(_QWORD *)a8 = v18;
    return 0i64;
  }
  else
  {
    ExFreePoolWithTag(v18, 0);
    return(unsigned int)Enclave;
  }
}

Referenced by:

MiCreateVsmEnclave