MiWsleFlush
NTSTATUS __stdcall MiWsleFlush(INT64 a1, UINT64 a2, CHAR a3, INT64 a4){
wchar_t *v4;
INT64 v5;
int v6;
_MMPTE *v7;
_MMPTE *Pml4eBase;
__int64 Long;
unsigned __int64 PxeUserLimit;
__int64 v11;
_MMPFN *v12;
int v13;
_MMPFN *v14;
int v15;
char v16;
__int64 v17;
NTSTATUS v18;
int v19;
__int64 v20;
_MMPTE *PteBase;
int v22;
int v23;
UINT64 v24;
VOID *v25;
__int64 v26;
INT64 v27;
_MMPTE *PteLimit;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v29;
__int64 v30;
UINT64 v31;
NTSTATUS WsleProtection;
__int64 v33;
__int64 v34;
__int64 v35;
__int64 v36;
_MMCLONE_DESCRIPTOR *CloneAddress;
__int64 v38;
_MMSUPPORT_INSTANCE *AnyMultiplexedVm;
INT64 v41;
__int64 v42;
char v43;
__int64 v44;
int v45;
INT64 v46;
VOID *v47;
_MMPTE *v48;
_MMPTE *v49;
NTSTATUS HasShadow;
char v51;
__int64 v52;
int v53;
union {unsigned __int64 Long;volatile unsigned __int64 VolatileLong;_MMPTE_HARDWARE Hard;_MMPTE_PROTOTYPE Proto;_MMPTE_SOFTWARE Soft;_MMPTE_TIMESTAMP TimeStamp;_MMPTE_TRANSITION Trans;_MMPTE_SUBSECTION Subsect;_MMPTE_LIST List;} v54;
_MMSUPPORT_INSTANCE *v55;
_MI_PARTITION *v56;
int v57;
_MMPTE *v58;
UINT64 SpinCount;
__int64 v60;
__int64 v61;
VOID *v64;
v4 = (wchar_t *)a2;
v5 = a1;
v6 = 0;
v7 = (_MMPTE *)((char *)MmGetPteBase() + ((a2 >> 9) & 0x7FFFFFFFF8i64));
Pml4eBase = MmGetPml4eBase();
Long = v7->u.Long;
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
if( v7 >= Pml4eBase && (unsigned __int64)v7 <= PxeUserLimit )
PxeUserLimit = (unsigned __int64)MmGetPxeUserLimit();
v60 = v7->u.Long;
if( &v60 < (__int64 *)Pml4eBase || (unsigned __int64)&v60 > PxeUserLimit )
PxeUserLimit = Long;
v11 = (PxeUserLimit >> 12) & 0xFFFFFFFFFi64;
v12 = &MmGetPfnDb()[v11];
if( (v12->u2._bf_0 & 0x3FFFFFFFFFFFFFFFui64) > 1 )
{
LOBYTE(v13) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v12, (_UNICODE_STRING *)v11, (UINT8)Pml4eBase, v4);
if( !v13 )
return 0;
}
if( (*(_BYTE *)(v5 + 184) & 7) != 0 )
{
if( v12->u3.ReferenceCount > 1u )
return 0;
LODWORD(SpinCount) = 0;
v14 = v12;
if( _interlockedbittestandset64((volatile signed __int32 *)&v12->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( v12->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v12->u2, 0x3Fui64) );
v4 = (wchar_t *)a2;
v5 = a1;
}
}
else
{
v14 = 0i64;
}
if( (v12->u2._bf_0 & 0x3FFFFFFFFFFFFFFFui64) > 1
&& (LOBYTE(v15) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v12, (_UNICODE_STRING *)v11, (UINT8)Pml4eBase, v4), !v15)
|| (v16 = *(_BYTE *)(v5 + 184) & 7) != 0 && v12->u3.ReferenceCount > 1u )
{
LABEL_48:
if( v14 )
_InterlockedAnd64(&v14->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
return 0;
}
v17 = 0x7FFFFFFEFi64;
v18 = Long & 0xFFFFFFFB;
if( v16 )
goto LABEL_27;
LOBYTE(v19) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v12, (_UNICODE_STRING *)0x3FFFFFFF78i64, (UINT8)Pml4eBase, v4);
PteBase = MmGetPteBase();
if( !v19 && v7 <= &PteBase[v17] && v7 >= PteBase && (Long & 0x42) != 0 && (*(_DWORD *)(v20 - 540) & 0x8000) != 0 )
{
MiCaptureWriteWatchDirtyBit((_EPROCESS *)(v20 - 1664), v4, 0i64);
LABEL_27:
LOBYTE(PteBase) = (unsigned __int8)MmGetPteBase();
}
v22 = 0;
LOBYTE(v23) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v12, (_UNICODE_STRING *)(v17 * 8), (UINT8)PteBase, v4);
PteLimit = MmGetPteLimit();
if( v23 )
{
v29.Long = (unsigned __int64)v7->u;
LODWORD(v61) = (_DWORD)v7;
MiPteInShadowRange((UINT64)v7);
v30 = HIBYTE(v29.Trans._bf_0) & 0xFu | (unsigned __int8)(16 * ((v29.Long >> 60) & 7));
v31 = a2;
WsleProtection = MiGetWsleProtection(a2, v30);
if( WsleProtection )
{
v60 = MiSwizzleInvalidPte(32 * (WsleProtection & 0x1F | 0xFFFFFFFFF8000020ui64));
}
else
{
v34 = MiSwizzleInvalidPte(((v12->PteLong | 0x8000000000000000ui64) << 16) | 0x400);
LOBYTE(v33) = v34;
v60 = v34;
v36 = v34;
if( (*(_BYTE *)(a1 + 184) & 7u) >= 2 && (Long & 0xA00) == 0 && Long < 0 )
{
LOBYTE(v33) = v34 | 8;
v60 = v34 | 8;
v36 = v34 | 8;
}
if( (v12->u4._bf_0 & 0x1000000000i64) != 0 || v35 <= 0 )
{
if( (a3 & 2) != 0 )
{
if( *(_QWORD *)(a1 - 400) )
{
CloneAddress = MiLocateCloneAddress((_EPROCESS *)(a1 - 1664), v25);
if( CloneAddress )
{
if( *(_QWORD *)(*(_QWORD *)(v38 + 1680) + 360i64) > CloneAddress->NestingLevel )
{
v33 |= 8ui64;
v60 = v33;
}
}
}
}
}
else
{
v60 = v36 | 0x800;
}
}
goto LABEL_66;
}
if( a2 >= v24 && a2 <= (unsigned __int64)PteLimit )
{
v22 = 1;
MiLockPageTableInternal(v27, (UINT64)v7, 0i64);
if( (v12->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) != 1 || MiLockedPageTableHasActiveLargeEntries(a2) )
{
MiUnlockPageTableInternal(a1, (UINT64)v7);
goto LABEL_48;
}
}
if( (((unsigned __int64)v12->u4._bf_0 >> 60) & 7) == 4 )
{
AnyMultiplexedVm = MiGetAnyMultiplexedVm(MiWorkingSetTypePagedPool, PteLimit);
v41 = a1;
if( (_MMSUPPORT_INSTANCE *)a1 == AnyMultiplexedVm )
{
MiReleasePageFileSpace(&Irp, v12->OriginalPte, 1ui64);
v64 = (VOID *)(a2 & 0xFFFFFFFFFFFFF000ui64);
LODWORD(v42) = MI_READ_PTE_LOCK_FREE((INT64)v64);
v43 = v42 | 2;
v18 |= 4u;
v60 = v42 | 2;
v44 = v42 | 2;
v6 = 1;
LOBYTE(v45) = MiPteInShadowRange((UINT64)v7);
if( v45 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v43 & 1) != 0 )
v44 |= 0x8000000000000000ui64;
v7->u.Long = v44;
MiInsertTbFlushEntry((_MI_TB_FLUSH_LIST *)a4, v64, 1ui64, 0i64);
MiFlushTbList((_MI_TB_FLUSH_LIST *)a4);
goto LABEL_88;
}
}
else
{
v41 = a1;
}
v33 = Long & 0xFFFFFFFFF000i64 | (32 * ((*((_DWORD *)&v12->3 + 4) >> 5) & 0x1F | 0x40i64));
if( *(&stru_140C4DB30 + 42) )
{
if( (*(&stru_140C4DB30 + 42) & v33) != 0 )
v33 |= 0x10ui64;
else
v33 |= *(&stru_140C4DB30 + 42);
}
v60 = v33;
if( v22 )
{
MiUnlockNestedPageTableWritePte(v41, (INT64 *)v7, v33, 0i64);
v47 = (VOID *)(a2 & 0xFFFFFFFFFFFFF000ui64);
goto LABEL_87;
}
v31 = a2;
LABEL_66:
v46 = v7->u.Long;
v48 = MmGetPml4eBase();
v49 = MmGetPxeUserLimit();
if( v7 >= v48 && v7 <= v49 )
{
HasShadow = MiPteHasShadow();
v49 = MmGetPxeUserLimit();
if( HasShadow )
v46 |= 0x20ui64;
}
if( (MiFlags & 0x800) != 0 )
{
v46 = 32i64;
}
else if( (MiFlags & 0x4000000) != 0 )
{
_mm_lfence();
}
if( (v46 & 0x20) != 0 )
{
v52 = v60;
if( v7 >= v48 && v7 <= v49 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v60 & 1) != 0 )
v52 = v26 | v60;
v7->u.Long = v52;
}
else
{
v51 = _InterlockedExchange64((volatile __int64 *)v7, v60);
if( v7 >= v48 && v7 <= v49 )
MiWritePteShadow();
if( (v51 & 0x20) == 0 )
goto LABEL_88;
}
v47 = (VOID *)(v31 & 0xFFFFFFFFFFFFF000ui64);
LABEL_87:
MiInsertTbFlushEntry((_MI_TB_FLUSH_LIST *)a4, v47, 1ui64, 0i64);
LABEL_88:
if( v14 )
_InterlockedAnd64(&v14->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v6 != 1 )
{
LOBYTE(v53) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v12, (_UNICODE_STRING *)v46, v33, (PWCHAR)v25);
if( !v53 )
{
v54.Long = (unsigned __int64)v12->OriginalPte.u;
if( (v54.Long & 1) == 0 && (!v54.Long || !*(&stru_140C4DB30 + 42) || (v54.Long & *(&stru_140C4DB30 + 42)) != 0) )
{
if( *(_DWORD *)(*(_QWORD *)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v12->u4._bf_0 >> 39) & 0x3FF))
+ 1036i64) )
{
if( (v54.Long & 2) == 0 && !MiGetWorkingSetSwapSupport((_MMSUPPORT_INSTANCE *)a1) )
{
MI_IS_RESET_PTE();
if( !v57 || (*(_BYTE *)(&v12->u3 + 1) & 0x10) != 0 || (v7->u.Long & 0x42) != 0 )
{
v58 = MmGetPteBase();
if( v7 <= &v58[0x7FFFFFFEFi64] && v7 >= v58 && v7 <= MmGetPteLimit() )
MiReservePageFileSpace(v56, v7, v55);
}
}
}
}
}
}
return v18;
}Referenced by:
MiFreeWsleList