MiRelocateImagePfn
__int64 __fastcall MiRelocateImagePfn(
ULONG_PTR BugCheckParameter2,
unsigned __int64 a2,
unsigned int a3,
__int64 a4,
__int64 a5,
int a6,
int a7){
__int64 v8;
__int64 *v12;
__int64 v13;
UINT64 v14;
int v15;
_MMPFN *v17;
__int64 v18;
_MMPTE *PteBase;
unsigned __int64 v20;
int ProtectionPfnCompatible;
_ETHREAD *CurrentThread;
unsigned __int64 v23;
v8 = a5;
v12 = *(__int64 **)(*(_QWORD *)(BugCheckParameter2 + 96) + 32i64);
v13 = *v12;
if( a3 >= (unsigned __int64)v12[7] )
return 1i64;
v14 = a3;
while( !*(_QWORD *)(v13 + 8i64 * (unsigned int)v14) && !MiDoesPageRequireRetpolineFixups((INT64)(v12 + 9), v14) )
{
v14 = (unsigned int)(v15 + 1);
if( (_DWORD)v14 != a3 )
return 1i64;
}
v17 = (_MMPFN *)((char *)MmGetPfnDb() + 48 * a4);
v18 = 0i64;
PteBase = MmGetPteBase();
if( a2 && (a2 < (unsigned __int64)PteBase || a2 > (unsigned __int64)MmGetPteLimit()) )
{
v20 = 0i64;
v23 = 0i64;
}
else
{
v23 = a2;
v20 = MiReservePtes((INT64)&qword_140C4EC80, 1ui64);
if( !v20 )
{
if( !a2 )
return 3221225626i64;
v20 = a2;
}
a2 = (__int64)((v20 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16;
ProtectionPfnCompatible = MiMakeProtectionPfnCompatible(4ui64, v17);
*(_QWORD *)v20 = MiMakeValidPte(v20, a4, ProtectionPfnCompatible | 0xA0000000);
v18 = 0i64;
}
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (_ETHREAD *)v12[1] == CurrentThread )
{
CurrentThread = 0i64;
}
else
{
--*((_WORD *)CurrentThread + 243);
ExAcquirePushLockSharedEx((UINT64)(v12 + 3), 0i64);
v18 = 0i64;
}
if( !a5 )
v8 = v12[5];
if( a5 )
v18 = v12[5];
MiPerformFixups(a2, BugCheckParameter2, a3, v8, v18, a7);
if( CurrentThread )
{
if( _InterlockedCompareExchange64(v12 + 3, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v12 + 3);
KeAbPostRelease(v12 + 3);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
if( v20 )
{
if( v20 == v23 )
{
*(_QWORD *)v20 = ZeroPte;
KeFlushSingleTb(a2, 0i64, 1i64);
}
else
{
MiReleasePtes((INT64)&qword_140C4EC80, v20, 1ui64);
}
}
return 0i64;
}Referenced by:
MiFillPerSessionProtos
MiPrivateFixup
MiValidateInPage
MiWalkEntireImage