PspGetSetContextInternal
VOID __fastcall PspGetSetContextInternal(_KAPC *Apc, VOID *OperationType){
__int64 v2;
_CONTEXT *v5;
_ETHREAD *CurrentThread;
_KTRAP_FRAME *TrapFrame;
_QWORD *v8;
void(__fastcall *KernelRoutine)(_KAPC *, void(__fastcall **)(void *, void *, void *), void **, void **, void **);
INT64 v10;
INT64 v11;
_QWORD *i;
char v13;
_DWORD *Object;
INT64 v15;
signed int v16;
void(__fastcall *v17)(_KAPC *, void(__fastcall **)(void *, void *, void *), void **, void **, void **);
unsigned int v18;
signed int v19;
signed int v20;
_KAPC *v21;
INT64 CurrentUmsTeb;
CHAR DoesTebMatchThread;
INT64 v24;
CHAR v25;
signed int v26;
signed int updated;
_QWORD *j;
void(__fastcall *v29)(_KAPC *, void(__fastcall **)(void *, void *, void *), void **, void **, void **);
INT64 v30;
INT64 v31;
INT64 v32;
UINT64 v33;
UINT64 v34;
INT64 v35;
INT64 v36;
_IMAGE_ARM64_RUNTIME_FUNCTION_ENTRY *v37;
_ETHREAD **p_Thread;
void(__fastcall *v39)(_KAPC *, void(__fastcall **)(void *, void *, void *), void **, void **, void **);
INT64 v40;
INT64 v41;
INT64 v42;
INT64 v43;
INT64 v44;
UINT64 v45;
INT64 v46;
CHAR *v47;
INT64 v48;
_QWORD *v49;
char v50[3];
int v51;
UINT64 HighLimit;
UINT64 LowLimit;
_KTRAP_FRAME *v54;
VOID *v55;
UINT64 v56[2];
__int64 v57;
__int64 v58;
_INVERTED_FUNCTION_TABLE_ENTRY FunctionTableInfo;
INT64 v60[2];
__int64 v61;
_KERNEL_STACK_SEGMENT LastSegment;
INT64 result[18];
char v64;
UINT64 StackFrame;
char v66;
char v67;
char v68;
char v69;
char v70;
char v71;
char v72;
UINT64 ControlPc;
char v74;
char v75;
char v76;
char v77;
char v78;
char v79;
char v80;
char v81;
char v82;
char v83;
_MDL MemoryDescriptorList;
INT64 v85;
INT64 v86;
v49 = (_QWORD *)v2;
v55 = OperationType;
v57 = v2;
v56[1] = (UINT64)Apc;
memset(&MemoryDescriptorList.AllocationProcessorNumber, 0, 20);
v85 = 0i64;
v86 = 0i64;
v54 = 0i64;
v58 = 0i64;
HighLimit = 0i64;
LowLimit = 0i64;
v50[0] = 0;
v51 = 0;
v5 = (_CONTEXT *)&Apc[1].Reserved[1];
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
if( !Apc[1].Type )
{
TrapFrame = CurrentThread->Tcb.TrapFrame;
if( !TrapFrame || TrapFrame->SegCs != 16 )
{
Apc[1].SpareLong0 = -1073741823;
v8 = (_QWORD *)v2;
LABEL_59:
v21 = Apc;
goto LABEL_60;
}
goto LABEL_29;
}
if( (CurrentThread->SameThreadPassiveFlags & 0x200) != 0 )
{
KernelRoutine = Apc[1].KernelRoutine;
MemoryDescriptorList.Next = 0i64;
MemoryDescriptorList.Size = 8 * (((unsigned __int16)(((unsigned __int16)KernelRoutine & 0xFFF) + 5327) >> 12) + 6);
MemoryDescriptorList.MdlFlags = 0;
MemoryDescriptorList.StartVa = (void *)((unsigned __int64)KernelRoutine & 0xFFFFFFFFFFFFF000ui64);
MemoryDescriptorList.ByteOffset = (unsigned __int16)KernelRoutine & 0xFFF;
MemoryDescriptorList.ByteCount = 1232;
MmProbeAndLockPages(&MemoryDescriptorList, 0, IoModifyAccess);
Apc[1].SpareLong0 = VslGetSetSecureContext((INT64)OperationType, (INT64)Apc[1].KernelRoutine, v85, v86);
MmUnlockPages((INT64)&MemoryDescriptorList, v10, v11);
goto LABEL_58;
}
for( i = CurrentThread->Tcb.InitialStack; (i[1] & 1) != 0; i = (_QWORD *)i[5] )
;
TrapFrame = (_KTRAP_FRAME *)(i - 50);
v13 = CurrentThread->Tcb.gap0[3];
if( (v13 & 0x40) == 0 || (Object = CurrentThread->Tcb.WaitBlock[3].Object, (Object[20] & 4) == 0) )
{
if( v13 < 0 )
{
CurrentUmsTeb = KeGetCurrentUmsTeb(CurrentThread);
DoesTebMatchThread = KeDoesTebMatchThread((INT64)CurrentThread, CurrentUmsTeb);
v25 = DoesTebMatchThread;
if( v55 )
{
updated = KeUpdatePrimaryThreadContext(v24, (_CONTEXT *)Apc[1].KernelRoutine);
Apc[1].SpareLong0 = updated;
if( !v25 || updated < 0 )
goto LABEL_58;
}
else if( !DoesTebMatchThread )
{
v26 = KeBuildPrimaryThreadContext(v24, 0i64, (INT64)Apc[1].KernelRoutine, 1i64, 0i64, 0i64);
LABEL_26:
Apc[1].SpareLong0 = v26;
goto LABEL_58;
}
}
LABEL_29:
if( (Apc[1].SpareByte0 & 2) != 0 )
{
if( RtlpGetStackLimits(&LowLimit, &HighLimit) )
{
memset(&LastSegment, 0, sizeof(LastSegment));
FunctionTableInfo = *(_INVERTED_FUNCTION_TABLE_ENTRY *)&byte_140E00020;
RtlpCaptureContext((INT64)result, v30, v31, v32, v40, v42, v44, v46, v48);
v5->_Rsp = (unsigned __int64)&v64;
v5->_Rsi = (unsigned __int64)&v66;
v5->_Rdi = (unsigned __int64)&v67;
v5->_R8 = (unsigned __int64)&v68;
v5->_R13 = (unsigned __int64)&v69;
v5->_R14 = (unsigned __int64)&v70;
v5->_R15 = (unsigned __int64)&v71;
v5->_Rip = (unsigned __int64)&v72;
*(_QWORD *)&v5->ContextFlags = &v74;
*(_QWORD *)&v5->SegCs = &v75;
*(_QWORD *)&v5->SegGs = &v76;
v5->Dr0 = (unsigned __int64)&v77;
v5->Dr1 = (unsigned __int64)&v78;
v5->Dr2 = (unsigned __int64)&v79;
v5->Dr3 = (unsigned __int64)&v80;
v5->Dr6 = (unsigned __int64)&v81;
v5->Dr7 = (unsigned __int64)&v82;
v5->_Rax = (unsigned __int64)&v83;
v5->_Rbp = (unsigned __int64)&StackFrame;
v33 = StackFrame;
while( 1 )
{
v34 = ControlPc;
if( ControlPc <= 0xFFFF800000000000ui64
|| !(unsigned __int8)RtlpIsFrameInBoundsEx(&LowLimit, v33, &HighLimit, &LastSegment) )
{
break;
}
v37 = RtlpLookupFunctionEntryForStackWalks(v34, &FunctionTableInfo, v35, v36, v41, v43, v45, v47);
if( v37 )
{
if( (int)RtlpVirtualUnwind(
0i64,
(__int64)FunctionTableInfo.ImageBase,
v34,
(__int64)v37,
(__int64)result,
(__int64)v50,
(__int64)&v58,
(__int64)&v54,
(__int64)v5,
(__int64)&LowLimit,
(__int64)&HighLimit,
0i64) < 0 )
{
if( (_BYTE)KdDebuggerEnabled && !(_BYTE)KdDebuggerNotPresent )
NT_ASSERT(
"*** Ps: Context unwind failure
A stack frame did not unwind properly
Perform a stack trace to"
" find the culprit
Use gh to continue!!
");
goto LABEL_57;
}
v33 = StackFrame;
}
else
{
if( !FunctionTableInfo.ImageBase )
goto LABEL_57;
ControlPc = *(_QWORD *)StackFrame;
v33 = StackFrame + 8;
StackFrame += 8i64;
}
if( v54 == TrapFrame )
goto LABEL_33;
}
if( (_BYTE)KdDebuggerEnabled && !(_BYTE)KdDebuggerNotPresent )
NT_ASSERT(
"*** Ps: Context unwind failure
A stack frame did not unwind properly
Perform a stack trace to find "
"the culprit
Use gh to continue!!
");
}
LABEL_57:
Apc[1].SpareLong0 = -1073741823;
goto LABEL_58;
}
for( j = CurrentThread->Tcb.InitialStack; (j[1] & 1) != 0; j = (_QWORD *)j[5] )
;
v5->_Rsp = (unsigned __int64)(j - 58);
v5->_Rdi = (unsigned __int64)(j - 56);
v5->_R8 = (unsigned __int64)(j - 57);
v5->_R13 = (unsigned __int64)(j - 55);
v5->_R14 = (unsigned __int64)(j - 54);
v5->_R15 = (unsigned __int64)(j - 53);
v5->_Rip = (unsigned __int64)(j - 52);
*(_QWORD *)&v5->ContextFlags = j - 84;
*(_QWORD *)&v5->SegCs = j - 82;
*(_QWORD *)&v5->SegGs = j - 80;
v5->Dr0 = (unsigned __int64)(j - 78);
v5->Dr1 = (unsigned __int64)(j - 76);
v5->Dr2 = (unsigned __int64)(j - 74);
v5->Dr3 = (unsigned __int64)(j - 72);
v5->Dr6 = (unsigned __int64)(j - 70);
v5->Dr7 = (unsigned __int64)(j - 68);
v5->_Rax = (unsigned __int64)(j - 66);
v5->_Rsi = (unsigned __int64)&TrapFrame->_Rbp;
LABEL_33:
v29 = Apc[1].KernelRoutine;
if( !v55 )
{
if( (*((_DWORD *)v29 + 12) & 0x100008) == 1048584 && Apc[1].Type == 1 )
_fxsave((char *)v29 + 256);
if( CurrentThread->SetContextState && Apc[1].Type == 1 )
{
v39 = Apc[1].KernelRoutine;
PspGetContext(TrapFrame, v5);
if( (CurrentThread->Tcb.gap0[3] & 8) != 0 )
{
RtlCopyContext(
(_X86_NT5_CONTEXT *)v39,
*((unsigned int *)v39 + 12),
(_X86_NT5_CONTEXT *)CurrentThread->SetContextState);
Apc[1].SpareLong0 = 0;
goto LABEL_58;
}
}
else
{
PspGetContext(TrapFrame, v5);
}
Apc[1].SpareLong0 = 0;
goto LABEL_58;
}
if( Apc[1].Type != 1
|| (v56[0] = 0i64, v26 = KeVerifyContextXStateCetU((__int64)CurrentThread, v29, v56), v26 >= 0)
&& ((Apc[1].SpareByte0 & 4) == 0
|| (*(_OWORD *)v60 = 0i64,
v61 = 0i64,
LODWORD(v60[0]) = 3,
v26 = KeVerifyContextIpForUserCet((INT64)CurrentThread, (INT64)Apc[1].KernelRoutine, v60, v56),
v26 >= 0)) )
{
if( CurrentThread->SetContextState
&& Apc[1].Type == 1
&& ((Apc[1].SpareByte0 & 2) != 0 || (CurrentThread->Tcb.gap0[3] & 8) != 0) )
{
PspSetContextState((INT64)CurrentThread, (_CONTEXT *)Apc[1].KernelRoutine);
Apc[1].SpareLong0 = 0;
}
else
{
PspSetContext((__int64)TrapFrame, (__int64)v5, (__int64)Apc[1].KernelRoutine, Apc[1].Type);
Apc[1].SpareLong0 = 0;
}
goto LABEL_58;
}
goto LABEL_26;
}
v15 = *(_QWORD *)Object;
v16 = PspRundownUmsThreadForApcDelivery(CurrentThread, &v51, *(_QWORD *)Object, 0);
Apc[1].SpareLong0 = v16;
if( v16 < 0 )
{
LABEL_58:
v8 = v49;
goto LABEL_59;
}
v17 = Apc[1].KernelRoutine;
if( OperationType )
{
v18 = PspSetUmsThreadContext((__int64)CurrentThread, (INT64)Apc[1].KernelRoutine, &v51);
}
else
{
v18 = 0;
if( (v51 & 2) != 0 )
v18 = KeCopyContextFromUmsContext((_CONTEXT *)v17, *(_QWORD *)CurrentThread->Tcb.WaitBlock[3].Object);
else
KeCopyContextFromUch((_CONTEXT *)v17, (INT64)CurrentThread->Tcb.WaitBlock[3].SparePtr);
}
Apc[1].SpareLong0 = v18;
v19 = KeClearUmsThreadKernelLock(v15);
if( v19 < 0 )
Apc[1].SpareLong0 = v19;
if( (v51 & 8) != 0 )
{
v20 = KeUpdateUmsThreadState(v15, 0i64, 1);
v21 = Apc;
if( v20 < 0 )
{
Apc[1].SpareLong0 = v20;
v8 = v49;
goto LABEL_60;
}
}
else
{
v21 = Apc;
}
v8 = v49;
LABEL_60:
p_Thread = &v21[1].Thread;
if( (Apc[1].SpareByte0 & 1) == 0 )
p_Thread = 0i64;
*v8 = p_Thread;
}Referenced by:
PspGetSetContextSpecialApc