RtlpHpLfhSubsegmentFreeBlock
INT64 __fastcall RtlpHpLfhSubsegmentFreeBlock(INT64 a1, INT64 a2, UINT64 a3, CHAR a4){
signed __int64 v4;
unsigned int 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;
unsigned int v35;
UINT64 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;
UINT64 v48;
_ETHREAD *v49;
ULONG_PTR v50;
unsigned __int64 v51;
char v52;
int v53;
bool v54;
__int64 v55;
unsigned __int64 v56;
unsigned __int8 v57;
__int64 v58;
UINT64 v59;
_ETHREAD *v60;
char v61;
int v62;
__int64 v63;
unsigned __int64 v64;
__int64 v65;
_ETHREAD *CurrentThread;
unsigned int SessionId;
int v68;
__int64 v69;
int v70;
unsigned __int64 v71;
__int64 v72;
signed __int64 v73;
unsigned int i;
int v75;
int v76;
int v77;
int v78;
int v79;
int v80;
unsigned int v81;
int v82;
unsigned __int64 v83;
unsigned __int8 v85;
char v86;
v85 = -1;
v4 = 0i64;
v81 = DWORD2(RtlpHpHeapGlobals) ^ *(_DWORD *)(a2 + 40) ^ ((unsigned int)a2 >> 12);
v7 = 1;
v8 = (__int64 *)a2;
if( !a3 )
goto LABEL_17;
v9 = (unsigned __int16)v81;
v82 = 0;
v10 = a3 - HIWORD(v81) - a2;
v11 = *(_QWORD *)(a1
+ 8i64
* *((unsigned __int8 *)RtlpLfhBucketIndexMap + (((unsigned int)(unsigned __int16)v81 + 15) >> 4))
+ 128);
v12 = *(_DWORD *)(v11 + 72);
v13 = *(_BYTE *)(v11 + 76);
if( v12 )
{
v14 = (v10 * (unsigned __int64)v12) >> v13;
v15 = v10 - v14 * (unsigned __int16)v81;
}
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(17i64, *(_QWORD *)a1, a3, (INT64)v8, (unsigned int)v14, 0i64);
return 0;
}
if( *((_BYTE *)v8 + 45) > 1u )
{
v19 = *((_BYTE *)v8 + 44);
v20 = a3 - (_DWORD)v8;
v21 = (unsigned int)(a3 - (_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((INT64 *)(v34 + 16), v35);
v34 = v8[2];
v85 = v37;
if( v4 == v34 )
{
v30 = v37;
goto LABEL_33;
}
if( i )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v36);
v30 = v85;
__writecr8(v85);
v35 = i;
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v36, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v36);
v75 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v36) == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)CurrentThread + 23));
else
SessionId = -1;
--*((_WORD *)CurrentThread + 243);
++*((_BYTE *)CurrentThread + 794);
v68 = (*((char *)CurrentThread + 792) | *((char *)CurrentThread + 870)) ^ 0x3F;
v86 = *((_BYTE *)CurrentThread + 794);
v54 = !_BitScanReverse((unsigned int *)&v69, v68);
v76 = v69;
if( v54 )
goto LABEL_146;
while( 1 )
{
v70 = ~(1 << v69);
v71 = *((_QWORD *)CurrentThread + 100) + 96 * v69;
v68 &= v70;
v83 = v71;
if( (*(_BYTE *)(v71 + 26) & 1) != 0
&& (*(_DWORD *)(v71 + 32) & 1) == 0
&& (*(_QWORD *)(v71 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v36 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v71 + 40) == SessionId )
{
*(_BYTE *)(v71 + 26) &= ~1u;
if( *(_QWORD *)(v71 + 32) )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v69, v68);
v76 = v69;
if( v54 )
goto LABEL_146;
}
if( !v71 )
{
LABEL_146:
if( (*((_DWORD *)CurrentThread + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)CurrentThread, v36, SessionId, 0i64);
}
else
{
*(_BYTE *)(v71 + 32) |= 2u;
if( *(__int64 *)(v71 + 32) < 0 )
{
KiAbEntryRemoveFromTree(v71);
v71 = v83;
}
v75 = 0;
v75 = *(_DWORD *)(v71 + 88) & 0x1FFFF;
*(_DWORD *)(v71 + 88) &= 0xFFFE0000;
*(_BYTE *)(v71 + 25) &= ~1u;
*(_QWORD *)(v71 + 32) = 0i64;
v72 = (__int64)(v71 - *((_QWORD *)CurrentThread + 100)) / 96;
if( v86 == 1 )
*((_BYTE *)CurrentThread + 792) |= 1 << v72;
else
_InterlockedOr8((volatile signed __int8 *)CurrentThread + 870, 1 << v72);
}
--*((_BYTE *)CurrentThread + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)CurrentThread, v36, (unsigned int *)&v75);
v54 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v54 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
v35 = 0;
v30 = v85;
}
}
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((volatile INT64 *)v48);
v78 = 0;
v49 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v48) == 1 )
{
v50 = (unsigned int)MmGetSessionIdEx(*((_QWORD *)v49 + 23));
v32 = -1;
}
else
{
v32 = -1;
v50 = 0xFFFFFFFFi64;
}
--*((_WORD *)v49 + 243);
v52 = ++*((_BYTE *)v49 + 794);
v53 = (*((char *)v49 + 792) | *((char *)v49 + 870)) ^ 0x3F;
v54 = !_BitScanReverse((unsigned int *)&v55, v53);
v77 = v55;
if( v54 )
goto LABEL_70;
while( 1 )
{
v56 = *((_QWORD *)v49 + 100) + 96 * v55;
v53 &= ~(1 << v55);
if( (*(_BYTE *)(v56 + 26) & 1) != 0
&& (*(_DWORD *)(v56 + 32) & 1) == 0
&& (*(_QWORD *)(v56 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v48 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v56 + 40) == (_DWORD)v50 )
{
*(_BYTE *)(v56 + 26) &= ~1u;
if( *(_QWORD *)(v56 + 32) )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v55, v53);
v77 = v55;
if( v54 )
goto LABEL_70;
}
if( !v56 )
{
LABEL_70:
if( (*((_DWORD *)v49 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v49, v48, v50, 0i64);
}
else
{
*(_BYTE *)(v56 + 32) |= 2u;
if( *(__int64 *)(v56 + 32) < 0 )
KiAbEntryRemoveFromTree(v56);
v78 = *(_DWORD *)(v56 + 88) & 0x1FFFF;
*(_DWORD *)(v56 + 88) &= 0xFFFE0000;
*(_BYTE *)(v56 + 25) &= ~1u;
*(_QWORD *)(v56 + 32) = 0i64;
v57 = 1 << ((__int64)(v56 - *((_QWORD *)v49 + 100)) / 96);
if( v52 == 1 )
*((_BYTE *)v49 + 792) |= v57;
else
_InterlockedOr8((volatile signed __int8 *)v49 + 870, v57);
}
--*((_BYTE *)v49 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v49, v48, (unsigned int *)&v78);
v54 = (*((_WORD *)v49 + 243))++ == 0xFFFF;
if( v54 && *((_ETHREAD **)v49 + 19) != (_ETHREAD *)((char *)v49 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
v47 = a1;
}
v4 = 0i64;
if( v8 )
RtlpHpLfhBucketAddSubsegment(
v47,
*(_QWORD *)(v47
+ 8i64 * *((unsigned __int8 *)RtlpLfhBucketIndexMap + (((unsigned int)(unsigned __int16)v81 + 15) >> 4))
+ 128),
(INT64)v8,
a4);
LABEL_25:
if( v4 )
{
v59 = v4 + 16;
if( *(_BYTE *)(a1 + 57) )
{
ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)v59);
__writecr8(v85);
}
else
{
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v59, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v59);
v80 = 0;
v60 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v59) == 1 )
v32 = MmGetSessionIdEx(*((_QWORD *)v60 + 23));
--*((_WORD *)v60 + 243);
v61 = ++*((_BYTE *)v60 + 794);
v62 = (*((char *)v60 + 792) | *((char *)v60 + 870)) ^ 0x3F;
v54 = !_BitScanReverse((unsigned int *)&v63, v62);
v79 = v63;
if( v54 )
goto LABEL_104;
while( 1 )
{
v64 = *((_QWORD *)v60 + 100) + 96 * v63;
v62 &= ~(1 << v63);
if( (*(_BYTE *)(v64 + 26) & 1) != 0
&& (*(_DWORD *)(v64 + 32) & 1) == 0
&& (*(_QWORD *)(v64 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v59 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v64 + 40) == v32 )
{
*(_BYTE *)(v64 + 26) &= ~1u;
if( *(_QWORD *)(v64 + 32) )
break;
}
v54 = !_BitScanReverse((unsigned int *)&v63, v62);
v79 = v63;
if( v54 )
goto LABEL_104;
}
if( !v64 )
{
LABEL_104:
if( (*((_DWORD *)v60 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v60, v59, v32, 0i64);
}
else
{
*(_BYTE *)(v64 + 32) |= 2u;
if( *(__int64 *)(v64 + 32) < 0 )
KiAbEntryRemoveFromTree(v64);
v80 = *(_DWORD *)(v64 + 88) & 0x1FFFF;
*(_DWORD *)(v64 + 88) &= 0xFFFE0000;
*(_BYTE *)(v64 + 25) &= ~1u;
*(_QWORD *)(v64 + 32) = 0i64;
v65 = (__int64)(v64 - *((_QWORD *)v60 + 100)) / 96;
if( v61 == 1 )
*((_BYTE *)v60 + 792) |= 1 << v65;
else
_InterlockedOr8((volatile signed __int8 *)v60 + 870, 1 << v65);
}
--*((_BYTE *)v60 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v60, v59, (unsigned int *)&v80);
v54 = (*((_WORD *)v60 + 243))++ == 0xFFFF;
if( v54 && *((_ETHREAD **)v60 + 19) != (_ETHREAD *)((char *)v60 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)KeGetCurrentThread());
}
}
return v7;
}Referenced by:
ExFreeHeapPool
RtlpHpLfhSlotAllocate
RtlpHpSegFree