MiUnlockImageSection
VOID __stdcall MiUnlockImageSection(
INT64 *SectionLockCountPointer,
MMPTE *PointerPte,
MMPTE *LastPte,
IMAGE_SECTION_HEADER *NtSection){
_ETHREAD *CurrentThread;
UINT64 *v5;
__int64 CurrentIrql;
signed __int32 v8;
unsigned int v9;
WCHAR *v10;
struct _KPRCB *Pml4eBase;
int v12;
_MMPFN *PfnDb;
_MMPTE *PteBase;
signed __int64 v15;
INT64 v16;
unsigned __int8 v17;
UINT64 v18;
bool v19;
__int16 v20;
__int64 v21;
__int64 v22;
__int64 v23;
int v24;
unsigned __int64 v25;
char v26;
int v27;
INT64 v28;
unsigned __int64 v29;
int v30;
__int64 v31;
__int64 v32;
unsigned __int64 v33;
__int64 v34;
signed __int32 v35;
int v36[8];
UINT64 SpinCount;
UINT64 v38;
_ETHREAD *v39;
__int64 v40;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v5 = (UINT64 *)PointerPte;
v39 = CurrentThread;
CurrentIrql = KeGetCurrentIrql();
v40 = CurrentIrql;
if( !(_BYTE)CurrentIrql )
--*((_WORD *)CurrentThread + 242);
v8 = _InterlockedDecrement((volatile signed __int32 *)SectionLockCountPointer);
if( (unsigned int)(v8 + 1) <= 1 )
KeBugCheckEx(
0x1Au,
0x1010ui64,
(__int64)(((_QWORD)PointerPte << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16,
(ULONG_PTR)NtSection,
v8);
if( v8 == 1 )
{
if( PointerPte <= LastPte )
{
v9 = MiPteInShadowRange((UINT64)&v38);
v10 = (WCHAR *)v9;
HIDWORD(SpinCount) = v9;
Pml4eBase = (struct _KPRCB *)MmGetPml4eBase();
v12 = 1;
PfnDb = MmGetPfnDb();
PteBase = MmGetPteBase();
while( 1 )
{
v38 = *v5;
v15 = 48 * ((v38 >> 12) & 0xFFFFFFFFFi64);
v16 = (INT64)PfnDb + v15;
v17 = KeGetCurrentIrql();
__writecr8(2ui64);
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)(v16 + 24), 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( *(__int64 *)(v16 + 24) < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)(v16 + 24), 0x3Fui64) );
v12 = 1;
}
v18 = *(unsigned __int16 *)(v16 + 32);
if( !(_WORD)v18 )
MiBadRefCount((_MMPFN *)v16, v18);
v19 = (_WORD)v18 == 1;
v20 = v18 - 1;
*(_WORD *)(v16 + 32) = v20;
if( v19 && MiIsPfnFileOnly(v16) )
{
LABEL_52:
MiPfnReferenceCountIsZero((_MMPFN *)v16, v15 / 48, (UINT8 *)Pml4eBase);
goto LABEL_53;
}
v21 = *(_QWORD *)(v16 + 40);
if( (v21 & 0x1000000000i64) != 0 || (v21 & 0x2000000000000i64) != 0 )
goto LABEL_53;
v22 = *(_QWORD *)(v16 + 24);
v23 = v22 & 0x3FFFFFFFFFFFFFFFi64;
if( v20 )
break;
v24 = v12;
LABEL_25:
v25 = *(_QWORD *)(v16 + 8) | 0x8000000000000000ui64;
if( v25 > (unsigned __int64)PteBase + 0x3FFFFFFF78i64 || v25 < (unsigned __int64)PteBase )
{
v26 = *(_BYTE *)(v16 + 35);
if( (v26 & 0x20) != 0 )
{
*(_BYTE *)(v16 + 35) = v26 & 0xDF;
goto LABEL_51;
}
}
LOBYTE(v27) = MI_PFN_IS_PROTO(
(UNICODE_STRING *)v16,
(UNICODE_STRING *)0x8000000000000000i64,
(UINT8)Pml4eBase,
v10);
if( v27 && (*(_DWORD *)(v16 + 16) & 0x400i64) != 0 )
{
v30 = 1;
}
else if( (unsigned int)MiIsPfnCommitNotCharged(v28) )
{
v30 = 1;
}
else if( v24 == 1 && (v22 & 0x4000000000000000i64) != 0 )
{
v30 = 1;
}
v31 = (v29 >> 39) & 0x3FF;
v32 = *(_QWORD *)(qword_140C4E388 + 8 * v31);
if( v30 == 1 )
MiReturnCommit(*(_MI_PARTITION **)(qword_140C4E388 + 8 * v31), 1ui64);
v33 = 1i64;
if( (ULONG_PTR *)v32 != &MiSystemPartition
|| (Pml4eBase = KeGetCurrentPrcb(), v34 = *((int *)Pml4eBase + 8391), (_DWORD)v34 == -1) )
{
LABEL_50:
_InterlockedExchangeAdd64((volatile signed __int64 *)(v32 + 7168), v33);
goto LABEL_51;
}
if( (unsigned __int64)(v34 + 1) > 0x100 )
{
LABEL_45:
if( (int)v34 > 192
&& (_DWORD)v34 != -1
&& (_DWORD)v34 == _InterlockedCompareExchange((volatile signed __int32 *)Pml4eBase + 8391, 192, v34) )
{
v33 = (int)v34 - 192 + 1i64;
}
if( v33 )
goto LABEL_50;
}
else
{
while( 1 )
{
v35 = _InterlockedCompareExchange((volatile signed __int32 *)Pml4eBase + 8391, v34 + 1, v34);
v19 = (_DWORD)v34 == v35;
LODWORD(v34) = v35;
if( v19 )
break;
if( v35 == -1 || (unsigned __int64)(v35 + 1i64) > 0x100 )
goto LABEL_45;
}
}
LABEL_51:
if( v24 )
goto LABEL_52;
LABEL_53:
_InterlockedAnd64((volatile signed __int64 *)(v16 + 24), 0x7FFFFFFFFFFFFFFFui64);
__writecr8(v17);
v10 = (WCHAR *)HIDWORD(SpinCount);
++v5;
v12 = 1;
Pml4eBase = (struct _KPRCB *)MmGetPml4eBase();
PfnDb = MmGetPfnDb();
if( v5 > (UINT64 *)LastPte )
{
CurrentThread = v39;
LOBYTE(CurrentIrql) = v40;
goto LABEL_55;
}
}
if( v20 == 1 )
{
if( v23 )
{
LABEL_23:
v24 = 0;
goto LABEL_25;
}
}
else if( v20 != 2 || !v23 )
{
goto LABEL_53;
}
if( (*(_BYTE *)(v16 + 34) & 8) == 0 )
goto LABEL_53;
goto LABEL_23;
}
LABEL_55:
_InterlockedDecrement((volatile signed __int32 *)SectionLockCountPointer);
_InterlockedOr(v36, 0);
if( PushLock.0 )
ExpUnblockPushLock(&PushLock, 0i64, 0i64);
}
if( !(_BYTE)CurrentIrql )
KeLeaveCriticalRegionThread((__int64)CurrentThread);
}Referenced by:
MiLockPagableImageSection