MiRelocateImagePfn
NTSTATUS __stdcall MiRelocateImagePfn(
_CONTROL_AREA *ControlArea,
VOID *Opaque,
UINT64 ImagePteIndex,
UINT64 PageFrameIndex,
UINT64 Diff,
UINT64 SessionId){
UINT64 Value;
unsigned int v9;
_EX_PUSH_LOCK *DynamicRelocations;
__int64 bf_0;
UINT64 v13;
int v14;
int v15;
_MMPFN *v17;
UINT64 PrivateFixup;
_MMPTE *PteBase;
UINT64 v20;
int v21;
__int64 v22;
__int64 v23;
int v24;
_ETHREAD *CurrentThread;
_KTBFLUSH_TYPE v26;
unsigned __int64 Long;
int v28;
UINT64 Direction;
VOID *v30;
int v31;
Value = Diff;
v9 = ImagePteIndex;
DynamicRelocations = (_EX_PUSH_LOCK *)ControlArea->u2.SeImageStub->DynamicRelocations;
bf_0 = DynamicRelocations->_bf_0;
if( (unsigned __int64)(unsigned int)ImagePteIndex >= DynamicRelocations[7]._bf_0 )
return 1;
v13 = (unsigned int)ImagePteIndex;
while( !*(_QWORD *)(bf_0 + 8i64 * (unsigned int)v13) )
{
LOBYTE(v14) = MiDoesPageRequireRetpolineFixups((INT64)&DynamicRelocations[9], v13);
if( v14 )
break;
v13 = (unsigned int)(v15 + 1);
if( (_DWORD)v13 != v9 )
return 1;
}
v17 = &MmGetPfnDb()[PageFrameIndex];
PrivateFixup = 0i64;
PteBase = MmGetPteBase();
if( Opaque && (Opaque < PteBase || Opaque > MmGetPteLimit()) )
{
v20 = 0i64;
v30 = 0i64;
}
else
{
v30 = Opaque;
v20 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64);
if( !v20 )
{
if( !Opaque )
return -1073741670;
v20 = (UINT64)Opaque;
}
Opaque = (VOID *)((__int64)((v20 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16);
MiMakeProtectionPfnCompatible((_BYTE *)4, v17);
LODWORD(v22) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v20, PageFrameIndex, v21 | 0xA0000000);
v23 = v22;
LOBYTE(v24) = MiPteInShadowRange(v20);
if( v24 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v23 & 1) != 0 )
v23 |= 0x8000000000000000ui64;
*(_QWORD *)v20 = v23;
PrivateFixup = 0i64;
}
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( (_ETHREAD *)DynamicRelocations[1]._bf_0 == CurrentThread )
{
CurrentThread = 0i64;
}
else
{
--CurrentThread->Tcb.SpecialApcDisable;
ExAcquirePushLockSharedEx(DynamicRelocations + 3, 0i64);
PrivateFixup = 0i64;
}
if( !Diff )
Value = DynamicRelocations[5].Value;
if( Diff )
PrivateFixup = DynamicRelocations[5].Value;
LODWORD(Direction) = v31;
MiPerformFixups(Opaque, ControlArea, v9, Value, PrivateFixup, Direction);
if( CurrentThread )
{
if( _InterlockedCompareExchange64(&DynamicRelocations[3]._bf_0, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(DynamicRelocations + 3);
KeAbPostRelease(&DynamicRelocations[3]);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
}
if( v20 )
{
if( (VOID *)v20 == v30 )
{
Long = ZeroPte.u.Long;
LOBYTE(v28) = MiPteInShadowRange(v20);
if( v28 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (ZeroPte.u.Long & 1) != 0 )
Long = ZeroPte.u.Long | 0x8000000000000000ui64;
*(_QWORD *)v20 = Long;
KeFlushSingleTb((UINT64)Opaque, FlushKernel, 1i64);
}
else
{
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v20, 1ui64, v26);
}
}
return 0;
}Referenced by:
MiFillPerSessionProtos
MiPrivateFixup
MiValidateInPage
MiWalkEntireImage