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