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.