KiContinuePreviousModeUser

VOID __stdcall KiContinuePreviousModeUser(
        _CONTEXT *UserContextRecord,
        _KEXCEPTION_FRAME *ExceptionFrame,
        _KTRAP_FRAME *TrapFrame){
  unsigned __int64 v3; 
  unsigned __int64 v4; 
  _ETHREAD *CurrentThread; 
  unsigned int ContextFlags; 
  NTSTATUS v7; 
  int v8; 
  int v9; 
  int v10; 
  unsigned int v11; 
  unsigned __int64 v12; 
  void *v13; 
  UINT64 *v14; 
  INT64 *v15; 
  unsigned __int64 v16; 
  int v17; 
  CHAR *ExtendedFeature2; 
  __int64 v19; 
  INT64 v20; 
  int v21; 
  __int64 v22; 
  VOID *v23; 
  UINT64 v24; 
  __int64 v25; 
  __int16 v26; 
  INT64 result; 
  UINT64 ChunksMask; 
  BYTE *v29; 
  UINT64 v30; 
  INT64 v31[3]; 
  unsigned int v32; 
  _KEXCEPTION_FRAME *ExceptionFramea; 
  _KTRAP_FRAME *TrapFramea; 
  PVOID v35; 
  TrapFramea = TrapFrame;
  ExceptionFramea = ExceptionFrame;
  v4 = 0i64;
  v29 = 0i64;
  HIDWORD(result) = 0;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  ContextFlags = UserContextRecord->ContextFlags;
  v32 = ContextFlags;
  if( v3 <= 0xFF )
  {
    memset(v31, 0, sizeof(v31));
  }
  else
  {
    *(_OWORD *)v31 = *(_OWORD *)v3;
    v31[2] = *(_QWORD *)(v3 + 16);
    if( (v31[0] & 0xFFFFFFFC00000000ui64) != 0 || LODWORD(v31[0]) >= 4 || v31[1] || v31[2] )
      return;
  }
  if( ((ContextFlags & 0x10000) == 0 || (ContextFlags & 0x27FEFF80) != 0)
    && (ContextFlags & 0x27FFFFA0) != 0x100000
    && (ContextFlags & 0x7FFFFF0) != 0x200000
    && (ContextFlags & 0x7FFFFE0) != 0x400000 )
  {
    goto LABEL_47;
  }
  if( ((ContextFlags & 0x100040) == 1048640 || (ContextFlags & 0x10040) == 65600)
    && !KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    return;
  }
  if( (ContextFlags & 0x100000) == 0 )
LABEL_47:
    ContextFlags = ContextFlags & 0xD800001F | 0x100000;
  LODWORD(result) = 0;
  v7 = RtlpValidateContextFlags(ContextFlags, (UINT64 *)&result);
  if( v7 < 0 )
  {
    v11 = HIDWORD(result);
    goto LABEL_23;
  }
  if( (result & 2) != 0 )
    v4 = KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures;
  LODWORD(ChunksMask) = 0;
  v7 = RtlpValidateContextFlags(ContextFlags, &ChunksMask);
  if( v7 < 0 )
  {
    v11 = HIDWORD(result);
    goto LABEL_23;
  }
  v8 = 0;
  v9 = 0;
  if( (ContextFlags & 0x10000) != 0 )
  {
    v8 = 716;
    v9 = 4;
  }
  else
  {
    if( (ContextFlags & 0x100000) != 0 )
    {
      v8 = 1232;
    }
    else
    {
      if( (ContextFlags & 0x200000) != 0 )
      {
        v8 = 416;
        v9 = 8;
        goto LABEL_21;
      }
      if( (ContextFlags & 0x400000) == 0 )
        goto LABEL_21;
      v8 = 912;
    }
    v9 = 16;
  }
LABEL_21:
  v10 = v8 + 24;
  if( (ChunksMask & 2) != 0 )
  {
    if( (KUSER_SHARED_DATA.XState.ControlFlags & 2) != 0 )
      v4 &= KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures | 0x8000000000000000ui64;
    v10 = (-v9 & (v9 + v10 - 1)) - v9 - 448 + RtlpGetEntireXStateAreaLength(v4);
  }
  v11 = v9 + v10 - 1;
  v7 = 0;
LABEL_23:
  if( v7 < 0 )
    return;
  v12 = v11 + 15i64;
  if( v12 <= v11 )
    v12 = 0xFFFFFFFFFFFFFF0i64;
  v13 = alloca(v12 & 0xFFFFFFFFFFFFFFF0ui64);
  memset((INT64)&result, 0i64);
  if( (ContextFlags & 0x10000) != 0 && (ContextFlags & 0x27FEFF80) == 0
    || (ContextFlags & 0x27FFFFA0) == 0x100000
    || (ContextFlags & 0x7FFFFF0) == 0x200000
    || (ContextFlags & 0x7FFFFE0) == 0x400000 )
  {
    LOBYTE(v15) = (ContextFlags & 0x100040) != 1048640;
    if( ((unsigned __int8)v15 & ((ContextFlags & 0x10040) != 65600)) != 0 )
    {
      v21 = 0;
    }
    else
    {
      if( !KUSER_SHARED_DATA.XState.EnabledFeatures )
      {
        v17 = -1073741637;
        goto LABEL_33;
      }
      v21 = 2;
    }
    v16 = 0i64;
    if( v21 )
      v16 = KUSER_SHARED_DATA.XState.EnabledFeatures | KUSER_SHARED_DATA.XState.EnabledUserVisibleSupervisorFeatures;
    v17 = RtlInitializeExtendedContext2((INT64)&result, ContextFlags, &v29, v16);
  }
  else
  {
    v17 = -1073741811;
  }
LABEL_33:
  if( v17 >= 0 )
  {
    LOBYTE(v14) = 1;
    if( (int)RtlpReadExtendedContext(v15, v14, v29) >= 0 )
    {
      v30 = 0i64;
      if( (v31[2] & 0x100040) == 1048640 )
      {
        ExtendedFeature2 = RtlLocateExtendedFeature2(&STACK[0x500], 0xBui64, 0xFFFFF780000003D8ui64, 0i64);
        if( ExtendedFeature2 )
        {
          v22 = SLODWORD(STACK[0x510]);
          v23 = (VOID *)__readmsr(0x6A7u);
          v30 = (UINT64)v23;
          v24 = *(INT64 *)((char *)&result + v22 + 1232) & 0x800;
          if( (*((_DWORD *)CurrentThread + 29) & 0x100000) != 0 )
          {
            if( v24 )
            {
              if( (int)KiVerifyContextXStateCetUEnabled(ExtendedFeature2, v23) < 0 )
                return;
            }
            else
            {
              *(INT64 *)((char *)&result + v22 + 1232) |= 0x800ui64;
              *(_QWORD *)ExtendedFeature2 = 1i64;
              *((_QWORD *)ExtendedFeature2 + 1) = v23;
            }
          }
          else if( v24 && (*(_QWORD *)ExtendedFeature2 || *((_QWORD *)ExtendedFeature2 + 1)) )
          {
            return;
          }
        }
      }
      v19 = *((_QWORD *)CurrentThread + 68);
      if( (*(_DWORD *)(v19 + 632) & 0x20) == 0
        || (v31[2] & 0x100001) != 1048577
        || (v20 = *((_QWORD *)CurrentThread + 30), (unsigned int)RtlGuardIsValidStackPointer(v35))
        || (v25 = *(_QWORD *)(v19 + 1408)) != 0
        && ((v26 = *(_WORD *)(v25 + 8), v26 == 332) || v26 == 452)
        && (unsigned __int64)v35 < 0xFFFFFFFF
        && RtlGuardIsValidWow64StackPointer((unsigned int)v35, v20) )
      {
        if( (int)KiVerifyContextRecord((INT64)CurrentThread, (INT64)&result, (INT64)ExtendedFeature2, v31, &v30) >= 0 )
          KeContextToKframes(TrapFramea, ExceptionFramea, (_CONTEXT *)&result, ContextFlags, 1);
      }
    }
  }
}

Referenced by:

KiContinueEx