MmReplaceImportEntry
VOID __stdcall MmReplaceImportEntry(UINT64 *ImportThunk, UINT64 NewFunction){
_LIST_ENTRY *v4;
_LIST_ENTRY *v5;
UINT64 *v6;
_MMPTE *PteBase;
unsigned __int64 v8;
VOID *v9;
INT64 v10;
INT16 v11;
_MMSUPPORT_INSTANCE *SessionVm;
UINT64 v13;
_MMSUPPORT_INSTANCE *v14;
char v15;
char v16;
__int64 v17;
char v18;
unsigned __int64 v19;
__int64 v20;
_MMPFN *v21;
_UNICODE_STRING *v22;
UINT8 v23;
int v24;
UINT64 v25;
NTSTATUS v26;
UINT64 v27;
UINT64 v28;
UINT64 *v29;
_MMPTE v30;
_MI_PARTITION *v31;
UINT64 v32;
__int64 v33[9];
UINT64 Size;
UINT64 SpinCount;
LODWORD(Size) = 0;
if( PsLoadedModuleList )
{
v4 = MiLookupDataTableEntry(ImportThunk, 1ui64);
v5 = v4;
if( !v4 )
KeBugCheckEx(0x1Au, (PVOID)0x1014, 0i64, ImportThunk, (PVOID)NewFunction);
v6 = (UINT64 *)RtlImageDirectoryEntryToData(v4[3].Flink, 1u, 0xCu, &Size);
if( !v6 || !(_DWORD)Size || ImportThunk < v6 || ImportThunk >= (UINT64 *)((char *)v6 + (unsigned int)Size) )
KeBugCheckEx(0x1Au, (PVOID)0x1014, v5, ImportThunk, (PVOID)NewFunction);
}
if( MI_IS_PHYSICAL_ADDRESS(ImportThunk) )
{
*ImportThunk = NewFunction;
return;
}
PteBase = MmGetPteBase();
v8 = (unsigned __int64)PteBase + (((unsigned __int64)ImportThunk >> 9) & 0x7FFFFFFFF8i64);
if( MiGetSystemRegionType((UINT64)ImportThunk) == 1 )
SessionVm = MiGetSessionVm(v10, (INT64)v9, v11);
else
SessionVm = MiGetAnyMultiplexedVm(MiWorkingSetTypeSystemViews, v9);
v13 = 0i64;
v14 = SessionVm;
MiLockWorkingSetShared();
v16 = v15;
while( 1 )
{
while( 1 )
{
if( v13 )
{
if( (v8 & 0xFFF) != 0 )
goto LABEL_18;
MiUnlockPageTableInternal((INT64)v14, v13);
}
v13 = (UINT64)PteBase + ((v8 >> 9) & 0x7FFFFFFFF8i64);
MiLockPageTableInternal((INT64)v14, v13, 0i64);
LABEL_18:
LODWORD(v17) = MI_READ_PTE_LOCK_FREE(v8);
v33[0] = v17;
v18 = v17;
if( (v17 & 1) != 0 )
break;
MiUnlockPageTableInternal((INT64)v14, v13);
LOBYTE(v28) = v16;
MiUnlockWorkingSetShared(v14, v28);
MiLockWorkingSetShared();
MiLockPageTableInternal((INT64)v14, v13, 0i64);
}
LODWORD(v19) = MI_READ_PTE_LOCK_FREE((INT64)v33);
v20 = (v19 >> 12) & 0xFFFFFFFFFi64;
v21 = &MmGetPfnDb()[v20];
LOBYTE(v24) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v21, v22, v23, (PWCHAR)v20);
if( !v24 )
break;
v26 = MiCopyOnWrite((UINT64)ImportThunk, (INT64 *)v8, 0xFFFFFFFFFFFFFFFFui64, 0i64);
if( v26 < 0 )
{
MiUnlockPageTableInternal((INT64)v14, v13);
LOBYTE(v27) = v16;
MiUnlockWorkingSetShared(v14, v27);
MiCopyOnWriteCheckConditions((INT64)v14, (unsigned int)v26);
MiLockWorkingSetShared();
MiLockPageTableInternal((INT64)v14, v13, 0i64);
}
PteBase = MmGetPteBase();
}
if( (v18 & 0x42) != 0 )
{
*ImportThunk = NewFunction;
}
else
{
v29 = (UINT64 *)((char *)MiMapPageInHyperSpaceWorker(v25, 0i64, 0x80000000ui64)
+ ((unsigned __int16)ImportThunk & 0xFFF));
*v29 = NewFunction;
MiUnmapPageInHyperSpaceWorker(v29, 0x11u, 0x80000000ui64);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v21->u2, 0x3Fui64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v21->u2._bf_0 < 0 );
}
MiCaptureDirtyBitToPfn();
v31 = *(_MI_PARTITION **)(*(&stru_140C4DB30 + 267) + 8 * (((unsigned __int64)v21->u4._bf_0 >> 39) & 0x3FF));
_InterlockedAnd64(&v21->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
if( v30.u.Long )
MiReleasePageFileInfo(v31, v30, 1ui64);
}
MiUnlockPageTableInternal((INT64)v14, v13);
LOBYTE(v32) = v16;
MiUnlockWorkingSetShared(v14, v32);
}Referenced by:
KsepPatchImportTableEntry
ViThunkReplaceImportEntry
ViThunkReplaceImportIfThunkedOrderDependent
ViThunkReplaceImportIfThunkedRegular
ViThunkReplaceSharedExports