RtlpDeCommitFreeBlock
VOID __fastcall RtlpDeCommitFreeBlock(INT64 a1, UINT64 a2, UINT64 a3, CHAR a4){
char v4;
UINT64 v5;
INT64 v6;
char v7;
UINT64 v8;
void *v9;
_HEAP_FREE_ENTRY *v10;
INT64 v11;
UINT64 v12;
UINT64 v13;
INT64 v14;
unsigned __int64 v15;
_QWORD *i;
_QWORD *v17;
_HEAP_FREE_ENTRY *v18;
INT64 v19;
__int64 v20;
__int64 v21;
INT64 v22;
void *v23;
INT64 v24;
bool v25;
_QWORD *v26;
unsigned __int64 v27;
ULONG_PTR v28;
unsigned __int64 v29;
char *v30;
ULONG_PTR v31;
bool v32;
INT64 v33;
INT64 v34;
_LIST_ENTRY *v35;
__int64 v36;
__int64 v37;
unsigned __int64 v38;
ULONG_PTR v39;
char *v40;
ULONG_PTR v41;
INT64 v42;
INT64 v43;
INT64 v44;
UINT64 *v45;
VOID *v46;
PVOID BaseAddress;
__int64 v48;
INT64 v49;
PVOID v50;
INT64 v51[2];
ULONG_PTR RegionSize;
UINT64 FreeSize;
CHAR v54;
v54 = a4;
FreeSize = a3;
v4 = 0;
v25 = RtlpHeapKey == *(_QWORD *)(a1 + 360);
v5 = a2;
v6 = a1;
v51[0] = 0i64;
v48 = 0i64;
v7 = 0;
v54 = 0;
if( !v25 || a3 < *(_QWORD *)(a1 + 176) )
goto LABEL_80;
v8 = a3 + *(_QWORD *)(a1 + 192);
if( v8 < *(_QWORD *)(a1 + 184) || v8 < *(_QWORD *)(a1 + 576) >> (*(_BYTE *)(a1 + 688) + 4) )
{
LABEL_79:
a1 = v6;
LABEL_80:
RtlpInsertFreeBlock(a1, a2, a3);
return;
}
v10 = RtlpCoalesceFreeBlocks((_HEAP *)a1, (_HEAP_FREE_ENTRY *)a2, &FreeSize, (UINT64 *)v8, v45, v46);
if( *(_BYTE *)(v5 + 14) )
{
v9 = (void *)((unsigned __int64)*(unsigned __int8 *)(v5 + 14) << 16);
v11 = (v5 & 0xFFFFFFFFFFFF0000ui64) - (_QWORD)v9 + 0x10000;
}
else
{
v11 = v6;
}
v12 = FreeSize;
v13 = (UINT64)v10 + 16 * FreeSize;
if( *(_BYTE *)(v13 + 15) == 3 )
{
RtlpRemoveUCRBlock(v9, (PVOID)(v13 + 16));
v14 = *(_QWORD *)(v13 + 56);
v48 = *(_QWORD *)(v13 + 48);
v49 = v14;
--*(_DWORD *)(v11 + 84);
*(_DWORD *)(v11 + 80) -= *(_QWORD *)(v13 + 56) >> 12;
*(_QWORD *)(v6 + 576) += *(_QWORD *)(v13 + 56);
--*(_DWORD *)(v6 + 604);
v15 = *(_QWORD *)(v13 + 56);
if( v15 >= 0xFF000 )
{
*(_QWORD *)(v6 + 584) -= v15;
v15 = *(_QWORD *)(v13 + 56);
}
v54 = 1;
v12 += (v15 >> 4) + 64;
v7 = 1;
FreeSize = v12;
}
else
{
v49 = 0i64;
}
if( *(_WORD *)(v6 + 140) != v10->HeapEntry.UnpackedEntry.PreviousSize )
{
v35 = (_LIST_ENTRY *)(((unsigned __int64)&v10[129].FreeList.Blink + 7) & 0xFFFFFFFFFFFFF000ui64);
BaseAddress = v35;
if( v35 == &v10[2].FreeList )
{
v35 += 256;
BaseAddress = v35;
}
if( v7 )
{
v36 = 16 * v12;
v37 = (__int64)v10 + 16 * v12;
}
else
{
v36 = 16 * v12;
v37 = (__int64)&v10[-1] + 16 * v12;
}
v38 = v37 & 0xFFFFFFFFFFFFF000ui64;
if( v38 < (unsigned __int64)v35 )
{
if( RtlpHeapErrorHandlerThreshold >= 1 && v54 )
{
DbgPrint("(!TrailingUCR)");
RtlpHeapHandleError(v44);
}
goto LABEL_29;
}
v39 = v38 - (_QWORD)v35;
RegionSize = v39;
if( *(_BYTE *)(v13 + 15) != 3 && (!v39 || v39 < *(_QWORD *)(v6 + 176)) )
{
LABEL_29:
a3 = v12;
LABEL_30:
a2 = (UINT64)v10;
goto LABEL_79;
}
if( !v39
|| (++*(_DWORD *)(v6 + 612),
ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x4000ui64) >= 0) )
{
if( !v54 )
{
v40 = (char *)BaseAddress + RegionSize;
*(_WORD *)((char *)BaseAddress + RegionSize + 12) = *(_WORD *)(v6 + 140);
if( (char *)v10 + v36 == (char *)BaseAddress + RegionSize )
{
if( *(_DWORD *)(v6 + 124) )
{
v40[11] = v40[8] ^ v40[9] ^ v40[10];
*((_DWORD *)v40 + 2) ^= *(_DWORD *)(v6 + 136);
}
}
else
{
v40[15] = 0;
v40[10] = 0;
v41 = ((unsigned __int64)v10 + v36 - RegionSize - (_QWORD)BaseAddress) >> 4;
v32 = RtlpHeapErrorHandlerThreshold < 1;
*((_WORD *)v40 + 4) = v41;
if( !v32 && (unsigned __int16)v41 <= 1u )
{
DbgPrint("(LONG)FreeEntry->Size > 1");
RtlpHeapHandleError(v42);
}
v40[11] = 0;
v43 = *(_QWORD *)(v11 + 40);
if( v43 != v11 )
{
if( ((unsigned __int64)&v40[-v11] >> 16) + 1 >= 0xFE )
{
RtlpLogHeapFailure(3i64, v43, (UINT64)v40, v11, 0i64, 0i64);
LOWORD(v41) = *((_WORD *)v40 + 4);
}
v4 = ((unsigned int)((_DWORD)v40 - v11) >> 16) + 1;
}
v40[14] = v4;
RtlpInsertFreeBlock(v6, (UINT64)v40, (unsigned __int16)v41);
}
}
RtlpCreateUCREntry(v6, v11, (INT64)BaseAddress - 48, RegionSize, (UINT64)v10, v51);
a3 = v51[0];
goto LABEL_30;
}
RtlpUpdateHeapRates((_DWORD *)v6, 3);
v25 = v54 == 0;
LABEL_33:
if( !v25 )
{
RtlpCreateUCREntry(v24, v11, v48 - 48, v49, (UINT64)v10, (INT64 *)&FreeSize);
v12 = FreeSize;
}
goto LABEL_29;
}
BaseAddress = v10;
for( i = *(_QWORD **)(v11 + 96); (_QWORD *)(v11 + 96) != i; i = (_QWORD *)*i )
{
v17 = i - 2;
v18 = (_HEAP_FREE_ENTRY *)(i[2] + i[3]);
v50 = i - 2;
if( v18 == v10 )
goto LABEL_19;
}
v17 = 0i64;
v50 = 0i64;
LABEL_19:
if( RtlpHeapErrorHandlerThreshold >= 1 && !v17 )
{
DbgPrint("(UCRBlock != NULL)");
RtlpHeapHandleError(v19);
}
v20 = 16 * v12;
if( v7 )
{
v21 = (__int64)v10 + v20;
v51[0] = (INT64)v10 + v20;
}
else
{
v51[0] = (INT64)v10 + v20;
v21 = (__int64)&v10[-1] + v20;
}
RegionSize = (v21 & 0xFFFFFFFFFFFFF000ui64) - (_QWORD)v10;
if( !RegionSize )
{
if( RtlpHeapErrorHandlerThreshold >= 1 )
{
if( v7 )
{
DbgPrint("(!TrailingUCR)");
RtlpHeapHandleError(v22);
}
}
goto LABEL_29;
}
if( ZwFreeVirtualMemory((PVOID)0xFFFFFFFFFFFFFFFFi64, &BaseAddress, &RegionSize, 0x4000ui64) < 0 )
{
RtlpUpdateHeapRates((_DWORD *)v6, 3);
v25 = v7 == 0;
goto LABEL_33;
}
v26 = v50;
++*(_DWORD *)(v6 + 612);
v27 = v26[5];
if( v27 >= 0xFF000 )
*(_QWORD *)(v6 + 584) -= v27;
RtlpRemoveUCRBlock(v23, v26);
v26[5] += RegionSize;
RtlpInsertUCRBlock(v6, (INT64 **)v26);
*(_DWORD *)(v11 + 80) += RegionSize >> 12;
v28 = RegionSize;
*(_QWORD *)(v6 + 576) -= RegionSize;
v29 = v26[5];
if( v29 >= 0xFF000 )
*(_QWORD *)(v6 + 584) += v29;
if( !v7 )
{
v30 = (char *)BaseAddress + v28;
*(_WORD *)((char *)BaseAddress + v28 + 12) = *(_WORD *)(v6 + 140);
if( (PVOID)v51[0] != (char *)BaseAddress + RegionSize )
{
v30[15] = 0;
v30[10] = 0;
v31 = (v20 - RegionSize) >> 4;
v32 = RtlpHeapErrorHandlerThreshold < 1;
*((_WORD *)v30 + 4) = v31;
if( !v32 && (unsigned __int16)v31 <= 1u )
{
DbgPrint("((LONG)FreeEntry->Size > 1)");
RtlpHeapHandleError(v33);
}
v30[11] = 0;
v34 = *(_QWORD *)(v11 + 40);
if( v34 != v11 )
{
if( ((unsigned __int64)&v30[-v11] >> 16) + 1 >= 0xFE )
{
RtlpLogHeapFailure(3i64, v34, (UINT64)v30, v11, 0i64, 0i64);
LOWORD(v31) = *((_WORD *)v30 + 4);
}
v4 = ((unsigned int)((_DWORD)v30 - v11) >> 16) + 1;
}
v30[14] = v4;
a2 = (UINT64)v30;
a3 = (unsigned __int16)v31;
goto LABEL_79;
}
if( *(_DWORD *)(v6 + 124) )
{
v30[11] = v30[8] ^ v30[9] ^ v30[10];
*((_DWORD *)v30 + 2) ^= *(_DWORD *)(v6 + 136);
}
}
}Referenced by:
RtlpFreeHeap