MiCopyToUserVa
VOID __fastcall MiCopyToUserVa(VOID *Va, _MMVAD *Vad, VOID *SourceAddress, UINT64 NumberOfBytes){
_EPROCESS *Process;
signed __int64 v5;
int v6;
unsigned int v7;
UINT8 v8;
UINT8 v9;
INT64 v10;
UINT64 v11;
unsigned __int64 v12;
__int64 v13;
_UNICODE_STRING *v14;
UINT8 v15;
PWCHAR v16;
int v17;
__int64 v18;
_MMCLONE_DESCRIPTOR *CloneAddress;
UINT64 v20;
INT64 v21;
unsigned __int64 v22;
UINT64 v23;
char *v24;
UINT64 v25;
INT64 v26;
char v27;
INT64 v28;
int v29;
_KTBFLUSH_TYPE v30;
UINT64 v31;
UINT64 Flags;
UINT8 WsIrql;
int v34;
INT64 v35;
INT64 *a2;
UINT64 v37;
_MMCLONE_DESCRIPTOR *v38;
_MMPFN *Pfn1;
_EPROCESS *TargetProcess;
size_t Size;
Size = NumberOfBytes;
Process = KeGetCurrentThread()->ApcState.Process;
TargetProcess = Process;
v5 = (signed __int64)MmGetPteBase() + (((unsigned __int64)Va >> 9) & 0x7FFFFFFFF8i64);
a2 = (INT64 *)v5;
v6 = 0;
v34 = 0;
v7 = (Vad->Core.u.LongFlags >> 12) & 0x3F;
LABEL_2:
MiLockWorkingSetShared();
LABEL_3:
v9 = v8;
for( WsIrql = v8; ; v9 = WsIrql )
{
v37 = (UINT64)MmGetPteBase() + (((unsigned __int64)v5 >> 9) & 0x7FFFFFFFF8i64);
LODWORD(Flags) = 0;
MiMakeSystemAddressValid((VOID *)v5, 0i64, v7, v9, Flags);
LODWORD(v10) = MI_READ_PTE_LOCK_FREE(v5);
v35 = v10;
if( (v10 & 1) == 0 )
{
MiUnlockPageTable((INT64)&Process->Vm, v37);
LOBYTE(v11) = WsIrql;
MiUnlockWorkingSetShared(&Process->Vm.Instance, v11);
goto LABEL_2;
}
LODWORD(v12) = MI_READ_PTE_LOCK_FREE((INT64)&v35);
v13 = (v12 >> 12) & 0xFFFFFFFFFi64;
Pfn1 = &MmGetPfnDb()[v13];
LOBYTE(v17) = MI_PFN_IS_PROTO((_UNICODE_STRING *)Pfn1, v14, v15, v16);
if( !v17 )
break;
v38 = 0i64;
if( (*(_QWORD *)(v18 + 40) & 0x1000000000i64) != 0 || *(__int64 *)(v18 + 8) <= 0 )
{
if( Process->CloneRoot.Root )
{
CloneAddress = MiLocateCloneAddress(Process, (VOID *)(*(_QWORD *)(v18 + 8) | 0x8000000000000000ui64));
v38 = CloneAddress;
if( CloneAddress )
{
if( Process->Vm.Instance.VmWorkingSetList[9].NextPteToTrim <= (_MMPTE *)CloneAddress->NestingLevel )
{
v38 = 0i64;
}
else if( !v6 )
{
MiUnlockPageTable((INT64)&Process->Vm, v37);
LOBYTE(v20) = WsIrql;
MiUnlockWorkingSetShared(&Process->Vm.Instance, v20);
if( MiChargeFullProcessCommitment((ULONG_PTR)Process, 1ui64) < 0 )
goto LABEL_34;
v6 = 1;
v34 = 1;
MiLockWorkingSetShared();
v5 = (signed __int64)a2;
goto LABEL_3;
}
}
}
}
v5 = (signed __int64)a2;
LODWORD(v35) = MiCopyOnWrite((UINT64)Va, a2, 0xFFFFFFFFFFFFFFFFui64, 0i64);
if( (int)v35 >= 0 )
{
LODWORD(v21) = MI_READ_PTE_LOCK_FREE(v5);
v35 = v21;
LODWORD(v22) = MI_READ_PTE_LOCK_FREE((INT64)&v35);
v13 = (v22 >> 12) & 0xFFFFFFFFFi64;
Pfn1 = &MmGetPfnDb()[v13];
if( v38 )
v6 = 0;
v34 = v6;
break;
}
MiUnlockPageTable((INT64)&Process->Vm, v37);
LOBYTE(v25) = WsIrql;
MiUnlockWorkingSetShared(&Process->Vm.Instance, v25);
MiCopyOnWriteCheckConditions((INT64)&Process->Vm, (unsigned int)v35);
MiLockWorkingSetShared();
}
v23 = (UINT64)MiReservePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), 1ui64);
if( v23 )
{
a2 = (INT64 *)((__int64)((v23 << 25) - ((_QWORD)MmGetPteBase() << 25)) >> 16);
LODWORD(v26) = MiMakeValidPte((_XSTATE_CONFIGURATION *)v23, v13, 2684354564i64);
v27 = v26;
v35 = v26;
v28 = v26;
LOBYTE(v29) = MiPteInShadowRange(v23);
if( v29 && (KeGetCurrentThread()->ApcState.Process->Flags3 & 0x1000) != 0 && (v27 & 1) != 0 )
v28 |= 0x8000000000000000ui64;
*(_QWORD *)v23 = v28;
v24 = (char *)a2;
}
else
{
v24 = (char *)MiMapPageInHyperSpaceWorker(v13, 0i64, 0x80000000ui64);
}
memmove(&v24[(unsigned __int16)Va & 0xFFF], SourceAddress, Size);
if( v23 )
MiReleasePtes((_MI_SYSTEM_PTE_TYPE *)((char *)&stru_140C4DB30 + 4432), (_MMPTE *)v23, 1ui64, v30);
else
MiUnmapPageInHyperSpaceWorker(v24, 0x11u, 0x80000000ui64);
MiLockPageAndSetDirty(Pfn1, (VOID *)1);
v31 = v37;
if( v37 )
MiUnlockPageTable((INT64)&Process->Vm, v37);
LOBYTE(v31) = WsIrql;
MiUnlockWorkingSetShared(&Process->Vm.Instance, v31);
v6 = v34;
LABEL_34:
if( v6 )
MiReturnFullProcessCommitment(Process, 1ui64);
}Referenced by:
MiCopyToCfgBitMap