KiRestoreUchFromUmsContext

NTSTATUS __stdcall KiRestoreUchFromUmsContext(INT64 a1, INT64 a2, INT64 a3){
  _OWORD *v6; 
  _CONTEXT *p_ContextFrame; 
  __int64 v8; 
  __int64 v10; 
  int v11; 
  _OWORD *v12; 
  __int64 v13; 
  unsigned __int64 v14; 
  _KPROCESSOR_MODE PreviousMode; 
  __int64 v16; 
  _CONTEXT ContextFrame; 

  memset(&ContextFrame, 0i64, sizeof(ContextFrame));
  v6 = (_OWORD *)(a3 + 16);
  p_ContextFrame = &ContextFrame;
  v8 = 9i64;
  do
  {
    *(_OWORD *)&p_ContextFrame->P1Home = *v6;
    *(_OWORD *)&p_ContextFrame->P3Home = v6[1];
    *(_OWORD *)&p_ContextFrame->P5Home = v6[2];
    *(_OWORD *)&p_ContextFrame->ContextFlags = v6[3];
    *(_OWORD *)&p_ContextFrame->SegGs = v6[4];
    *(_OWORD *)&p_ContextFrame->Dr1 = v6[5];
    *(_OWORD *)&p_ContextFrame->Dr3 = v6[6];
    p_ContextFrame = (_CONTEXT *)((char *)p_ContextFrame + 128);
    *(_OWORD *)&p_ContextFrame[-1].LastExceptionToRip = v6[7];
    v6 += 8;
    --v8;
  }
  while( v8 );
  *(_OWORD *)&p_ContextFrame->P1Home = *v6;
  *(_OWORD *)&p_ContextFrame->P3Home = v6[1];
  *(_OWORD *)&p_ContextFrame->P5Home = v6[2];
  *(_OWORD *)&p_ContextFrame->ContextFlags = v6[3];
  *(_OWORD *)&p_ContextFrame->SegGs = v6[4];
  v16 = *(_QWORD *)(a1 + 240);
  if( (*(_DWORD *)(*(_QWORD *)(a1 + 544) + 632i64) & 0x20) != 0
    && (ContextFrame._Rsp < *(_QWORD *)(v16 + 16) || ContextFrame._Rsp > *(_QWORD *)(v16 + 8)) )
  {
    return -1073741571;
  }
  v10 = *(_QWORD *)(a2 + 64);
  v11 = *(_DWORD *)(v10 + 24);
  if( KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    KiCopyXStateArea(
      *(_QWORD *)(a2 + 64),
      KUSER_SHARED_DATA.XState.EnabledFeatures & 0xFFFFFFFFFFFFFFFDui64,
      (a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64);
  }
  else
  {
    v12 = (_OWORD *)((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64);
    v13 = 4i64;
    do
    {
      *(_OWORD *)v10 = *v12;
      *(_OWORD *)(v10 + 16) = v12[1];
      *(_OWORD *)(v10 + 32) = v12[2];
      *(_OWORD *)(v10 + 48) = v12[3];
      *(_OWORD *)(v10 + 64) = v12[4];
      *(_OWORD *)(v10 + 80) = v12[5];
      *(_OWORD *)(v10 + 96) = v12[6];
      v10 += 128i64;
      *(_OWORD *)(v10 - 16) = v12[7];
      v12 += 8;
      --v13;
    }
    while( v13 );
  }
  *(_DWORD *)(*(_QWORD *)(a2 + 64) + 24i64) = v11;
  **(_WORD **)(a2 + 64) = *(_WORD *)((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) & 0x1F3F;
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 112i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xA0);
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 128i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xB0);
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 144i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xC0);
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 160i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xD0);
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 176i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xE0);
  *(_OWORD *)(*(_QWORD *)(a2 + 80) + 192i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0xF0);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 48i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x100);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 64i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x110);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 80i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x120);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 96i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x130);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 112i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x140);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 128i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x150);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 144i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x160);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 160i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x170);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 176i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x180);
  *(_OWORD *)(*(_QWORD *)(a2 + 88) + 192i64) = *(_OWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x190);
  *(_DWORD *)(*(_QWORD *)(a2 + 80) + 44i64) = KiMxCsrMask & *(_DWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x18);
  if( KUSER_SHARED_DATA.XState.EnabledFeatures )
  {
    if( (*(_DWORD *)(a3 + 1264) & 4) != 0 )
      v14 = KUSER_SHARED_DATA.XState.EnabledFeatures & *(_QWORD *)(((a3 + 1375) & 0xFFFFFFFFFFFFFFC0ui64) + 0x200) & 0xFFFFFFFFFFFFFFFDui64;
    else
      v14 = 1i64;
    *(_QWORD *)(*(_QWORD *)(a2 + 64) + 512i64) = v14;
  }
  if( (*(_DWORD *)(a3 + 1264) & 4) == 0 )
  {
    *(_WORD *)(*(_QWORD *)(a2 + 64) + 2i64) = 0;
    *(_BYTE *)(*(_QWORD *)(a2 + 64) + 4i64) = 0;
  }
  LOBYTE(PreviousMode) = 1;
  KeContextToKframes(*(_KTRAP_FRAME **)(a2 + 80), *(_KTRAP_FRAME **)(a2 + 88), &ContextFrame, 0x100003u, PreviousMode);
  return 0;
}

Referenced by:

KeFixUserSwitchContext