MmReplaceImportEntry
VOID __stdcall MmReplaceImportEntry(UINT64 *ImportThunk, UINT64 NewFunction){
__int64 v4;
ULONG_PTR v5;
unsigned __int64 v6;
_MMPTE *PteBase;
unsigned __int64 v8;
INT64 SessionVm;
UINT64 v10;
INT64 v11;
UINT8 v12;
char v13;
unsigned __int64 v14;
char *v15;
UNICODE_STRING *v16;
UINT8 v17;
int v18;
UINT64 v19;
int v20;
__int64 v21;
UINT64 *v22;
UINT64 v23;
INT64 v24;
INT64 v25;
ULONG_PTR BugCheckParameter4;
INT64 v27;
__int64 v28[9];
UINT64 Size;
UINT64 SpinCount;
LODWORD(Size) = 0;
if( PsLoadedModuleList )
{
v4 = MiLookupDataTableEntry((unsigned __int64)ImportThunk, 1);
v5 = v4;
if( !v4 )
KeBugCheckEx(0x1Au, 0x1014ui64, 0i64, (ULONG_PTR)ImportThunk, NewFunction);
LODWORD(v6) = RtlImageDirectoryEntryToData(*(PVOID *)(v4 + 48), 1u, 0xCu, &Size);
if( !v6
|| !(_DWORD)Size
|| (unsigned __int64)ImportThunk < v6
|| (unsigned __int64)ImportThunk >= v6 + (unsigned int)Size )
{
KeBugCheckEx(0x1Au, 0x1014ui64, v5, (ULONG_PTR)ImportThunk, NewFunction);
}
}
if( (unsigned int)MI_IS_PHYSICAL_ADDRESS(ImportThunk) )
{
*ImportThunk = NewFunction;
return;
}
PteBase = MmGetPteBase();
v8 = (unsigned __int64)PteBase + (((unsigned __int64)ImportThunk >> 9) & 0x7FFFFFFFF8i64);
if( (unsigned int)MiGetSystemRegionType((UINT64)ImportThunk) == 1 )
SessionVm = MiGetSessionVm();
else
SessionVm = (INT64)MiGetAnyMultiplexedVm(1i64);
v10 = 0i64;
v11 = SessionVm;
v12 = MiLockWorkingSetShared(SessionVm);
while( 1 )
{
while( 1 )
{
if( v10 )
{
if( (v8 & 0xFFF) != 0 )
goto LABEL_18;
MiUnlockPageTableInternal(v11, v10);
}
v10 = (UINT64)PteBase + ((v8 >> 9) & 0x7FFFFFFFF8i64);
MiLockPageTableInternal(v11, v10, 0i64);
LABEL_18:
v28[0] = MI_READ_PTE_LOCK_FREE(v8);
v13 = v28[0];
if( (v28[0] & 1) != 0 )
break;
MiUnlockPageTableInternal(v11, v10);
MiUnlockWorkingSetShared(v11, v12);
MiLockWorkingSetShared(v11);
MiLockPageTableInternal(v11, v10, 0i64);
}
v14 = ((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)v28) >> 12) & 0xFFFFFFFFFi64;
v15 = (char *)MmGetPfnDb() + 48 * v14;
LOBYTE(v18) = MI_PFN_IS_PROTO((UNICODE_STRING *)v15, v16, v17, (PWCHAR)v14);
if( !v18 )
break;
v20 = MiCopyOnWrite((UINT64)ImportThunk, (UINT64 *)v8, -1i64, 0i64);
if( v20 < 0 )
{
MiUnlockPageTableInternal(v11, v10);
MiUnlockWorkingSetShared(v11, v12);
MiCopyOnWriteCheckConditions(v11, (unsigned int)v20);
MiLockWorkingSetShared(v11);
MiLockPageTableInternal(v11, v10, 0i64);
}
PteBase = MmGetPteBase();
}
if( (v13 & 0x42) != 0 )
{
*ImportThunk = NewFunction;
}
else
{
LODWORD(v21) = MiMapPageInHyperSpaceWorker(v19, 0i64, 0x80000000ui64);
v22 = (UINT64 *)(((unsigned __int16)ImportThunk & 0xFFF) + v21);
*v22 = NewFunction;
MiUnmapPageInHyperSpaceWorker(v22, 0x11u, 0x80000000ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)v15 + 6, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((__int64 *)v15 + 3) < 0 );
}
v23 = MiCaptureDirtyBitToPfn((INT64)v15);
v25 = *(_QWORD *)(qword_140C4E388 + 8 * ((*((_QWORD *)v15 + 5) >> 39) & 0x3FFi64));
_InterlockedAnd64((volatile signed __int64 *)v15 + 3, 0x7FFFFFFFFFFFFFFFui64);
if( v23 )
MiReleasePageFileInfo(v25, v23, 1, v24, BugCheckParameter4, v27, v28[0], v28[1], v28[2], v28[3], v28[4], v28[5]);
}
MiUnlockPageTableInternal(v11, v10);
MiUnlockWorkingSetShared(v11, v12);
}Referenced by:
KsepPatchImportTableEntry
ViThunkReplaceImportEntry
ViThunkReplaceImportIfThunkedOrderDependent
ViThunkReplaceImportIfThunkedRegular
ViThunkReplaceSharedExports