KeUserModeCallback

NTSTATUS __stdcall KeUserModeCallback(
        UINT64 ApiNumber,
        VOID *InputBuffer,
        UINT64 InputLength,
        VOID **OutputBuffer,
        UINT64 *OutputLength){
  __int64 v5; 
  _ETHREAD *CurrentThread; 
  unsigned __int8 CallbackNestingLevel; 
  char *KernelStack; 
  char *v9; 
  _KTRAP_FRAME *TrapFrame; 
  unsigned __int64 Rsp; 
  unsigned __int64 v12; 
  unsigned __int64 v13; 
  unsigned __int64 v14; 
  unsigned __int64 v15; 
  unsigned __int64 v16; 
  unsigned __int8 BpbRetpolineState; 
  NTSTATUS v18; 
  NTSTATUS v19; 
  unsigned __int64 v21; 
  PVOID retaddr; 
  int v23; 

  v23 = ApiNumber;
  v5 = (unsigned int)InputLength;
  CurrentThread = (_ETHREAD *)KeGetCurrentThread();
  if( (CurrentThread->Tcb._bf_0 & 0x1000) != 0 )
    KeBugCheckEx(0x107u, CurrentThread, 0i64, 0i64, 0i64);
  if( KeGetCurrentIrql() )
    KeBugCheckEx(0x4Au, retaddr, (PVOID)KeGetCurrentIrql(), 0i64, 0i64);
  if( CurrentThread->Tcb.ApcStateIndex || CurrentThread->Tcb.WaitBlock[3].SpareLong )
    KeBugCheckEx(
      1u,
      retaddr,
      (PVOID)CurrentThread->Tcb.ApcStateIndex,
      (PVOID)CurrentThread->Tcb.CombinedApcDisable,
      0i64);
  CallbackNestingLevel = CurrentThread->Tcb.CallbackNestingLevel;
  CurrentThread->Tcb.CallbackNestingLevel = CallbackNestingLevel + 1;
  if( (unsigned __int8)(CallbackNestingLevel + 1) > 0x1Fu )
  {
    CurrentThread->Tcb.CallbackNestingLevel = CallbackNestingLevel;
    return -1073741571;
  }
  else
  {
    KernelStack = (char *)MmCreateKernelStack(
                            0i64,
                            (*(&KiProcessorBlock + CurrentThread->Tcb.IdealProcessor))->ParentNode->Affinity.Reserved[0],
                            &CurrentThread->Tcb);
    v9 = KernelStack;
    if( KernelStack )
    {
      *((_QWORD *)KernelStack - 6) = KernelStack;
      *((_QWORD *)KernelStack - 5) = &KernelStack[-(unsigned int)KeKernelStackSize];
      *((_QWORD *)KernelStack - 4) = CurrentThread->Tcb.StackBase;
      *((_QWORD *)KernelStack - 3) = CurrentThread->Tcb.StackLimit;
      *((_QWORD *)KernelStack - 1) = CurrentThread->Tcb.InitialStack;
      TrapFrame = CurrentThread->Tcb.TrapFrame;
      Rsp = TrapFrame->_Rsp;
      v12 = (Rsp - (((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 88)) & 0xFFFFFFFFFFFFFFF0ui64;
      v13 = v12;
      v14 = v12 + ((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 87;
      if( v12 > v14 || v14 >= 0x7FFFFFFF0000i64 )
        ExRaiseAccessViolation();
      v15 = (v14 & 0xFFFFFFFFFFFFF000ui64) + 4096;
      do
      {
        *(_BYTE *)v13 = *(_BYTE *)v13;
        v13 = (v13 & 0xFFFFFFFFFFFFF000ui64) + 4096;
      }
      while( v13 != v15 );
      memmove((VOID *)(v12 + 88), InputBuffer, v5);
      *(_QWORD *)(v12 + 32) = v12 + 88;
      *(_DWORD *)(((Rsp - (((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 88)) & 0xFFFFFFFFFFFFFFF0ui64) + 0x28) = v5;
      *(_DWORD *)(((Rsp - (((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 88)) & 0xFFFFFFFFFFFFFFF0ui64) + 0x2C) = v23;
      *(_QWORD *)(((Rsp - (((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 88)) & 0xFFFFFFFFFFFFFFF0ui64) + 0x48) = Rsp;
      *(_QWORD *)(((Rsp - (((v5 + 15) & 0xFFFFFFFFFFFFFFF0ui64) + 88)) & 0xFFFFFFFFFFFFFFF0ui64) + 0x30) = TrapFrame->_Rip;
      v16 = 0i64;
      if( (CurrentThread->Tcb._bf_0 & 0x100000) != 0 )
      {
        v21 = __readmsr(0x6A0u);
        if( (v21 & 1) != 0 )
          v16 = __readmsr(0x6A7u);
      }
      BpbRetpolineState = KeGetPcr()->Prcb.BpbRetpolineState;
      TrapFrame->_Rsp = v12;
      KiCallUserMode(OutputBuffer, OutputLength, v9 - 48, v9);
      v19 = v18;
      if( (BpbRetpolineState & 1) != 0 )
        KeExitRetpoline();
      _mm_lfence();
      if( *((_DWORD *)CurrentThread->Tcb.Teb + 1488) )
      {
        TrapFrame->_Rsp -= 256i64;
        PsInvokeWin32Callout(Win32BatchFlushCallout, 0i64, PsWin32SessionAttachNone, 0i64);
      }
      if( v16 )
        __writemsr(0x6A7u, v16);
      TrapFrame->_Rsp = Rsp;
      --CurrentThread->Tcb.CallbackNestingLevel;
      MmDeleteKernelStack(v9, 0i64);
      return v19;
    }
    else
    {
      --CurrentThread->Tcb.CallbackNestingLevel;
      return -1073741801;
    }
  }
}

Referenced by:

No references.