MiGetPageProtection
NTSTATUS __stdcall MiGetPageProtection(PVOID Vad, PVOID PointerPte, UINT8 WsIrql, UINT64 WsExclusive){
unsigned __int16 *v4;
int v5;
_MMPTE v6;
_MMPTE *v8;
_MMPTE *Pml4eBase;
_MMPTE *PxeUserLimit;
unsigned int v12;
int v13;
NTSTATUS result;
unsigned __int64 v15;
_MMPFN *v16;
int v17;
NTSTATUS v18;
int v19;
unsigned __int64 EntireField;
int v21;
_MMPTE *PteBase;
_QWORD *v23;
NTSTATUS v24;
__int64 v25;
_EPROCESS *Process;
int v27;
__int64 v28;
unsigned __int64 v29;
_MMPTE *v30;
INT64 v31;
_QWORD *v32;
__int64 v33;
__int64 v34;
__int64 bf_0;
__int64 v36;
_MI_PARTITION *Partition;
_EPROCESS *CurrentProcess;
_MMCLONE_DESCRIPTOR *CloneAddress;
_MMPFN *v40;
INT64 *v41;
unsigned __int16 *Long;
v41 = (INT64 *)WsIrql;
v4 = Long;
v5 = 0;
v6.u.Long = *(_QWORD *)PointerPte;
v8 = (_MMPTE *)PointerPte;
*Long = 0;
*(_QWORD *)WsIrql = 0i64;
*(_DWORD *)WsExclusive = 0;
Pml4eBase = MmGetPml4eBase();
PxeUserLimit = MmGetPxeUserLimit();
v12 = *((_DWORD *)Vad + 12);
v13 = v12 & 0x70;
Long = (unsigned __int16 *)v6.u.Long;
if( v13 == 48 && ((v12 & 0x100000) == 0 || (v12 & 0x1000000) != 0 || (v12 & 0x2000000) == 0) )
{
*v4 = MiGetValidAwePartitionId(v6.u.Hard._bf_0);
return MiGetValidAweProtection((INT64)Vad, v6.u.Long);
}
if( (v6.u.Long & 1) == 0 )
{
if( (v6.u.Long & 0x400) == 0 )
{
if( (v6.u.Long & 0x800) != 0 && (v40 = MiLockTransitionLeafPage((ULONG_PTR)PointerPte, 0i64)) != 0i64 )
{
*v4 = ((unsigned __int64)v40->u4._bf_0 >> 39) & 0x3FF;
_InterlockedAnd64(&v40->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
}
else
{
*v4 = **(_WORD **)(*(&stru_140C4DB30 + 267) + 8i64 * PsGetCurrentProcess()[1].IdealProcessorPadding[5]);
}
v28 = (v6.u.Long >> 5) & 0x1F;
if( (*((_DWORD *)Vad + 12) & 0x1100000) == 17825792 )
*(_DWORD *)WsExclusive = 0;
return v28;
}
LOBYTE(v27) = MiIsPrototypePteVadLookup(v6.u.Long);
if( !v27 )
{
bf_0 = v6.u.Hard._bf_0;
if( *(&stru_140C4DB30 + 42) && (v6.u.Long & 0x10) == 0 )
bf_0 = v6.u.Long & ~*(&stru_140C4DB30 + 42);
v36 = bf_0 >> 16;
if( MI_PROTO_FORMAT_COMBINED(v6) )
{
Partition = **(_MI_PARTITION ***)(((v36 - 48) & 0xFFFFFFFFFFFFF000ui64) + 0x10);
}
else
{
CurrentProcess = (_EPROCESS *)PsGetCurrentProcess();
if( !CurrentProcess->CloneRoot.Root
|| (CloneAddress = MiLocateCloneAddress(CurrentProcess, (VOID *)v36)) == 0i64 )
{
if( v13 != 32 || (v12 & 0xF80) != 896 )
KeBugCheckEx(0x1Au, (PVOID)0x41202, v8, (PVOID)v6.u.Long, Vad);
*v4 = **(_WORD **)(*(&stru_140C4DB30 + 267) + 8i64 * (*(_WORD *)(**((_QWORD **)Vad + 9) + 60i64) & 0x3FF));
MiGetImageProtoProtection((_MMVAD_SHORT *)Vad, (_MMPTE *)v36);
return result;
}
Partition = CloneAddress->CloneHeader->Partition;
}
*v4 = Partition->Core.PartitionId;
return MmMakeProtectNotWriteCopy[MiCaptureProtectionFromLockedProto((_MMPTE *)v36)];
}
v28 = (v6.u.Long >> 5) & 0x1F;
if( (v12 & 0x100000) == 0 )
{
*v4 = **(_WORD **)(*(&stru_140C4DB30 + 267) + 8i64 * (*(_WORD *)(**((_QWORD **)Vad + 9) + 60i64) & 0x3FF));
v29 = (unsigned __int64)((__int64)(((_QWORD)v8 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16) >> 12;
MiGetProtoPteAddress();
v31 = (INT64)v30;
if( v30 )
{
v32 = (_QWORD *)*((_QWORD *)Vad + 15);
if( (__int64)v32 >= 0
|| v29 - (*((unsigned int *)Vad + 6) | ((unsigned __int64)*((unsigned __int8 *)Vad + 32) << 32)) <= (unsigned __int64)(*v32 - 1i64) >> 12 )
{
if( *(_QWORD *)(MEMORY[0] + 64i64) || (*(_DWORD *)(MEMORY[0] + 56i64) & 0x2000) != 0 )
return v28;
if( (int)MiTryLockProtoPoolPageAtDpc(v30, (UINT64)v32) < 0 )
{
LODWORD(v28) = 256;
*v41 = v31;
return v28;
}
LODWORD(v33) = MI_READ_PTE_LOCK_FREE(v31);
v34 = v33;
MiUnlockProtoPoolPage(0, 2u);
if( v34 )
v5 = v28;
}
}
LODWORD(v28) = v5;
}
return v28;
}
if( &Long < (unsigned __int16 **)Pml4eBase || &Long > (unsigned __int16 **)PxeUserLimit )
PointerPte = (PVOID)v6.u.Long;
v15 = ((unsigned __int64)PointerPte >> 12) & 0xFFFFFFFFFi64;
v16 = &MmGetPfnDb()[v15];
if( v13 == 16 )
{
MiIsPfn(v15);
if( v17 )
*v4 = ((unsigned __int64)v16->u4._bf_0 >> 39) & 0x3FF;
return(v12 >> 7) & 0x1F;
}
else if( v13 == 64 && MiRotatedToFrameBuffer(v8) )
{
v18 = 4;
if( (v6.u.Long & 0x800) == 0 )
v18 = 1;
v19 = v12 & 0xC00;
if( v19 == 3072 && (v12 & 0x380) != 0 )
{
return v18 | 0x18;
}
else
{
if( v19 == 1024 )
return v18 | 8;
return v18;
}
}
else
{
EntireField = v16->u4.EntireField;
*v4 = (EntireField >> 39) & 0x3FF;
if( (EntireField & 0x1000000000i64) != 0 )
{
result = MiGetProtectionFromPte(Vad, (PVOID)v6.u.Long);
if( (*((_DWORD *)Vad + 12) & 0x1100000) == 17825792 )
*(_DWORD *)WsExclusive = 0;
}
else
{
LOBYTE(v21) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v16, (_UNICODE_STRING *)0x3FF, WsIrql, (PWCHAR)WsExclusive);
if( !v21 )
return(*((_DWORD *)&v16->3 + 4) >> 5) & 0x1F;
PteBase = MmGetPteBase();
v23 = (unsigned __int64 *)((char *)&PteBase->u.Long
+ ((((__int64)(((_QWORD)v8 << 25) - ((_QWORD)PteBase << 25)) >> 16) & 0xFFFFFFFFF000ui64) >> 9));
v24 = (*v23 >> 60) & 7;
if( ((*v23 >> 60) & 7) != 0 )
{
if( (*v23 & 0x10) != 0 || (*v23 & 8) == 0 )
{
if( (*v23 & 0x10i64) != 0 )
return v24 | 8;
}
else
{
return v24 | 0x18;
}
}
else
{
v25 = (v16->OriginalPte.u.Long >> 5) & 0x1F;
if( (__int64)v16->ListEntry.Blink > 0 )
return MmMakeProtectNotWriteCopy[v25];
Process = KeGetCurrentThread()->ApcState.Process;
if( Process->CloneRoot.Root && MiLocateCloneAddress(Process, (VOID *)(v16->PteLong | 0x8000000000000000ui64)) )
LODWORD(v25) = MmMakeProtectNotWriteCopy[v25];
return v25;
}
return v24;
}
}
return result;
}Referenced by:
MiCommitExistingVad
MiProtectPrivateMemory
MiQueryAddressState