KiUpdateStibpPairing
NTSTATUS __stdcall KiUpdateStibpPairing(_EPROCESS *Process){
struct _KPRCB *CurrentPrcb;
NTSTATUS v2;
int v3;
int v4;
unsigned int Flags3;
int v6;
unsigned __int64 SecurityDomain;
_KPRCB *PairPrcb;
unsigned int v9;
int v10;
unsigned __int8 v11;
char bf_8;
unsigned __int8 BpbState;
signed __int16 v14;
signed __int16 v15;
signed __int16 PairRegister;
signed __int16 v17;
signed __int16 v18;
__int64 TrappedSecurityDomain;
int v20;
signed __int16 v21;
signed __int16 v22;
signed __int16 v23;
signed __int16 v24;
signed __int16 v25;
signed __int16 v26;
signed __int16 v27;
unsigned __int8 BpbKernelSpecCtrl;
NTSTATUS result;
int v30;
CurrentPrcb = KeGetCurrentPrcb();
v2 = 0;
v3 = 0;
v4 = 1;
if( !Process )
{
v4 = 0;
Process = KeGetCurrentThread()->Process;
}
Flags3 = Process->Flags3;
v6 = 0;
SecurityDomain = Process->SecurityDomain;
PairPrcb = CurrentPrcb->PairPrcb;
v9 = Flags3 >> 23;
v10 = Flags3 & 0xC00000;
v30 = v9 & 1;
if( v4 )
{
if( ((Process->Flags3 >> 22) & 1) != 0 && CurrentPrcb->TrappedSecurityDomain )
{
__writemsr(0x49u, 1ui64);
if( (KiSpeculationFeatures & 8) != 0 )
{
bf_8 = CurrentPrcb->_bf_8;
}
else
{
KiFlushCurrentRsb();
BpbState = CurrentPrcb->BpbState;
CurrentPrcb->BpbTrappedBpbState &= ~0x40u;
bf_8 = BpbState & 0xDF;
}
CurrentPrcb->BpbState = bf_8 & 0xFB;
_InterlockedOr16(&PairPrcb->PairRegister, 0x20u);
CurrentPrcb->BpbRetpolineState |= 2u;
v3 = 1;
CurrentPrcb->TrappedSecurityDomain = SecurityDomain;
v6 = 1;
CurrentPrcb->BpbTrappedBpbState &= ~0x10u;
}
}
else
{
if( SecurityDomain != CurrentPrcb->TrappedSecurityDomain )
{
_InterlockedOr16(&PairPrcb->PairRegister, 0x20u);
CurrentPrcb->TrappedSecurityDomain = SecurityDomain;
v3 = 1;
CurrentPrcb->BpbState |= 4u;
if( (KiSpeculationFeatures & 8) == 0 )
CurrentPrcb->BpbState |= 0x20u;
}
v11 = CurrentPrcb->BpbState;
if( (v11 & 4) != 0 )
{
__writemsr(0x49u, 1ui64);
CurrentPrcb->BpbState &= ~4u;
v11 = CurrentPrcb->BpbState;
}
if( (v11 & 0x20) != 0 )
{
KiFlushCurrentRsb();
CurrentPrcb->BpbState &= ~0x20u;
}
}
if( v10 == 0x400000 )
{
_m_prefetchw((char *)&CurrentPrcb->2 + 14);
PairRegister = CurrentPrcb->PairRegister;
if( v4 )
{
do
{
v17 = PairRegister;
PairRegister = _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, PairRegister & 0xFEFD, PairRegister);
}
while( v17 != PairRegister );
}
else
{
do
{
v18 = PairRegister;
PairRegister = _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, PairRegister & 0xFEFD, PairRegister);
}
while( v18 != PairRegister );
}
LOBYTE(v15) = PairRegister;
}
else if( v30 )
{
v15 = CurrentPrcb->PairRegister;
SecurityDomain = 2i64;
}
else
{
do
{
v14 = CurrentPrcb->PairRegister;
v15 = v14 & 0xFEFD | 2;
}
while( v14 != _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, v15, v14) );
SecurityDomain = 2i64;
}
TrappedSecurityDomain = PairPrcb->TrappedSecurityDomain;
v20 = 0;
if( !TrappedSecurityDomain && (v15 & 0x10) != 0 )
{
TrappedSecurityDomain = 1i64;
_InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
}
if( SecurityDomain == TrappedSecurityDomain || (v15 & 8) != 0 )
{
do
{
v21 = PairPrcb->PairRegister;
v22 = v21 & 0xFFEE | 1;
if( SecurityDomain )
v22 = v21 & 0xFFEE | 0x11;
v23 = v22 | 2;
if( (v15 & 1) != 0 )
v23 = v22;
}
while( (v23 & 0x100) == 0 && v23 != v21 && v21 != _InterlockedCompareExchange16(&PairPrcb->PairRegister, v23, v21) );
if( (v21 & 0x100) != 0 )
{
TrappedSecurityDomain = 1i64;
}
else
{
TrappedSecurityDomain = PairPrcb->TrappedSecurityDomain;
if( !TrappedSecurityDomain && (v15 & 0x10) != 0 )
{
TrappedSecurityDomain = 1i64;
_InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
}
}
}
if( TrappedSecurityDomain != SecurityDomain && (v15 & 8) == 0 || v30 || TrappedSecurityDomain == 1 )
{
do
v24 = PairPrcb->PairRegister;
while( (((unsigned __int8)v24 | (unsigned __int8)v15) & 1) != 0
&& v24 != _InterlockedCompareExchange16(&PairPrcb->PairRegister, v24 & 0xFFEC | 2, v24) );
CurrentPrcb->BpbUserSpecCtrl |= 2u;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
else
{
CurrentPrcb->BpbUserSpecCtrl &= ~2u;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
CurrentPrcb->BpbKernelSpecCtrl &= ~2u;
v20 = 1;
}
if( v3 )
{
do
v25 = PairPrcb->PairRegister;
while( v25 != _InterlockedCompareExchange16(&PairPrcb->PairRegister, v25 & 0xFFDD | 2, v25) );
}
if( !v20 )
{
if( v30 )
{
_m_prefetchw((char *)&CurrentPrcb->2 + 14);
v26 = CurrentPrcb->PairRegister;
do
{
v27 = v26;
v26 = _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, v26 | 0x100, v26);
}
while( v27 != v26 );
if( (v26 & 1) != 0 && v4 )
v2 = 1;
}
}
BpbKernelSpecCtrl = CurrentPrcb->BpbKernelSpecCtrl;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
BpbKernelSpecCtrl = CurrentPrcb->BpbRetpolineExitSpecCtrl;
if( SecurityDomain )
{
if( (BpbKernelSpecCtrl & 3) != 0 )
goto LABEL_75;
BpbKernelSpecCtrl = BpbKernelSpecCtrl & 0xFC | 1;
CurrentPrcb->BpbRetpolineExitSpecCtrl = BpbKernelSpecCtrl;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
goto LABEL_75;
}
else
{
if( (v15 & 0x10) == 0 )
{
BpbKernelSpecCtrl &= 0xFCu;
CurrentPrcb->BpbRetpolineExitSpecCtrl = BpbKernelSpecCtrl;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
{
CurrentPrcb->BpbKernelSpecCtrl &= ~2u;
CurrentPrcb->BpbUserSpecCtrl &= ~2u;
}
else
{
CurrentPrcb->BpbUserSpecCtrl &= ~2u;
CurrentPrcb->BpbKernelSpecCtrl = BpbKernelSpecCtrl;
}
goto LABEL_75;
}
BpbKernelSpecCtrl = BpbKernelSpecCtrl & 0xFC | 2;
}
CurrentPrcb->BpbKernelSpecCtrl = BpbKernelSpecCtrl;
LABEL_75:
result = v2;
if( v6 )
{
CurrentPrcb->BpbTrappedBpbState &= ~0x10u;
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = BpbKernelSpecCtrl;
}
return result;
}Referenced by:
KePrepareToDispatchVirtualProcessor
KiApcInterrupt
KiBoundFault
KiControlProtectionFault
KiCopyCounters
KiDpcInterrupt
KiExceptionDispatch
KiFastFailDispatch
KiInvalidOpcodeFault
KiIpiInterrupt
KiPageFault
KiRestoreSetContextState
KiSpuriousDispatchNoEOI
KiSwInterrupt
KiSystemCall64
KiUmsFastReturnToUser
KiUpdateSpeculationControl
KiVirtualizationException
KxIsrLinkage
KxMcheckAlternateReturn
KxStartUserThread
NtCallEnclave
NtContinueEx
NtRaiseException