RtlpCoalesceFreeBlocks
_HEAP_FREE_ENTRY *__fastcall RtlpCoalesceFreeBlocks(
_HEAP *Heap,
_HEAP_FREE_ENTRY *FreeBlock,
UINT64 *FreeSize,
UINT64 *RemoveFromFreeList,
UINT64 *a5,
VOID *a6){
_HEAP_FREE_ENTRY *v7;
unsigned __int64 v8;
char *v10;
unsigned int EncodeFlagMask;
INT64 *v12;
UINT64 v13;
INT64 v14;
INT64 v15;
INT64 v16;
unsigned int *BlocksIndex;
unsigned __int64 i;
unsigned int *v19;
int v20;
char v21;
SIZE_T v22;
SIZE_T v23;
__int64 v24;
UINT64 v25;
unsigned int v26;
INT64 *v27;
INT64 v28;
INT64 v29;
INT64 v30;
unsigned int *v31;
unsigned __int64 j;
unsigned int *v33;
INT64 v34;
char v35;
SIZE_T v36;
SIZE_T v37;
UINT64 v39;
v7 = FreeBlock;
v8 = 16
* (Heap->Encoding.UnpackedEntry.PreviousSize ^ (unsigned __int64)FreeBlock->HeapEntry.UnpackedEntry.PreviousSize);
v10 = (char *)FreeBlock - v8;
if( (_HEAP_FREE_ENTRY *)((char *)FreeBlock - v8) != FreeBlock )
{
EncodeFlagMask = Heap->EncodeFlagMask;
if( (((unsigned __int8)v10[10] ^ Heap->Encoding.UnpackedEntry.Flags & (EncodeFlagMask >> 20)) & 1) == 0 )
{
if( EncodeFlagMask )
{
*((_DWORD *)v10 + 2) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( v10[11] != ((unsigned __int8)v10[8] ^ (unsigned __int8)(v10[9] ^ v10[10])) )
RtlpAnalyzeHeapFailure((INT64)Heap, (UINT64)FreeBlock - v8);
}
v12 = (INT64 *)*((_QWORD *)v10 + 3);
v13 = (UINT64)(v10 + 16);
v14 = *((_QWORD *)v10 + 2);
v15 = *v12;
v16 = *(_QWORD *)(v14 + 8);
if( *v12 == v16 && v15 == v13 )
{
Heap->TotalFreeSize -= *((unsigned __int16 *)v10 + 4);
BlocksIndex = (unsigned int *)Heap->BlocksIndex;
if( BlocksIndex )
{
for( i = BlocksIndex[2]; ; i = v19[2] )
{
if( *((unsigned __int16 *)v10 + 4) < i )
{
v20 = *((unsigned __int16 *)v10 + 4);
goto LABEL_14;
}
v19 = *(unsigned int **)BlocksIndex;
if( !*(_QWORD *)BlocksIndex )
break;
BlocksIndex = *(unsigned int **)BlocksIndex;
}
v20 = BlocksIndex[2] - 1;
LABEL_14:
LODWORD(v39) = v20;
LOBYTE(v13) = 1;
RtlpHeapRemoveListEntry(
(INT64)Heap,
(INT64)BlocksIndex,
v13,
(INT64 *)v10 + 2,
v39,
*((unsigned __int16 *)v10 + 4));
}
*v12 = v14;
*(_QWORD *)(v14 + 8) = v12;
v21 = v10[10];
if( (v21 & 4) != 0 )
{
v22 = 16i64 * *((unsigned __int16 *)v10 + 4) - 32;
if( (v21 & 2) != 0 && v22 > 4 )
v22 = 16i64 * *((unsigned __int16 *)v10 + 4) - 36;
v23 = RtlCompareMemoryUlong(v10 + 32, v22, 0xFEEEFEEE);
if( v23 != v22 )
{
DbgPrint("HEAP: Free Heap block %p modified at %p after it was freed\n", v10, &v10[v23 + 32]);
if( (_BYTE)KdDebuggerEnabled )
__debugbreak();
}
}
v24 = *((unsigned __int16 *)v10 + 4);
v7 = (_HEAP_FREE_ENTRY *)v10;
v10[10] = 0;
v10[15] = 0;
*FreeSize += v24;
*((_WORD *)v10 + 4) = *(_WORD *)FreeSize;
*(_WORD *)&v10[16 * *FreeSize + 12] = Heap->Encoding.UnpackedEntry.PreviousSize ^ *(_WORD *)FreeSize;
}
else
{
RtlpLogHeapFailure(13i64, (INT64)Heap, v13, v16, v15, 0i64);
}
}
}
v25 = (UINT64)v7 + 16 * *FreeSize;
if( Heap->EncodeFlagMask )
{
v26 = *(_DWORD *)(v25 + 8) ^ Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( HIBYTE(v26) != ((unsigned __int8)v26 ^ (unsigned __int8)(BYTE1(v26) ^ BYTE2(v26))) )
RtlpLogHeapFailure(3i64, (INT64)Heap, v25, 0i64, 0i64, 0i64);
}
while( ((*(_BYTE *)(v25 + 10) ^ Heap->Encoding.UnpackedEntry.Flags & (Heap->EncodeFlagMask >> 20)) & 1) == 0 )
{
if( Heap->EncodeFlagMask )
{
*(_DWORD *)(v25 + 8) ^= Heap->Encoding.UnpackedEntry.SubSegmentCode;
if( *(_BYTE *)(v25 + 11) != (*(_BYTE *)(v25 + 8) ^ (unsigned __int8)(*(_BYTE *)(v25 + 9) ^ *(_BYTE *)(v25 + 10))) )
RtlpAnalyzeHeapFailure((INT64)Heap, v25);
}
v27 = *(INT64 **)(v25 + 24);
v28 = *(_QWORD *)(v25 + 16);
v29 = *v27;
v30 = *(_QWORD *)(v28 + 8);
if( *v27 == v30 && v29 == v25 + 16 )
{
Heap->TotalFreeSize -= *(unsigned __int16 *)(v25 + 8);
v31 = (unsigned int *)Heap->BlocksIndex;
if( v31 )
{
for( j = v31[2]; ; j = v33[2] )
{
if( *(unsigned __int16 *)(v25 + 8) < j )
{
v34 = *(unsigned __int16 *)(v25 + 8);
goto LABEL_41;
}
v33 = *(unsigned int **)v31;
if( !*(_QWORD *)v31 )
break;
v31 = *(unsigned int **)v31;
}
v34 = v31[2] - 1;
LABEL_41:
LODWORD(v39) = v34;
LOBYTE(v34) = 1;
RtlpHeapRemoveListEntry((INT64)Heap, (INT64)v31, v34, (INT64 *)(v25 + 16), v39, *(unsigned __int16 *)(v25 + 8));
}
*v27 = v28;
*(_QWORD *)(v28 + 8) = v27;
v35 = *(_BYTE *)(v25 + 10);
if( (v35 & 4) != 0 )
{
v36 = 16i64 * *(unsigned __int16 *)(v25 + 8) - 32;
if( (v35 & 2) != 0 && v36 > 4 )
v36 = 16i64 * *(unsigned __int16 *)(v25 + 8) - 36;
v37 = RtlCompareMemoryUlong((PVOID)(v25 + 32), v36, 0xFEEEFEEE);
if( v37 != v36 )
{
DbgPrint(
"HEAP: Free Heap block %p modified at %p after it was freed\n",
(const void *)v25,
(const void *)(v37 + v25 + 32));
if( (_BYTE)KdDebuggerEnabled )
__debugbreak();
}
}
v7->HeapEntry.UnpackedEntry.Flags = 0;
v7->HeapEntry.UnpackedEntry.UnusedBytes = 0;
*FreeSize += *(unsigned __int16 *)(v25 + 8);
v7->HeapEntry.UnpackedEntry.Size = *(_WORD *)FreeSize;
*(&v7->HeapEntry.UnpackedEntry.PreviousSize + 8 * *FreeSize) = Heap->Encoding.UnpackedEntry.PreviousSize ^ *(_WORD *)FreeSize;
return v7;
}
RtlpLogHeapFailure(13i64, (INT64)Heap, v25 + 16, v30, v29, 0i64);
}
return v7;
}Referenced by:
RtlpDeCommitFreeBlock
RtlpExtendHeap
RtlpFreeHeap