RtlCreateHeap

VOID *__stdcall RtlCreateHeap(
        UINT64 Flags,
        VOID *HeapBase,
        UINT64 ReserveSize,
        UINT64 CommitSize,
        VOID *Lock,
        _RTL_HEAP_PARAMETERS *Parameters){
  unsigned int v9; 
  _HEAP_LOCK *v10; 
  UINT64 v11; 
  __int128 *v12; 
  INT64 v13; 
  _HEAP *v14; 
  _HEAP *v15; 
  _HEAP_LOCK *v16; 
  unsigned int v18; 
  INT64 v19; 
  int v20; 
  int v21; 
  int v22; 
  INT64 v23; 
  INT64 v24; 
  INT64 v25; 
  INT64 v26; 
  __int64 v27; 
  int v28; 
  INT64 v29; 
  unsigned __int64 v30; 
  UINT64 v31; 
  int v32; 
  unsigned int v33; 
  char *v34; 
  char *v35; 
  UINT64 v36; 
  char *v37; 
  _HEAP_LIST_LOOKUP *v38; 
  unsigned __int64 v39; 
  unsigned int v40; 
  UINT8 v41; 
  _LIST_ENTRY *p_FreeLists; 
  _LIST_ENTRY *p_VirtualAllocdBlocks; 
  _LIST_ENTRY *p_SegmentList; 
  _LIST_ENTRY *p_UCRList; 
  _HEAP *v46; 
  UINT64 MemoryInformationLength; 
  PSIZE_T ReturnLength; 
  _HEAP *Heap; 
  unsigned __int64 v50; 
  INT16 v51[4]; 
  UINT64 Flagsa; 
  UINT64 v53; 
  VOID *UnCommittedAddress; 
  UINT64 RegionSize; 
  UINT64 v56; 
  VOID *BaseAddress; 
  __int64 v58; 
  unsigned __int64 v59; 
  unsigned __int64 v60; 
  unsigned __int64 v61; 
  unsigned __int64 v62; 
  __int128 v63; 
  __int128 MemoryInformation; 
  __int128 v65; 
  __int128 v66; 
  INT64 v67[14]; 
  __int128 v68; 
  __int128 v69; 
  __int128 v70; 
  __int64 v71[8]; 

  v9 = Flags;
  v50 = (unsigned __int64)Lock;
  v58 = (__int64)HeapBase;
  RegionSize = (UINT64)Lock;
  UnCommittedAddress = 0i64;
  *(_DWORD *)v51 = NtGlobalFlag;
  MemoryInformation = 0i64;
  v65 = 0i64;
  v66 = 0i64;
  v68 = 0i64;
  v69 = 0i64;
  v70 = 0i64;
  LODWORD(Flagsa) = 0;
  v53 = 0i64;
  memset(v71, 0i64, sizeof(v71));
  Heap = 0i64;
  v10 = 0i64;
  if( (v9 & 0x100) == 0 )
  {
    if( (v9 & 0x200) != 0 )
      goto LABEL_14;
    if( (v9 & 0x10000000) == 0 )
    {
      v18 = v9 & 0xFFF80C00;
      if( RtlpHeapErrorHandlerThreshold < 2 )
      {
        if( v18 )
          v9 &= 0x7F3FFu;
      }
      else if( v18 )
      {
        DbgPrint("!(CheckedFlags & ~HEAP_CREATE_VALID_MASK)");
        RtlpHeapHandleError(v19);
      }
    }
    memset(&v67[2], 0i64, 0x60u);
    if( Parameters && Parameters->Length == 96 )
    {
      *(_OWORD *)&v67[2] = *(_OWORD *)&Parameters->Length;
      *(_OWORD *)&v67[4] = *(_OWORD *)&Parameters->DeCommitTotalFreeThreshold;
      *(_OWORD *)&v67[6] = *(_OWORD *)&Parameters->InitialReserve;
      *(_OWORD *)&v67[8] = *(_OWORD *)Parameters->Reserved;
      *(_OWORD *)&v67[10] = *(_OWORD *)&Parameters[1].SegmentCommit;
      *(_OWORD *)&v67[12] = *(_OWORD *)&Parameters[1].VirtualMemoryThreshold;
    }
    v20 = v9 | 0x20;
    if( (v51[0] & 0x10) == 0 )
      v20 = v9;
    v21 = v20 | 0x40;
    if( (v51[0] & 0x20) == 0 )
      v21 = v20;
    v22 = v21 | 0x80;
    if( (*(_DWORD *)v51 & 0x200000) == 0 )
      v22 = v21;
    v23 = v67[3];
    if( !v67[3] )
      v23 = qword_140CFA1B8;
    v60 = v23;
    v24 = v67[4];
    if( !v67[4] )
      v24 = qword_140CFA1B0;
    v61 = v24;
    v25 = v67[5];
    if( !v67[5] )
      v25 = qword_140CFA1A0;
    v62 = v25;
    v26 = v67[6];
    if( !v67[6] )
      v26 = qword_140CFA1A8;
    v67[0] = v26;
    v27 = qword_140CF9D28;
    if( !qword_140CF9D28 )
    {
      qword_140CF9D30 = 0x10000i64;
      ZwQuerySystemInformation();
      if( v28 < 0 )
        goto LABEL_14;
      v27 = v71[5];
      qword_140CF9D28 = v71[5];
    }
    v59 = v67[7];
    if( !v67[7] )
      v59 = v27 - qword_140CF9D30 - 4096;
    v29 = v67[8];
    if( (unsigned __int64)(v67[8] - 1) > 0xFEFFF )
      v29 = 1044480i64;
    *(_QWORD *)&v63 = v29;
    if( CommitSize )
      v30 = (CommitSize + 0x1FFF) & 0xFFFFFFFFFFFFE000ui64;
    else
      v30 = 0x2000i64;
    v53 = v30;
    if( ReserveSize )
      v31 = (ReserveSize + 0x1FFF) & 0xFFFFFFFFFFFFE000ui64;
    else
      v31 = (v30 + 0xFFFF) & 0xFFFFFFFFFFFF0000ui64;
    *(_QWORD *)v51 = v31;
    if( v30 > v31 )
    {
      v53 = v31;
      v30 = v31;
    }
    if( (v22 & 2) == 0 || HeapBase )
    {
      v58 = 0i64;
    }
    else
    {
      v58 = 4096i64;
      LODWORD(Flagsa) = 2;
      if( v31 - 4096 < v30 )
      {
        v31 = (v31 + 69631) & 0xFFFFFFFFFFFF0000ui64;
        *(_QWORD *)v51 = v31;
      }
    }
    if( !v30 || !v31 )
      goto LABEL_14;
    v32 = 704;
    v16 = (_HEAP_LOCK *)v50;
    v33 = v22;
    if( (v22 & 1) != 0 )
    {
      if( v50 )
        goto LABEL_73;
    }
    else
    {
      v32 = v50 != 0 ? 704 : 808;
      v33 = v22 | 0x80000000;
      if( !v50 )
        v33 = v22;
      v10 = (_HEAP_LOCK *)(v50 & -(__int64)(v50 != 0));
    }
    if( HeapBase )
    {
      if( v67[11] )
      {
        if( !v67[9] || !v67[10] || v67[9] > (unsigned __int64)v67[10] || (v33 & 2) != 0 )
          goto LABEL_14;
        UnCommittedAddress = HeapBase;
        v34 = (char *)HeapBase + v67[9];
        *(_QWORD *)v51 = v67[10];
        memset(HeapBase, 0i64, 0x1000u);
        v35 = (char *)HeapBase;
      }
      else
      {
        if( ZwQueryVirtualMemory(-1, HeapBase, MemoryBasicInformation, &MemoryInformation, 48, 0i64) < 0 )
          goto LABEL_14;
        v34 = (char *)MemoryInformation;
        if( (VOID *)MemoryInformation != HeapBase || (_DWORD)v66 == 0x10000 )
          goto LABEL_14;
        v35 = (char *)MemoryInformation;
        UnCommittedAddress = (VOID *)MemoryInformation;
        if( (_DWORD)v66 == 4096 )
        {
          if( (v33 & 0x40000) != 0 && (BYTE4(v66) & 0x40) == 0 )
            goto LABEL_14;
          memset((VOID *)MemoryInformation, 0i64, 0x1000u);
          if( ZwQueryVirtualMemory(-1, HeapBase, MemoryRegionInformation, &v68, 48, 0i64) < 0 )
            goto LABEL_14;
          *(_QWORD *)v51 = v69;
          v53 = *((_QWORD *)&v65 + 1);
          v35 = (char *)UnCommittedAddress;
          v34 = (char *)UnCommittedAddress + *((_QWORD *)&v65 + 1);
        }
        else
        {
          *(_QWORD *)v51 = *((_QWORD *)&v65 + 1);
          v36 = v53;
          if( v53 > *((_QWORD *)&v65 + 1) )
            v36 = *((_QWORD *)&v65 + 1);
          v53 = v36;
          if( v36 < 0x2000 )
            goto LABEL_14;
        }
      }
      LODWORD(Flagsa) = Flagsa | 1;
      v37 = (char *)HeapBase;
      Heap = (_HEAP *)HeapBase;
      goto LABEL_93;
    }
    BaseAddress = 0i64;
    if( !v67[11] )
    {
      v56 = (RtlpHeapGenerateRandomValue64() & 0x1F) << 16;
      RegionSize = *(_QWORD *)v51 + v56;
      if( *(_QWORD *)v51 + v56 < *(_QWORD *)v51 )
      {
        RegionSize = *(_QWORD *)v51;
        v56 = 0i64;
      }
      LODWORD(ReturnLength) = 4;
      LODWORD(MemoryInformationLength) = 0x2000;
      if( ZwAllocateVirtualMemory(
             (VOID *)0xFFFFFFFFFFFFFFFFi64,
             &BaseAddress,
             0i64,
             &RegionSize,
             MemoryInformationLength,
             (UINT64)ReturnLength) < 0 )
        goto LABEL_14;
      v37 = (char *)BaseAddress;
      Heap = (_HEAP *)BaseAddress;
      *(_QWORD *)v51 = RegionSize;
      if( v56 )
      {
        ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &v56, 0x8000ui64);
        v37 = (char *)BaseAddress + v56;
        Heap = (_HEAP *)((char *)BaseAddress + v56);
        *(_QWORD *)v51 = RegionSize - v56;
      }
      v35 = v37;
      UnCommittedAddress = v37;
      v34 = v37;
LABEL_93:
      if( v35 != v34 )
        goto LABEL_96;
      LODWORD(ReturnLength) = 4;
      LODWORD(MemoryInformationLength) = 4096;
      if( ZwAllocateVirtualMemory(
             (VOID *)0xFFFFFFFFFFFFFFFFi64,
             &UnCommittedAddress,
             0i64,
             &v53,
             MemoryInformationLength,
             (UINT64)ReturnLength) >= 0 )
      {
        v34 += v53;
        v37 = (char *)Heap;
LABEL_96:
        v38 = (_HEAP_LIST_LOOKUP *)(v37 + 704);
        if( (NtGlobalFlag & 0x800) != 0 )
        {
          v39 = (unsigned __int64)(v37 + 711) & 0xFFFFFFFFFFFFFFF8ui64;
          *((_QWORD *)v37 + 41) = v39;
          v32 += 2064;
          v38 = (_HEAP_LIST_LOOKUP *)(v39 + 2064);
          v33 |= 0x4000000u;
          v37 = (char *)Heap;
        }
        v40 = (v32 + 15) & 0xFFFFFFF0;
        *((_WORD *)v37 + 4) = v40 >> 4;
        Heap->Segment.Entry.UnpackedEntry.Flags = 1;
        Heap->Segment.Entry.UnpackedEntry.UnusedBytes = 1;
        Heap->Signature = -285217025;
        Heap->Flags = v33 & 0xEFFFFFFF;
        Heap->Interceptor = 0;
        memset(&Heap->Counters, 0i64, sizeof(Heap->Counters));
        RtlpCreateHeapEncoding(Heap);
        Heap->ForceFlags = v33 & 0x6001007D;
        Heap->HeaderValidateLength = (_WORD)v38 - (_WORD)Heap;
        Heap->HeaderValidateCopy = 0i64;
        p_FreeLists = &Heap->FreeLists;
        Heap->FreeLists.Blink = &Heap->FreeLists;
        p_FreeLists->Flink = p_FreeLists;
        p_VirtualAllocdBlocks = &Heap->VirtualAllocdBlocks;
        Heap->VirtualAllocdBlocks.Blink = &Heap->VirtualAllocdBlocks;
        p_VirtualAllocdBlocks->Flink = p_VirtualAllocdBlocks;
        p_SegmentList = &Heap->SegmentList;
        Heap->SegmentList.Blink = &Heap->SegmentList;
        p_SegmentList->Flink = p_SegmentList;
        p_UCRList = &Heap->UCRList;
        Heap->UCRList.Blink = &Heap->UCRList;
        p_UCRList->Flink = p_UCRList;
        if( !v10 && (v33 & 1) == 0 )
        {
          v10 = (_HEAP_LOCK *)v38;
          if( ExInitializeResourceLite((INT64)v38) < 0 )
          {
            v10 = 0i64;
            goto LABEL_14;
          }
          v38 = (_HEAP_LIST_LOOKUP *)((char *)v38 + 104);
        }
        Heap->LockVariable = v10;
        Heap->CompatibilityFlags |= 0x80000000;
        LODWORD(MemoryInformationLength) = Flagsa;
        if( (unsigned __int8)RtlpInitializeHeapSegment(
                                Heap,
                                &Heap->Segment,
                                v40 + 1104,
                                v41,
                                MemoryInformationLength,
                                UnCommittedAddress,
                                v34,
                                (char *)UnCommittedAddress + *(_QWORD *)v51 - v58) )
        {
          if( HeapBase )
            memset(v38, 0i64, 0x80u);
          v38->ArraySize = 128;
          v38->ListsInUseUlong = (unsigned int *)&v38[1];
          v38->ListHead = &Heap->FreeLists;
          v38->ListHints = (_LIST_ENTRY **)&v38[1].ItemCount;
          RtlpPopulateListIndex(Heap, v38);
          Heap->ProcessHeapsListIndex = 0;
          Heap->SegmentReserve = v60;
          Heap->SegmentCommit = v61;
          Heap->DeCommitFreeBlockThreshold = v62 >> 4;
          Heap->DeCommitTotalFreeThreshold = (unsigned __int64)v67[0] >> 4;
          Heap->MaximumAllocationSize = v59;
          Heap->VirtualMemoryThreshold = (unsigned __int64)(v63 + 15) >> 4;
          Heap->CommitRoutine = (int(__fastcall *)(void *, void **, unsigned __int64 *))(RtlpHeapKey ^ v67[11]);
          Heap->TuningParameters.CommittThresholdShift = 4;
          Heap->TuningParameters.MaxPreCommittThreshold = 2088960i64;
          Heap->AlignRound = 31i64;
          Heap->AlignMask = -16i64;
          v46 = Heap;
          if( (Heap->Flags & 0x20) != 0 )
          {
            Heap->AlignRound += 16i64;
            v46 = Heap;
          }
          v46->CompatibilityFlags &= ~0x80000000;
          v15 = Heap;
          Heap = 0i64;
          v10 = 0i64;
          goto LABEL_10;
        }
      }
LABEL_14:
      v15 = 0i64;
      goto LABEL_10;
    }
LABEL_73:
    v15 = 0i64;
    goto LABEL_11;
  }
  if( !HeapBase )
    goto LABEL_14;
  if( v50 )
    goto LABEL_14;
  if( (v9 & 2) != 0 )
    goto LABEL_14;
  RtlpHpConvertCreationFlags(v9, v51[0]);
  if( *(_QWORD *)&Parameters[1].DeCommitTotalFreeThreshold )
  {
    v11 = *(_QWORD *)&Parameters[1].Length;
    if( !v11 )
      goto LABEL_14;
    ReserveSize = *(_QWORD *)&Parameters[1].SegmentCommit;
    if( !ReserveSize || v11 > ReserveSize )
      goto LABEL_14;
  }
  LODWORD(v12) = RtlpHpLegacyGetEnvHandle((INT64)v67);
  v63 = *v12;
  LODWORD(v14) = RtlpHpFixedHeapCreate(HeapBase, v13, ReserveSize);
  v15 = v14;
LABEL_10:
  v16 = (_HEAP_LOCK *)v50;
LABEL_11:
  if( v10 && v10 != v16 )
    ExDeleteResourceLite((UINT64)v10);
  if( Heap && !HeapBase )
  {
    *(_QWORD *)v51 = 0i64;
    ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, (VOID **)&Heap, (UINT64 *)v51, 0x8000ui64);
  }
  return v15;
}

Referenced by:

No references.