RtlpFreeHeap
UINT64 __stdcall RtlpFreeHeap(_HEAP *Heap, UINT64 Flags, _HEAP_ENTRY *BusyBlock, VOID *BaseAddress){
char v6;
int v8;
int v9;
void **BlocksIndex;
unsigned __int8 v11;
_HEAP_FREE_ENTRY *v12;
unsigned __int16 v13;
bool v14;
UINT64 v15;
_LIST_ENTRY *p_FreeLists;
_LIST_ENTRY *Entry;
unsigned int Blink;
unsigned __int16 v19;
_LIST_ENTRY *p_FreeList;
VOID **p_Flink;
_HEAP_LIST_LOOKUP *v22;
_LIST_ENTRY *ArraySize;
int Size;
_HEAP_FREE_ENTRY *v25;
unsigned __int64 v26;
_LIST_ENTRY *v27;
_LIST_ENTRY *Flink;
unsigned int v29;
unsigned __int16 v30;
VOID **v31;
_HEAP_ENTRY *v32;
void *PreviousBlockPrivateData;
_QWORD *v34;
VOID **CompactHeader;
_HEAP_ENTRY *v36;
VOID *v37;
UINT64 *Param2;
VOID *Param2a;
VOID *v40;
char v41;
VOID *BaseAddressa;
_HEAP_FREE_ENTRY *v43;
unsigned int v44;
unsigned int v45;
_HEAP_FREE_ENTRY *v46;
UINT64 FreeSize;
FreeSize = 0i64;
v6 = 0;
v41 = 0;
BaseAddressa = 0i64;
if( Heap == (_HEAP *)BusyBlock )
{
RtlpLogHeapFailure(heap_failure_invalid_argument, Heap, BusyBlock, 0i64, 0i64);
return 0i64;
}
v8 = Heap->ForceFlags | Flags;
v9 = v8 & 0x3C010F60;
if( (v8 & 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(Heap, BusyBlock);
}
}
else
{
ExAcquireResourceExclusiveLite((UINT64)Heap->LockVariable, 1, (INT64)BusyBlock);
v6 = 1;
v41 = 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(Heap, BusyBlock);
}
BlocksIndex = (void **)Heap->BlocksIndex;
do
{
if( BusyBlock->UnpackedEntry.Size < (unsigned __int64)*((unsigned int *)BlocksIndex + 2) )
break;
BlocksIndex = (void **)*BlocksIndex;
}
while( BlocksIndex );
}
v11 = BusyBlock->UnpackedEntry.Flags;
if( (v11 & 8) != 0 )
BusyBlock->UnpackedEntry.Flags = v11 & 0xF7;
if( BusyBlock->UnpackedEntry.UnusedBytes == 4 )
{
v32 = BusyBlock - 3;
PreviousBlockPrivateData = BusyBlock[-1].UnpackedEntry.PreviousBlockPrivateData;
BaseAddressa = (VOID *)((unsigned __int64)&BusyBlock[-3] & 0xFFFFFFFFFFFF0000ui64);
Heap->Counters.TotalSizeInVirtualBlocks -= (unsigned __int64)PreviousBlockPrivateData;
v34 = BusyBlock[-3].UnpackedEntry.PreviousBlockPrivateData;
CompactHeader = (VOID **)BusyBlock[-3].UnpackedEntry.CompactHeader;
v36 = (_HEAP_ENTRY *)*CompactHeader;
v37 = (VOID *)v34[1];
if( *CompactHeader == v37 && v36 == v32 )
{
*CompactHeader = v34;
v34[1] = CompactHeader;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, v32, v37, v36);
}
if( v6 )
{
ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
v6 = 0;
}
FreeSize = 0i64;
ZwFreeVirtualMemory((VOID *)0xFFFFFFFFFFFFFFFFi64, &BaseAddressa, &FreeSize, 0x8000ui64);
goto LABEL_82;
}
FreeSize = BusyBlock->UnpackedEntry.Size;
v12 = RtlpCoalesceFreeBlocks(Heap, (_HEAP_FREE_ENTRY *)BusyBlock, &FreeSize, (UINT64 *)BaseAddress, Param2, v40);
v46 = v12;
v13 = FreeSize;
if( FreeSize < Heap->DeCommitFreeBlockThreshold || FreeSize + Heap->TotalFreeSize < Heap->DeCommitTotalFreeThreshold )
{
if( FreeSize > 0xFF00 )
{
RtlpInsertFreeBlock(Heap, v12, FreeSize);
goto LABEL_82;
}
v14 = v9 == 0;
v15 = (unsigned __int16)FreeSize;
if( v14 )
{
v12->HeapEntry.UnpackedEntry.Flags = 0;
v12->HeapEntry.UnpackedEntry.UnusedBytes = 0;
p_FreeLists = &Heap->FreeLists;
if( Heap->BlocksIndex )
Entry = RtlpFindEntry(Heap, v13);
else
Entry = p_FreeLists->Flink;
while( p_FreeLists != Entry )
{
if( Heap->EncodeFlagMask )
{
Blink = (unsigned int)Entry[-1].Blink;
v44 = Blink;
if( (Blink & Heap->EncodeFlagMask) != 0 )
v44 = Blink ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
v19 = v44;
v12 = v46;
v6 = v41;
}
else
{
v19 = (unsigned __int16)Entry[-1].Blink;
}
if( v15 <= v19 )
break;
Entry = Entry->Flink;
}
p_FreeList = &v12->FreeList;
p_Flink = (VOID **)&Entry->Blink->Flink;
if( *p_Flink == Entry )
{
p_FreeList->Flink = Entry;
v12->FreeList.Blink = (_LIST_ENTRY *)p_Flink;
*p_Flink = p_FreeList;
Entry->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, Entry, 0i64, *p_Flink);
}
Heap->TotalFreeSize += v12->HeapEntry.UnpackedEntry.Size;
v22 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( !v22 )
goto LABEL_70;
while( 1 )
{
ArraySize = (_LIST_ENTRY *)v22->ArraySize;
if( v12->HeapEntry.UnpackedEntry.Size < (unsigned __int64)ArraySize )
{
Size = v12->HeapEntry.UnpackedEntry.Size;
goto LABEL_69;
}
if( !v22->ExtendedLookup )
break;
v22 = v22->ExtendedLookup;
}
Size = (_DWORD)ArraySize - 1;
LABEL_69:
LODWORD(Param2a) = Size;
RtlpHeapAddListEntry(Heap, v22, ArraySize, (UINT64)p_FreeList, (UINT64)Param2a);
LABEL_70:
if( Heap->EncodeFlagMask )
{
v12->HeapEntry.UnpackedEntry.SmallTagIndex = LOBYTE(v12->InterceptorValue) ^ BYTE1(v12->Code1) ^ v12->HeapEntry.UnpackedEntry.Flags;
v12->HeapEntry.UnpackedEntry.SubSegmentCode ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
}
goto LABEL_82;
}
v12->HeapEntry.UnpackedEntry.Flags &= 0xF0u;
v12->HeapEntry.UnpackedEntry.UnusedBytes = 0;
if( (Heap->Flags & 0x40) == 0 )
{
LABEL_50:
v27 = &Heap->FreeLists;
if( Heap->BlocksIndex )
Flink = RtlpFindEntry(Heap, v15);
else
Flink = v27->Flink;
while( v27 != Flink )
{
if( Heap->EncodeFlagMask )
{
v29 = (unsigned int)Flink[-1].Blink;
v45 = v29;
if( (v29 & Heap->EncodeFlagMask) != 0 )
v45 = v29 ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
v30 = v45;
v12 = v46;
v6 = v41;
}
else
{
v30 = (unsigned __int16)Flink[-1].Blink;
}
if( v15 <= v30 )
break;
Flink = Flink->Flink;
}
p_FreeList = &v12->FreeList;
v31 = (VOID **)&Flink->Blink->Flink;
if( *v31 == Flink )
{
p_FreeList->Flink = Flink;
v12->FreeList.Blink = (_LIST_ENTRY *)v31;
*v31 = p_FreeList;
Flink->Blink = p_FreeList;
}
else
{
RtlpLogHeapFailure(heap_failure_freelists_corruption, 0i64, Flink, 0i64, *v31);
}
Heap->TotalFreeSize += v12->HeapEntry.UnpackedEntry.Size;
v22 = (_HEAP_LIST_LOOKUP *)Heap->BlocksIndex;
if( !v22 )
goto LABEL_70;
while( 1 )
{
ArraySize = (_LIST_ENTRY *)v22->ArraySize;
if( v12->HeapEntry.UnpackedEntry.Size < (unsigned __int64)ArraySize )
{
Size = v12->HeapEntry.UnpackedEntry.Size;
goto LABEL_69;
}
if( !v22->ExtendedLookup )
break;
v22 = v22->ExtendedLookup;
}
Size = (_DWORD)ArraySize - 1;
goto LABEL_69;
}
v25 = v12 + 1;
v43 = v12 + 1;
v26 = (16 * v15 - 32) >> 2;
if( v26 )
{
if( ((unsigned __int8)v25 & 4) == 0 )
goto LABEL_47;
LODWORD(v25->HeapEntry.UnpackedEntry.PreviousBlockPrivateData) = -17891602;
if( --v26 )
{
v25 = (_HEAP_FREE_ENTRY *)((char *)v12 + 36);
v43 = (_HEAP_FREE_ENTRY *)((char *)v12 + 36);
LABEL_47:
memset64(v25, 0xFEEEFEEEFEEEFEEEui64, v26 >> 1);
if( (v26 & 1) != 0 )
*((_DWORD *)&v25->HeapEntry.UnpackedEntry + v26 - 1) = -17891602;
}
}
v12->HeapEntry.UnpackedEntry.Flags |= 4u;
goto LABEL_50;
}
RtlpDeCommitFreeBlock(Heap, v12, FreeSize);
LABEL_82:
if( v6 )
ExReleaseResourceLite((PERESOURCE)Heap->LockVariable);
return 1i64;
}Referenced by:
RtlpFreeHeapInternal