MmCopyVirtualMemory
VOID __fastcall MmCopyVirtualMemory(
_EPROCESS *FromProcess,
const VOID *FromAddress,
_EPROCESS *ToProcess,
VOID *ToAddress,
UINT64 BufferSize,
CHAR PreviousMode,
UINT64 *NumberOfBytesRead){
char *v8;
unsigned int v9;
__int64 v10;
UINT64 v11;
int v12;
ULONG_PTR v13;
char NextEnclaveBoundary;
int v15;
unsigned __int8 v16;
UINT64 v17;
unsigned __int64 v18;
char i;
__int64 v20;
VOID *v21;
int v22;
$66B5187701DB455CD8F8862345C5A268 *v23;
unsigned __int8 v24;
int v25;
NTSTATUS v26;
VOID *v27;
char *v28;
int v29;
NTSTATUS v30;
INT64 v31;
INT64 v32;
bool v33;
INT64 v34;
INT64 v35;
UINT64 *ReturnedBytesTransferred;
UINT64 Priority;
int v38;
char *Buffer;
int v40;
UINT64 v41;
VOID *EnclaveAddress;
char *v43;
UINT64 v44;
ULONG_PTR Process[2];
int v46;
UINT64 *v47;
ULONG_PTR v48[2];
UINT64 v49;
char *v50;
unsigned __int64 v51;
VOID *Src;
int v53;
UINT64 v54;
VOID *v55;
UINT64 BytesToNextBoundary;
UINT64 v57[5];
_ETHREAD *CurrentThread;
$66B5187701DB455CD8F8862345C5A268 *v59;
__int64 v60;
INT64 v61;
_KAPC_STATE ApcState;
char MemoryDescriptorList[168];
char v64[512];
v43 = (char *)ToAddress;
*(_QWORD *)v48 = ToProcess;
v8 = (char *)FromAddress;
v50 = (char *)FromAddress;
*(_QWORD *)Process = FromProcess;
v57[3] = (UINT64)FromProcess;
v57[1] = (UINT64)FromAddress;
v57[2] = (UINT64)ToProcess;
v55 = ToAddress;
v54 = BufferSize;
v47 = NumberOfBytesRead;
memset(&ApcState, 0, sizeof(ApcState));
memset(MemoryDescriptorList, 0i64, sizeof(MemoryDescriptorList));
v41 = 0i64;
if( !BufferSize )
return;
*v47 = 0i64;
v9 = 0;
v51 = 0i64;
v10 = *(_QWORD *)Process;
if( !*(_QWORD *)(*(_QWORD *)Process + 1264i64) )
v9 = 1;
Src = v8;
EnclaveAddress = ToAddress;
v11 = BufferSize;
v49 = BufferSize;
v61 = (INT64)MemoryDescriptorList;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v38 = 0;
Buffer = 0i64;
v57[4] = 0i64;
v46 = 0;
BytesToNextBoundary = BufferSize;
v57[0] = BufferSize;
LABEL_5:
v12 = ((unsigned __int8)v9 ^ (unsigned __int8)(2 * v9)) & 2 ^ v9;
if( (*(_BYTE *)(v10 + 992) & 1) != 0 )
v12 |= 0x40u;
v13 = v48[0];
if( (*(_BYTE *)(*(_QWORD *)v48 + 992i64) & 1) != 0 )
v12 |= 0x80u;
NextEnclaveBoundary = MiFindNextEnclaveBoundary(v10, &v8[BufferSize - v11], v11, &BytesToNextBoundary);
v15 = 4 * (NextEnclaveBoundary & 3 | (4 * (MiFindNextEnclaveBoundary(v13, &v43[BufferSize - v11], v11, v57) & 3)));
v16 = v12 & 0xC3;
v9 = v12 & 0xFFFFFFC3 | v15;
if( ((v16 | (unsigned __int8)v15) & 0xC0) != 0 || (v9 & 0xC) != 0 )
v9 &= ~2u;
v17 = v11;
v44 = v11;
if( BytesToNextBoundary < v11 )
{
v17 = BytesToNextBoundary;
v44 = BytesToNextBoundary;
}
if( v57[0] < v17 )
{
v17 = v57[0];
v44 = v57[0];
}
LABEL_15:
if( v17 >= 0x200 && (v9 & 2) != 0 )
{
v18 = 57344i64;
v33 = BufferSize <= 0xE000;
goto LABEL_73;
}
v9 &= ~2u;
if( v51 )
{
v18 = v17;
if( v17 > v51 )
v18 = v51;
goto LABEL_20;
}
if( v17 > 0x200 )
{
v18 = 0x10000i64;
if( v11 <= 0x10000 )
v18 = v11;
do
{
Buffer = (char *)MiAllocatePool(256i64, v18, 0x77526D4Dui64);
if( Buffer )
{
v51 = v18;
goto LABEL_86;
}
v18 >>= 1;
}
while( v18 > 0x200 );
Buffer = v64;
v18 = 512i64;
LABEL_86:
v33 = v17 <= v18;
LABEL_73:
if( !v33 )
goto LABEL_20;
goto LABEL_19;
}
Buffer = v64;
LABEL_19:
v18 = v17;
LABEL_20:
for( i = v9; ; i = v9 )
{
v10 = *(_QWORD *)Process;
if( !v17 )
{
v8 = v50;
if( v11 )
goto LABEL_5;
if( v51 )
ExFreePoolWithTag(Buffer, 0);
*v47 = BufferSize;
return;
}
v20 = v17;
if( v17 >= v18 )
v20 = v18;
v18 = v20;
v60 = v20;
KiStackAttachProcess(*(PVOID *)Process, 0i64, &ApcState);
v21 = Src;
if( PreviousMode
&& Src == v50
&& ((unsigned __int64)&v50[BufferSize] > 0x7FFFFFFF0000i64 || &v50[BufferSize] < v50) )
{
MEMORY[0x7FFFFFFF0000] = 0;
}
v22 = i & 2;
v40 = v22;
v53 = v22;
if( (i & 2) != 0 )
{
*(_QWORD *)MemoryDescriptorList = 0i64;
*(_WORD *)&MemoryDescriptorList[8] = 8 * (((v18 + ((unsigned __int16)Src & 0xFFF) + 4095i64) >> 12) + 6);
*(_WORD *)&MemoryDescriptorList[10] = 0;
*(_QWORD *)&MemoryDescriptorList[32] = (unsigned __int64)Src & 0xFFFFFFFFFFFFF000ui64;
*(_DWORD *)&MemoryDescriptorList[44] = (unsigned __int16)Src & 0xFFF;
*(_DWORD *)&MemoryDescriptorList[40] = v18;
v22 = i & 2;
}
v23 = &CurrentThread->Tcb.116;
v59 = &CurrentThread->Tcb.116;
v24 = _bittestandset((signed __int32 *)&CurrentThread->Tcb.116, 5u);
if( v22 )
{
MmProbeAndLockPages((PMDL)MemoryDescriptorList, (unsigned __int8)PreviousMode, IoReadAccess);
v25 = v38;
}
else
{
if( (v9 & 0x40) != 0 || (v9 & 0xC) == 8 )
{
v26 = VslDebugReadWriteSecureProcess(*(__int64 *)Process, (__int64)v21, (INT64)Buffer, v18, 1u, &v41);
}
else
{
if( (v9 & 0xC) != 4 )
{
memmove(Buffer, v21, v18);
v25 = v38;
goto LABEL_40;
}
v26 = MiDbgReadWriteEnclave(v21, Buffer, v18, 1ui64, &v41);
}
v38 = v26;
v25 = v26;
}
LABEL_40:
if( !v24 )
v23->_bf_0 &= ~0x20u;
if( v25 < 0 )
{
if( !v40 )
{
*v47 = BufferSize - v17;
goto LABEL_79;
}
LABEL_87:
v9 &= ~2u;
KiUnstackDetachProcess(&ApcState, 0i64);
v11 = v49;
goto LABEL_15;
}
if( v40 )
{
LODWORD(Priority) = -1073741792;
LODWORD(ReturnedBytesTransferred) = 0;
v27 = MmMapLockedPagesSpecifyCache(
(_MDL *)MemoryDescriptorList,
0,
MmCached,
0i64,
(UINT64)ReturnedBytesTransferred,
Priority);
if( !v27 )
{
MmUnlockPages((INT64)MemoryDescriptorList, v34, v35);
goto LABEL_87;
}
}
else
{
v27 = Buffer;
}
KiUnstackDetachProcess(&ApcState, 0i64);
KiStackAttachProcess(*(PVOID *)v48, 0i64, &ApcState);
if( PreviousMode && Src == v50 )
{
v28 = v43;
if( (unsigned __int64)&v43[BufferSize] > 0x7FFFFFFF0000i64 || &v43[BufferSize] < v43 )
MEMORY[0x7FFFFFFF0000] = 0;
}
else
{
v28 = v43;
}
if( (v9 & 0x80u) != 0 || (v9 & 0x30) == 32 )
{
v30 = VslDebugReadWriteSecureProcess(*(__int64 *)v48, (__int64)EnclaveAddress, (INT64)Buffer, v18, 0, &v41);
}
else
{
if( (v9 & 0x30) != 16 )
{
memmove(EnclaveAddress, v27, v18);
v29 = 0;
v38 = 0;
v41 = v18;
goto LABEL_54;
}
v30 = MiDbgReadWriteEnclave(EnclaveAddress, Buffer, v18, 0i64, &v41);
}
v38 = v30;
v29 = v30;
LABEL_54:
if( v29 == -1073741819 )
break;
if( v29 < 0 )
goto LABEL_79;
KiUnstackDetachProcess(&ApcState, 0i64);
if( v40 )
MmUnlockPages((INT64)MemoryDescriptorList, v31, v32);
v17 -= v18;
v44 = v17;
v11 = v49 - v18;
v49 -= v18;
Src = (char *)Src + v18;
EnclaveAddress = (char *)EnclaveAddress + v18;
}
*v47 = (UINT64)EnclaveAddress + v41 - (_QWORD)v28;
LABEL_79:
KiUnstackDetachProcess(&ApcState, 0i64);
if( v51 )
ExFreePoolWithTag(Buffer, 0);
}Referenced by:
KiTpWriteUmMemory
LpcpCopyRequestData
MiReadWriteVirtualMemory
NtQueryInformationProcess
NtQueryInformationThread
PsQueryProcessCommandLine