ExAllocateHeapSpecialPool
UINT64 __fastcall ExAllocateHeapSpecialPool(UINT64 a1, UINT64 NumberOfBytes, UINT64 Key){
unsigned int v3;
__int64 v4;
int v6;
unsigned __int8 CurrentIrql;
INT64 HeapFromType;
UINT64 v9;
UINT64 v10;
unsigned __int64 v11;
char LowPart;
UINT64 v13;
POOL_TYPE v14;
POOL_TYPE v15;
__int64 v16;
__int64 v17;
int v18;
int v19;
__int64 v20;
UINT8 *v21;
unsigned int v22;
unsigned int v23;
__int64 v24;
volatile signed __int32 *v25;
int v26;
volatile signed __int32 v27;
__int64 v28;
ULONG_PTR BugCheckParameter4;
int v31;
__int64 v32;
UINT8 *v33;
struct _KLOCK_QUEUE_HANDLE LockHandle;
unsigned int v35;
v3 = a1;
v4 = (unsigned int)Key;
v6 = a1 & 1;
if( !v6 && (_bittest(&ExpPoolFlags, 0xAu) & ((v3 & 0x200) == 0)) != 0 )
v3 |= 0x200u;
CurrentIrql = KeGetCurrentIrql();
if( CurrentIrql > (unsigned __int8)(2 - (v6 != 0)) )
KeBugCheckEx(0xC1u, CurrentIrql, (int)v3, NumberOfBytes, 0x30ui64);
HeapFromType = ExGetHeapFromType(v3, 0x80000000ui64, 1i64);
LODWORD(BugCheckParameter4) = 4;
v9 = RtlpHpSegAlloc(HeapFromType + 256, 0x1000ui64, 4096i64, 4096i64, BugCheckParameter4);
v10 = v9;
if( !v9 )
return 0i64;
LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
memset(v9 + 16, LOBYTE(KUSER_SHARED_DATA.TickCountQuad) | 1u);
v13 = NumberOfBytes - 8;
if( (v3 & 0x40) == 0 )
v13 = NumberOfBytes;
*(_QWORD *)(v10 + 8) = 0i64;
*(_DWORD *)v10 = v13;
*(_BYTE *)(v10 + 2) = LowPart | 1;
*(_DWORD *)(v10 + 4) = v4;
if( (v3 & 0x40) != 0 )
*(_DWORD *)v10 |= 0x4000u;
v11 = (v10 - v13 + 4096) & 0xFFFFFFFFFFFFFFF0ui64;
if( (v3 & 0x400) != 0 )
memset((v10 - v13 + 4096) & 0xFFFFFFFFFFFFFFF0ui64, 0i64);
v14 = (unsigned int)MiDeterminePoolType(v10);
v15 = NonPagedPool;
LockHandle.LockQueue = 0i64;
v16 = 8i64;
if( v14 != NonPagedPoolSession )
v15 = v14;
*(_QWORD *)&LockHandle.OldIrql = 0i64;
if( (_DWORD)v4 == PoolHitTag )
__debugbreak();
v17 = HIDWORD(PerfGlobalGroupMask);
v18 = v15 & 0x20;
if( (v15 & 0x20) != 0 )
{
v21 = (UINT8 *)ExpSessionPoolTrackTable;
v19 = ExpSessionPoolTrackTableMask;
v20 = ExpSessionPoolTrackTableSize;
}
else
{
LODWORD(v17) = *((_DWORD *)KeGetPcr() + 105);
v19 = PoolTrackTableMask;
v20 = PoolTrackTableSize;
v21 = (&ExPoolTagTables)[v17];
}
v32 = v20;
v31 = v19;
v33 = v21;
v22 = v19 & ((40543 * v4) ^ ((unsigned __int64)(40543 * v4) >> 32));
v23 = v22;
v35 = v22;
while( 1 )
{
v24 = 56i64 * v22;
v25 = (volatile signed __int32 *)&v21[v24];
v26 = *(_DWORD *)&v21[v24];
if( v26 == (_DWORD)v4 )
break;
if( v26 )
goto LABEL_35;
if( !v18 )
{
v27 = *(_DWORD *)((char *)PoolTrackTable + v24);
if( v27 )
{
*v25 = v27;
goto LABEL_27;
}
v23 = v35;
}
if( v22 == v20 - 1 )
{
LABEL_35:
v22 = v19 & (v22 + 1);
if( v22 == v23 )
{
ExpInsertPoolTrackerExpansion((unsigned int)v4, v13, v15);
return v11;
}
}
else if( v18 )
{
_InterlockedCompareExchange(v25, v4, 0);
}
else
{
KeAcquireInStackQueuedSpinLock(&ExpTaggedPoolLock, &LockHandle);
if( !*(_DWORD *)((char *)PoolTrackTable + v24) )
{
*(_DWORD *)((char *)PoolTrackTable + v24) = v4;
*v25 = v4;
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
v18 = v15 & 0x20;
v19 = v31;
v20 = v32;
v21 = v33;
LABEL_27:
v23 = v35;
}
}
if( (v15 & 1) != 0 )
{
v28 = 10i64;
}
else
{
v28 = 4i64;
v16 = 2i64;
}
_InterlockedIncrement64((volatile signed __int64 *)&v25[v28]);
_InterlockedExchangeAdd64((volatile signed __int64 *)&v25[v16], v13);
return v11;
}Referenced by:
ExAllocateHeapPool