PspSetContextThreadInternal
NTSTATUS __stdcall PspSetContextThreadInternal(
PETHREAD Thread,
_CONTEXT *ProbeMode,
INT8 CtxMode,
INT8 PerformUnwind,
UINT8 PerformUnwinda){
_ETHREAD *CurrentThread;
NTSTATUS result;
UINT8 v11;
char v12;
_EPROCESS *v13;
int v14;
__int64 p_ContextFlags;
unsigned int v16;
unsigned __int64 v17;
void *v18;
_CONTEXT_EX *v19;
CHAR v20;
CHAR v21;
UINT64 ContextFlags;
_CONTEXT_EX *ContextEx;
_BYTE Apc[384];
ContextEx = 0i64;
memset(Apc, 0i64, sizeof(Apc));
HIDWORD(ContextFlags) = 0;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( CtxMode )
{
p_ContextFlags = (__int64)&ProbeMode->ContextFlags;
if( (unsigned __int64)&ProbeMode->ContextFlags >= 0x7FFFFFFF0000i64 )
p_ContextFlags = 0x7FFFFFFF0000i64;
LODWORD(ContextFlags) = *(_DWORD *)p_ContextFlags;
}
else
{
LODWORD(ContextFlags) = ProbeMode->ContextFlags;
}
result = RtlpSanitizeContextFlags(&ContextFlags, CtxMode);
if( result >= 0 )
{
if( !CtxMode )
{
*(_QWORD *)&Apc[120] = ProbeMode;
goto LABEL_6;
}
v16 = ContextFlags;
result = RtlGetExtendedContextLength((unsigned int)ContextFlags, (UINT64 *)((char *)&ContextFlags + 4));
if( result >= 0 )
{
v17 = HIDWORD(ContextFlags) + 15i64;
if( v17 <= HIDWORD(ContextFlags) )
v17 = 0xFFFFFFFFFFFFFF0i64;
v18 = alloca(v17 & 0xFFFFFFFFFFFFFFF0ui64);
*(_QWORD *)&Apc[120] = &ContextFlags;
memset(&ContextFlags, 0i64, HIDWORD(ContextFlags));
result = RtlInitializeExtendedContext(*(VOID **)&Apc[120], v16, &ContextEx);
if( result >= 0 )
{
*(_QWORD *)&Apc[120] = (char *)ContextEx - 1232;
LOBYTE(v19) = 1;
result = RtlpReadExtendedContext(v20, v19, (UINT64)ContextEx, (VOID *)v16, (_CONTEXT_EX *)ProbeMode);
if( result >= 0 )
{
LABEL_6:
if( PerformUnwind && (Thread->Tcb._bf_0 & 0x400) != 0 )
return -1073741776;
Apc[89] &= ~4u;
v12 = Apc[89];
if( PerformUnwind )
{
if( (PerformUnwinda & 2) == 0 )
{
v13 = IoThreadToProcess(CurrentThread);
if( IoThreadToProcess(Thread) == v13 )
{
v14 = KeVerifyContextRecord(&Thread->Tcb, *(_CONTEXT **)&Apc[120]);
if( v14 < 0 )
return v14;
v12 = Apc[89] | 4;
}
}
}
Apc[88] = PerformUnwind;
if( Thread == CurrentThread )
{
*(_QWORD *)&Apc[64] = 1i64;
*(_QWORD *)&Apc[72] = Thread;
Apc[89] = v12 & 0xFC | (2 * (PerformUnwinda & 1));
--CurrentThread->Tcb.SpecialApcDisable;
PspGetSetContextSpecialApc((_KAPC *)Apc, 0i64, 0i64, (VOID **)&Apc[64]);
KiLeaveGuardedRegionUnsafe((__int64)CurrentThread);
LABEL_15:
v14 = *(_DWORD *)&Apc[92];
if( *(int *)&Apc[92] >= 0 && CtxMode == 1 && PerformUnwind == 1 )
EtwTiLogSetContextThread(
KeGetCurrentThread()->PreviousMode,
(INT64)Thread,
*(INT64 *)&Apc[120],
(unsigned int)ContextFlags);
return v14;
}
Apc[89] = v12 & 0xFD | (2 * (PerformUnwinda & 1)) | 1;
KeInitializeGate((_KGATE *)&Apc[96], v11);
KeInitializeApc((INT64)Apc, (INT64)Thread, 0i64, (INT64)PspGetSetContextSpecialApc, 0i64, 0i64, 0, 0i64);
if( KeInsertQueueApc((INT64)Apc, 1i64, (INT64)Thread, 2i64) )
{
KeWaitForGate((_KGATE *)&Apc[96], Executive, v21);
goto LABEL_15;
}
return -1073741823;
}
}
}
}
return result;
}Referenced by:
NtSetContextThread
PsSetContextThread
PspDisassociateUmsThreadFromPrimary
PspInitializeThunkContext
PspPicoSetContextThreadEx
PspWow64SetContextThread
WbSetTrapFrame