MiPrepareImagePagesForHotPatch
NTSTATUS __stdcall MiPrepareImagePagesForHotPatch(INT64 *a1, UINT64 a2, INT64 a3){
_EPROCESS *Process;
_MMSUPPORT_INSTANCE *p_Instance;
_MMVAD *v6;
unsigned __int64 v7;
__int64 v8;
UINT64 v9;
UINT64 v10;
NTSTATUS result;
char *v12;
int v13;
UINT8 v14;
INT64 v15;
__int16 v16;
UINT64 v17;
unsigned __int64 v18;
_MMPFN *v19;
_UNICODE_STRING *v20;
UINT8 v21;
PWCHAR v22;
int v23;
__int64 v24;
NTSTATUS v25;
UINT64 v26;
UINT64 v27;
INT64 v28;
_MDL *v29;
INT64 v30;
NTSTATUS v31;
_EPROCESS *v32;
__int64 v33;
_MMPTE *v34;
_MMPTE *v35;
unsigned __int8 CurrentIrql;
__int64 v37;
_MMPFN *v38;
unsigned int v39;
union {_MI_SECTION_IMAGE_INFORMATION *ImageInformation;void *FirstMappedVa;} v40;
INT64 v41;
unsigned __int64 v42;
UINT64 v43;
UINT64 v44;
int v45;
UINT64 rcx0a;
UINT64 SpinCount;
_MMVAD *v48;
__int64 v49;
PMDL Mdl;
_MMPTE *v51;
INT64 v52;
_EPROCESS *v53;
_EPROCESS *TargetProcess;
UINT64 v55;
__int64 v56;
UINT8 WsIrql;
_MMPTE *WsIrqla;
v52 = 0i64;
v56 = 0i64;
Process = KeGetCurrentThread()->ApcState.Process;
v53 = Process;
TargetProcess = Process;
p_Instance = &Process->Vm.Instance;
v6 = (_MMVAD *)*a1;
v48 = v6;
Mdl = 0i64;
v7 = (unsigned __int64)MmGetPteBase() + ((a2 >> 9) & 0x7FFFFFFFF8i64);
v51 = (_MMPTE *)(v7 + 8 * (a3 - 1));
v8 = 0i64;
v49 = 0i64;
LODWORD(v9) = MiCountSharedPages(v6, (_MMPTE *)v7, v51);
v10 = v9;
v55 = v9;
if( v9 )
{
result = MiChargeFullProcessCommitment((ULONG_PTR)Process, v9);
if( result < 0 )
return result;
}
rcx0a = a2;
v12 = 0i64;
v13 = 1;
v45 = 1;
MiLockWorkingSetShared();
WsIrql = v14;
while( v7 <= (unsigned __int64)v51 )
{
if( v13 || (v7 & 0xFFF) == 0 )
{
if( v12 )
MiUnlockPageTableInternal((INT64)p_Instance, (UINT64)v12);
v12 = (char *)MmGetPteBase() + ((v7 >> 9) & 0x7FFFFFFFF8i64);
LODWORD(v44) = 0;
MiMakeSystemAddressValid((VOID *)v7, 0i64, (v6->Core.u.LongFlags >> 12) & 0x3F, WsIrql, v44);
v45 = 0;
}
LODWORD(v15) = MI_READ_PTE_LOCK_FREE(v7);
v16 = v15;
v52 = v15;
if( (*(_BYTE *)v7 & 1) != 0 )
{
LODWORD(v18) = MI_READ_PTE_LOCK_FREE((INT64)&v52);
v19 = &MmGetPfnDb()[(v18 >> 12) & 0xFFFFFFFFFi64];
LOBYTE(v23) = MI_PFN_IS_PROTO((_UNICODE_STRING *)v19, v20, v21, v22);
if( v23
&& ((v19->u4._bf_0 & 0x1000000000i64) != 0 || (__int64)v19->ListEntry.Blink <= 0)
&& (MiGetProtoPteAddress(), (v19->PteLong | 0x8000000000000000ui64) == v24) )
{
v25 = MiCopyOnWrite(rcx0a, (INT64 *)v7, 0xFFFFFFFFFFFFFFFFui64, 0i64);
if( v25 >= 0 )
{
if( (v16 & 0x200) == 0 )
v49 = ++v8;
goto LABEL_20;
}
MiUnlockPageTableInternal((INT64)p_Instance, (UINT64)v12);
LOBYTE(v26) = WsIrql;
MiUnlockWorkingSetShared(p_Instance, v26);
v12 = 0i64;
MiCopyOnWriteCheckConditions((INT64)p_Instance, (unsigned int)v25);
v13 = 1;
v45 = 1;
MiLockWorkingSetShared();
v6 = v48;
}
else
{
LABEL_20:
v7 += 8i64;
rcx0a += 4096i64;
v6 = v48;
v13 = v45;
}
}
else
{
MiUnlockPageTableInternal((INT64)p_Instance, (UINT64)v12);
LOBYTE(v17) = WsIrql;
MiUnlockWorkingSetShared(p_Instance, v17);
v12 = 0i64;
v13 = 1;
v45 = 1;
MiLockWorkingSetShared();
}
}
MiUnlockPageTableInternal((INT64)p_Instance, (UINT64)v12);
LOBYTE(v27) = WsIrql;
MiUnlockWorkingSetShared(p_Instance, v27);
v28 = a3;
v29 = IoAllocateMdl((VOID *)a2, (unsigned int)((_DWORD)a3 << 12), 0, 0, 0i64);
v30 = (INT64)v29;
Mdl = v29;
if( v29 )
{
MiProbeAndLockPages((INT64)v29, 0, 0i64);
*(_WORD *)(v30 + 10) |= 0x80u;
v33 = 0i64;
v34 = (_MMPTE *)(v30 + 48);
WsIrqla = (_MMPTE *)(v30 + 48);
v35 = (_MMPTE *)(v30 + 8 * (a3 + 6));
v51 = v35;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
if( v30 + 48 < (unsigned __int64)v35 )
{
do
{
v37 = v33;
v38 = &MmGetPfnDb()[v34->u.Long];
LODWORD(SpinCount) = 0;
if( _interlockedbittestandset64((volatile signed __int32 *)&v38->u2, 0x3Fui64) )
{
do
{
do
KeYieldProcessorEx(&SpinCount);
while( v38->u2._bf_0 < 0 );
}
while( _interlockedbittestandset64((volatile signed __int32 *)&v38->u2, 0x3Fui64) );
v34 = WsIrqla;
v35 = v51;
v37 = v33;
}
v39 = ((v38->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) != 0) + 2;
if( (*(_BYTE *)(&v38->u3 + 1) & 8) == 0 )
v39 = ((v38->u2._bf_0 & 0x3FFFFFFFFFFFFFFFi64) != 0) + 1;
v33 = v37 + 1;
if( v38->u3.ReferenceCount <= v39 )
v33 = v37;
_InterlockedAnd64(&v38->u2.Lock, 0x7FFFFFFFFFFFFFFFui64);
WsIrqla = ++v34;
}
while( v34 < v35 );
v28 = a3;
}
__writecr8(CurrentIrql);
if( v33 )
{
v40.ImageInformation = (_MI_SECTION_IMAGE_INFORMATION *)v6->Subsection->ControlArea->Segment->u2;
MiLogHotPatchPagesLocked(
a2,
(v28 << 12) + a2 - 1,
v40.ImageInformation->ExportedImageInformation.CheckSum,
v40.ImageInformation->InternalImageInformation.TimeDateStamp,
v33);
}
v41 = a1[7];
if( v41 )
*(_QWORD *)v30 = v41;
a1[7] = v30;
v31 = 0;
}
else
{
v31 = -1073741670;
}
v32 = v53;
if( v8 )
{
v42 = v8 + (v6->Core.u1.LongFlags1 & 0x7FFFFFFF | ((unsigned __int64)v6->Core.CommitChargeHigh << 31));
v6->Core.u1.LongFlags1 ^= (v6->Core.u1.LongFlags1 ^ (v8
+ (v6->Core.u1.LongFlags1 & 0x7FFFFFFF | (v6->Core.CommitChargeHigh << 31)))) & 0x7FFFFFFF;
v6->Core.CommitChargeHigh = v42 >> 31;
}
v43 = v10 - v8;
if( v43 )
MiReturnFullProcessCommitment(v32, v43);
return v31;
}Referenced by:
MiPrepareToHotPatchImage