MiSwapStackPage
NTSTATUS __stdcall MiSwapStackPage(
_MMPFN *Pfn1,
_MMPTE_COPY_LIST *PteCopyList,
UINT64 ReplacementColor,
UINT64 *ReplacementPage,
UINT64 *FastPath){
int v7;
_QWORD *Pool;
_QWORD *v9;
unsigned __int64 v10;
__int64 v11;
NTSTATUS SystemRegionType;
VOID *v13;
_MI_WORKING_SET_TYPE v14;
_MMSUPPORT_INSTANCE *AnyMultiplexedVm;
_MMSUPPORT_INSTANCE *v16;
unsigned int v17;
__int128 v18;
signed __int64 v19;
unsigned int v20;
__int64 v21;
int v22;
UINT64 v23;
_MMPFN *v24;
UINT64 v25;
char v26;
char v27;
NTSTATUS v28;
char *v29;
UINT64 v30;
UINT64 v31;
_ETHREAD *LeafPfnBuddy;
_MMPTE *PteFromCopyList;
char v34;
char v35;
_KPRCB *v36;
unsigned __int64 Long;
int v38;
UINT64 v39;
UINT64 v40;
unsigned __int64 v41;
int v42;
UINT64 v43;
_ETHREAD *v44;
INT64 v45;
NTSTATUS v46;
unsigned __int64 v47;
int v48;
_MMPFN *v49;
unsigned __int64 v50;
unsigned __int64 v51;
char WsIrql;
int WsIrql_4;
INT64 v55;
UINT64 DestinationPage;
VOID *Token;
_ETHREAD *CurrentThread;
__int64 v59;
UINT64 *v62;
_DWORD *v63;
Token = 0i64;
v7 = (int)ReplacementPage;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
Pool = MiAllocatePool(64i64, 0x50ui64, 0x734B694Dui64);
v9 = Pool;
if( !Pool )
return 0;
Pool[4] = Pfn1;
v10 = *((_QWORD *)PteCopyList + 1) | 0x8000000000000000ui64;
v11 = (__int64)((v10 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
Pool[6] = v11;
SystemRegionType = MiGetSystemRegionType(v11);
LODWORD(v55) = SystemRegionType;
if( SystemRegionType == 14 )
{
v14 = MiWorkingSetTypeKernelStacks;
}
else
{
if( SystemRegionType != 12 )
{
LABEL_59:
ExFreePoolWithTag(v9, 0);
return 0;
}
v14 = MiWorkingSetTypeSystemViews;
}
AnyMultiplexedVm = MiGetAnyMultiplexedVm(v14, v13);
v9[8] = AnyMultiplexedVm;
v16 = AnyMultiplexedVm;
if( !*(&stru_140C4DB30 + 4332) )
goto LABEL_59;
v17 = 512;
v18 = ((char *)PteCopyList - (char *)MmGetPfnDb()) * (__int128)0x2AAAAAAAAAAAAAABi64;
v19 = ((char *)PteCopyList - (char *)MmGetPfnDb()) / 48;
v59 = v19;
if( v7 == -1 )
{
LODWORD(v21) = MiSearchNumaNodeTable((PVOID)((*((_QWORD *)&v18 + 1) >> 63) + (*((__int64 *)&v18 + 1) >> 3)));
v22 = *(_DWORD *)(v21 + 8);
v20 = (MiGetPfnChannel((INT64)PteCopyList) << *(&stru_140C4DB30 + 157)) | *(&stru_140C4DB30 + 66) & v19 | (v22 << *(&stru_140C4DB30 + 156));
if( ((unsigned int)FastPath & 0x3000000) != 0 )
v17 = 66048;
}
else
{
v17 = 560;
v20 = *(&stru_140C4DB30 + 66) & v19 | v7 & ~*(&stru_140C4DB30 + 66);
}
LODWORD(v23) = MiGetPage((ULONG_PTR *)Pfn1, v20, v17);
DestinationPage = v23;
if( v23 == -1i64 )
goto LABEL_59;
v24 = &MmGetPfnDb()[v23];
MiSetPfnTbFlushStamp(v24, 0i64, 0i64);
v9[7] = 0i64;
MiLockWorkingSetShared();
WsIrql_4 = 0;
v27 = v26;
WsIrql = v26;
while( _interlockedbittestandset64(PteCopyList + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx((UINT64 *)&WsIrql_4);
while( *((__int64 *)PteCopyList + 3) < 0 );
}
if( *(_MMPFN **)(*(&stru_140C4DB30 + 267) + 8 * ((*((_QWORD *)PteCopyList + 5) >> 39) & 0x3FFi64)) != Pfn1
|| v10 != (*((_QWORD *)PteCopyList + 1) | 0x8000000000000000ui64)
|| (v28 = MiGetSystemRegionType(v9[6]), (_DWORD)v55 != v28)
|| !MiCanStealKernelStack((_MMPFN *)PteCopyList, 1u)
|| (v29 = (char *)MmGetPteBase() + ((v10 >> 9) & 0x7FFFFFFFF8i64),
!MiLockPageTableInternal((INT64)v16, (UINT64)v29, (UINT8 *)1)) )
{
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
goto LABEL_57;
}
if( (MiFlags & 0x800) != 0
|| MiSwapStackPageNoDpc((_MMPTE_COPY_LIST *)ReplacementColor, (_MMPFN *)PteCopyList, v24) != 1 )
{
LeafPfnBuddy = (_ETHREAD *)MiGetLeafPfnBuddy(PteCopyList);
v55 = (INT64)LeafPfnBuddy;
if( ((unsigned __int64)&LeafPfnBuddy->Tcb.QuantumTarget & 0xFFFFFFFFFFFFFFDFui64) != 0 )
{
PteFromCopyList = MiGetPteFromCopyList(
(_MMPTE_COPY_LIST *)ReplacementColor,
DestinationPage,
0xFFFFFFFFFFFFFFFFui64);
if( LeafPfnBuddy != (_ETHREAD *)-16i64 && LeafPfnBuddy != CurrentThread )
{
KeTryToFreezeThreadStack(LeafPfnBuddy, &Token);
if( v34 == 1 )
{
MiCopyKstack(v24, (_MMPFN *)PteCopyList, PteFromCopyList);
MiLockNestedPageAtDpcInline(v24);
MiSwitchKstackPages(v24, (_MMPFN *)PteCopyList);
_InterlockedAnd64(&v24->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
v35 = *((_BYTE *)PteCopyList + 34);
*((_QWORD *)PteCopyList + 5) &= ~0x8000000000000000ui64;
*((_BYTE *)PteCopyList + 34) = v35 & 0xC7;
*((_BYTE *)PteCopyList + 35) &= ~0x20u;
*((_QWORD *)PteCopyList + 3) &= 0xC000000000000000ui64;
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
KeFlushSingleTb(v9[6], FlushKernel, 2i64);
KiReleaseThreadStateLock(v36, (_KSHARED_READY_QUEUE *)Token);
KiReleaseThreadLockSafe(v55);
Long = ZeroPte.u.Long;
LOBYTE(v38) = MiPteInShadowRange((UINT64)PteFromCopyList);
if( v38 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
PteFromCopyList->u.Long = Long;
MiUnlockPageTableInternal((INT64)v16, (UINT64)v29);
LOBYTE(v39) = WsIrql;
MiUnlockWorkingSetShared(v16, v39);
v31 = DestinationPage;
*v63 = 1;
goto LABEL_52;
}
goto LABEL_39;
}
if( MiAddLockedPageCharge((_MMPFN *)PteCopyList, 0i64) )
{
v9[7] = PteCopyList;
LABEL_39:
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal((INT64)v16, (UINT64)v29);
LOBYTE(v43) = WsIrql;
MiUnlockWorkingSetShared(v16, v43);
v44 = CurrentThread;
v31 = DestinationPage;
*v9 = v59;
v45 = v55;
v9[3] = v44;
v9[1] = v31;
v9[2] = PteFromCopyList;
*((_DWORD *)v9 + 10) = 0;
if( v45 == -16 || (_ETHREAD *)v45 == v44 )
{
v46 = KeExpandKernelStackAndCalloutInternal(MiJumpStack, v9, 0x6000ui64, 1, 0i64);
if( v46 < 0 )
*((_DWORD *)v9 + 10) = v46;
}
else
{
KeGenericCallDpc((__int64)MiDoStackCopy, (__int64)v9);
}
if( *((int *)v9 + 10) >= 0 )
{
*v63 = 0;
v51 = MiLockPageInline((_MMPFN *)PteCopyList);
*((_QWORD *)PteCopyList + 3) &= 0xC000000000000000ui64;
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v51);
goto LABEL_52;
}
v47 = ZeroPte.u.Long;
LOBYTE(v48) = MiPteInShadowRange((UINT64)PteFromCopyList);
if( v48 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
v47 = ZeroPte.u.Long | 0x8000000000000000ui64;
PteFromCopyList->u.Long = v47;
MiReleaseFreshPage(v24);
v49 = (_MMPFN *)v9[7];
if( v49 )
{
v50 = MiLockPageInline(v49);
MiRemoveLockedPageChargeAndDecRef((_MMPFN *)v9[7]);
_InterlockedAnd64((volatile signed __int64 *)(v9[7] + 24i64), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v50);
}
goto LABEL_59;
}
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal((INT64)v16, (UINT64)v29);
LOBYTE(v40) = WsIrql;
MiUnlockWorkingSetShared(v16, v40);
v41 = ZeroPte.u.Long;
LOBYTE(v42) = MiPteInShadowRange((UINT64)PteFromCopyList);
if( v42 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
v41 = ZeroPte.u.Long | 0x8000000000000000ui64;
PteFromCopyList->u.Long = v41;
goto LABEL_58;
}
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal((INT64)v16, (UINT64)v29);
LABEL_57:
LOBYTE(v25) = v27;
MiUnlockWorkingSetShared(v16, v25);
LABEL_58:
MiReleaseFreshPage(v24);
goto LABEL_59;
}
_InterlockedAnd64((volatile signed __int64 *)PteCopyList + 3, 0x7FFFFFFFFFFFFFFFui64);
MiUnlockPageTableInternal((INT64)v16, (UINT64)v29);
LOBYTE(v30) = v27;
MiUnlockWorkingSetShared(v16, v30);
v31 = DestinationPage;
*v63 = 1;
LABEL_52:
*((_WORD *)PteCopyList + 16) = 0;
if( v62 )
*v62 = v31;
ExFreePoolWithTag(v9, 0);
return 1;
}Referenced by:
MiTradePage