KiUpdateSpeculationControl
VOID __stdcall KiUpdateSpeculationControl(PEPROCESS Process){
struct _KPRCB *CurrentPrcb;
int v3;
unsigned __int8 BpbCurrentSpecCtrl;
bool v5;
int v6;
unsigned __int8 BpbRetpolineState;
char v8;
int v9;
unsigned __int64 SecurityDomain;
int v11;
int v12;
unsigned __int8 v13;
unsigned __int8 BpbState;
unsigned __int8 v15;
unsigned __int8 v16;
unsigned __int8 v17;
unsigned __int8 v18;
unsigned __int8 v19;
unsigned __int8 v20;
unsigned __int8 BpbUserSpecCtrl;
NTSTATUS updated;
char v23;
NTSTATUS v24;
bool v25;
char v26;
signed __int16 PairRegister;
signed __int16 v28;
int v29;
unsigned __int8 BpbRetpolineExitSpecCtrl;
unsigned __int8 BpbTrappedRetpolineExitSpecCtrl;
unsigned __int8 BpbKernelSpecCtrl;
unsigned int v33;
unsigned __int64 TrappedSecurityDomain;
__int128 v35;
char v36;
int v37;
_BOOL4 v38;
CurrentPrcb = KeGetCurrentPrcb();
v35 = KiSpeculationFeatures;
v3 = KiSpeculationFeatures;
if( (KiSpeculationFeatures & 0x100000) == 0 )
return;
_disable();
CurrentPrcb->BpbState &= 0x81u;
if( (v3 & 1) != 0 )
{
KiUpdateSpecCtrlEnhancedIBRS((INT64)CurrentPrcb, (INT64)Process);
_enable();
return;
}
BpbCurrentSpecCtrl = CurrentPrcb->BpbCurrentSpecCtrl;
v5 = 0;
v36 = 0;
v6 = v3 & 0x2000000;
if( (v3 & 0x2000000) != 0 )
{
BpbRetpolineState = CurrentPrcb->BpbRetpolineState;
if( (BpbRetpolineState & 2) == 0 && (BpbRetpolineState & 1) != 0 )
{
BpbCurrentSpecCtrl = CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl;
v5 = (CurrentPrcb->BpbTrappedBpbState & 0x10) != 0;
v36 = 1;
}
}
if( (v3 & 0x400000) != 0 && KiSsbdMsr == 72 )
{
BpbCurrentSpecCtrl |= 4u;
v8 = 4;
}
else
{
v8 = 0;
}
CurrentPrcb->BpbKernelSpecCtrl = v8;
CurrentPrcb->BpbUserSpecCtrl = v8;
CurrentPrcb->BpbRetpolineExitSpecCtrl = v8;
v37 = v3 & 0x2000;
if( (v3 & 0x2000) != 0 )
{
CurrentPrcb->BpbKernelSpecCtrl |= 0x80u;
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 0x80u;
}
v9 = v3 & 0x8000000;
if( v9 )
{
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
}
TrappedSecurityDomain = CurrentPrcb->TrappedSecurityDomain;
SecurityDomain = Process->SecurityDomain;
v11 = v35;
v38 = (Process->Flags3 & 0x400000) != 0;
v33 = (Process->Flags3 >> 23) & 1;
if( (Process->Flags3 & 0x400000) == 0 )
SecurityDomain = 1i64;
v12 = v35 & 0x200000;
if( (v35 & 0x200000) == 0 )
{
if( !SecurityDomain )
{
if( (v35 & 2) != 0 )
{
if( (v35 & 0x40) != 0 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
else if( (v35 & 0x10) != 0 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 1u;
}
}
goto LABEL_24;
}
if( KiIsBranchConfusionMitigationEnabled(&v35) )
{
v13 = CurrentPrcb->BpbState | 8;
CurrentPrcb->BpbState = v13;
if( (v11 & 8) == 0 )
CurrentPrcb->BpbState = v13 | 2;
if( (v11 & 2) != 0 )
{
if( (v11 & 0x40) != 0 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
else if( (v11 & 0x10) != 0 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 1u;
}
}
goto LABEL_70;
}
if( (v11 & 0x10) != 0 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 1u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 1u;
if( (v11 & 0x20) == 0 )
CurrentPrcb->BpbState |= 2u;
goto LABEL_70;
}
if( (v11 & 0x42) == 66 )
{
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 2u;
if( !v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
BpbState = CurrentPrcb->BpbState;
if( v6 )
{
v15 = BpbState | 0x10;
CurrentPrcb->BpbState = v15;
if( (v11 & 0x20) != 0 )
{
if( (v11 & 8) != 0 )
goto LABEL_70;
v16 = v15 | 0x40;
LABEL_69:
CurrentPrcb->BpbState = v16;
goto LABEL_70;
}
}
else
{
v15 = BpbState | 8;
CurrentPrcb->BpbState = v15;
if( (v11 & 8) != 0 )
goto LABEL_70;
}
v16 = v15 | 2;
goto LABEL_69;
}
LABEL_70:
if( !SecurityDomain || (v11 & 0x800000) == 0 )
{
LABEL_24:
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl &= ~4u;
goto LABEL_25;
}
CurrentPrcb->BpbRetpolineExitSpecCtrl |= 4u;
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl |= 4u;
CurrentPrcb->BpbKernelSpecCtrl |= 4u;
BpbCurrentSpecCtrl |= 4u;
LABEL_25:
if( (v11 & 0x42) == 66 && ((v11 & 0x10000) != 0 || (Process->MitigationFlags & 0x40000000) != 0) )
{
CurrentPrcb->BpbUserSpecCtrl |= 2u;
if( v6 )
{
if( Process != PsInitialSystemProcess )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
}
if( v9 )
CurrentPrcb->BpbUserSpecCtrl |= 2u;
if( (v11 & 0x800000) != 0 && (Process->MitigationFlags2 & 0x2000) != 0 )
CurrentPrcb->BpbUserSpecCtrl |= 4u;
if( !TrappedSecurityDomain
|| TrappedSecurityDomain == SecurityDomain
|| TrappedSecurityDomain == Process->ParentSecurityDomain )
{
goto LABEL_88;
}
if( (BpbCurrentSpecCtrl & 1) == 0 )
{
if( !v12 && (v11 & 0x10) == 0 && (!v6 || (CurrentPrcb->BpbRetpolineState & 2) != 0) )
goto LABEL_88;
LABEL_86:
v17 = CurrentPrcb->BpbState | 4;
CurrentPrcb->BpbState = v17;
if( (v11 & 8) == 0 )
CurrentPrcb->BpbState = v17 | 0x20;
goto LABEL_88;
}
if( (v11 & 2) == 0 )
{
BpbCurrentSpecCtrl &= 4u;
goto LABEL_78;
}
if( (CurrentPrcb->PairRegister & 4) != 0 )
goto LABEL_77;
if( v6 && (CurrentPrcb->BpbRetpolineState & 1) == 0 )
{
BpbCurrentSpecCtrl &= 4u;
LABEL_77:
LOBYTE(v11) = v35;
goto LABEL_78;
}
LOBYTE(v11) = v35;
if( (v35 & 0x40) != 0 )
BpbCurrentSpecCtrl = BpbCurrentSpecCtrl & 4 | 2;
LABEL_78:
if( (BpbCurrentSpecCtrl & 1) != 0 )
goto LABEL_86;
v5 = 1;
v36 = 1;
LABEL_88:
v18 = BpbCurrentSpecCtrl | 0x80;
if( !v37 )
v18 = BpbCurrentSpecCtrl;
v19 = v18 | 2;
if( !v9 )
v19 = v18;
if( v5 )
{
__writemsr(0x49u, 1ui64);
if( (v11 & 8) == 0 )
KiFlushCurrentRsb();
CurrentPrcb->BpbState &= 0xDBu;
CurrentPrcb->BpbTrappedBpbState &= 0xAFu;
CurrentPrcb->TrappedSecurityDomain = 0i64;
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = v19;
}
v20 = v19;
if( (CurrentPrcb->PairRegister & 4) == 0 )
goto LABEL_127;
if( TrappedSecurityDomain == SecurityDomain )
{
BpbUserSpecCtrl = CurrentPrcb->BpbUserSpecCtrl;
if( (CurrentPrcb->PairPrcb->PairRegister & 1) != 0 )
{
CurrentPrcb->BpbUserSpecCtrl = BpbUserSpecCtrl & 0xFD;
if( v6 )
CurrentPrcb->BpbKernelSpecCtrl &= ~2u;
}
else
{
CurrentPrcb->BpbUserSpecCtrl = BpbUserSpecCtrl | 2;
if( v6 )
CurrentPrcb->BpbKernelSpecCtrl |= 2u;
}
}
else
{
_InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
}
if( !SecurityDomain )
{
updated = KiUpdateStibpPairing(&Process->Pcb);
v23 = CurrentPrcb->BpbRetpolineExitSpecCtrl & 3;
v24 = updated;
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = v23 | CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl & 0xFC;
if( v6 && (CurrentPrcb->BpbRetpolineState & 1) != 0 )
v25 = v23 != 0;
else
v25 = (CurrentPrcb->BpbKernelSpecCtrl & 3) != 0;
v26 = 1;
v20 = (v25 ? 2 : 0) | v19 & 0xFC;
if( !v38 )
_InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
goto LABEL_129;
}
if( !v33 )
{
LABEL_127:
v24 = 0;
goto LABEL_128;
}
_m_prefetchw((char *)&CurrentPrcb->2 + 14);
PairRegister = CurrentPrcb->PairRegister;
do
{
v28 = PairRegister;
PairRegister = _InterlockedCompareExchange16(&CurrentPrcb->PairRegister, PairRegister | 0x100, PairRegister);
}
while( v28 != PairRegister );
v29 = PairRegister & 1;
if( (KiSpeculationFeatures & 0x2000000) != 0 )
{
BpbRetpolineExitSpecCtrl = CurrentPrcb->BpbRetpolineExitSpecCtrl;
if( (BpbRetpolineExitSpecCtrl & 3) == 0 )
CurrentPrcb->BpbRetpolineExitSpecCtrl = BpbRetpolineExitSpecCtrl | 2;
BpbTrappedRetpolineExitSpecCtrl = CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl;
if( (BpbTrappedRetpolineExitSpecCtrl & 3) == 0 )
CurrentPrcb->BpbTrappedRetpolineExitSpecCtrl = BpbTrappedRetpolineExitSpecCtrl | 2;
v20 = v19;
if( (CurrentPrcb->BpbRetpolineState & 1) == 0 )
goto LABEL_126;
}
else
{
BpbKernelSpecCtrl = CurrentPrcb->BpbKernelSpecCtrl;
if( (BpbKernelSpecCtrl & 3) == 0 )
CurrentPrcb->BpbKernelSpecCtrl = BpbKernelSpecCtrl | 2;
v20 = v19;
}
if( (v19 & 3) == 0 )
v20 |= 2u;
LABEL_126:
_InterlockedOr16(&CurrentPrcb->PairRegister, 2u);
v24 = v29;
LABEL_128:
v26 = v36;
LABEL_129:
if( v20 != CurrentPrcb->BpbCurrentSpecCtrl )
{
CurrentPrcb->BpbCurrentSpecCtrl = v20;
__writemsr(0x48u, v20);
}
if( v26 )
CurrentPrcb->BpbRetpolineState |= 2u;
_mm_lfence();
_enable();
if( v24 )
KiSynchronizeStibpPairing((INT64)CurrentPrcb);
}Referenced by:
SwapContext