RtlpExtendHeap
_HEAP_FREE_ENTRY *__stdcall RtlpExtendHeap(_HEAP *Heap, UINT64 AllocationSize){
_HEAP_FREE_ENTRY *v4;
UINT64 *v5;
_HEAP_FREE_ENTRY *v6;
unsigned __int64 SegmentReserve;
UINT64 v8;
UINT64 v9;
unsigned __int64 v10;
NTSTATUS v11;
UINT64 v12;
UINT64 v13;
unsigned __int64 SegmentCommit;
INT64 v15;
NTSTATUS v16;
__int64 v17;
UINT64 *AllocationType;
UINT64 AllocationTypea;
UINT64 AllocationTypeb;
VOID *Protect;
UINT64 Protecta;
__int64 v24[2];
UINT64 RegionSize;
VOID *BaseAddress;
UINT64 Size;
Size = ((_DWORD)AllocationSize + 4095) & 0xFFFFF000;
v4 = RtlpFindAndCommitPages(Heap, &Size);
if( v4 )
{
Size >>= 4;
v6 = RtlpCoalesceFreeBlocks(Heap, v4, &Size, v5, AllocationType, Protect);
RtlpInsertFreeBlock(Heap, v6, Size);
if( Heap->EncodeFlagMask )
{
v6->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( v6->HeapEntry.UnpackedEntry.SmallTagIndex != (LOBYTE(v6->InterceptorValue) ^ (unsigned __int8)(BYTE1(v6->Code1) ^ v6->HeapEntry.UnpackedEntry.Flags)) )
RtlpAnalyzeHeapFailure(Heap, &v6->HeapEntry);
}
return v6;
}
if( (Heap->Flags & 2) == 0 )
return 0i64;
SegmentReserve = Heap->SegmentReserve;
v8 = AllocationSize + 0x2000;
BaseAddress = 0i64;
LODWORD(Protect) = 4;
v9 = AllocationSize + 0x2000;
LODWORD(AllocationType) = 0x2000;
if( AllocationSize + 0x2000 <= SegmentReserve )
v9 = SegmentReserve;
v10 = (v9 + 0xFFFF) & 0xFFFFFFFFFFFF0000ui64;
if( v10 >= 0xFD0000 )
v10 = 16580608i64;
RegionSize = v10;
v11 = ZwAllocateVirtualMemory(
(VOID *)0xFFFFFFFFFFFFFFFFi64,
&BaseAddress,
0i64,
&RegionSize,
(UINT64)AllocationType,
(UINT64)Protect);
if( v11 >= 0 )
{
v12 = RegionSize;
}
else
{
while( 1 )
{
v12 = RegionSize;
if( RegionSize == v8 )
break;
v13 = RegionSize >> 1;
LODWORD(Protecta) = 4;
LODWORD(AllocationTypea) = 0x2000;
if( RegionSize >> 1 < v8 )
v13 = AllocationSize + 0x2000;
RegionSize = v13;
v11 = ZwAllocateVirtualMemory(
(VOID *)0xFFFFFFFFFFFFFFFFi64,
&BaseAddress,
0i64,
&RegionSize,
AllocationTypea,
Protecta);
if( v11 >= 0 )
{
v12 = RegionSize;
break;
}
}
if( v11 < 0 )
{
++Heap->Counters.CommitFailures;
return 0i64;
}
}
Heap->SegmentReserve += v12;
SegmentCommit = AllocationSize + 4096;
if( AllocationSize + 4096 <= Heap->SegmentCommit )
SegmentCommit = Heap->SegmentCommit;
v15 = Heap->Counters.TotalMemoryCommitted - Heap->Counters.InBlockDeccomitSize;
v24[0] = (SegmentCommit + 4095) & 0xFFFFFFFFFFFFF000ui64;
if( !RtlpHpHeapCheckCommitLimit((VOID *)v24[0], v15, Heap, (INT8 *)&Heap->CommitLimitData) )
goto LABEL_30;
LODWORD(Protecta) = 4;
LODWORD(AllocationTypea) = 4096;
v16 = ZwAllocateVirtualMemory(
(VOID *)0xFFFFFFFFFFFFFFFFi64,
&BaseAddress,
0i64,
(UINT64 *)v24,
AllocationTypea,
Protecta);
if( v16 < 0 )
goto LABEL_30;
LODWORD(AllocationTypeb) = 2;
if( !(unsigned __int8)RtlpInitializeHeapSegment(
Heap,
(_HEAP_SEGMENT *)BaseAddress,
0x70ui64,
(_BYTE)BaseAddress + RegionSize,
AllocationTypeb,
BaseAddress,
(char *)BaseAddress + v24[0],
(char *)BaseAddress + RegionSize - 4096) )
v16 = -1073741801;
if( v16 < 0 )
{
LABEL_30:
ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x8000ui64);
return 0i64;
}
v17 = *((_QWORD *)BaseAddress + 8);
if( Heap->EncodeFlagMask )
{
*(_DWORD *)(v17 + 8) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( *(_BYTE *)(v17 + 11) != (*(_BYTE *)(v17 + 8) ^ (unsigned __int8)(*(_BYTE *)(v17 + 9) ^ *(_BYTE *)(v17 + 10))) )
RtlpAnalyzeHeapFailure(Heap, (_HEAP_ENTRY *)v17);
}
return(_HEAP_FREE_ENTRY *)*((_QWORD *)BaseAddress + 8);
}Referenced by:
RtlpAllocateHeap