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.