MiReplaceTransitionPage
VOID __stdcall MiReplaceTransitionPage(PVOID Pfn1, PVOID Pfn2, _MMPTE_COPY_LIST *PteCopyList){
_MMPTE_COPY_LIST *v3;
_MMPFN *PfnDb;
int v5;
unsigned __int64 v8;
__int64 v9;
_MMPFNLIST *v10;
char v11;
unsigned int v12;
int v13;
unsigned int v14;
UINT64 v15;
_MMLISTS ListName;
unsigned int PfnPriority;
char v18;
_KSPIN_LOCK_QUEUE *v19;
int v20;
__int64 v21;
_BOOL8 v22;
__int64 v23;
__int64 v24;
_MMPFN *v25;
_MMPFN *v26;
int v27;
$559D8309DABD45803AD694472C7FC28A *v28;
__int64 v29;
__int64 v30;
_UNICODE_STRING *v31;
UINT8 v32;
PWCHAR v33;
int v34;
char v35;
unsigned __int64 v36;
UINT64 v37;
volatile signed __int32 *v38;
unsigned int v39;
unsigned __int64 v40;
__int64 v41;
_QWORD *v42;
INT64 v43;
__int64 v44;
__int64 v45;
int v46;
_UNICODE_STRING *v47;
UINT8 v48;
wchar_t *v49;
int v50;
UINT8 v51;
__int64 v52;
signed __int32 v53[8];
UINT64 SourcePage;
_KLOCK_QUEUE_HANDLE LockQueue;
int v56;
_MI_PARTITION *Partition;
int v58;
_MMPTE_COPY_LIST *PteCopyLista;
PteCopyLista = v3;
v58 = (int)PteCopyList;
PfnDb = MmGetPfnDb();
v5 = 0xFFFFFF;
memset(&LockQueue, 0, sizeof(LockQueue));
v56 = 0xFFFFFF;
v8 = (__int64)((unsigned __int128)(((_BYTE *)Pfn1 - (_BYTE *)PfnDb) * (__int128)0x2AAAAAAAAAAAAAABi64) >> 64) >> 3;
SourcePage = (v8 >> 63) + v8;
v9 = ((_BYTE *)Pfn2 - (_BYTE *)PfnDb) / 48;
Partition = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * ((*((_QWORD *)Pfn1 + 5) >> 39) & 0x3FFi64));
v10 = Partition->PageLists.PageLocationList[*((_BYTE *)Pfn1 + 34) & 7];
if( (*((_BYTE *)Pfn1 + 34) & 7) == 3 && (*((_DWORD *)Pfn1 + 4) & 0x400i64) != 0 )
{
v11 = *((_BYTE *)Pfn1 + 39);
*((_BYTE *)Pfn1 + 39) = v11 & 0xF0;
}
else
{
v11 = *((_BYTE *)Pfn2 + 39);
}
v12 = v11 & 0xF;
MiLockNestedPageAtDpcInline((_MMPFN *)Pfn2);
LOBYTE(v13) = MiIsPfnFromSlabAllocation((INT64)Pfn2);
v14 = 0;
if( v13 )
v14 = 4;
MiFinalizePageAttribute((_MMPFN *)Pfn2, (_MI_PFN_CACHE_ATTRIBUTE)(*((unsigned __int8 *)Pfn1 + 34) >> 6), 1ui64);
MiCopyPfnEntryEx((INT64)Pfn2, (INT64)Pfn1);
v15 = SourcePage;
*((_BYTE *)Pfn2 + 39) = v12 | *((_BYTE *)Pfn2 + 39) & 0xF0;
if( (*((_QWORD *)Pfn1 + 5) & 0xFFFFFFFFFi64) == v15 )
*((_QWORD *)Pfn2 + 5) ^= (v9 ^ *((_QWORD *)Pfn2 + 5)) & 0xFFFFFFFFFi64;
MiCopyPage(v9, v15, PteCopyLista, 6ui64);
_InterlockedOr(v53, 0);
*((_QWORD *)Pfn2 + 3) ^= (*((_QWORD *)Pfn2 + 3) ^ ((unsigned __int64)(unsigned int)KiTbFlushTimeStamp << 56)) & 0xF00000000000000i64;
ListName = v10->ListName;
if( ListName == StandbyPageList )
{
if( v58 && (*(_QWORD *)Pfn1 & 0x8000000000000000ui64) != 0 )
{
MiUnlinkPageFromList((_MMPFN *)Pfn1, 0i64);
v14 |= 8u;
goto LABEL_53;
}
PfnPriority = MiGetPfnPriority((_MMPFN *)Pfn1);
v18 = *((_BYTE *)Pfn1 + 35);
v5 = PfnPriority;
v56 = PfnPriority;
LockQueue.LockQueue.Next = v19;
v10 = (_MMPFNLIST *)((char *)Partition->PageLists.StandbyPageListByPriority + 32 * PfnPriority + 8 * PfnPriority);
LockQueue.LockQueue.Lock = &v10->Lock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &v10->Lock);
v20 = v14 | 2;
if( (v18 & 8) == 0 )
v20 = v14;
v14 = v20;
}
else
{
LockQueue.LockQueue.Next = 0i64;
if( ListName == ModifiedPageList )
{
if( (*((_DWORD *)Pfn2 + 4) & 0x400i64) == 0 )
{
LockQueue.LockQueue.Lock = &v10->Lock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &v10->Lock);
v10 = MiDetermineModifiedPageListHead((_MMPFN *)Pfn2, Partition);
goto LABEL_21;
}
v10 = (_MMPFNLIST *)((char *)Partition->PageLists.MappedPageListHead + 32 * v12 + 8 * v12);
}
LockQueue.LockQueue.Lock = &v10->Lock;
KxAcquireQueuedSpinLock(&LockQueue.LockQueue, &v10->Lock);
}
LABEL_21:
v21 = *(_QWORD *)Pfn1 & 0xFFFFFFFFFi64;
v22 = v5 != 0xFFFFFF;
v23 = *((_QWORD *)Pfn1 + 3) & 0xFFFFFFFFFi64;
*(_QWORD *)Pfn2 = v21 | *(_QWORD *)Pfn2 & 0xFFFFFFF000000000ui64;
MiSetPfnBlink((_MMPFN *)Pfn2, v23, v22);
v24 = 0xFFFFFFFFFi64;
v25 = MmGetPfnDb();
if( v21 == 0xFFFFFFFFFi64 )
{
v10->Blink = v9;
}
else
{
v26 = &v25[v21];
if( v56 != 0xFFFFFF && (v14 & 2) != 0 && MiIsDecayPfn(v21) == 1 )
{
v26->u4._bf_0 ^= v24 & (v9 ^ v26->u4._bf_0);
goto LABEL_29;
}
MiSetPfnBlink(v26, v9, 0i64);
v24 = 0xFFFFFFFFFi64;
v25 = MmGetPfnDb();
}
v27 = v56;
LABEL_29:
if( v23 == v24 )
{
v10->Flink = v9;
}
else
{
v28 = ($559D8309DABD45803AD694472C7FC28A *)&v25[v23];
if( v27 != 0xFFFFFF && (v14 & 2) != 0 && MiIsDecayPfn(v23) == 1 )
{
LODWORD(v29) = MiUpdateTransitionPteFrame(v28[2]._bf_0, v9);
*(_QWORD *)(v30 + 16) = v29;
}
else
{
v28->_bf_0 ^= v24 & (v9 ^ v28->_bf_0);
}
}
if( v27 != 0xFFFFFF )
{
if( v14 >= 4 || v58 )
{
MiUpdatePfnOnSlabStandbyList((UINT64 *)Pfn2, 0i64);
if( !v58 )
{
MiUnlinkNumaStandbyPage((_MMPFN *)Pfn1);
--v10->Total;
LOBYTE(v34) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, v31, v32, v33);
_InterlockedAdd64(
(volatile signed __int64 *)((char *)&Partition->PageLists.TransitionPrivatePages
+ (-(__int64)(v34 != 0) & 0xFFFFFFFFFFFFFD40ui64)),
0xFFFFFFFFFFFFFFFFui64);
MiDecreaseAvailablePages(Partition, 1ui64, 0xFFFFFFFFFFFFFFFFui64, 0i64);
}
}
else
{
MiReplaceNumaStandbyPage((_MMPFN *)Pfn1, (_MMPFN *)Pfn2);
}
}
if( *(&stru_140C4DB30 + 567) != 1 )
goto LABEL_52;
v35 = SourcePage;
LOBYTE(v36) = 1;
v37 = SourcePage & 0x1F;
v38 = (volatile signed __int32 *)(*(&stru_140C4DB30 + 295) + 4 * (SourcePage >> 5));
if( v37 + 1 > 0x20 )
{
if( (SourcePage & 0x1F) != 0 )
{
_InterlockedOr(v38++, ((1 << (32 - (SourcePage & 0x1F))) - 1) << v37);
v36 = 1i64 - (32 - (v35 & 0x1Fu));
if( v36 >= 0x20 )
{
v40 = v36 >> 5;
v36 += -32i64 * (v36 >> 5);
do
{
*v38++ = -1;
--v40;
}
while( v40 );
}
if( !v36 )
goto LABEL_52;
}
v39 = (1 << v36) - 1;
}
else
{
v39 = 1 << v37;
}
_InterlockedOr(v38, v39);
LABEL_52:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockQueue);
LABEL_53:
*((_BYTE *)Pfn1 + 34) = *((_BYTE *)Pfn1 + 34) & 0xF8 | 5;
MiSetPfnBlink((_MMPFN *)Pfn1, 0i64, 1ui64);
_InterlockedOr(v53, 0);
*((_QWORD *)Pfn1 + 3) ^= (*((_QWORD *)Pfn1 + 3) ^ ((unsigned __int64)(unsigned int)KiTbFlushTimeStamp << 56)) & 0xF00000000000000i64;
v41 = *((_QWORD *)Pfn1 + 5) & 0xFFFFFFFFFi64;
if( v41 == SourcePage )
{
v42 = (_QWORD *)(*((_QWORD *)Pfn1 + 1) | 0x8000000000000000ui64);
}
else
{
v14 |= 1u;
v42 = (char *)MiMapPageInHyperSpaceWorker(v41, 0i64, 0x80000000ui64) + 8 * ((*((_DWORD *)Pfn1 + 2) >> 3) & 0x1FF);
}
LODWORD(v43) = MI_READ_PTE_LOCK_FREE((INT64)v42);
LODWORD(v44) = MiUpdateTransitionPteFrame(v43, v9);
v45 = v44;
LOBYTE(v46) = MiPteInShadowRange((UINT64)v42);
if( v46 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v45 & 1) != 0 )
v45 |= 0x8000000000000000ui64;
*v42 = v45;
if( (v14 & 1) != 0 )
{
MiUnmapPageInHyperSpaceWorker(v42, 0x11u, 0x80000000ui64);
v42 = (_QWORD *)(*((_QWORD *)Pfn1 + 1) | 0x8000000000000000ui64);
}
LOBYTE(v50) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, v47, v48, v49);
if( !v50 && MiGetSystemRegionType((UINT64)v42) == 5 )
{
LODWORD(v52) = KeMakeKernelDirectoryTableBase(v9 << 12);
*(v42 - 174) = v52;
}
if( v14 >= 8 )
MiInsertPageInList((_MMPFN *)Pfn2, 0x800ui64, v51);
_InterlockedAnd64((volatile signed __int64 *)Pfn2 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( (v14 & 2) != 0 )
*((_BYTE *)Pfn1 + 35) &= ~8u;
*((_QWORD *)Pfn1 + 5) &= 0xFFFFFFFFFFFFFFFui64;
*((_BYTE *)Pfn1 + 34) &= 0xC7u;
*((_BYTE *)Pfn1 + 35) &= ~0x20u;
}Referenced by:
MiFinalizeImageHeaderPage
MiMakeVaRangePhysicallyContiguous
MiTradeTransitionPage
MiWalkEntireImage