ExpSaAllocatorFree
VOID __fastcall ExpSaAllocatorFree(UINT64 P2, INT64 a2, UINT64 a3, UINT64 a4){
char v7;
_ETHREAD *CurrentThread;
unsigned __int8 v9;
__int64 v10;
__int64 v11;
int SessionId;
bool v13;
int v14;
_ETHREAD *v15;
unsigned __int8 v16;
__int64 v17;
__int64 v18;
__int64 v19;
int v20;
__int64 v21;
_QWORD *v22;
INT64 *v23;
__int64 v24;
_ETHREAD *v25;
ULONG_PTR v26;
char v27;
int v28;
__int64 v29;
unsigned __int64 v30;
__int64 v31;
int v32;
int v33;
unsigned int v34;
int v35;
unsigned int v36[4];
unsigned int v37;
v37 = a4;
if( *(_DWORD *)(a2 + 40) != 1 )
{
v36[0] = 0;
v7 = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)CurrentThread + 243);
if( ++*((_BYTE *)CurrentThread + 794) != 1 )
KeBugCheckEx(0x192u, (ULONG_PTR)CurrentThread, P2, KeGetCurrentIrql(), 0i64);
v9 = *((_BYTE *)CurrentThread + 792);
v35 = 0;
if( !v9 )
{
if( !*((_BYTE *)CurrentThread + 870) )
{
v11 = 0i64;
goto LABEL_25;
}
v24 = *((unsigned __int8 *)CurrentThread + 870);
*((_BYTE *)CurrentThread + 870) = 0;
v9 = v24 | *((_BYTE *)CurrentThread + 792);
}
_BitScanForward((unsigned int *)&v10, v9);
v35 = v10;
*((_BYTE *)CurrentThread + 792) = v9 & ~(1 << v10);
v11 = *((_QWORD *)CurrentThread + 100) + 96 * v10;
if( v11 )
{
if( P2 >= 0xFFFF800000000000ui64 && MiState[((P2 >> 39) & 0x1FF) + 12296] == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)CurrentThread + 23));
else
SessionId = -1;
*(_DWORD *)(v11 + 40) = SessionId;
*(_QWORD *)(v11 + 32) = P2 & 0x7FFFFFFFFFFFFFFCi64;
goto LABEL_9;
}
LABEL_25:
_interlockedbittestandset((volatile signed __int32 *)CurrentThread + 30, 0x10u);
LABEL_9:
--*((_BYTE *)CurrentThread + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)CurrentThread, P2, v36);
v13 = (*((_WORD *)CurrentThread + 243))++ == 0xFFFF;
if( v13 && *((_ETHREAD **)CurrentThread + 19) != (_ETHREAD *)((char *)CurrentThread + 152) )
KiCheckForKernelApcDelivery();
if( _InterlockedCompareExchange64((volatile signed __int64 *)P2, 17i64, 0i64) )
ExfAcquirePushLockSharedEx((UINT64 *)P2, (VOID *)v11, (VOID *)P2);
if( v11 )
*(_BYTE *)(v11 + 26) |= 1u;
goto LABEL_16;
}
v34 = 0;
v7 = 1;
v15 = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)v15 + 243);
if( ++*((_BYTE *)v15 + 794) != 1 )
KeBugCheckEx(0x192u, (ULONG_PTR)v15, P2, KeGetCurrentIrql(), 0i64);
v16 = *((_BYTE *)v15 + 792);
v33 = 0;
if( !v16 )
{
if( !*((_BYTE *)v15 + 870) )
{
v19 = 0i64;
goto LABEL_37;
}
v17 = *((unsigned __int8 *)v15 + 870);
*((_BYTE *)v15 + 870) = 0;
v16 = v17 | *((_BYTE *)v15 + 792);
}
_BitScanForward((unsigned int *)&v18, v16);
v33 = v18;
*((_BYTE *)v15 + 792) = v16 & ~(1 << v18);
v19 = *((_QWORD *)v15 + 100) + 96 * v18;
if( v19 )
{
if( P2 >= 0xFFFF800000000000ui64 && MiState[((P2 >> 39) & 0x1FF) + 12296] == 1 )
v20 = MmGetSessionIdEx(*((_QWORD *)v15 + 23));
else
v20 = -1;
*(_DWORD *)(v19 + 40) = v20;
*(_QWORD *)(v19 + 32) = P2 & 0x7FFFFFFFFFFFFFFCi64;
goto LABEL_40;
}
LABEL_37:
_interlockedbittestandset((volatile signed __int32 *)v15 + 30, 0x10u);
LABEL_40:
--*((_BYTE *)v15 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v15, P2, &v34);
v13 = (*((_WORD *)v15 + 243))++ == 0xFFFF;
if( v13 && *((_ETHREAD **)v15 + 19) != (_ETHREAD *)((char *)v15 + 152) )
KiCheckForKernelApcDelivery();
if( _interlockedbittestandset64((volatile signed __int32 *)P2, 0i64) )
ExfAcquirePushLockExclusiveEx((UINT64 *)P2, (VOID *)v19, (VOID *)P2);
if( v19 )
*(_BYTE *)(v19 + 26) |= 1u;
*(_DWORD *)(a2 + 40) = 0;
v21 = *(_QWORD *)a2;
if( *(_QWORD *)(*(_QWORD *)a2 + 8i64) != a2
|| (v22 = *(_QWORD **)(a2 + 8), *v22 != a2)
|| (*v22 = v21, *(_QWORD *)(v21 + 8) = v22, v23 = *(INT64 **)(P2 + 16), *v23 != P2 + 8) )
{
__fastfail(3u);
}
*(_QWORD *)a2 = P2 + 8;
*(_QWORD *)(a2 + 8) = v23;
*v23 = a2;
*(_QWORD *)(P2 + 16) = a2;
LABEL_16:
if( ExpSaPageGroupFreeMemory(a2, a3, v37) )
{
_m_prefetchw((const void *)(P2 + 64));
LOBYTE(v14) = _InterlockedOr((volatile signed __int32 *)(P2 + 64), 2u) | 2;
}
else
{
v14 = *(_DWORD *)(P2 + 64);
}
if( (v14 & 2) != 0 )
{
if( v7 || _InterlockedCompareExchange64((volatile signed __int64 *)P2, 1i64, 17i64) == 17 )
goto LABEL_59;
v7 = 0;
}
if( !v7 )
{
if( _InterlockedCompareExchange64((volatile signed __int64 *)P2, 0i64, 17i64) != 17 )
ExfReleasePushLockShared((INT64 *)P2);
KeAbPostRelease((PVOID)P2);
return;
}
LABEL_59:
ExpSaAllocatorOptimizeList(P2);
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)P2, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)P2);
v32 = 0;
v25 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(P2) == 1 )
v26 = (unsigned int)MmGetSessionIdEx(*((_QWORD *)v25 + 23));
else
v26 = 0xFFFFFFFFi64;
--*((_WORD *)v25 + 243);
v27 = ++*((_BYTE *)v25 + 794);
v28 = (*((char *)v25 + 792) | *((char *)v25 + 870)) ^ 0x3F;
while( 1 )
{
v13 = !_BitScanReverse((unsigned int *)&v29, v28);
if( v13 )
goto LABEL_66;
v30 = *((_QWORD *)v25 + 100) + 96 * v29;
v28 &= ~(1 << v29);
if( (*(_BYTE *)(v30 + 26) & 1) != 0
&& (*(_DWORD *)(v30 + 32) & 1) == 0
&& (*(_QWORD *)(v30 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (P2 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v30 + 40) == (_DWORD)v26 )
{
*(_BYTE *)(v30 + 26) &= ~1u;
if( *(_QWORD *)(v30 + 32) )
break;
}
}
if( !v30 )
{
LABEL_66:
if( (*((_DWORD *)v25 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v25, P2, v26, 0i64);
goto LABEL_78;
}
*(_BYTE *)(v30 + 32) |= 2u;
if( *(__int64 *)(v30 + 32) < 0 )
KiAbEntryRemoveFromTree(v30);
v32 = *(_DWORD *)(v30 + 88) & 0x1FFFF;
*(_DWORD *)(v30 + 88) &= 0xFFFE0000;
*(_BYTE *)(v30 + 25) &= ~1u;
*(_QWORD *)(v30 + 32) = 0i64;
v31 = (__int64)(v30 - *((_QWORD *)v25 + 100)) / 96;
if( v27 == 1 )
*((_BYTE *)v25 + 792) |= 1 << v31;
else
_InterlockedOr8((volatile signed __int8 *)v25 + 870, 1 << v31);
LABEL_78:
--*((_BYTE *)v25 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v25, P2, (unsigned int *)&v32);
v13 = (*((_WORD *)v25 + 243))++ == 0xFFFF;
if( v13 && *((_ETHREAD **)v25 + 19) != (_ETHREAD *)((char *)v25 + 152) )
KiCheckForKernelApcDelivery();
}Referenced by:
ExSaFree