RtlpHpLargeFree
UINT64 __stdcall RtlpHpLargeFree(PVOID HeapAddress, PVOID Address, INT8 a3){
UINT64 v3;
UINT64 v4;
__m128i *v6;
UINT8 v7;
unsigned __int64 *v8;
unsigned __int64 v9;
unsigned __int64 v10;
unsigned __int64 v11;
unsigned __int64 v12;
int v13;
__m128i v14;
UINT64 v15;
unsigned __int64 v16;
char v17;
__int64 v18;
_ETHREAD *CurrentThread;
unsigned int SessionId;
char v22;
int v23;
bool v24;
__int64 v25;
unsigned __int64 v26;
__int64 v27;
__m128i v28;
UINT64 v29;
_ETHREAD *v30;
unsigned int v31;
char v32;
int v33;
__int64 v34;
unsigned __int64 v35;
__int64 v36;
unsigned int v37[2];
int v38;
UINT64 a2[2];
__int128 a4;
__int128 v41;
UINT64 a1;
int v44;
a1 = (UINT64)Address;
v3 = (UINT64)Address;
v4 = 0i64;
a2[0] = 0i64;
v6 = (__m128i *)HeapAddress;
v7 = RtlpHpLargeLockAcquire((INT64)HeapAddress, a3);
v8 = &v6[4].m128i_u64[1];
v9 = v7;
v10 = v6[4].m128i_u64[1];
if( (v6[5].m128i_i8[0] & 1) != 0 )
{
if( v10 )
v10 ^= (unsigned __int64)v8;
else
v10 = 0i64;
}
while( v10 )
{
v11 = *(_QWORD *)(v10 + 24) & 0xFFFFFFFFFFFF0000ui64;
if( v3 >= v11 )
{
if( v3 <= v11 )
goto LABEL_16;
v12 = *(_QWORD *)(v10 + 8);
}
else
{
v12 = *(_QWORD *)v10;
}
if( (v6[5].m128i_i8[0] & 1) != 0 && v12 )
v10 ^= v12;
else
v10 = v12;
}
v10 = 0i64;
LABEL_16:
v13 = a3 & 1;
if( v10 )
{
RtlRbRemoveNode(v8, v10);
if( !v13 )
{
v14 = *v6;
v15 = (UINT64)&v6[4];
if( (_mm_cvtsi128_si32(v14) & 1) != 0 )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v15);
__writecr8(v9);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v15, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v15);
v38 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v15) == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)CurrentThread + 23));
else
SessionId = -1;
--*((_WORD *)CurrentThread + 243);
v22 = ++*((_BYTE *)CurrentThread + 794);
v23 = (*((char *)CurrentThread + 792) | *((char *)CurrentThread + 870)) ^ 0x3F;
while( 1 )
{
v24 = !_BitScanReverse((unsigned int *)&v25, v23);
v37[1] = v25;
if( v24 )
break;
v26 = *((_QWORD *)CurrentThread + 100) + 96 * v25;
v23 &= ~(1 << v25);
if( (*(_BYTE *)(v26 + 26) & 1) != 0
&& (*(_DWORD *)(v26 + 32) & 1) == 0
&& (*(_QWORD *)(v26 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v15 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v26 + 40) == SessionId )
{
*(_BYTE *)(v26 + 26) &= ~1u;
if( *(_QWORD *)(v26 + 32) )
{
if( v26 )
{
*(_BYTE *)(v26 + 32) |= 2u;
if( *(__int64 *)(v26 + 32) < 0 )
KiAbEntryRemoveFromTree(v26);
v38 = *(_DWORD *)(v26 + 88) & 0x1FFFF;
*(_DWORD *)(v26 + 88) &= 0xFFFE0000;
*(_BYTE *)(v26 + 25) &= ~1u;
*(_QWORD *)(v26 + 32) = 0i64;
v27 = (__int64)(v26 - *((_QWORD *)CurrentThread + 100)) / 96;
if( v22 == 1 )
*((_BYTE *)CurrentThread + 792) |= 1 << v27;
else
_InterlockedOr8((volatile signed __int8 *)CurrentThread + 870, 1 << v27);
goto LABEL_40;
}
break;
}
}
}
if( (*((_DWORD *)CurrentThread + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)CurrentThread, v15, SessionId, 0i64);
LABEL_40:
--*((_BYTE *)CurrentThread + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)CurrentThread, v15, (unsigned int *)&v38);
v24 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v24 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
}
v6 = (__m128i *)HeapAddress;
}
v16 = *(_QWORD *)(v10 + 32);
v17 = (unsigned __int8)v16 >> 2;
a4 = (__int128)*v6;
v18 = (((v16 >> 12) + ((v16 >> 1) & 1)) << 12) - 1;
a2[0] = (1i64 << v17) - (((1i64 << v17) - 1) & ((1i64 << v17) + v18)) + v18;
RtlpHpFreeVA(&a1, a2, 0x8000i64, &a4);
_InterlockedExchangeAdd64(v6[6].m128i_i64, -(*(_QWORD *)(v10 + 32) >> 12));
_InterlockedExchangeAdd64(&v6[5].m128i_i64[1], -(a2[0] >> 12));
v41 = (__int128)*v6;
RtlpHpMetadataFree(v10, &v41);
return a2[0];
}
else
{
if( !v13 )
{
v28 = *v6;
v29 = (UINT64)&v6[4];
if( (_mm_cvtsi128_si32(v28) & 1) != 0 )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v29);
__writecr8(v9);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v29, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v29);
v37[0] = 0;
v30 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v29) == 1 )
v31 = MmGetSessionIdEx(*((_QWORD *)v30 + 23));
else
v31 = -1;
--*((_WORD *)v30 + 243);
v32 = ++*((_BYTE *)v30 + 794);
v33 = (*((char *)v30 + 792) | *((char *)v30 + 870)) ^ 0x3F;
while( 1 )
{
v24 = !_BitScanReverse((unsigned int *)&v34, v33);
v44 = v34;
if( v24 )
goto LABEL_56;
v35 = *((_QWORD *)v30 + 100) + 96 * v34;
v33 &= ~(1 << v34);
if( (*(_BYTE *)(v35 + 26) & 1) != 0
&& (*(_DWORD *)(v35 + 32) & 1) == 0
&& (*(_QWORD *)(v35 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v29 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v35 + 40) == v31 )
{
*(_BYTE *)(v35 + 26) &= ~1u;
if( *(_QWORD *)(v35 + 32) )
break;
}
}
if( !v35 )
{
LABEL_56:
if( (*((_DWORD *)v30 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v30, v29, v31, 0i64);
goto LABEL_68;
}
*(_BYTE *)(v35 + 32) |= 2u;
if( *(__int64 *)(v35 + 32) < 0 )
KiAbEntryRemoveFromTree(v35);
v37[0] = *(_DWORD *)(v35 + 88) & 0x1FFFF;
*(_DWORD *)(v35 + 88) &= 0xFFFE0000;
*(_BYTE *)(v35 + 25) &= ~1u;
*(_QWORD *)(v35 + 32) = 0i64;
v36 = (__int64)(v35 - *((_QWORD *)v30 + 100)) / 96;
if( v32 == 1 )
*((_BYTE *)v30 + 792) |= 1 << v36;
else
_InterlockedOr8((volatile signed __int8 *)v30 + 870, 1 << v36);
LABEL_68:
--*((_BYTE *)v30 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v30, v29, v37);
v24 = (*((_WORD *)v30 + 243))++ == 0xFFFF;
if( v24 && *((_ETHREAD **)v30 + 19) != (_ETHREAD *)((char *)v30 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
v3 = a1;
}
v6 = (__m128i *)HeapAddress;
}
RtlpLogHeapFailure(8i64, (INT64)v6, v3, 0i64, 0i64, 0i64);
}
return v4;
}Referenced by:
ExFreeHeapPool
RtlpHpFreeHeap