PspWow64SetContextThread

NTSTATUS __stdcall PspWow64SetContextThread(PETHREAD Thread){
  _CONTEXT_EX *v1; 
  int v2; 
  char v3; 
  char v4; 
  int v5; 
  _CONTEXT_EX *v6; 
  INT64 v8; 
  INT64 v9; 
  _ETHREAD *CurrentThread; 
  _EPROCESS *Process; 
  _EWOW64PROCESS *WoW64Process; 
  __int64 v13; 
  NTSTATUS result; 
  bool v15; 
  unsigned int v16; 
  unsigned __int64 v17; 
  signed __int64 v18; 
  void *v19; 
  void *v20; 
  UINT8 *p_Buffer; 
  _CONTEXT_EX *v22; 
  CHAR v23; 
  VOID *ThreadTeb; 
  UINT8 v25; 
  unsigned __int64 v26; 
  signed __int64 v27; 
  void *v28; 
  void *v29; 
  bool v30; 
  int v31; 
  _CONTEXT_EX *v32; 
  int v33; 
  UINT64 CpuAreaContextLength; 
  UINT64 CpuAreaContextLengtha; 
  UINT64 v36; 
  UINT64 v37; 
  UINT16 v38; 
  UINT16 v39; 
  UINT8 Buffer; 
  char v41; 
  char v42; 
  UINT64 ContextFlags; 
  char CpuAreaFlags[12]; 
  _CONTEXT_EX *ContextEx; 
  _EPROCESS *TargetProcess; 
  _X86_NT5_CONTEXT CpuAreaContext[180]; 

  v4 = v3;
  v42 = v3;
  v5 = v2;
  v6 = v1;
  ContextEx = 0i64;
  memset(CpuAreaContext, 0i64, 0x2CCu);
  HIDWORD(ContextFlags) = 0;
  Buffer = 0;
  memset(CpuAreaFlags, 0, sizeof(CpuAreaFlags));
  v41 = 0;
  if( v5 != 716 )
    return -1073741820;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  Process = Thread->Tcb.Process;
  TargetProcess = Process;
  WoW64Process = Process->WoW64Process;
  if( !WoW64Process || WoW64Process->Machine != 332 )
    return -1073741811;
  if( v4 )
  {
    v13 = (__int64)v6;
    if( (unsigned __int64)v6 >= 0x7FFFFFFF0000i64 )
      v13 = 0x7FFFFFFF0000i64;
    LODWORD(ContextFlags) = *(_DWORD *)v13;
  }
  else
  {
    LODWORD(ContextFlags) = v6->All.Offset;
  }
  LOBYTE(v8) = v4;
  result = RtlpWow64SanitizeContextFlags(&ContextFlags, v8, v9);
  if( result >= 0 )
  {
    v15 = v4 == 0;
    v16 = ContextFlags;
    if( v15 )
    {
      p_Buffer = (UINT8 *)v6;
      *(_QWORD *)&CpuAreaFlags[4] = (char *)v6 + 716;
      goto LABEL_15;
    }
    result = RtlGetExtendedContextLength((unsigned int)ContextFlags, (UINT64 *)((char *)&ContextFlags + 4));
    if( result >= 0 )
    {
      v17 = HIDWORD(ContextFlags) + 15i64;
      if( v17 <= HIDWORD(ContextFlags) )
        v17 = 0xFFFFFFFFFFFFFF0i64;
      v18 = v17 & 0xFFFFFFFFFFFFFFF0ui64;
      v19 = alloca(v18);
      v20 = alloca(v18);
      p_Buffer = &Buffer;
      result = RtlInitializeExtendedContext(&Buffer, v16, (_CONTEXT_EX **)&CpuAreaFlags[4]);
      if( result >= 0 )
      {
        v36 = 0i64;
        LOBYTE(v22) = 1;
        result = RtlpReadExtendedContext(v23, v22, *(UINT64 *)&CpuAreaFlags[4], (VOID *)v16, v6);
        if( result >= 0 )
        {
LABEL_15:
          if( Thread != CurrentThread
            || (Process->Pcb._bf_0 & 0x20) == 0
            || (*(_DWORD *)p_Buffer & 0x10001) != 65537
            || (ThreadTeb = PsGetThreadTeb(Thread),
                RtlGuardIsValidWow64StackPointer(*((_DWORD *)p_Buffer + 49), (__int64)ThreadTeb)) )
          {
            result = PspWow64ReadOrWriteThreadCpuArea(
                       Process,
                       Thread,
                       1u,
                       CpuAreaContext,
                       CpuAreaContextLength,
                       v36,
                       (UINT64 *)CpuAreaFlags,
                       &Buffer,
                       v38);
            if( result >= 0 )
            {
              v25 = Buffer;
              if( Buffer && (v16 & 0x10040) == 65600 )
              {
                return -1073741637;
              }
              else
              {
                result = RtlGetExtendedContextLength(0x10001Fui64, (UINT64 *)((char *)&ContextFlags + 4));
                if( result >= 0 )
                {
                  v26 = HIDWORD(ContextFlags) + 15i64;
                  if( v26 <= HIDWORD(ContextFlags) )
                    v26 = 0xFFFFFFFFFFFFFF0i64;
                  v27 = v26 & 0xFFFFFFFFFFFFFFF0ui64;
                  v28 = alloca(v27);
                  v29 = alloca(v27);
                  result = RtlInitializeExtendedContext(&Buffer, 0x10001Fui64, &ContextEx);
                  if( result >= 0 )
                  {
                    result = PspGetContextThreadInternal(Thread, (_CONTEXT *)&Buffer, 0, 1, 1u);
                    if( result >= 0 )
                    {
                      result = v25 ? RtlCopyContext(
                                       CpuAreaContext,
                                       *(unsigned int *)p_Buffer,
                                       (_X86_NT5_CONTEXT *)p_Buffer) : RtlpWow64SetContextOnAmd64(
                                                                         (INT64)CpuAreaContext,
                                                                         (INT64)&Buffer,
                                                                         (INT64)p_Buffer,
                                                                         &v41);
                      if( result >= 0 )
                      {
                        if( LOWORD(CpuAreaContext[2]) != 35 )
                        {
                          v30 = 0;
                          if( (v16 & 0x10040) != 65600 )
                            v30 = (v16 & 0x10002) != 65538 && (v16 & 0x10020) != 65568;
                          if( !v30 )
                            *(_DWORD *)CpuAreaFlags |= 1u;
                        }
                        result = PspWow64ReadOrWriteThreadCpuArea(
                                   TargetProcess,
                                   Thread,
                                   0,
                                   CpuAreaContext,
                                   CpuAreaContextLengtha,
                                   v37,
                                   (UINT64 *)CpuAreaFlags,
                                   0i64,
                                   v39);
                        v31 = result;
                        if( result >= 0 )
                        {
                          if( v41 )
                          {
                            if( (v16 & 0x10040) == 65600 )
                            {
                              CpuAreaContext[0] |= 0x100040u;
                              v32 = ContextEx;
                              v33 = *(_DWORD *)&CpuAreaFlags[4];
                              ContextEx->XState = *(_CONTEXT_CHUNK *)(*(_QWORD *)&CpuAreaFlags[4] + 16i64);
                              v32->XState.Offset += v33 - (_DWORD)v32;
                              v32->All.Length = v32->XState.Offset + v32->XState.Length - v32->All.Offset;
                            }
                            v31 = PspSetContextThreadInternal(Thread, (_CONTEXT *)&Buffer, 0, 1, 1u);
                          }
                          if( v31 >= 0 )
                          {
                            if( v42 )
                              EtwTiLogSetContextThread(
                                KeGetCurrentThread()->PreviousMode,
                                (INT64)Thread,
                                (INT64)p_Buffer,
                                (unsigned int)ContextFlags);
                          }
                          return v31;
                        }
                      }
                    }
                  }
                }
              }
            }
            return result;
          }
          return -1073741811;
        }
      }
    }
  }
  return result;
}

Referenced by:

NtSetInformationThread
WbSetWowTrapFrame