MmUnlockPages
NTSTATUS __fastcall MmUnlockPages(INT64 a1, INT64 a2, INT64 a3){
__int16 v3;
unsigned __int64 *v4;
unsigned int v6;
__int64 v7;
__int64 v8;
_MMPTE *PteBase;
unsigned __int64 v10;
char *v11;
int v12;
int v13;
__int64 v14;
__int64 v15;
unsigned __int64 v16;
unsigned __int64 v17;
_MMPTE *v18;
unsigned __int64 v19;
int v20;
__int64 v21;
_QWORD *v22;
_MMPTE *v23;
_CONTROL_AREA *v24;
unsigned __int64 v25;
int v26;
unsigned __int64 v27;
int v28;
__int64 v29;
__int64 CurrentIrql;
unsigned __int64 v31;
UINT8 v32;
union {$8D9ED47C9F2F2CD645B633E301950288 __s0;unsigned __int64 EntireField;} *p_u4;
__int64 v34;
_MMPFN *PfnDb;
INT64 v36;
unsigned __int64 v37;
int v38;
_CONTROL_AREA *v39;
__int64 v40;
_MMPFN *BaseResidentPage;
_MI_PARTITION *v42;
char v43;
__int64 v44;
__int64 v45;
int v46;
__int64 v47;
__int16 v48;
bool v49;
__int16 v50;
int v51;
struct _KPRCB *CurrentPrcb;
__int64 v53;
__int64 v54;
int v55;
_MMPTE *v56;
char v57;
int v58;
int v59;
unsigned __int64 v60;
unsigned __int64 v61;
__int64 v62;
__int64 v63;
_MI_PARTITION *v64;
unsigned __int64 v65;
__int64 CachedResidentAvailable;
signed __int32 v67;
__int64 v68;
unsigned __int8 v69;
_MMPFN *v70;
_MI_PARTITION *v71;
unsigned __int64 v72;
unsigned __int64 v73;
_MMPTE *PteLimit;
unsigned __int64 v75;
int v76;
unsigned __int64 v77;
UINT64 v78;
__int64 v79;
__int64 v80;
unsigned __int64 v81;
struct _KPRCB *v82;
__int64 v83;
signed __int32 v84;
NTSTATUS result;
INT64 v86;
UINT64 v87;
__int64 v88;
__int64 v89;
unsigned __int64 v90;
__int64 v91;
unsigned __int64 v92;
__int64 v93;
__int64 v94;
unsigned __int64 v95;
unsigned __int64 v96;
unsigned __int64 v97;
__int64 v98;
__int16 v100;
int v101;
UINT64 SpinCount;
v3 = *(_WORD *)(a1 + 10);
v4 = (unsigned __int64 *)(a1 + 48);
v94 = *(_QWORD *)(a1 + 16);
v100 = v3;
v86 = a1 + 48;
if( (v3 & 0x200) != 0 )
MiRetardMdl((_MDL *)a1);
v6 = *(_DWORD *)(a1 + 44);
v7 = *(_QWORD *)(a1 + 32);
v8 = *(unsigned int *)(a1 + 40);
PteBase = MmGetPteBase();
v10 = ((unsigned __int64)(((_WORD)v7 + (_WORD)v6) & 0xFFF) + v8 + 4095) >> 12;
v92 = v10;
if( (v3 & 1) != 0 )
{
v11 = *(char **)(a1 + 24);
v12 = 0;
if( (*(_WORD *)(a1 + 10) & 0x200) != 0 )
{
MiRetardMdl((_MDL *)a1);
v6 = *(_DWORD *)(a1 + 44);
v12 = v13;
v7 = *(_QWORD *)(a1 + 32);
LODWORD(v8) = *(_DWORD *)(a1 + 40);
}
v14 = v7 + v6;
v15 = ((_WORD)v7 + (_WORD)v6) & 0xFFF;
v16 = (v15 + (unsigned __int64)(unsigned int)v8 + 4095) >> 12;
if( (unsigned __int64)v11 > 0x7FFFFFFEFFFFi64 )
{
v17 = (unsigned __int64)&v11[-v12];
*(_WORD *)(a1 + 10) &= 0xFFDEu;
v18 = (_MMPTE *)((char *)PteBase + ((v17 >> 9) & 0x7FFFFFFFF8i64));
if( (*(_WORD *)(a1 + 10) & 4) != 0 )
*(_QWORD *)(a1 + 24) = v14;
v95 = (unsigned __int64)PteBase + ((v17 >> 9) & 0x7FFFFFFFF8i64);
v19 = v95;
v20 = 4;
v96 = (unsigned __int64)PteBase + (((unsigned __int64)v18 >> 9) & 0x7FFFFFFFF8i64);
v97 = (unsigned __int64)PteBase + ((v96 >> 9) & 0x7FFFFFFFF8i64);
v21 = 4i64;
v98 = (__int64)PteBase + ((v97 >> 9) & 0x7FFFFFFFF8i64);
do
{
v22 = (_QWORD *)*(&v94 + v21--);
--v20;
if( (*v22 & 1) == 0 )
break;
if( (*v22 & 0x80u) != 0i64 )
goto LABEL_15;
}
while( v21 != 1 );
v20 = 0;
LABEL_15:
if( v20 )
{
v23 = MmGetPteBase();
do
{
v19 = (unsigned __int64)v23 + ((v19 >> 9) & 0x7FFFFFFFF8i64);
--v20;
}
while( v20 );
}
if( (*(_QWORD *)v19 & 0x200i64) != 0 )
MiZeroAndFlushPtes((VOID *)v17, v16);
if( MmProtectFreedNonPagedPool == 1 )
++v16;
if( (dword_140CFA17C & 1) != 0 )
MiRemovePteTracker((_MDL *)a1, (VOID *)v17, v16);
MiReleasePtes(
(_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432),
v18,
(unsigned int)v16,
(_KTBFLUSH_TYPE)v19);
v10 = v92;
}
else
{
MiUnmapLockedPagesInUserSpace(v11, (_MDL *)((v15 + (unsigned __int64)(unsigned int)v8 + 4095) >> 12));
}
v4 = (unsigned __int64 *)v86;
}
if( (MmTrackLockedPages & 1) != 0 )
MiFreeMdlTracker(a1, v10);
v24 = 0i64;
v25 = (unsigned __int64)&v4[v10];
v26 = 1;
v91 = 0i64;
v90 = v25;
v27 = 0i64;
v101 = 1;
v28 = 1;
v88 = 0xFFFFFFFFFi64;
v29 = 0xFFFFFFFFFi64;
CurrentIrql = KeGetCurrentIrql();
v89 = CurrentIrql;
__writecr8(2ui64);
do
{
v31 = *v4;
v32 = 0;
p_u4 = &MmGetPfnDb()->u4;
if( *v4 == -1i64 )
break;
v34 = 0xFFFFFFFFFi64;
if( v31 > 0xFFFFFFFFFi64 || (p_u4[6 * v31]._bf_0 & 0x4000000000000i64) == 0 )
{
MiDereferenceIoPages(0i64, v31, 1i64);
goto LABEL_123;
}
PfnDb = MmGetPfnDb();
v93 = 48 * v31;
v36 = (INT64)&PfnDb[v31];
if( (v3 & 0x100) != 0 )
{
v37 = *(_QWORD *)(v36 + 40);
if( (v37 & 0x1000000000i64) == 0 && ((v37 >> 60) & 7) != 1 )
{
v31 = 0xFFFFFFFFDi64;
if( (v37 & 0xFFFFFFFFFi64) != 0xFFFFFFFFDi64 && v29 != (v37 & 0xFFFFFFFFFi64) )
{
if( v29 != 0xFFFFFFFFFi64 )
{
MiUnlockPageTableCharges((_DWORD)PfnDb + 48 * v29, v28, 0x1000000000ui64);
v37 = *(_QWORD *)(v36 + 40);
}
v88 = v37 & 0xFFFFFFFFFi64;
LOBYTE(v38) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v36, (_UNICODE_STRING *)v31, v32, (PWCHAR)0xFFFFFFFFFi64);
v101 = 2 - (v38 != 0);
}
}
}
LODWORD(SpinCount) = (_DWORD)v24;
v39 = v24;
v40 = (__int64)v24;
BaseResidentPage = (_MMPFN *)v24;
if( _interlockedbittestandset64((volatile signed __int32 *)(v36 + 24), 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v36 + 24) < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)(v36 + 24), 0x3Fui64) );
v24 = 0i64;
}
v42 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * ((*(_QWORD *)(v36 + 40) >> 39) & 0x3FFi64));
v43 = *(_BYTE *)(v36 + 34);
if( (v43 & 0x20) != 0 && (v43 & 8) == 0 && (*(_QWORD *)(v36 + 24) & 0x3FFFFFFFFFFFFFFFi64) == 0 )
{
v40 = *(_QWORD *)v36 - 32i64;
_InterlockedDecrement64((volatile signed __int64 *)(v40 + 264));
}
if( (v3 & 0x80u) != 0 )
{
if( !v40 )
{
v44 = *(_QWORD *)(v36 + 16);
if( (v44 & 0x400) == 0 && (*(_BYTE *)(v36 + 34) & 8) == 0 )
{
if( (v44 & 4) != 0 )
{
LODWORD(v45) = MI_READ_PTE_LOCK_FREE(v36 + 16);
v27 = v45 & 0xFFFFFFFFFFFFFFFDui64;
*(_QWORD *)(v36 + 16) = v44 & 0xFFFFFFFFFFFFFFFBui64;
}
else
{
v27 = (unsigned __int64)v24;
}
}
v39 = (_CONTROL_AREA *)BaseResidentPage;
*(_BYTE *)(v36 + 34) |= 0x10u;
}
if( (*(_QWORD *)(v36 + 40) & 0x1000000000i64) == 0 )
{
LOBYTE(v46) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v36, (_UNICODE_STRING *)v31, v32, (PWCHAR)v34);
if( v46 )
{
v47 = *(_QWORD *)(v36 + 16);
if( (v47 & 0x400) != 0 )
{
if( *(&stru_140C4DB30 + 42) && (v47 & 0x10) == 0 )
v47 &= ~*(&stru_140C4DB30 + 42);
v39 = *(_CONTROL_AREA **)(v47 >> 16);
}
}
}
}
v48 = *(_WORD *)(v36 + 32);
if( !v48 )
MiBadRefCount((_MMPFN *)v36);
v49 = v48 == 1;
v50 = v48 - 1;
*(_WORD *)(v36 + 32) = v50;
if( !v49 || (LOBYTE(v51) = MiIsPfnFileOnly(v36), !v51) )
{
v53 = *(_QWORD *)(v36 + 40);
if( (v53 & 0x1000000000i64) != 0 || (v53 & 0x2000000000000i64) != 0 )
goto LABEL_107;
v54 = *(_QWORD *)(v36 + 24) & 0x3FFFFFFFFFFFFFFFi64;
if( v50 )
{
if( v50 != 1 )
{
if( v50 != 2 || !v54 )
goto LABEL_107;
goto LABEL_74;
}
if( !v54 )
{
LABEL_74:
if( (*(_BYTE *)(v36 + 34) & 8) == 0 )
goto LABEL_107;
}
v55 = 0;
}
else
{
v55 = 1;
}
v56 = MmGetPteBase();
CurrentPrcb = (struct _KPRCB *)(*(_QWORD *)(v36 + 8) | 0x8000000000000000ui64);
if( CurrentPrcb > (struct _KPRCB *)&v56[0x7FFFFFFEFi64] || CurrentPrcb < (struct _KPRCB *)v56 )
{
v57 = *(_BYTE *)(v36 + 35);
if( (v57 & 0x20) != 0 )
{
*(_BYTE *)(v36 + 35) = v57 & 0xDF;
goto LABEL_105;
}
}
LOBYTE(v58) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v36, 0i64, *(_BYTE *)(v36 + 8), (PWCHAR)&v56[0x7FFFFFFEFi64]);
if( v58 && (*(_DWORD *)(v36 + 16) & 0x400i64) != 0 )
{
v59 = 1;
}
else if( (unsigned __int64)CurrentPrcb <= v60
&& CurrentPrcb >= (struct _KPRCB *)MmGetPteBase()
&& (*(_BYTE *)(v36 + 35) & 0x20) != 0 )
{
v59 = 1;
}
else if( v55 == 1 && (v62 & 0x4000000000000000i64) != 0 )
{
v59 = 1;
}
v63 = (v61 >> 39) & 0x3FF;
v64 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v63);
if( v59 == 1 )
MiReturnCommit(*(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * v63), 1ui64);
v65 = 1i64;
if( v64 == &Irp )
{
CurrentPrcb = KeGetCurrentPrcb();
CachedResidentAvailable = (int)CurrentPrcb->CachedResidentAvailable;
if( (_DWORD)CachedResidentAvailable != -1 )
{
if( (unsigned __int64)(CachedResidentAvailable + 1) <= 0x100 )
{
while( 1 )
{
v67 = _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
CachedResidentAvailable + 1,
CachedResidentAvailable);
v49 = (_DWORD)CachedResidentAvailable == v67;
LODWORD(CachedResidentAvailable) = v67;
if( v49 )
break;
if( v67 == -1 || (unsigned __int64)(v67 + 1i64) > 0x100 )
goto LABEL_99;
}
LABEL_105:
if( !v55 )
goto LABEL_107;
goto LABEL_106;
}
LABEL_99:
if( (int)CachedResidentAvailable > 192
&& (_DWORD)CachedResidentAvailable != -1
&& (_DWORD)CachedResidentAvailable == _InterlockedCompareExchange(
(volatile signed __int32 *)&CurrentPrcb->CachedResidentAvailable,
192,
CachedResidentAvailable) )
{
v65 = (int)CachedResidentAvailable - 192 + 1i64;
}
if( !v65 )
goto LABEL_105;
}
}
_InterlockedExchangeAdd64((volatile signed __int64 *)&v64->Vp.ResidentAvailablePages, v65);
goto LABEL_105;
}
LABEL_106:
MiPfnReferenceCountIsZero((_MMPFN *)v36, v93 / 48, (UINT8)CurrentPrcb);
LABEL_107:
if( (*(_QWORD *)(v36 + 40) & 0x1000000000i64) != 0
&& (*(_QWORD *)(v36 + 24) & 0x4000000000000000i64) != 0
&& *(_WORD *)(v36 + 32) == 2 )
{
*(_QWORD *)(v36 + 24) &= ~0x4000000000000000ui64;
BaseResidentPage = MiGetBaseResidentPage((_MMPFN *)v36);
v68 = (BaseResidentPage->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 & 0xFFFFFFFFFi64)
- 1;
BaseResidentPage->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0 ^= (v68 ^ BaseResidentPage->u1.$976DF529DAC3D73085C9E386D94B91E6::$E228DCF3D8940E384DBC5EFCA756D8B6::_bf_0) & 0xFFFFFFFFFi64;
if( BaseResidentPage != (_MMPFN *)v36 )
_InterlockedAnd64(&BaseResidentPage->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v68 )
BaseResidentPage = 0i64;
}
_InterlockedAnd64((volatile signed __int64 *)(v36 + 24), 0x7FFFFFFFFFFFFFFFui64);
if( v27 )
{
MiReleasePageFileInfo(v42, (_MMPTE)v27, 1ui64);
v27 = 0i64;
}
if( BaseResidentPage )
MiFinishLargePageFree((INT64)BaseResidentPage, 1ui64);
if( v39 )
MiDereferenceControlAreaProbe(v39, 1ui64);
if( v42 != &Irp )
ExReleaseRundownProtectionCacheAware(v42->Segments.ProbeRundownReference);
v3 = v100;
LOBYTE(CurrentIrql) = v89;
v25 = v90;
v4 = (unsigned __int64 *)v86;
v29 = v88;
LABEL_123:
v86 = (INT64)++v4;
if( (++v91 & 0x3F) == 0 && (unsigned __int8)CurrentIrql < 2u )
{
if( (unsigned __int64)v4 >= v25 )
{
v28 = v101;
break;
}
if( (unsigned int)KeShouldYieldProcessor() )
{
__writecr8((unsigned __int8)CurrentIrql);
v69 = KeGetCurrentIrql();
__writecr8(2ui64);
LOBYTE(CurrentIrql) = v69;
v89 = v69;
}
}
v28 = v101;
v24 = 0i64;
}
while( (unsigned __int64)v4 < v25 );
if( v29 != 0xFFFFFFFFFi64 )
{
v70 = &MmGetPfnDb()[v29];
v71 = 0i64;
if( v28 == 2 )
{
if( (*(_BYTE *)(&v70->u3 + 1) & 7) != 6
|| (v70->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) == 0
|| (v72 = v70->PteLong | 0x8000000000000000ui64, v73 = (unsigned __int64)MmGetPteBase(), v72 < v73)
|| (PteLimit = MmGetPteLimit(), v72 > (unsigned __int64)PteLimit)
|| (v75 = (__int64)((v72 << 25) - (v73 << 25)) >> 16, v75 < v73)
|| v75 > (unsigned __int64)PteLimit )
{
v26 = 0;
}
v76 = 3;
if( v26 )
goto LABEL_145;
goto LABEL_179;
}
v76 = 1;
if( !v28 )
v76 = 4;
LABEL_145:
if( (v70->u2._bf_0 & 0x3FFFFFFFFFFFFFFFui64) < 0x10000 )
LABEL_179:
KeBugCheckEx(
0x1Au,
(PVOID)0x41791,
v70,
(PVOID)(v70->PteLong | 0x8000000000000000ui64),
(PVOID)(v70->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64));
v77 = 0i64;
v78 = 0i64;
while( 1 )
{
v79 = v70->u4._bf_0 & 0xFFFFFFFFFi64;
LODWORD(v87) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v70->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&v87);
while( v70->u2._bf_0 < 0 );
}
v80 = v70->u2._bf_0 ^ ((v70->u2._bf_0 - 0x10000) ^ v70->u2._bf_0) & 0x3FFFFFFFFFFFFFFFi64;
v70->u2._bf_0 = v80;
v81 = v80 & 0x3FFFFFFFFFFFFFFFi64;
if( v81 >= 0x10000 )
break;
if( !v71 )
v71 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v70->u4._bf_0 >> 39) & 0x3FF));
++v77;
if( !v81 && MiPfnShareCountIsZero(v70, 0i64) != PageStillReferenced )
++v78;
_InterlockedAnd64(&v70->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( !--v76 )
goto LABEL_159;
v70 = &MmGetPfnDb()[v79];
}
_InterlockedAnd64(&v70->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
LABEL_159:
if( v77 )
{
if( v71 == &Irp )
{
v82 = KeGetCurrentPrcb();
v83 = (int)v82->CachedResidentAvailable;
if( (_DWORD)v83 != -1 )
{
if( v77 + v83 <= 0x100 )
{
do
{
if( v77 >= 0x80000 )
break;
v84 = _InterlockedCompareExchange(
(volatile signed __int32 *)&v82->CachedResidentAvailable,
v77 + v83,
v83);
v49 = (_DWORD)v83 == v84;
LODWORD(v83) = v84;
if( v49 )
goto LABEL_173;
}
while( v84 != -1 && v77 + v84 <= 0x100 );
}
if( (int)v83 > 192
&& (_DWORD)v83 != -1
&& (_DWORD)v83 == _InterlockedCompareExchange(
(volatile signed __int32 *)&v82->CachedResidentAvailable,
192,
v83) )
{
v77 += (int)v83 - 192;
}
}
}
if( v77 )
_InterlockedExchangeAdd64((volatile signed __int64 *)&v71->Vp.ResidentAvailablePages, v77);
}
LABEL_173:
if( v78 )
MiReturnCommit(v71, v78);
}
__writecr8((unsigned __int8)CurrentIrql);
if( v94 )
_InterlockedExchangeAdd64((volatile signed __int64 *)(v94 + 1280), -(__int64)v92);
result = a1;
*(_WORD *)(a1 + 10) &= 0xF6FDu;
return result;
}Referenced by:
AlpcpFreeCompletionList
AlpcpInitializeCompletionList
CcCopyBytesToUserBuffer
CcLockSystemCacheBuffer
CcMapAndCopyInToCache
CcMdlReadComplete2
CcMdlWriteAbort
CcMdlWriteComplete2
CcZeroDataInCache
ExUnlockUserBuffer
ExpGetLookasideInformation
ExpProfileDelete
FsRtlpFreeMdlChain
IopCleanupFileObjectIosbRange
IopSetFileObjectIosbRange
IopfCompleteRequest
KiOpPatchCode
MiAllocatePerSessionProtos
MiApplyImageHotPatch
MiCopyPagesIntoEnclave
MiGetWorkingSetInfo
MiGetWorkingSetInfoList
MiLoadDataIntoVsmEnclave
MiLoadSectionIntoVsmEnclave
MiProbeAndLockComplete
MiProbeAndLockPages
MiQueryMemoryPhysicalContiguity
MiReleaseHotPatchResources
MmCopyVirtualMemory
MmRotatePhysicalView
NT_DISK::Read
NT_DISK::Write
NtLoadEnclaveData
NtPssCaptureVaSpaceBulk
NtStartProfile
NtStopProfile
PopReadPagesFromHiberFile
PspCreateSecureThread
PspExitThread
PspGetSetContextInternal
PspIumAllocatePartitionState
PspIumFreePartitionState
SmPrepareForFatalPageError
SmProcessStatsRequest
VmProbeAndLockPages
VmUnlockPages
VslCallEnclave
VslFinalizeSecureImageHash
VslObtainHotPatchUndoTable
VslValidateDynamicCodePages
VslpLockPagesForTransfer
VslpUnlockPagesForTransfer
WbMakeUserDataPagesKernelWritable
WbMakeUserExecutablePagesKernelWritable
sub_14064F46C