RtlpFreeHeap
INT64 __fastcall RtlpFreeHeap(
_HEAP *Heap,
UINT64 Flags,
_HEAP_ENTRY *BusyBlock,
VOID *BaseAddress,
UINT64 *a5,
VOID *a6){
char v8;
int v10;
int v11;
void **BlocksIndex;
unsigned __int8 v13;
_HEAP_FREE_ENTRY *v14;
CHAR v15;
unsigned __int16 v16;
bool v17;
unsigned __int64 v18;
_LIST_ENTRY *p_FreeLists;
__int64 *Entry;
unsigned int v21;
unsigned __int16 v22;
_QWORD *p_Flink;
INT64 *v24;
unsigned int *v25;
unsigned __int64 Size;
unsigned __int64 v27;
int v28;
_HEAP_FREE_ENTRY *v29;
unsigned __int64 v30;
_LIST_ENTRY *v31;
__int64 *Flink;
unsigned int v33;
unsigned __int16 v34;
INT64 *v35;
_HEAP_ENTRY *v36;
void *PreviousBlockPrivateData;
_QWORD *v38;
INT64 *CompactHeader;
INT64 v40;
INT64 v41;
UINT64 *v42;
INT64 v43;
VOID *v44;
char v45;
PVOID BaseAddressa;
_HEAP_FREE_ENTRY *v47;
unsigned int v48;
unsigned int v49;
_HEAP_FREE_ENTRY *v50;
ULONG_PTR RegionSize;
RegionSize = 0i64;
v8 = 0;
v45 = 0;
BaseAddressa = 0i64;
if( Heap == (_HEAP *)BusyBlock )
{
RtlpLogHeapFailure(9i64, (INT64)Heap, (UINT64)BusyBlock, 0i64, 0i64, 0i64);
return 0i64;
}
v10 = Heap->ForceFlags | Flags;
v11 = v10 & 0x3C010F60;
if( (v10 & 1) != 0 )
{
if( Heap->EncodeFlagMask )
{
BusyBlock->UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( BusyBlock->UnpackedEntry.SmallTagIndex != (LOBYTE(BusyBlock->Code1) ^ (unsigned __int8)(BYTE1(BusyBlock->AgregateCode) ^ BusyBlock->UnpackedEntry.Flags)) )
RtlpAnalyzeHeapFailure((INT64)Heap, (UINT64)BusyBlock);
}
}
else
{
ExAcquireResourceExclusiveLite((ERESOURCE *)Heap->LockVariable, 1u);
v8 = 1;
v45 = 1;
if( Heap->EncodeFlagMask )
{
BusyBlock->UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( BusyBlock->UnpackedEntry.SmallTagIndex != (LOBYTE(BusyBlock->Code1) ^ (unsigned __int8)(BYTE1(BusyBlock->AgregateCode) ^ BusyBlock->UnpackedEntry.Flags)) )
RtlpAnalyzeHeapFailure((INT64)Heap, (UINT64)BusyBlock);
}
BlocksIndex = (void **)Heap->BlocksIndex;
do
{
if( BusyBlock->UnpackedEntry.Size < (unsigned __int64)*((unsigned int *)BlocksIndex + 2) )
break;
BlocksIndex = (void **)*BlocksIndex;
}
while( BlocksIndex );
}
v13 = BusyBlock->UnpackedEntry.Flags;
if( (v13 & 8) != 0 )
BusyBlock->UnpackedEntry.Flags = v13 & 0xF7;
if( BusyBlock->UnpackedEntry.UnusedBytes == 4 )
{
v36 = BusyBlock - 3;
PreviousBlockPrivateData = BusyBlock[-1].UnpackedEntry.PreviousBlockPrivateData;
BaseAddressa = (PVOID)((unsigned __int64)&BusyBlock[-3] & 0xFFFFFFFFFFFF0000ui64);
Heap->Counters.TotalSizeInVirtualBlocks -= (unsigned __int64)PreviousBlockPrivateData;
v38 = BusyBlock[-3].UnpackedEntry.PreviousBlockPrivateData;
CompactHeader = (INT64 *)BusyBlock[-3].UnpackedEntry.CompactHeader;
v40 = *CompactHeader;
v41 = v38[1];
if( *CompactHeader == v41 && (_HEAP_ENTRY *)v40 == v36 )
{
*CompactHeader = (INT64)v38;
v38[1] = CompactHeader;
}
else
{
RtlpLogHeapFailure(13i64, 0i64, (UINT64)v36, v41, v40, 0i64);
}
if( v8 )
{
ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
v8 = 0;
}
RegionSize = 0i64;
ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &BaseAddressa, &RegionSize, 0x8000ui64);
goto LABEL_84;
}
RegionSize = BusyBlock->UnpackedEntry.Size;
v14 = RtlpCoalesceFreeBlocks(Heap, (_HEAP_FREE_ENTRY *)BusyBlock, &RegionSize, (UINT64 *)BaseAddress, v42, v44);
v50 = v14;
v16 = RegionSize;
if( RegionSize < Heap->DeCommitFreeBlockThreshold
|| RegionSize + Heap->TotalFreeSize < Heap->DeCommitTotalFreeThreshold )
{
if( RegionSize > 0xFF00 )
{
RtlpInsertFreeBlock((INT64)Heap, (UINT64)v14, RegionSize);
goto LABEL_84;
}
v17 = v11 == 0;
v18 = (unsigned __int16)RegionSize;
if( v17 )
{
v14->HeapEntry.UnpackedEntry.Flags = 0;
v14->HeapEntry.UnpackedEntry.UnusedBytes = 0;
p_FreeLists = &Heap->FreeLists;
if( Heap->BlocksIndex )
Entry = RtlpFindEntry((__int64)Heap, v16);
else
Entry = (__int64 *)p_FreeLists->Flink;
while( p_FreeLists != (_LIST_ENTRY *)Entry )
{
if( Heap->EncodeFlagMask )
{
v21 = *((_DWORD *)Entry - 2);
v48 = v21;
if( (v21 & Heap->EncodeFlagMask) != 0 )
v48 = v21 ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
v22 = v48;
v14 = v50;
v8 = v45;
}
else
{
v22 = *((_WORD *)Entry - 4);
}
if( v18 <= v22 )
break;
Entry = (__int64 *)*Entry;
}
p_Flink = &v14->FreeList.Flink;
v24 = (INT64 *)Entry[1];
if( (__int64 *)*v24 == Entry )
{
*p_Flink = Entry;
v14->FreeList.Blink = (_LIST_ENTRY *)v24;
*v24 = (INT64)p_Flink;
Entry[1] = (__int64)p_Flink;
}
else
{
RtlpLogHeapFailure(13i64, 0i64, (UINT64)Entry, 0i64, *v24, 0i64);
}
Heap->TotalFreeSize += v14->HeapEntry.UnpackedEntry.Size;
v25 = (unsigned int *)Heap->BlocksIndex;
if( !v25 )
goto LABEL_72;
Size = v14->HeapEntry.UnpackedEntry.Size;
while( 1 )
{
v27 = v25[2];
if( Size < v27 )
{
v28 = v14->HeapEntry.UnpackedEntry.Size;
goto LABEL_71;
}
if( !*(_QWORD *)v25 )
break;
v25 = *(unsigned int **)v25;
}
v28 = v27 - 1;
LABEL_71:
LODWORD(v43) = v28;
RtlpHeapAddListEntry((INT64)Heap, (INT64)v25, v27, (INT64)p_Flink, v43, Size);
LABEL_72:
if( Heap->EncodeFlagMask )
{
v14->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(v14->InterceptorValue) ^ BYTE1(v14->Code1) ^ v14->HeapEntry.UnpackedEntry.Flags;
v14->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
goto LABEL_84;
}
v14->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
v14->HeapEntry.UnpackedEntry.UnusedBytes = 0;
if( (Heap->Flags & 0x40) == 0 )
{
LABEL_51:
v31 = &Heap->FreeLists;
if( Heap->BlocksIndex )
Flink = RtlpFindEntry((__int64)Heap, v18);
else
Flink = (__int64 *)v31->Flink;
while( v31 != (_LIST_ENTRY *)Flink )
{
if( Heap->EncodeFlagMask )
{
v33 = *((_DWORD *)Flink - 2);
v49 = v33;
if( (v33 & Heap->EncodeFlagMask) != 0 )
v49 = v33 ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
v34 = v49;
v14 = v50;
v8 = v45;
}
else
{
v34 = *((_WORD *)Flink - 4);
}
if( v18 <= v34 )
break;
Flink = (__int64 *)*Flink;
}
p_Flink = &v14->FreeList.Flink;
v35 = (INT64 *)Flink[1];
if( (__int64 *)*v35 == Flink )
{
*p_Flink = Flink;
v14->FreeList.Blink = (_LIST_ENTRY *)v35;
*v35 = (INT64)p_Flink;
Flink[1] = (__int64)p_Flink;
}
else
{
RtlpLogHeapFailure(13i64, 0i64, (UINT64)Flink, 0i64, *v35, 0i64);
}
Heap->TotalFreeSize += v14->HeapEntry.UnpackedEntry.Size;
v25 = (unsigned int *)Heap->BlocksIndex;
if( !v25 )
goto LABEL_72;
Size = v14->HeapEntry.UnpackedEntry.Size;
while( 1 )
{
v27 = v25[2];
if( Size < v27 )
{
v28 = v14->HeapEntry.UnpackedEntry.Size;
goto LABEL_71;
}
if( !*(_QWORD *)v25 )
break;
v25 = *(unsigned int **)v25;
}
v28 = v27 - 1;
goto LABEL_71;
}
v29 = v14 + 1;
v47 = v14 + 1;
v30 = (16 * v18 - 32) >> 2;
if( v30 )
{
if( ((unsigned __int8)v29 & 4) == 0 )
goto LABEL_48;
LODWORD(v29->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
if( --v30 )
{
v29 = (_HEAP_FREE_ENTRY *)((char *)v14 + 36);
v47 = (_HEAP_FREE_ENTRY *)((char *)v14 + 36);
LABEL_48:
memset64(v29, 0xFEEEFEEEFEEEFEEEui64, v30 >> 1);
if( (v30 & 1) != 0 )
*((_DWORD *)&v29->HeapEntry.UnpackedEntry + v30 - 1) = -17891602;
}
}
v14->HeapEntry.UnpackedEntry.Flags |= 4u;
goto LABEL_51;
}
RtlpDeCommitFreeBlock((INT64)Heap, (UINT64)v14, RegionSize, v15);
LABEL_84:
if( v8 )
ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
return 1i64;
}Referenced by:
RtlpFreeHeapInternal