MiPrepareImagePagesForHotPatch
INT64 __fastcall MiPrepareImagePagesForHotPatch(INT64 *a1, UINT64 a2, INT64 a3){
ULONG_PTR v4;
INT64 v5;
INT64 v6;
UINT64 v7;
__int64 v8;
unsigned __int64 v9;
unsigned __int64 v10;
INT64 result;
char *v12;
int v13;
INT64 v14;
__int16 v15;
UNICODE_STRING *v16;
UNICODE_STRING *v17;
UINT8 v18;
PWCHAR v19;
int v20;
int v21;
INT64 v22;
struct _MDL *v23;
INT64 v24;
unsigned int v25;
ULONG_PTR v26;
__int64 v27;
_QWORD *v28;
unsigned __int64 v29;
unsigned __int8 CurrentIrql;
__int64 v31;
char *v32;
unsigned int v33;
__int64 v34;
INT64 v35;
unsigned __int64 v36;
unsigned __int64 v37;
INT64 a5;
int v39;
UINT64 v40;
UINT64 SpinCount;
_MMVAD *Vad;
__int64 v43;
PMDL Mdl;
UINT64 v45;
INT64 v46;
ULONG_PTR v47;
ULONG_PTR v48;
unsigned __int64 v49;
void *ContainingSubsection[9];
UINT8 v54;
_QWORD *v55;
v46 = 0i64;
ContainingSubsection[0] = 0i64;
v4 = *((_QWORD *)KeGetCurrentThread() + 23);
v47 = v4;
v48 = v4;
v5 = v4 + 1664;
v6 = *a1;
Vad = (_MMVAD *)v6;
Mdl = 0i64;
v7 = (UINT64)MmGetPteBase() + ((a2 >> 9) & 0x7FFFFFFFF8i64);
v45 = v7 + 8 * (a3 - 1);
v8 = 0i64;
v43 = 0i64;
v9 = MiCountSharedPages(v6, v7, v45);
v10 = v9;
v49 = v9;
if( v9 )
{
result = MiChargeFullProcessCommitment(v4, v9);
if( (int)result < 0 )
return result;
}
v40 = a2;
v12 = 0i64;
v13 = 1;
v39 = 1;
v54 = MiLockWorkingSetShared(v5);
while( v7 <= v45 )
{
if( v13 || (v7 & 0xFFF) == 0 )
{
if( v12 )
MiUnlockPageTableInternal(v5, (UINT64)v12);
v12 = (char *)MmGetPteBase() + ((v7 >> 9) & 0x7FFFFFFFF8i64);
MiMakeSystemAddressValid(v7, 0i64, (*(_DWORD *)(v6 + 48) >> 12) & 0x3F, v54, 0);
v39 = 0;
}
v14 = MI_READ_PTE_LOCK_FREE(v7);
v15 = v14;
v46 = v14;
if( (*(_BYTE *)v7 & 1) != 0 )
{
v16 = (UNICODE_STRING *)((char *)MmGetPfnDb()
+ 48 * (((unsigned __int64)MI_READ_PTE_LOCK_FREE((INT64)&v46) >> 12) & 0xFFFFFFFFFi64));
LOBYTE(v20) = MI_PFN_IS_PROTO(v16, v17, v18, v19);
if( v20
&& (((__int64)v16[2].Buffer & 0x1000000000i64) != 0 || (__int64)v16->Buffer <= 0)
&& (_MMPTE *)((unsigned __int64)v16->Buffer | 0x8000000000000000ui64) == MiGetProtoPteAddress(
Vad,
v40 >> 12,
0i64,
(_SUBSECTION **)ContainingSubsection) )
{
v21 = MiCopyOnWrite(v40, (UINT64 *)v7, -1i64, 0i64);
if( v21 >= 0 )
{
if( (v15 & 0x200) == 0 )
v43 = ++v8;
goto LABEL_20;
}
MiUnlockPageTableInternal(v5, (UINT64)v12);
MiUnlockWorkingSetShared(v5, v54);
v12 = 0i64;
MiCopyOnWriteCheckConditions(v5, (unsigned int)v21);
v13 = 1;
v39 = 1;
MiLockWorkingSetShared(v5);
v6 = (INT64)Vad;
}
else
{
LABEL_20:
v7 += 8i64;
v40 += 4096i64;
v6 = (INT64)Vad;
v13 = v39;
}
}
else
{
MiUnlockPageTableInternal(v5, (UINT64)v12);
MiUnlockWorkingSetShared(v5, v54);
v12 = 0i64;
v13 = 1;
v39 = 1;
MiLockWorkingSetShared(v5);
}
}
MiUnlockPageTableInternal(v5, (UINT64)v12);
MiUnlockWorkingSetShared(v5, v54);
v22 = a3;
v23 = IoAllocateMdl((PVOID)a2, (_DWORD)a3 << 12, 0, 0, 0i64);
v24 = (INT64)v23;
Mdl = v23;
if( v23 )
{
MiProbeAndLockPages((INT64)v23, 0, 0i64);
*(_WORD *)(v24 + 10) |= 0x80u;
v27 = 0i64;
v28 = (_QWORD *)(v24 + 48);
v55 = (_QWORD *)(v24 + 48);
v29 = v24 + 8 * (a3 + 6);
v45 = v29;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( v24 + 48 < v29 )
{
do
{
v31 = v27;
v32 = (char *)MmGetPfnDb() + 48 * *v28;
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)v32 + 6, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( *((__int64 *)v32 + 3) < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)v32 + 6, 0x3Fui64) );
v28 = v55;
v29 = v45;
v31 = v27;
}
v33 = ((*((_QWORD *)v32 + 3) & 0x3FFFFFFFFFFFFFFFi64) != 0) + 2;
if( (v32[34] & 8) == 0 )
v33 = ((*((_QWORD *)v32 + 3) & 0x3FFFFFFFFFFFFFFFi64) != 0) + 1;
v27 = v31 + 1;
if( *((unsigned __int16 *)v32 + 16) <= v33 )
v27 = v31;
_InterlockedAnd64((volatile signed __int64 *)v32 + 3, 0x7FFFFFFFFFFFFFFFui64);
v55 = ++v28;
}
while( (unsigned __int64)v28 < v29 );
v22 = a3;
}
__writecr8(CurrentIrql);
if( v27 )
{
v34 = *(_QWORD *)(***(_QWORD ***)(v6 + 72) + 56i64);
LODWORD(a5) = v27;
MiLogHotPatchPagesLocked(a2, (v22 << 12) + a2 - 1, *(unsigned int *)(v34 + 60), *(unsigned int *)(v34 + 72), a5);
}
v35 = a1[7];
if( v35 )
*(_QWORD *)v24 = v35;
a1[7] = v24;
v25 = 0;
}
else
{
v25 = -1073741670;
}
v26 = v47;
if( v8 )
{
v36 = v8 + (*(_DWORD *)(v6 + 52) & 0x7FFFFFFF | ((unsigned __int64)*(unsigned __int8 *)(v6 + 34) << 31));
*(_DWORD *)(v6 + 52) ^= (*(_DWORD *)(v6 + 52) ^ (v8
+ (*(_DWORD *)(v6 + 52) & 0x7FFFFFFF | (*(unsigned __int8 *)(v6 + 34) << 31)))) & 0x7FFFFFFF;
*(_BYTE *)(v6 + 34) = v36 >> 31;
}
v37 = v10 - v8;
if( v37 )
MiReturnFullProcessCommitment(v26, v37);
return v25;
}Referenced by:
MiPrepareToHotPatchImage