PspWow64SetContextThread

NTSTATUS __stdcall PspWow64SetContextThread(_ETHREAD *Thread){
  _TRANSACTION_NOTIFICATION *v1; 
  int v2; 
  INT8 v3; 
  INT8 v4; 
  int v5; 
  _TRANSACTION_NOTIFICATION *v6; 
  _ETHREAD *CurrentThread; 
  ULONG_PTR v9; 
  __int64 v10; 
  __int64 v11; 
  NTSTATUS ExtendedContextLength; 
  bool v13; 
  unsigned int TransactionKey_high; 
  unsigned __int64 v15; 
  signed __int64 v16; 
  void *v17; 
  void *v18; 
  _TRANSACTION_NOTIFICATION *p_ContextFlags; 
  UINT64 *v20; 
  INT64 *v21; 
  __int64 ThreadTeb; 
  char TransactionKey; 
  unsigned __int64 v24; 
  signed __int64 v25; 
  void *v26; 
  void *v27; 
  _LARGE_INTEGER *v28; 
  bool v29; 
  int v30; 
  _DWORD *v31; 
  ULONG LowPart; 
  UINT64 CpuAreaContextLength; 
  UINT64 *CpuAreaContextLengtha; 
  UINT64 CpuAreaContextLengthb; 
  UINT64 v36; 
  UINT64 v37; 
  UINT64 v38; 
  UINT64 *CpuAreaFlags; 
  UINT16 v40; 
  UINT16 v41; 
  _TRANSACTION_NOTIFICATION ContextFlags; 
  ULONG_PTR BugCheckParameter1; 
  INT64 result; 
  __int16 v45; 
  v4 = v3;
  BYTE2(ContextFlags.TransactionKey) = v3;
  v5 = v2;
  v6 = v1;
  memset((INT64)&result, 0i64);
  memset(&ContextFlags.TransactionNotification, 0, 24);
  LOWORD(ContextFlags.TransactionKey) = 0;
  if( v5 != 716 )
    return -1073741820;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  v9 = *((_QWORD *)Thread + 68);
  BugCheckParameter1 = v9;
  v10 = *(_QWORD *)(v9 + 1408);
  if( !v10 || *(_WORD *)(v10 + 8) != 332 )
    return -1073741811;
  if( v4 )
  {
    v11 = (__int64)v6;
    if( (unsigned __int64)v6 >= 0x7FFFFFFF0000i64 )
      v11 = 0x7FFFFFFF0000i64;
    HIDWORD(ContextFlags.TransactionKey) = *(_DWORD *)v11;
  }
  else
  {
    HIDWORD(ContextFlags.TransactionKey) = v6->TransactionKey;
  }
  ExtendedContextLength = RtlpWow64SanitizeContextFlags((UINT64 *)((char *)&ContextFlags.TransactionKey + 4), v4);
  if( ExtendedContextLength >= 0 )
  {
    v13 = v4 == 0;
    TransactionKey_high = HIDWORD(ContextFlags.TransactionKey);
    if( v13 )
    {
      p_ContextFlags = v6;
      ContextFlags.TmVirtualClock.QuadPart = (LONGLONG)(&v6[22].TransactionNotification + 1);
      goto LABEL_15;
    }
    ExtendedContextLength = RtlGetExtendedContextLength(
                              HIDWORD(ContextFlags.TransactionKey),
                              (UINT64 *)&ContextFlags.TransactionNotification);
    if( ExtendedContextLength >= 0 )
    {
      v15 = ContextFlags.TransactionNotification + 15i64;
      if( v15 <= ContextFlags.TransactionNotification )
        v15 = 0xFFFFFFFFFFFFFF0i64;
      v16 = v15 & 0xFFFFFFFFFFFFFFF0ui64;
      v17 = alloca(v16);
      v18 = alloca(v16);
      p_ContextFlags = &ContextFlags;
      ExtendedContextLength = RtlInitializeExtendedContext(
                                (INT64)&ContextFlags,
                                TransactionKey_high,
                                (LARGE_INTEGER *)&ContextFlags.TmVirtualClock.QuadPart);
      if( ExtendedContextLength >= 0 )
      {
        v36 = 0i64;
        CpuAreaContextLength = (UINT64)v6;
        LOBYTE(v20) = 1;
        ExtendedContextLength = RtlpReadExtendedContext(v21, v20, (BYTE *)ContextFlags.TmVirtualClock.QuadPart);
        if( ExtendedContextLength >= 0 )
        {
LABEL_15:
          if( Thread != CurrentThread
            || (*(_DWORD *)(v9 + 632) & 0x20) == 0
            || ((__int64)p_ContextFlags->TransactionKey & 0x10001) != 65537
            || (ThreadTeb = PsGetThreadTeb((__int64)Thread),
                RtlGuardIsValidWow64StackPointer(HIDWORD(p_ContextFlags[6].TransactionKey), ThreadTeb)) )
          {
            ExtendedContextLength = PspWow64ReadOrWriteThreadCpuArea(
                                      (_EPROCESS *)v9,
                                      Thread,
                                      1u,
                                      &result,
                                      CpuAreaContextLength,
                                      v36,
                                      (UINT64 *)(&ContextFlags.TransactionNotification + 1),
                                      (UINT8 *)&ContextFlags,
                                      v40);
            if( ExtendedContextLength >= 0 )
            {
              TransactionKey = (char)ContextFlags.TransactionKey;
              if( LOBYTE(ContextFlags.TransactionKey) && (TransactionKey_high & 0x10040) == 65600 )
              {
                return -1073741637;
              }
              else
              {
                ExtendedContextLength = RtlGetExtendedContextLength(
                                          0x10001Fui64,
                                          (UINT64 *)&ContextFlags.TransactionNotification);
                if( ExtendedContextLength >= 0 )
                {
                  v24 = ContextFlags.TransactionNotification + 15i64;
                  if( v24 <= ContextFlags.TransactionNotification )
                    v24 = 0xFFFFFFFFFFFFFF0i64;
                  v25 = v24 & 0xFFFFFFFFFFFFFFF0ui64;
                  v26 = alloca(v25);
                  v27 = alloca(v25);
                  ExtendedContextLength = RtlInitializeExtendedContext(
                                            (INT64)&ContextFlags,
                                            0x10001Fui64,
                                            &ContextFlags.ArgumentLength);
                  if( ExtendedContextLength >= 0 )
                  {
                    LODWORD(CpuAreaContextLengtha) = 1;
                    LOBYTE(v28) = 1;
                    ExtendedContextLength = PspGetContextThreadInternal(
                                              Thread,
                                              &ContextFlags,
                                              0i64,
                                              v28,
                                              CpuAreaContextLengtha,
                                              v37,
                                              (UINT64)CpuAreaFlags);
                    if( ExtendedContextLength >= 0 )
                    {
                      ExtendedContextLength = TransactionKey ? RtlCopyContext(
                                                                 (_CONTEXT *)&result,
                                                                 LODWORD(p_ContextFlags->TransactionKey),
                                                                 (_CONTEXT *)p_ContextFlags) : RtlpWow64SetContextOnAmd64(
                                                                                                 (INT64)&result,
                                                                                                 (INT64)&ContextFlags,
                                                                                                 (INT64)p_ContextFlags,
                                                                                                 (BYTE *)&ContextFlags.TransactionKey
                                                                                               + 1);
                      if( ExtendedContextLength >= 0 )
                      {
                        if( v45 != 35 )
                        {
                          v29 = 0;
                          if( (TransactionKey_high & 0x10040) != 65600 )
                            v29 = (TransactionKey_high & 0x10002) != 65538 && (TransactionKey_high & 0x10020) != 65568;
                          if( !v29 )
                            *(&ContextFlags.TransactionNotification + 1) |= 1u;
                        }
                        ExtendedContextLength = PspWow64ReadOrWriteThreadCpuArea(
                                                  (_EPROCESS *)BugCheckParameter1,
                                                  Thread,
                                                  0,
                                                  &result,
                                                  CpuAreaContextLengthb,
                                                  v38,
                                                  (UINT64 *)(&ContextFlags.TransactionNotification + 1),
                                                  0i64,
                                                  v41);
                        v30 = ExtendedContextLength;
                        if( ExtendedContextLength >= 0 )
                        {
                          if( BYTE1(ContextFlags.TransactionKey) )
                          {
                            if( (TransactionKey_high & 0x10040) == 65600 )
                            {
                              LODWORD(result) = result | 0x100040;
                              v31 = *(_DWORD **)&ContextFlags.ArgumentLength;
                              LowPart = ContextFlags.TmVirtualClock.LowPart;
                              *(_QWORD *)(*(_QWORD *)&ContextFlags.ArgumentLength + 16i64) = *(_QWORD *)(ContextFlags.TmVirtualClock.QuadPart + 16);
                              v31[4] += LowPart - (_DWORD)v31;
                              v31[1] = v31[4] + v31[5] - *v31;
                            }
                            v30 = PspSetContextThreadInternal(Thread, (__int64)&ContextFlags, 0, 1, 1);
                          }
                          if( v30 >= 0 )
                          {
                            if( BYTE2(ContextFlags.TransactionKey) )
                              EtwTiLogSetContextThread(
                                *((_BYTE *)KeGetCurrentThread() + 562),
                                (INT64)Thread,
                                (INT64)p_ContextFlags,
                                HIDWORD(ContextFlags.TransactionKey));
                          }
                          return v30;
                        }
                      }
                    }
                  }
                }
              }
            }
            return ExtendedContextLength;
          }
          return -1073741811;
        }
      }
    }
  }
  return ExtendedContextLength;
}

Referenced by:

NtSetInformationThread
WbSetWowTrapFrame