MiExpandPtes
INT64 __fastcall MiExpandPtes(INT64 a1, UINT64 a2){
int v3;
unsigned int v4;
int v5;
unsigned __int64 v6;
UINT64 v7;
UINT64 v8;
INT64 v9;
UINT64 v10;
__int64 v11;
INT64 v12;
unsigned __int64 v13;
unsigned __int64 v14;
_ETHREAD *CurrentThread;
UINT64 *v16;
unsigned __int64 v17;
VOID *v18;
int v19;
int v20;
unsigned __int64 v21;
unsigned __int64 v22;
UINT64 v23;
UINT64 v24;
char v25;
volatile signed __int32 *v26;
UINT64 v27;
int v29;
UINT64 v30;
_ETHREAD *v31;
unsigned int SessionId;
int v33;
bool v34;
__int64 v35;
unsigned __int64 v36;
unsigned __int8 v37;
INT64 v38;
_MMPTE *PteBase;
INT64 v40;
UINT64 v41;
char v42;
char *v43;
INT64 v44;
int v45;
unsigned int v46;
int v47;
UINT64 v48;
unsigned __int64 v49;
unsigned __int64 v50;
struct _KLOCK_QUEUE_HANDLE LockHandle;
unsigned __int64 v52;
_ETHREAD *v53;
char v55;
unsigned int VaType;
memset(&LockHandle, 0, sizeof(LockHandle));
if( a2 + 511 <= a2 )
return 0i64;
v3 = *(_DWORD *)(a1 + 24);
v4 = *(_DWORD *)(a1 + 28);
VaType = v4;
v5 = 0;
v6 = (v3 & 4) != 0 ? 16i64 : 1i64;
v52 = v6;
if( a2 >= 0x200 && (INT64 *)a1 == &qword_140C4EC80 )
v5 = 1;
v7 = (a2 + 511) & 0xFFFFFFFFFFFFFE00ui64;
v8 = v7 >> 9;
v49 = v7 / v6;
if( (v3 & 2) != 0 )
{
v46 = 16;
v9 = v4;
if( v5 == 1 )
v9 = 13i64;
v10 = MiObtainSystemVa(v8, v9);
}
else
{
v46 = 1;
LODWORD(v10) = MiObtainSessionVa(v8);
}
v48 = v10;
v11 = v10;
if( !v10 )
return 0i64;
v12 = (INT64)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64);
v13 = (v12 - *(_QWORD *)(a1 + 16)) >> 3;
v50 = v13;
if( v5 )
goto LABEL_22;
v14 = v13 / v6;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v16 = (UINT64 *)(a1 + 48);
v53 = CurrentThread;
v17 = v14;
v18 = (VOID *)(*(_QWORD *)(a1 + 8) + (v14 >> 3));
if( (*(_DWORD *)(a1 + 24) & 2) != 0 )
{
KeAcquireInStackQueuedSpinLock((UINT64 *)(a1 + 48), &LockHandle);
}
else
{
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockExclusiveEx(*v16, 0i64);
}
v19 = MiSplitBitmapPages(VaType, v18, v49 + (v17 & 7));
v20 = *(_DWORD *)(a1 + 24);
v47 = v19;
if( (v20 & 2) != 0 )
{
if( v19 == 1 )
{
v21 = (v7 + v50) / v52;
if( v21 > *(_QWORD *)a1 )
*(_QWORD *)a1 = v21;
v22 = v17 & 0xFFFFFFFFFFFFFFC0ui64;
if( (v17 & 0x3F) == 0 )
v22 = v17;
if( v22 < *(_QWORD *)(a1 + 72) || (v20 & 8) == 0 )
{
*(_QWORD *)(a1 + 72) = v22;
*(_DWORD *)(a1 + 24) = v20 | 8;
}
}
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
else
{
v30 = *v16;
if( (_InterlockedExchangeAdd64((volatile signed __int64 *)v30, 0xFFFFFFFFFFFFFFFFui64) & 6) == 2 )
ExfTryToWakePushLock((volatile INT64 *)v30);
v45 = 0;
v31 = (_ETHREAD *)KeGetCurrentThread();
if( (unsigned int)MiGetSystemRegionType(v30) == 1 )
SessionId = MmGetSessionIdEx(*((_QWORD *)v31 + 23));
else
SessionId = -1;
--*((_WORD *)v31 + 243);
v55 = ++*((_BYTE *)v31 + 794);
v33 = (*((char *)v31 + 792) | *((char *)v31 + 870)) ^ 0x3F;
while( 1 )
{
v34 = !_BitScanReverse((unsigned int *)&v35, v33);
if( v34 )
break;
v36 = *((_QWORD *)v31 + 100) + 96 * v35;
v33 &= ~(1 << v35);
if( (*(_BYTE *)(v36 + 26) & 1) != 0
&& (*(_DWORD *)(v36 + 32) & 1) == 0
&& (*(_QWORD *)(v36 + 32) & 0x7FFFFFFFFFFFFFFCi64) == (v30 & 0x7FFFFFFFFFFFFFFCi64)
&& *(_DWORD *)(v36 + 40) == SessionId )
{
*(_BYTE *)(v36 + 26) &= ~1u;
if( *(_QWORD *)(v36 + 32) )
{
if( v36 )
{
*(_BYTE *)(v36 + 32) |= 2u;
if( *(__int64 *)(v36 + 32) < 0 )
KiAbEntryRemoveFromTree(v36);
v45 = *(_DWORD *)(v36 + 88) & 0x1FFFF;
*(_DWORD *)(v36 + 88) &= 0xFFFE0000;
*(_BYTE *)(v36 + 25) &= ~1u;
*(_QWORD *)(v36 + 32) = 0i64;
v37 = 1 << ((__int64)(v36 - *((_QWORD *)v31 + 100)) / 96);
if( v55 == 1 )
*((_BYTE *)v31 + 792) |= v37;
else
_InterlockedOr8((volatile signed __int8 *)v31 + 870, v37);
goto LABEL_56;
}
break;
}
}
}
if( (*((_DWORD *)v31 + 30) & 0x10000) == 0 )
KeBugCheckEx(0x162u, (ULONG_PTR)v31, v30, SessionId, 0i64);
LABEL_56:
--*((_BYTE *)v31 + 794);
KiAbThreadRemoveBoosts((ULONG_PTR)v31, v30, (unsigned int *)&v45);
v34 = (*((_WORD *)v31 + 243))++ == 0xFFFF;
if( v34 && *((_ETHREAD **)v31 + 19) != (_ETHREAD *)((char *)v31 + 152) )
KiCheckForKernelApcDelivery();
KiLeaveGuardedRegionUnsafe((__int64)v53);
}
if( v47 )
{
v6 = v52;
v4 = VaType;
v11 = v48;
LABEL_22:
LODWORD(v44) = 0;
if( (unsigned int)MiMakeZeroedPageTablesEx(v12, v12 + 8 * (v7 - 1), v46, v4, v44) )
{
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 88), v49);
_InterlockedExchangeAdd64((volatile signed __int64 *)(a1 + 56), v49);
if( (dword_140CFA17C & 2) != 0 && (INT64 *)a1 == &qword_140C4EC80 )
{
v42 = 2 * v50;
v43 = (char *)BitMap.Buffer + ((2 * v50) >> 3);
KeAcquireInStackQueuedSpinLock((UINT64 *)(a1 + 48), &LockHandle);
if( !(unsigned int)MiSplitBitmapPages(VaType, v43, (v42 & 7) + 2 * v49) )
dword_140CFA17C &= ~2u;
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
__writecr8(LockHandle.OldIrql);
}
if( v5 == 1 || a2 == v7 )
return v12;
v23 = (v7 - a2) / v6;
v24 = (a2 + v50) / v6;
v25 = v24 & 0x1F;
v26 = (volatile signed __int32 *)(*(_QWORD *)(a1 + 8) + 4 * (v24 >> 5));
if( (v24 & 0x1F) + v23 <= 0x20 )
{
if( v23 == 32 )
{
*v26 = 0;
return v12;
}
v29 = ~(((1 << v23) - 1) << v25);
}
else
{
if( (v24 & 0x1F) != 0 )
{
_InterlockedAnd(v26, ~(((1 << (32 - (v24 & 0x1F))) - 1) << v25));
v23 -= 32 - (unsigned int)(v24 & 0x1F);
++v26;
}
if( v23 >= 0x20 )
{
v27 = v23 >> 5;
v23 += -32i64 * (v23 >> 5);
do
{
*v26++ = 0;
--v27;
}
while( v27 );
}
if( !v23 )
return v12;
v29 = -1 << v23;
}
_InterlockedAnd(v26, v29);
return v12;
}
if( v5 == 1 )
v4 = 13;
v38 = v12 << 25;
PteBase = MmGetPteBase();
v40 = v4;
v41 = v11;
goto LABEL_71;
}
v38 = v12 << 25;
PteBase = MmGetPteBase();
v40 = VaType;
v41 = v48;
LABEL_71:
MiReturnSystemVa(v41, (__int64)((v7 << 28) + v38 - ((_QWORD)PteBase << 25)) >> 16, v40);
return 0i64;
}Referenced by:
MiReservePtes