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