RtlpHpLfhSubsegmentFreeBlock
NTSTATUS __stdcall RtlpHpLfhSubsegmentFreeBlock(INT64 a1, INT64 a2, UINT64 r8_0, CHAR a4){
signed __int64 v4;
NTSTATUS v7;
__int64 *v8;
int v9;
unsigned int v10;
__int64 v11;
unsigned int v12;
char v13;
unsigned __int64 v14;
int v15;
unsigned __int16 v16;
unsigned int v17;
__int64 *v18;
char v19;
int v20;
__int64 v21;
__int64 v22;
char *v23;
char *v24;
__int64 v25;
int v26;
signed __int16 v27;
int v28;
int v29;
unsigned __int8 v30;
unsigned __int16 v31;
unsigned int v32;
signed __int64 v34;
int v35;
unsigned __int64 v36;
UINT8 v37;
int v38;
char v39;
signed __int64 v40;
_QWORD *v41;
signed __int64 v42;
_QWORD *v43;
__int64 *v44;
__int64 **v45;
__int64 **v46;
INT64 v47;
unsigned __int64 v48;
_ETHREAD *v49;
__int64 v50;
unsigned __int64 v51;
unsigned __int8 v52;
int v53;
bool v54;
__int64 v55;
_KLOCK_ENTRY *v56;
unsigned __int8 v57;
__int64 v58;
unsigned __int64 v59;
_ETHREAD *v60;
unsigned __int8 v61;
int v62;
__int64 v63;
_KLOCK_ENTRY *v64;
__int64 v65;
_ETHREAD *CurrentThread;
unsigned int SessionId;
int v68;
__int64 v69;
int v70;
_KLOCK_ENTRY *v71;
__int64 v72;
signed __int64 v73;
int i;
UINT64 v75;
int v76;
UINT64 a3;
UINT64 v78;
int v79;
_KLOCK_ENTRY *v80;
unsigned __int8 v82;
unsigned __int8 AbAllocationRegionCount;
v82 = -1;
v4 = 0i64;
HIDWORD(v78) = DWORD2(RtlpHpHeapGlobals) ^ *(_DWORD *)(a2 + 40) ^ ((unsigned int)a2 >> 12);
v7 = 1;
v8 = (__int64 *)a2;
if( !r8_0 )
goto LABEL_17;
v9 = WORD2(v78);
v79 = 0;
v10 = r8_0 - HIWORD(HIDWORD(v78)) - a2;
v11 = *(_QWORD *)(a1
+ 8i64 * *((unsigned __int8 *)RtlpLfhBucketIndexMap + (((unsigned int)WORD2(v78) + 15) >> 4))
+ 128);
v12 = *(_DWORD *)(v11 + 72);
v13 = *(_BYTE *)(v11 + 76);
if( v12 )
{
v14 = (v10 * (unsigned __int64)v12) >> v13;
v15 = v10 - v14 * WORD2(v78);
}
else
{
LODWORD(v14) = v10 >> v13;
v15 = ((1 << v13) - 1) & v10;
}
if( v15 )
return 0;
v16 = *((_WORD *)v8 + 18);
v17 = 2 * v14;
if( v16 >= (unsigned __int16)v14 )
v16 = v14;
*((_WORD *)v8 + 18) = v16;
v18 = &v8[(unsigned __int64)v17 >> 6];
_m_prefetchw(v18 + 6);
if( (((unsigned __int64)_InterlockedAnd64(v18 + 6, ~(3i64 << (v17 & 0x3F))) >> (v17 & 0x3F)) & 1) == 0 )
{
RtlpLogHeapFailure(heap_failure_segment_lfh_double_free, *(VOID **)a1, (VOID *)r8_0, v8, (VOID *)(unsigned int)v14);
return 0;
}
if( *((_BYTE *)v8 + 45) > 1u )
{
v19 = *((_BYTE *)v8 + 44);
v20 = r8_0 - (_DWORD)v8;
v21 = (unsigned int)(r8_0 - (_DWORD)v8) >> v19;
v22 = 2 * v21;
v23 = (char *)v8 + 2 * v21 + *((unsigned __int16 *)v8 + 23);
_m_prefetchw(v23);
v24 = &v23[2 * (((unsigned int)(v9 + v20 - 1) >> v19) - (unsigned int)v21) + 2];
LODWORD(v25) = -1;
v26 = 0;
if( v23 < v24 )
{
do
{
v27 = _InterlockedDecrement16((volatile signed __int16 *)v23);
if( v27 )
{
if( v27 == -1 )
--v26;
}
else
{
++v26;
if( (_DWORD)v25 == -1 )
v25 = v22 >> 1;
}
v23 += 2;
v22 += 2i64;
}
while( v23 < v24 );
if( v26 )
{
v51 = (v26 << *((_BYTE *)v8 + 44)) / 4096;
if( (RtlpHpLfhPerfFlags & 0x20) != 0 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(*(__int16 *)(a1 + 58) + a1 + 24), v51);
}
if( (_DWORD)v25 != -1 )
RtlpHpLfhSubsegmentDecommitPages(a1, (INT64)v8, (unsigned int)v25, 2ui64, a4);
}
}
LABEL_17:
v28 = *((unsigned __int16 *)v8 + 17);
LOWORD(v29) = *((_WORD *)v8 + 16);
v30 = -1;
do
{
if( !v4 && (!(_WORD)v29 || (unsigned __int16)v29 == v28 - 1) )
{
v34 = v8[2];
v35 = *(unsigned __int8 *)(a1 + 57);
for( i = v35; ; v35 = i )
{
while( 1 )
{
while( !v34 )
{
v34 = _InterlockedCompareExchange64(v8 + 2, 3i64, 0i64);
if( !v34 )
{
v4 = 0i64;
goto LABEL_24;
}
}
if( (v34 & 1) != 0 )
break;
v36 = v34 + 16;
v4 = v34;
v37 = RtlpHpAcquireLockExclusive((_EX_PUSH_LOCK *)(v34 + 16), v35);
v34 = v8[2];
v82 = v37;
if( v4 == v34 )
{
v30 = v37;
goto LABEL_33;
}
if( i )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v36);
v30 = v82;
__writecr8(v82);
v35 = i;
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v36, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)v36);
LODWORD(v75) = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(v36) == 1 )
SessionId = MmGetSessionIdEx(CurrentThread->Tcb.ApcState.Process);
else
SessionId = -1;
--CurrentThread->Tcb.SpecialApcDisable;
++CurrentThread->Tcb.AbAllocationRegionCount;
v68 = ((char)CurrentThread->Tcb.AbEntrySummary | (char)CurrentThread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
AbAllocationRegionCount = CurrentThread->Tcb.AbAllocationRegionCount;
v54 = !_BitScanReverse((unsigned int *)&v69, v68);
HIDWORD(v75) = v69;
if( v54 )
goto LABEL_146;
while( 1 )
{
v70 = ~(1 << v69);
v71 = &CurrentThread->Tcb.LockEntries[v69];
v68 &= v70;
v80 = v71;
if( (v71->AcquiredByte & 1) != 0
&& (v71->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v71->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v36 & 0x7FFFFFFFFFFFFFFCi64)
&& v71->LockState.SessionId == SessionId )
{
v71->AcquiredByte &= ~1u;
if( v71->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v69, v68);
HIDWORD(v75) = v69;
if( v54 )
goto LABEL_146;
}
if( !v71 )
{
LABEL_146:
if( (*(&CurrentThread->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, CurrentThread, (PVOID)v36, (PVOID)SessionId, 0i64);
}
else
{
v71->CrossThreadReleasableAndBusyByte |= 2u;
if( v71->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
{
KiAbEntryRemoveFromTree(v71);
v71 = v80;
}
LODWORD(v75) = 0;
LODWORD(v75) = v71->BoostBitmap.AllFields & 0x1FFFF;
v71->BoostBitmap.AllFields &= 0xFFFE0000;
v71->ThreadLocalFlags &= ~1u;
v71->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v72 = v71 - CurrentThread->Tcb.LockEntries;
if( AbAllocationRegionCount == 1 )
CurrentThread->Tcb.AbEntrySummary |= 1 << v72;
else
_InterlockedOr8((volatile signed __int8 *)&CurrentThread->Tcb.AbOrphanedEntrySummary, 1 << v72);
}
--CurrentThread->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&CurrentThread->Tcb, (VOID *)v36, &v75);
v54 = CurrentThread->Tcb.SpecialApcDisable++ == -1;
if( v54
&& ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)CurrentThread->Tcb.ApcState.ApcListHead[0].Flink != &CurrentThread->Tcb.152 )
{
KiCheckForKernelApcDelivery();
}
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
v35 = 0;
v30 = v82;
}
}
v73 = _InterlockedCompareExchange64(v8 + 2, v34 & 1 | (v34 + 2) & 0xFFFFFFFFFFFFFFFEui64, v34);
v54 = v34 == v73;
v34 = v73;
if( v54 )
break;
}
v4 = 0i64;
LABEL_33:
if( !v4 )
{
LABEL_24:
v32 = -1;
goto LABEL_25;
}
}
v31 = v29 + 1;
v29 = (unsigned __int16)_InterlockedCompareExchange16((volatile signed __int16 *)v8 + 16, v29 + 1, v29);
}
while( v31 != v29 + 1 );
if( (_WORD)v29 )
{
if( v29 != v28 - 1 )
goto LABEL_24;
v38 = 2;
}
else
{
v38 = 0;
}
v39 = *((_BYTE *)v8 + 38);
switch( v39 )
{
case 1:
v40 = v4 + 40;
goto LABEL_38;
case 0:
v40 = v4 + 24;
v41 = (_QWORD *)(v4 + 8);
goto LABEL_39;
case 2:
v40 = 0i64;
LABEL_38:
v41 = 0i64;
LABEL_39:
if( v38 )
{
v42 = 0i64;
v43 = 0i64;
}
else
{
v42 = v4 + 24;
v43 = (_QWORD *)(v4 + 8);
}
if( v40 )
{
v44 = (__int64 *)*v8;
v45 = (__int64 **)v8[1];
if( *(__int64 **)(*v8 + 8) == v8 && *v45 == v8 )
{
*v45 = v44;
v44[1] = (__int64)v45;
if( v41 )
--*v41;
goto LABEL_46;
}
LABEL_155:
__fastfail(3u);
}
LABEL_46:
*((_BYTE *)v8 + 38) = v38;
if( v42 )
{
v46 = *(__int64 ***)(v42 + 8);
if( *v46 != (__int64 *)v42 )
goto LABEL_155;
*v8 = v42;
v8[1] = (__int64)v46;
*v46 = v8;
*(_QWORD *)(v42 + 8) = v8;
if( v43 )
++*v43;
v8 = 0i64;
}
if( (*(_BYTE *)v4 & 1) == 0 && *(_QWORD *)(v4 + 8) > 8ui64 )
{
v8 = *(__int64 **)v42;
v58 = **(_QWORD **)v42;
if( *(_QWORD *)(*(_QWORD *)v42 + 8i64) != v42 || *(__int64 **)(v58 + 8) != v8 )
goto LABEL_155;
*(_QWORD *)v42 = v58;
*(_QWORD *)(v58 + 8) = v42;
--*v43;
*((_BYTE *)v8 + 38) = 2;
}
if( v8 && *((_BYTE *)v8 + 38) == 2 )
v8[2] = 0i64;
break;
}
v47 = a1;
v48 = v4 + 16;
if( *(_BYTE *)(a1 + 57) )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v48);
__writecr8(v30);
v32 = -1;
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v48, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)v48);
LODWORD(a3) = 0;
v49 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(v48) == 1 )
{
v50 = (unsigned int)MmGetSessionIdEx(v49->Tcb.ApcState.Process);
v32 = -1;
}
else
{
v32 = -1;
v50 = 0xFFFFFFFFi64;
}
--v49->Tcb.SpecialApcDisable;
v52 = ++v49->Tcb.AbAllocationRegionCount;
v53 = ((char)v49->Tcb.AbEntrySummary | (char)v49->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
v54 = !_BitScanReverse((unsigned int *)&v55, v53);
v76 = v55;
if( v54 )
goto LABEL_70;
while( 1 )
{
v56 = &v49->Tcb.LockEntries[v55];
v53 &= ~(1 << v55);
if( (v56->AcquiredByte & 1) != 0
&& (v56->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v56->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v48 & 0x7FFFFFFFFFFFFFFCi64)
&& v56->LockState.SessionId == (_DWORD)v50 )
{
v56->AcquiredByte &= ~1u;
if( v56->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v55, v53);
v76 = v55;
if( v54 )
goto LABEL_70;
}
if( !v56 )
{
LABEL_70:
if( (*(&v49->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v49, (PVOID)v48, (PVOID)v50, 0i64);
}
else
{
v56->CrossThreadReleasableAndBusyByte |= 2u;
if( v56->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v56);
LODWORD(a3) = v56->BoostBitmap.AllFields & 0x1FFFF;
v56->BoostBitmap.AllFields &= 0xFFFE0000;
v56->ThreadLocalFlags &= ~1u;
v56->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v57 = 1 << (v56 - v49->Tcb.LockEntries);
if( v52 == 1 )
v49->Tcb.AbEntrySummary |= v57;
else
_InterlockedOr8((volatile signed __int8 *)&v49->Tcb.AbOrphanedEntrySummary, v57);
}
--v49->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v49->Tcb, (VOID *)v48, &a3);
v54 = v49->Tcb.SpecialApcDisable++ == -1;
if( v54 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v49->Tcb.ApcState.ApcListHead[0].Flink != &v49->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
v47 = a1;
}
v4 = 0i64;
if( v8 )
RtlpHpLfhBucketAddSubsegment(
v47,
*(_QWORD *)(v47 + 8i64 * *((unsigned __int8 *)RtlpLfhBucketIndexMap + (((unsigned int)WORD2(v78) + 15) >> 4)) + 128),
(INT64)v8,
a4);
LABEL_25:
if( v4 )
{
v59 = v4 + 16;
if( *(_BYTE *)(a1 + 57) )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v59);
__writecr8(v82);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v59, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((_EX_PUSH_LOCK *)v59);
LODWORD(v78) = 0;
v60 = (_ETHREAD *)KeGetCurrentThread();
if( MiGetSystemRegionType(v59) == 1 )
v32 = MmGetSessionIdEx(v60->Tcb.ApcState.Process);
--v60->Tcb.SpecialApcDisable;
v61 = ++v60->Tcb.AbAllocationRegionCount;
v62 = ((char)v60->Tcb.AbEntrySummary | (char)v60->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
v54 = !_BitScanReverse((unsigned int *)&v63, v62);
HIDWORD(a3) = v63;
if( v54 )
goto LABEL_104;
while( 1 )
{
v64 = &v60->Tcb.LockEntries[v63];
v62 &= ~(1 << v63);
if( (v64->AcquiredByte & 1) != 0
&& (v64->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 1) == 0
&& (v64->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 & 0x7FFFFFFFFFFFFFFCi64) == (v59 & 0x7FFFFFFFFFFFFFFCi64)
&& v64->LockState.SessionId == v32 )
{
v64->AcquiredByte &= ~1u;
if( v64->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v63, v62);
HIDWORD(a3) = v63;
if( v54 )
goto LABEL_104;
}
if( !v64 )
{
LABEL_104:
if( (*(&v60->Tcb.MiscFlags + 1) & 0x10000) == 0 )
KeBugCheckEx(0x162u, v60, (PVOID)v59, (PVOID)v32, 0i64);
}
else
{
v64->CrossThreadReleasableAndBusyByte |= 2u;
if( v64->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 < 0 )
KiAbEntryRemoveFromTree(v64);
LODWORD(v78) = v64->BoostBitmap.AllFields & 0x1FFFF;
v64->BoostBitmap.AllFields &= 0xFFFE0000;
v64->ThreadLocalFlags &= ~1u;
v64->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0 = 0i64;
v65 = v64 - v60->Tcb.LockEntries;
if( v61 == 1 )
v60->Tcb.AbEntrySummary |= 1 << v65;
else
_InterlockedOr8((volatile signed __int8 *)&v60->Tcb.AbOrphanedEntrySummary, 1 << v65);
}
--v60->Tcb.AbAllocationRegionCount;
KiAbThreadRemoveBoosts(&v60->Tcb, (VOID *)v59, &v78);
v54 = v60->Tcb.SpecialApcDisable++ == -1;
if( v54 && ($F25F8C4BA33AF922A5F1AF68CD89DDDF *)v60->Tcb.ApcState.ApcListHead[0].Flink != &v60->Tcb.152 )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
}
}
return v7;
}Referenced by:
ExFreeHeapPool
RtlpHpLfhSlotAllocate
RtlpHpSegFree