RtlpAllocateHeap

_DWORD *__fastcall RtlpAllocateHeap(
        __int64 a1,
        unsigned int a2,
        unsigned __int64 a3,
        unsigned __int64 a4,
        char a5,
        _DWORD *a6){
  unsigned __int64 v6; 
  __int16 v7; 
  char v8; 
  INT64 v10; 
  char v11; 
  unsigned __int64 v12; 
  unsigned __int64 v14; 
  unsigned __int64 v15; 
  __int64 *Entry; 
  UINT64 v17; 
  unsigned __int64 v18; 
  INT64 v19; 
  INT64 *v20; 
  INT64 v21; 
  INT64 v22; 
  INT64 v23; 
  unsigned __int64 v24; 
  unsigned __int64 v25; 
  INT64 v26; 
  INT64 *v27; 
  INT64 v28; 
  INT64 *v29; 
  INT64 v30; 
  INT64 v31; 
  INT64 v32; 
  unsigned __int64 v33; 
  unsigned __int64 v34; 
  CHAR v35; 
  char v36; 
  SIZE_T v37; 
  SIZE_T v38; 
  INT64 v39; 
  unsigned __int64 v40; 
  __int64 v41; 
  unsigned __int64 v42; 
  CHAR v43; 
  __int64 v44; 
  __int64 v45; 
  char v46; 
  void *v47; 
  unsigned __int64 v48; 
  _OWORD *v49; 
  unsigned __int64 v50; 
  VOID *v51; 
  CHAR *v52; 
  _QWORD *v53; 
  unsigned __int64 v54; 
  UINT64 v55; 
  INT64 *v56; 
  UINT64 v57; 
  CHAR v58; 
  int v59; 
  INT64 *v60; 
  INT64 *v61; 
  INT64 v62; 
  INT64 v63; 
  UINT64 a4a; 
  __int64 *v65; 
  UINT64 v66; 
  INT64 v67; 
  __int64 v68; 
  UINT64 v69; 
  UINT64 v70; 
  CHAR *v71; 
  __int64 v72; 
  __int64 *v73; 
  unsigned __int64 v74; 
  unsigned __int64 v75; 
  char v76; 
  unsigned __int64 a2a; 
  a2a = a4;
  v76 = a2;
  v6 = a4;
  v7 = a3;
  v8 = a2;
  v66 = 0i64;
  v59 = 1;
  v67 = 0i64;
  a5 = 0;
  v10 = 0i64;
  v71 = 0i64;
  a4a = 0i64;
  v70 = 0i64;
  if( (a2 & 0x3C010F60) != 0 || a3 >= 0x80000000 )
  {
    v59 = 0;
    *a6 = 4;
    if( a3 > 0x7FFFFFFFFFFFFFFFi64 )
      return 0i64;
    v14 = a3;
    if( !a3 )
      v14 = 1i64;
    v6 = *(_QWORD *)(a1 + 264) & (*(_QWORD *)(a1 + 256) + v14);
    if( v6 < 0x20 )
      v6 = 32i64;
    a2a = v6;
    v11 = (a2 >> 4) & 0xE0 | 1;
    if( (a2 & 0x3C000100) != 0 || (v15 = v6, *(_QWORD *)(a1 + 328)) )
    {
      v11 = (a2 >> 4) & 0xE0 | 3;
      v15 = v6 + 16;
      v6 = v15;
      a2a = v15;
    }
    v12 = v15 >> 4;
  }
  else
  {
    v11 = 1;
    v12 = a4 >> 4;
    if( a4 >> 4 < 2 )
    {
      v6 = a4 + 16;
      a2a = a4 + 16;
      v12 = 2i64;
    }
    *a6 = 3;
  }
  if( (a2 & 0x800000) != 0 && (RtlGetNtGlobalFlags() & 0x800) == 0 )
    v11 |= 8u;
  if( (v8 & 1) == 0 )
  {
    ExAcquireResourceExclusiveLite(*(ERESOURCE **)(a1 + 352), 1u);
    a5 = 1;
  }
  if( v12 > *(unsigned int *)(a1 + 148) )
  {
    if( (*(_DWORD *)(a1 + 112) & 2) != 0 )
    {
      v50 = v6 + 48;
      a2a = v50 + 8;
      if( (unsigned int)RtlpHpHeapCheckCommitLimit(
                           (v50 + 4103) & 0xFFFFFFFFFFFFF000ui64,
                           *(_QWORD *)(a1 + 576) - *(_QWORD *)(a1 + 664),
                           a1,
                           (UINT64 *)(a1 + 376)) )
      {
        v70 = (ExGenRandom(1i64) & 0xF) << 12;
        v52 = RtlpHpAllocVirtBlockCommitFirst(v51, &a2a, v70, &a4a);
        v53 = v52;
        v71 = v52;
        if( v52 )
        {
          v54 = a2a;
          *((_WORD *)v52 + 28) = a2a - v7;
          v52[58] = v11 | 2;
          *((_QWORD *)v52 + 4) = v54;
          *((_QWORD *)v52 + 5) = a4a;
          v52[63] = 4;
          *(_QWORD *)(a1 + 592) += v54;
          if( *(_DWORD *)(a1 + 124) )
          {
            v52[59] = v52[56] ^ v52[57] ^ v52[58];
            *((_DWORD *)v52 + 14) ^= *(_DWORD *)(a1 + 136);
          }
          v55 = a1 + 272;
          v56 = *(INT64 **)(a1 + 280);
          if( *v56 == a1 + 272 )
          {
            *v53 = v55;
            v53[1] = v56;
            *v56 = (INT64)v53;
            *(_QWORD *)(a1 + 280) = v53;
          }
          else
          {
            RtlpLogHeapFailure(13i64, 0i64, v55, 0i64, *v56, 0i64);
          }
          v10 = (INT64)(v53 + 8);
        }
        else
        {
          v10 = 0i64;
          ++*(_DWORD *)(a1 + 632);
        }
        goto LABEL_112;
      }
    }
    goto LABEL_111;
  }
  v72 = a1 + 336;
  Entry = RtlpFindEntry(a1, v12);
  v73 = Entry;
  if( (__int64 *)(a1 + 336) == Entry )
  {
LABEL_40:
    v26 = RtlpExtendHeap(a1, v6);
    v17 = v26;
    v65 = (__int64 *)v26;
    if( v26 )
    {
      v27 = (INT64 *)(v26 + 16);
      v28 = *(_QWORD *)(v26 + 16);
      v62 = v28;
      v29 = *(INT64 **)(v26 + 24);
      v61 = v29;
      v30 = *v29;
      v31 = *(_QWORD *)(v28 + 8);
      if( *v29 != v31 || (INT64 *)v30 != v27 )
      {
        RtlpLogHeapFailure(13i64, a1, (UINT64)v27, v31, v30, 0i64);
        goto LABEL_112;
      }
      *(_QWORD *)(a1 + 192) -= *(unsigned __int16 *)(v17 + 8);
      v32 = *(_QWORD *)(a1 + 312);
      if( v32 )
      {
        v33 = *(unsigned __int16 *)(v17 + 8);
        while( 1 )
        {
          v34 = *(unsigned int *)(v32 + 8);
          if( v33 < v34 )
            break;
          if( !*(_QWORD *)v32 )
          {
            LODWORD(v33) = v34 - 1;
            break;
          }
          v32 = *(_QWORD *)v32;
        }
        LODWORD(v57) = v33;
        RtlpHeapRemoveListEntry(a1, v32, (INT64)v27, v27, v57, *(unsigned __int16 *)(v17 + 8));
        v28 = v62;
        v29 = v61;
      }
      *v29 = v28;
      *(_QWORD *)(v28 + 8) = v29;
LABEL_50:
      v35 = *(_BYTE *)(v17 + 10);
      v58 = v35;
      v36 = v59;
      if( !v59 && (v35 & 4) != 0 )
      {
        v37 = 16i64 * *(unsigned __int16 *)(v17 + 8) - 32;
        if( (v35 & 2) != 0 && v37 > 4 )
          v37 = 16i64 * *(unsigned __int16 *)(v17 + 8) - 36;
        v38 = RtlCompareMemoryUlong((PVOID)(v17 + 32), v37, 0xFEEEFEEE);
        if( v38 != v37 )
        {
          DbgPrint(
            "HEAP: Free Heap block %p modified at %p after it was freed\n",
            (const void *)v17,
            (const void *)(v17 + v38 + 32));
          if( (_BYTE)KdDebuggerEnabled )
            __debugbreak();
        }
        v35 = v58;
        v36 = 0;
      }
      v66 = v17;
      if( (*(_BYTE *)(v17 + 10) & 1) != 0 )
      {
        RtlpLogHeapFailure(3i64, a1, v17, 0i64, 0i64, 0i64);
        goto LABEL_112;
      }
      *(_BYTE *)(v17 + 10) = v11;
      v39 = *(unsigned __int16 *)(v17 + 8) - v12;
      v67 = v39;
      *(_WORD *)(v17 + 8) = v12;
      v40 = v6 - a3;
      v74 = v40;
      v41 = 16 * v12;
      if( v40 >= 0x3F )
      {
        *(_QWORD *)(v41 + v17) = v40;
        *(_BYTE *)(v17 + 15) = 63;
      }
      else
      {
        *(_BYTE *)(v17 + 15) = v40;
      }
      *(_BYTE *)(v17 + 11) = 0;
      if( v39 )
      {
        if( v39 == 1 )
        {
          ++*(_WORD *)(v17 + 8);
          v42 = v40 + 16;
          v75 = v42;
          if( v42 >= 0x3F )
          {
            *(_QWORD *)(v17 + 16 * (v12 + 1)) = v42;
            *(_BYTE *)(v17 + 15) = 63;
          }
          else
          {
            *(_BYTE *)(v17 + 15) = v42;
          }
        }
        else
        {
          v43 = v36 ^ 1;
          v44 = *(unsigned __int8 *)(v17 + 14);
          if( (_BYTE)v44 )
            v45 = (v17 & 0xFFFFFFFFFFFF0000ui64) + ((1 - v44) << 16);
          else
            v45 = a1;
          v68 = v45;
          if( !RtlpCreateSplitBlock(a1, v45, v17 + v41, v35, v43, v12, v39) )
            goto LABEL_112;
        }
      }
      v10 = v17 + 16;
      if( v59 )
      {
        if( *(_DWORD *)(a1 + 124) )
        {
          *(_BYTE *)(v17 + 11) = *(_BYTE *)(v17 + 8) ^ *(_BYTE *)(v17 + 9) ^ *(_BYTE *)(v17 + 10);
          *(_DWORD *)(v17 + 8) ^= *(_DWORD *)(a1 + 136);
        }
        v46 = a5;
        if( a5 )
        {
          ExReleaseResourceLite(*(PERESOURCE *)(a1 + 352));
          a5 = 0;
          v46 = 0;
        }
        if( (v76 & 8) != 0 )
          memset(v10, 0i64);
        goto LABEL_113;
      }
      if( (v76 & 8) != 0 )
      {
        memset(v17 + 16, 0i64);
LABEL_90:
        if( (*(_DWORD *)(a1 + 112) & 0x20) != 0 )
        {
          *(__m128i *)(v10 + a3) = _mm_load_si128((const __m128i *)&_xmm_abababababababababababababababab);
          *(_BYTE *)(v17 + 10) |= 4u;
        }
        *(_BYTE *)(v17 + 11) = 0;
        if( (*(_BYTE *)(v17 + 10) & 2) != 0 )
        {
          if( *(_BYTE *)(v17 + 15) == 4 )
            v49 = (_OWORD *)(v17 - 32);
          else
            v49 = (_OWORD *)(v17 + 16i64 * *(unsigned __int16 *)(v17 + 8) - 16);
          *v49 = 0i64;
        }
        if( *(_DWORD *)(a1 + 124) )
        {
          *(_BYTE *)(v17 + 11) = *(_BYTE *)(v17 + 8) ^ *(_BYTE *)(v17 + 9) ^ *(_BYTE *)(v17 + 10);
          *(_DWORD *)(v17 + 8) ^= *(_DWORD *)(a1 + 136);
        }
        goto LABEL_112;
      }
      if( (*(_DWORD *)(a1 + 112) & 0x40) == 0 )
        goto LABEL_90;
      v47 = (void *)(v17 + 16);
      v69 = v17 + 16;
      v48 = (a3 & 0xFFFFFFFFFFFFFFFCui64) >> 2;
      if( !v48 )
        goto LABEL_90;
      if( (v10 & 4) != 0 )
      {
        *(_DWORD *)v10 = -1163005939;
        if( !--v48 )
          goto LABEL_90;
        v47 = (void *)(v17 + 20);
        v69 = v17 + 20;
      }
      memset64(v47, 0xBAADF00DBAADF00Dui64, v48 >> 1);
      if( (v48 & 1) != 0 )
        *((_DWORD *)v47 + v48 - 1) = -1163005939;
      goto LABEL_90;
    }
LABEL_111:
    v10 = 0i64;
    goto LABEL_112;
  }
  v17 = (UINT64)(Entry - 2);
  v65 = Entry - 2;
  if( *(_DWORD *)(a1 + 124) )
  {
    *(_DWORD *)(v17 + 8) ^= *(_DWORD *)(a1 + 136);
    if( *(_BYTE *)(v17 + 11) != (*(_BYTE *)(v17 + 8) ^ (unsigned __int8)(*(_BYTE *)(v17 + 9) ^ *(_BYTE *)(v17 + 10))) )
      RtlpAnalyzeHeapFailure(a1, v17);
  }
  v18 = *(unsigned __int16 *)(v17 + 8);
  if( v18 < v12 )
  {
    if( *(_DWORD *)(a1 + 124) )
    {
      *(_BYTE *)(v17 + 11) = *(_BYTE *)(v17 + 8) ^ *(_BYTE *)(v17 + 9) ^ *(_BYTE *)(v17 + 10);
      *(_DWORD *)(v17 + 8) ^= *(_DWORD *)(a1 + 136);
    }
    goto LABEL_40;
  }
  v19 = *(_QWORD *)(v17 + 16);
  v63 = v19;
  v20 = *(INT64 **)(v17 + 24);
  v60 = v20;
  v21 = *v20;
  v22 = *(_QWORD *)(v19 + 8);
  if( *v20 == v22 && v21 == v17 + 16 )
  {
    *(_QWORD *)(a1 + 192) -= v18;
    v23 = *(_QWORD *)(a1 + 312);
    if( v23 )
    {
      v24 = *(unsigned __int16 *)(v17 + 8);
      while( 1 )
      {
        v25 = *(unsigned int *)(v23 + 8);
        if( v24 < v25 )
          break;
        if( !*(_QWORD *)v23 )
        {
          LODWORD(v24) = v25 - 1;
          break;
        }
        v23 = *(_QWORD *)v23;
      }
      LODWORD(v57) = v24;
      RtlpHeapRemoveListEntry(a1, v23, (INT64)v20, (INT64 *)(v17 + 16), v57, *(unsigned __int16 *)(v17 + 8));
      v19 = v63;
      v20 = v60;
    }
    *v20 = v19;
    *(_QWORD *)(v19 + 8) = v20;
    goto LABEL_50;
  }
  RtlpLogHeapFailure(13i64, a1, v17 + 16, v22, v21, 0i64);
LABEL_112:
  v46 = a5;
LABEL_113:
  if( v46 )
    ExReleaseResourceLite(*(PERESOURCE *)(a1 + 352));
  return(_DWORD *)v10;
}

Referenced by:

RtlpAllocateHeapInternal