PspWow64ReadOrWriteThreadCpuArea
INT64 __stdcall PspWow64ReadOrWriteThreadCpuArea(
_EPROCESS *TargetProcess,
_ETHREAD *TargetThread,
UINT8 ReadCpuContext,
PVOID CpuAreaContext,
UINT64 CpuAreaContextLength,
UINT64 CpuAreaContextAlignment,
UINT64 *CpuAreaFlags,
UINT8 *SoftwareCpu,
UINT16 Machine){
_ETHREAD *CurrentThread;
INT64 *v13;
__int64 ThreadTeb;
__int64 v15;
__int64 v16;
_OWORD *v17;
__int64 v18;
__int64 v19;
__int64 v20;
_OWORD *v21;
__int64 v22;
__int64 v23;
_ETHREAD *v24;
_ETHREAD *v26;
int CpuAreaInfo;
__int64 v29;
volatile void *Address[2];
__int128 v31;
__int128 v32;
__int64 v33;
_KAPC_STATE ApcState;
memset(&ApcState, 0, sizeof(ApcState));
*(_OWORD *)Address = 0i64;
v31 = 0i64;
v32 = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)CurrentThread + 242);
v13 = (INT64 *)((char *)TargetThread + 1280);
ExAcquirePushLockSharedEx((UINT64)TargetThread + 1280, 0i64);
ThreadTeb = PsGetThreadTeb((__int64)TargetThread);
v29 = ThreadTeb;
if( ThreadTeb )
{
KiStackAttachProcess((_KPROCESS *)TargetProcess, 0i64, &ApcState);
v16 = *(_QWORD *)(ThreadTeb + 5256);
v33 = v16;
if( v16 )
{
CpuAreaInfo = RtlWow64GetCpuAreaInfo(v16, v15, (__int64)Address);
if( CpuAreaInfo >= 0 )
{
if( ReadCpuContext )
{
v17 = Address[0];
if( ((__int64)Address[0] & 3) != 0 )
ExRaiseDatatypeMisalignment();
if( (unsigned __int64)Address[0] + 716 > 0x7FFFFFFF0000i64 || (char *)Address[0] + 716 < Address[0] )
MEMORY[0x7FFFFFFF0000] = 0;
v18 = 5i64;
do
{
*(_OWORD *)CpuAreaContext = *v17;
*((_OWORD *)CpuAreaContext + 1) = v17[1];
*((_OWORD *)CpuAreaContext + 2) = v17[2];
*((_OWORD *)CpuAreaContext + 3) = v17[3];
*((_OWORD *)CpuAreaContext + 4) = v17[4];
*((_OWORD *)CpuAreaContext + 5) = v17[5];
*((_OWORD *)CpuAreaContext + 6) = v17[6];
CpuAreaContext = (char *)CpuAreaContext + 128;
*((_OWORD *)CpuAreaContext - 1) = v17[7];
v17 += 8;
--v18;
}
while( v18 );
*(_OWORD *)CpuAreaContext = *v17;
*((_OWORD *)CpuAreaContext + 1) = v17[1];
*((_OWORD *)CpuAreaContext + 2) = v17[2];
*((_OWORD *)CpuAreaContext + 3) = v17[3];
*((_QWORD *)CpuAreaContext + 8) = *((_QWORD *)v17 + 8);
*((_DWORD *)CpuAreaContext + 18) = *((_DWORD *)v17 + 18);
if( CpuAreaFlags )
{
v20 = *((_QWORD *)&v31 + 1);
if( *((_QWORD *)&v31 + 1) >= 0x7FFFFFFF0000ui64 )
v20 = 0x7FFFFFFF0000i64;
*(_DWORD *)CpuAreaFlags = *(_DWORD *)v20;
}
}
else
{
v21 = Address[0];
ProbeForWrite((VOID *)Address[0], 0x2CCui64, 4ui64);
v22 = 5i64;
do
{
*v21 = *(_OWORD *)CpuAreaContext;
v21[1] = *((_OWORD *)CpuAreaContext + 1);
v21[2] = *((_OWORD *)CpuAreaContext + 2);
v21[3] = *((_OWORD *)CpuAreaContext + 3);
v21[4] = *((_OWORD *)CpuAreaContext + 4);
v21[5] = *((_OWORD *)CpuAreaContext + 5);
v21[6] = *((_OWORD *)CpuAreaContext + 6);
v21 += 8;
*(v21 - 1) = *((_OWORD *)CpuAreaContext + 7);
CpuAreaContext = (char *)CpuAreaContext + 128;
--v22;
}
while( v22 );
*v21 = *(_OWORD *)CpuAreaContext;
v21[1] = *((_OWORD *)CpuAreaContext + 1);
v21[2] = *((_OWORD *)CpuAreaContext + 2);
v21[3] = *((_OWORD *)CpuAreaContext + 3);
*((_QWORD *)v21 + 8) = *((_QWORD *)CpuAreaContext + 8);
*((_DWORD *)v21 + 18) = *((_DWORD *)CpuAreaContext + 18);
ThreadTeb = v29;
if( CpuAreaFlags )
{
v23 = *((_QWORD *)&v31 + 1);
if( *((_QWORD *)&v31 + 1) >= 0x7FFFFFFF0000ui64 )
v23 = 0x7FFFFFFF0000i64;
*(_DWORD *)v23 = *(_DWORD *)CpuAreaFlags;
}
}
if( SoftwareCpu )
{
v19 = *(_QWORD *)(ThreadTeb + 5328);
if( v19 )
{
if( (v19 & 3) != 0 )
ExRaiseDatatypeMisalignment();
if( (unsigned __int64)(v19 + 8) > 0x7FFFFFFF0000i64 || v19 + 8 < (unsigned __int64)(v19 + 4) )
MEMORY[0x7FFFFFFF0000] = 0;
*SoftwareCpu = (*(_DWORD *)(v19 + 4) & 2) != 0;
}
else
{
*SoftwareCpu = 0;
}
}
}
}
else
{
CpuAreaInfo = -1073741811;
}
KiUnstackDetachProcess(&ApcState, 0i64);
v24 = (_ETHREAD *)KeGetCurrentThread();
if( _InterlockedCompareExchange64(v13, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v13);
KeAbPostRelease(v13);
KeLeaveCriticalRegionThread((__int64)v24);
return(unsigned int)CpuAreaInfo;
}
else
{
v26 = (_ETHREAD *)KeGetCurrentThread();
if( _InterlockedCompareExchange64(v13, 0i64, 17i64) != 17 )
ExfReleasePushLockShared(v13);
KeAbPostRelease(v13);
KeLeaveCriticalRegionThread((__int64)v26);
return 3221225547i64;
}
}Referenced by:
PspWow64GetContextThread
PspWow64SetContextThread