ReactOS 0.4.16-dev-91-g764881a
except.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for except.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NTAPI KeInitExceptions (VOID)
 
static BOOLEAN KiDispatchExceptionToUser (IN PKTRAP_FRAME TrapFrame, IN PCONTEXT Context, IN PEXCEPTION_RECORD ExceptionRecord)
 
static VOID KiPageInDirectory (PVOID ImageBase, USHORT Directory)
 
VOID KiPrepareUserDebugData (void)
 
VOID NTAPI KiDispatchException (IN PEXCEPTION_RECORD ExceptionRecord, IN PKEXCEPTION_FRAME ExceptionFrame, IN PKTRAP_FRAME TrapFrame, IN KPROCESSOR_MODE PreviousMode, IN BOOLEAN FirstChance)
 
NTSTATUS NTAPI KeRaiseUserException (IN NTSTATUS ExceptionCode)
 
VOID DECLSPEC_NORETURN KiSystemFatalException (IN ULONG ExceptionCode, IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiNpxNotAvailableFaultHandler (IN PKTRAP_FRAME TrapFrame)
 
static BOOLEAN KiIsPrivilegedInstruction (PUCHAR Ip, BOOLEAN Wow64)
 
static NTSTATUS KiGeneralProtectionFaultUserMode (_In_ PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiGeneralProtectionFaultHandler (IN PKTRAP_FRAME TrapFrame)
 
NTSTATUS NTAPI KiXmmExceptionHandler (IN PKTRAP_FRAME TrapFrame)
 

Variables

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange [256]
 
KIDT_INIT KiInterruptInitTable []
 
KIDTENTRY64 KiIdt [256]
 
KDESCRIPTOR KiIdtDescriptor = {{0}, sizeof(KiIdt) - 1, KiIdt}
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file except.c.

Function Documentation

◆ KeInitExceptions()

VOID NTAPI KeInitExceptions ( VOID  )

Definition at line 59 of file except.c.

60{
61 int i, j;
62
63 /* Initialize the Idt */
64 for (j = i = 0; i < 256; i++)
65 {
67
68 if (KiInterruptInitTable[j].InterruptId == i)
69 {
73 j++;
74 }
75 else
76 {
77 Offset = (ULONG64)&KiUnexpectedRange[i]._Op_push;
78 KiIdt[i].Dpl = 0;
79 KiIdt[i].IstIndex = 0;
80 }
81 KiIdt[i].OffsetLow = Offset & 0xffff;
83 KiIdt[i].Type = 0x0e;
84 KiIdt[i].Reserved0 = 0;
85 KiIdt[i].Present = 1;
86 KiIdt[i].OffsetMiddle = (Offset >> 16) & 0xffff;
87 KiIdt[i].OffsetHigh = (Offset >> 32);
88 KiIdt[i].Reserved1 = 0;
89 }
90
91 KeGetPcr()->IdtBase = KiIdt;
93}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
__INTRIN_INLINE void __lidt(void *Source)
Definition: intrin_x86.h:2018
unsigned __int64 ULONG64
Definition: imports.h:198
#define KGDT64_R0_CODE
Definition: ketypes.h:133
#define KeGetPcr()
Definition: ketypes.h:81
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
KIDT_INIT KiInterruptInitTable[]
Definition: except.c:20
KIDTENTRY64 KiIdt[256]
Definition: except.c:50
KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
KDESCRIPTOR KiIdtDescriptor
Definition: except.c:51
USHORT Limit
Definition: ketypes.h:570
UCHAR Dpl
Definition: ke.h:96
UCHAR IstIndex
Definition: ke.h:97
ULONG OffsetHigh
Definition: ketypes.h:559
USHORT Reserved0
Definition: ketypes.h:554
USHORT IstIndex
Definition: ketypes.h:553
USHORT OffsetMiddle
Definition: ketypes.h:558
USHORT OffsetLow
Definition: ketypes.h:551
ULONG Reserved1
Definition: ketypes.h:560
USHORT Dpl
Definition: ketypes.h:556
USHORT Present
Definition: ketypes.h:557
USHORT Selector
Definition: ketypes.h:552
USHORT Type
Definition: ketypes.h:555
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:800

◆ KeRaiseUserException()

NTSTATUS NTAPI KeRaiseUserException ( IN NTSTATUS  ExceptionCode)

Definition at line 413 of file except.c.

414{
416 return STATUS_UNSUCCESSFUL;
417}
#define UNIMPLEMENTED
Definition: debug.h:118
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by ObpCloseHandle(), and ObpCloseHandleTableEntry().

◆ KiDispatchException()

VOID NTAPI KiDispatchException ( IN PEXCEPTION_RECORD  ExceptionRecord,
IN PKEXCEPTION_FRAME  ExceptionFrame,
IN PKTRAP_FRAME  TrapFrame,
IN KPROCESSOR_MODE  PreviousMode,
IN BOOLEAN  FirstChance 
)

Definition at line 248 of file except.c.

253{
255
256 /* Increase number of Exception Dispatches */
257 KeGetCurrentPrcb()->KeExceptionDispatchCount++;
258
259 /* Zero out the context to avoid leaking kernel stack memor to user mode */
260 RtlZeroMemory(&Context, sizeof(Context));
261
262 /* Set the context flags */
263 Context.ContextFlags = CONTEXT_ALL;
264
265 /* Get the Context from the trap and exception frame */
266 KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
267
268 /* Look at our exception code */
269 switch (ExceptionRecord->ExceptionCode)
270 {
271 /* Breakpoint */
273
274 /* Decrement RIP by one */
275 Context.Rip--;
276 break;
277
278 /* Internal exception */
280
281 /* Set correct code */
282 ExceptionRecord->ExceptionCode = STATUS_ACCESS_VIOLATION;
283 if (PreviousMode == UserMode)
284 {
285 /* FIXME: Handle no execute */
286 }
287 break;
288 }
289
290 /* Handle kernel-mode first, it's simpler */
292 {
293 /* Check if this is a first-chance exception */
294 if (FirstChance)
295 {
296 /* Break into the debugger for the first time */
297 if (KiDebugRoutine(TrapFrame,
298 ExceptionFrame,
299 ExceptionRecord,
300 &Context,
302 FALSE))
303 {
304 /* Exception was handled */
305 goto Handled;
306 }
307
308 /* If the Debugger couldn't handle it, dispatch the exception */
309 if (RtlDispatchException(ExceptionRecord, &Context)) goto Handled;
310 }
311
312 /* This is a second-chance exception, only for the debugger */
313 if (KiDebugRoutine(TrapFrame,
314 ExceptionFrame,
315 ExceptionRecord,
316 &Context,
318 TRUE))
319 {
320 /* Exception was handled */
321 goto Handled;
322 }
323
324 /* Third strike; you're out */
325 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
326 ExceptionRecord->ExceptionCode,
327 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
328 (ULONG_PTR)TrapFrame,
329 0);
330 }
331 else
332 {
333 /* User mode exception, was it first-chance? */
334 if (FirstChance)
335 {
336 /*
337 * Break into the kernel debugger unless a user mode debugger
338 * is present or user mode exceptions are ignored, except if this
339 * is a debug service which we must always pass to KD
340 */
341 if ((!(PsGetCurrentProcess()->DebugPort) &&
343 (KdIsThisAKdTrap(ExceptionRecord, &Context, PreviousMode)))
344 {
345 /* Make sure the debugger can access debug directories */
347
348 /* Call the kernel debugger */
349 if (KiDebugRoutine(TrapFrame,
350 ExceptionFrame,
351 ExceptionRecord,
352 &Context,
354 FALSE))
355 {
356 /* Exception was handled */
357 goto Handled;
358 }
359 }
360
361 /* Forward exception to user mode debugger */
362 if (DbgkForwardException(ExceptionRecord, TRUE, FALSE)) return;
363
364 /* Forward exception to user mode */
365 if (KiDispatchExceptionToUser(TrapFrame, &Context, ExceptionRecord))
366 {
367 /* Success, the exception will be handled by KiUserExceptionDispatcher */
368 return;
369 }
370
371 /* Failed to dispatch, fall through for second chance handling */
372 }
373
374 /* Try second chance */
375 if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
376 {
377 /* Handled, get out */
378 return;
379 }
380 else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
381 {
382 /* Handled, get out */
383 return;
384 }
385
386 /* 3rd strike, kill the process */
387 DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n",
388 PsGetCurrentProcess()->ImageFileName,
389 ExceptionRecord->ExceptionCode,
390 ExceptionRecord->ExceptionAddress,
391 PsGetCurrentProcess()->SectionBaseAddress);
392
393 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
394 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
395 ExceptionRecord->ExceptionCode,
396 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
397 (ULONG_PTR)TrapFrame,
398 0);
399 }
400
401Handled:
402 /* Convert the context back into Trap/Exception Frames */
404 ExceptionFrame,
405 TrapFrame,
406 Context.ContextFlags,
408 return;
409}
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, IN BOOLEAN DebugPort, IN BOOLEAN SecondChance)
Definition: dbgkobj.c:317
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOLEAN KdIgnoreUmExceptions
Definition: kddata.c:85
PKDEBUG_ROUTINE KiDebugRoutine
Definition: kddata.c:74
BOOLEAN NTAPI KdIsThisAKdTrap(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT Context, IN KPROCESSOR_MODE PreviousMode)
Definition: kdtrap.c:317
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1161
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:144
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:43
#define NtCurrentProcess()
Definition: nt_native.h:1657
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
static BOOLEAN KiDispatchExceptionToUser(IN PKTRAP_FRAME TrapFrame, IN PCONTEXT Context, IN PEXCEPTION_RECORD ExceptionRecord)
Definition: except.c:97
VOID KiPrepareUserDebugData(void)
Definition: except.c:200
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
#define CONTEXT_ALL
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ BOOLEAN Handled
Definition: ketypes.h:349
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by KiRaiseException().

◆ KiDispatchExceptionToUser()

static BOOLEAN KiDispatchExceptionToUser ( IN PKTRAP_FRAME  TrapFrame,
IN PCONTEXT  Context,
IN PEXCEPTION_RECORD  ExceptionRecord 
)
static

Definition at line 97 of file except.c.

101{
102 EXCEPTION_RECORD LocalExceptRecord;
103 ULONG64 UserRsp;
104 PKUSER_EXCEPTION_STACK UserStack;
105
106 /* Make sure we have a valid SS */
107 if (TrapFrame->SegSs != (KGDT64_R3_DATA | RPL_MASK))
108 {
109 /* Raise an access violation instead */
110 LocalExceptRecord.ExceptionCode = STATUS_ACCESS_VIOLATION;
111 LocalExceptRecord.ExceptionFlags = 0;
112 LocalExceptRecord.NumberParameters = 0;
113 ExceptionRecord = &LocalExceptRecord;
114 }
115
116 /* Get new stack pointer and align it to 16 bytes */
117 UserRsp = (Context->Rsp - sizeof(KUSER_EXCEPTION_STACK)) & ~15;
118
119 /* Get pointer to the usermode context, exception record and machine frame */
120 UserStack = (PKUSER_EXCEPTION_STACK)UserRsp;
121
122 /* Enable interrupts */
123 _enable();
124
125 /* Set up the user-stack */
127 {
128 /* Probe the user stack frame and zero it out */
129 ProbeForWrite(UserStack, sizeof(*UserStack), TYPE_ALIGNMENT(KUSER_EXCEPTION_STACK));
130 RtlZeroMemory(UserStack, sizeof(*UserStack));
131
132 /* Copy Context and ExceptionFrame */
133 UserStack->Context = *Context;
134 UserStack->ExceptionRecord = *ExceptionRecord;
135
136 /* Setup the machine frame */
137 UserStack->MachineFrame.Rip = Context->Rip;
138 UserStack->MachineFrame.SegCs = Context->SegCs;
139 UserStack->MachineFrame.EFlags = Context->EFlags;
140 UserStack->MachineFrame.Rsp = Context->Rsp;
141 UserStack->MachineFrame.SegSs = Context->SegSs;
142 }
143 _SEH2_EXCEPT((LocalExceptRecord = *_SEH2_GetExceptionInformation()->ExceptionRecord),
145 {
146 // FIXME: handle stack overflow
147
148 /* Nothing we can do here */
149 _disable();
150 return FALSE;
151 }
152 _SEH2_END;
153
154 /* Now set the two params for the user-mode dispatcher */
155 TrapFrame->Rcx = (ULONG64)&UserStack->ExceptionRecord;
156 TrapFrame->Rdx = (ULONG64)&UserStack->Context;
157
158 /* Set new Stack Pointer */
159 TrapFrame->Rsp = UserRsp;
160
161 /* Force correct segments */
162 TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
163 TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
164 TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
165 TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
166 TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
167 TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
168
169 /* Set RIP to the User-mode Dispatcher */
170 TrapFrame->Rip = (ULONG64)KeUserExceptionDispatcher;
171
172 _disable();
173
174 /* Exit to usermode */
175 return TRUE;
176}
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
void __cdecl _disable(void)
Definition: intrin_arm.h:365
void __cdecl _enable(void)
Definition: intrin_arm.h:373
struct _KUSER_EXCEPTION_STACK * PKUSER_EXCEPTION_STACK
#define KGDT64_R3_CODE
Definition: ketypes.h:137
struct _KUSER_EXCEPTION_STACK KUSER_EXCEPTION_STACK
#define KGDT64_R3_DATA
Definition: ketypes.h:136
#define KGDT64_R3_CMTEB
Definition: ketypes.h:139
#define RPL_MASK
Definition: ketypes.h:130
#define TYPE_ALIGNMENT(t)
Definition: ntbasedef.h:117
PVOID KeUserExceptionDispatcher
Definition: ke.h:143
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:164
ULONG SegCs
Definition: nt_native.h:1477
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
MACHINE_FRAME MachineFrame
Definition: ketypes.h:1096
EXCEPTION_RECORD ExceptionRecord
Definition: ketypes.h:1094
USHORT SegSs
Definition: ketypes.h:1063
ULONG EFlags
Definition: ketypes.h:1060
ULONG64 Rsp
Definition: ketypes.h:1062
ULONG64 Rip
Definition: ketypes.h:1057
USHORT SegCs
Definition: ketypes.h:1058

Referenced by KiDispatchException().

◆ KiGeneralProtectionFaultHandler()

NTSTATUS NTAPI KiGeneralProtectionFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 625 of file except.c.

627{
628 PUCHAR Instructions;
629
630 /* Check for user-mode GPF */
631 if (TrapFrame->SegCs & 3)
632 {
633 return KiGeneralProtectionFaultUserMode(TrapFrame);
634 }
635
636 /* Check for lazy segment load */
637 if (TrapFrame->SegDs != (KGDT64_R3_DATA | RPL_MASK))
638 {
639 /* Fix it */
640 TrapFrame->SegDs = (KGDT64_R3_DATA | RPL_MASK);
641 return STATUS_SUCCESS;
642 }
643 else if (TrapFrame->SegEs != (KGDT64_R3_DATA | RPL_MASK))
644 {
645 /* Fix it */
646 TrapFrame->SegEs = (KGDT64_R3_DATA | RPL_MASK);
647 return STATUS_SUCCESS;
648 }
649
650 /* Get Instruction Pointer */
651 Instructions = (PUCHAR)TrapFrame->Rip;
652
653 /* Check for IRET */
654 if (Instructions[0] == 0x48 && Instructions[1] == 0xCF)
655 {
656 /* Not implemented */
658 ASSERT(FALSE);
659 }
660
661 /* Check for RDMSR/WRMSR */
662 if ((Instructions[0] == 0xF) && // 2-byte opcode
663 ((Instructions[1] == 0x30) || // RDMSR
664 (Instructions[1] == 0x32))) // WRMSR
665 {
666 /* Unknown CPU MSR, so raise an access violation */
668 }
669
670 ASSERT(FALSE);
671 return STATUS_UNSUCCESSFUL;
672}
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
static NTSTATUS KiGeneralProtectionFaultUserMode(_In_ PKTRAP_FRAME TrapFrame)
Definition: except.c:589
#define STATUS_SUCCESS
Definition: shellext.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53

◆ KiGeneralProtectionFaultUserMode()

static NTSTATUS KiGeneralProtectionFaultUserMode ( _In_ PKTRAP_FRAME  TrapFrame)
static

Definition at line 589 of file except.c.

591{
592 BOOLEAN Wow64 = TrapFrame->SegCs == KGDT64_R3_CMCODE;
593 PUCHAR InstructionPointer;
595
596 /* We need to decode the instruction at RIP */
597 InstructionPointer = (PUCHAR)TrapFrame->Rip;
598
600 {
601 /* Probe the instruction address */
602 ProbeForRead(InstructionPointer, 64, 1);
603
604 /* Check if it's a privileged instruction */
605 if (KiIsPrivilegedInstruction(InstructionPointer, Wow64))
606 {
608 }
609 else
610 {
612 }
613 }
615 {
617 }
619
620 return Status;
621}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
Status
Definition: gdiplustypes.h:25
#define KGDT64_R3_CMCODE
Definition: ketypes.h:135
static BOOLEAN KiIsPrivilegedInstruction(PUCHAR Ip, BOOLEAN Wow64)
Definition: except.c:446
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165

Referenced by KiGeneralProtectionFaultHandler().

◆ KiIsPrivilegedInstruction()

static BOOLEAN KiIsPrivilegedInstruction ( PUCHAR  Ip,
BOOLEAN  Wow64 
)
static

Definition at line 446 of file except.c.

447{
448 ULONG i;
449
450 /* Handle prefixes */
451 for (i = 0; i < 15; i++)
452 {
453 if (!Wow64)
454 {
455 /* Check for REX prefix */
456 if ((Ip[0] >= 0x40) && (Ip[0] <= 0x4F))
457 {
458 Ip++;
459 continue;
460 }
461 }
462
463 switch (Ip[0])
464 {
465 /* Check prefixes */
466 case 0x26: // ES
467 case 0x2E: // CS / null
468 case 0x36: // SS
469 case 0x3E: // DS
470 case 0x64: // FS
471 case 0x65: // GS
472 case 0x66: // OP
473 case 0x67: // ADDR
474 case 0xF0: // LOCK
475 case 0xF2: // REP
476 case 0xF3: // REP INS/OUTS
477 Ip++;
478 continue;
479 }
480
481 break;
482 }
483
484 if (i == 15)
485 {
486 /* Too many prefixes. Should only happen, when the code was concurrently modified. */
487 return FALSE;
488 }
489
490 switch (Ip[0])
491 {
492 case 0xF4: // HLT
493 case 0xFA: // CLI
494 case 0xFB: // STI
495 return TRUE;
496
497 case 0x0F:
498 {
499 switch (Ip[1])
500 {
501 case 0x06: // CLTS
502 case 0x07: // SYSRET
503 case 0x08: // INVD
504 case 0x09: // WBINVD
505 case 0x20: // MOV CR, XXX
506 case 0x21: // MOV DR, XXX
507 case 0x22: // MOV XXX, CR
508 case 0x23: // MOV YYY, DR
509 case 0x30: // WRMSR
510 case 0x32: // RDMSR
511 case 0x33: // RDPMC
512 case 0x35: // SYSEXIT
513 case 0x78: // VMREAD
514 case 0x79: // VMWRITE
515 return TRUE;
516
517 case 0x00:
518 {
519 /* Check MODRM Reg field */
520 switch ((Ip[2] >> 3) & 0x7)
521 {
522 case 2: // LLDT
523 case 3: // LTR
524 return TRUE;
525 }
526 break;
527 }
528
529 case 0x01:
530 {
531 switch (Ip[2])
532 {
533 case 0xC1: // VMCALL
534 case 0xC2: // VMLAUNCH
535 case 0xC3: // VMRESUME
536 case 0xC4: // VMXOFF
537 case 0xC8: // MONITOR
538 case 0xC9: // MWAIT
539 case 0xD1: // XSETBV
540 case 0xF8: // SWAPGS
541 return TRUE;
542 }
543
544 /* Check MODRM Reg field */
545 switch ((Ip[2] >> 3) & 0x7)
546 {
547 case 2: // LGDT
548 case 3: // LIDT
549 case 6: // LMSW
550 case 7: // INVLPG / SWAPGS / RDTSCP
551 return TRUE;
552 }
553 break;
554 }
555
556 case 0x38:
557 {
558 switch (Ip[2])
559 {
560 case 0x80: // INVEPT
561 case 0x81: // INVVPID
562 return TRUE;
563 }
564 break;
565 }
566
567 case 0xC7:
568 {
569 /* Check MODRM Reg field */
570 switch ((Ip[2] >> 3) & 0x7)
571 {
572 case 0x06: // VMPTRLD, VMCLEAR, VMXON
573 case 0x07: // VMPTRST
574 return TRUE;
575 }
576 break;
577 }
578 }
579
580 break;
581 }
582 }
583
584 return FALSE;
585}
uint32_t ULONG
Definition: typedefs.h:59

Referenced by KiGeneralProtectionFaultUserMode().

◆ KiNpxNotAvailableFaultHandler()

NTSTATUS NTAPI KiNpxNotAvailableFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 436 of file except.c.

438{
440 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
441 return -1;
442}
DECLSPEC_NORETURN VOID NTAPI KeBugCheckWithTf(ULONG BugCheckCode, ULONG_PTR BugCheckParameter1, ULONG_PTR BugCheckParameter2, ULONG_PTR BugCheckParameter3, ULONG_PTR BugCheckParameter4, PKTRAP_FRAME Tf)

◆ KiPageInDirectory()

static VOID KiPageInDirectory ( PVOID  ImageBase,
USHORT  Directory 
)
static

Definition at line 180 of file except.c.

181{
182 volatile CHAR *Pointer;
183 ULONG Size;
184
185 /* Get a pointer to the debug directory */
186 Pointer = RtlImageDirectoryEntryToData(ImageBase, 1, Directory, &Size);
187 if (!Pointer) return;
188
189 /* Loop all pages */
190 while ((LONG)Size > 0)
191 {
192 /* Touch it, to page it in */
193 (void)*Pointer;
194 Pointer += PAGE_SIZE;
195 Size -= PAGE_SIZE;
196 }
197}
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define PAGE_SIZE
Definition: env_spec_w32.h:49
long LONG
Definition: pedump.c:60
base for all directory entries
Definition: entries.h:138
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
char CHAR
Definition: xmlstorage.h:175

Referenced by KiPrepareUserDebugData().

◆ KiPrepareUserDebugData()

VOID KiPrepareUserDebugData ( void  )

Definition at line 200 of file except.c.

201{
202 PLDR_DATA_TABLE_ENTRY LdrEntry;
204 PLIST_ENTRY ListEntry;
205 PTEB Teb;
206
207 /* Get the Teb for this process */
208 Teb = KeGetCurrentThread()->Teb;
209 if (!Teb) return;
210
211 /* Enable interrupts */
212 _enable();
213
215 {
216 /* Get a pointer to the loader data */
218 if (!PebLdr) _SEH2_LEAVE;
219
220 /* Now loop all entries in the module list */
221 for (ListEntry = PebLdr->InLoadOrderModuleList.Flink;
222 ListEntry != &PebLdr->InLoadOrderModuleList;
223 ListEntry = ListEntry->Flink)
224 {
225 /* Get the loader entry */
226 LdrEntry = CONTAINING_RECORD(ListEntry,
228 InLoadOrderLinks);
229
232
235 }
236
237 }
239 {
240 }
241 _SEH2_END;
242
243 _disable();
244}
#define IMAGE_DIRECTORY_ENTRY_DEBUG
Definition: compat.h:152
#define _SEH2_LEAVE
Definition: filesup.c:20
#define KeGetCurrentThread
Definition: hal.h:55
PEB_LDR_DATA PebLdr
Definition: ldrinit.c:67
static VOID KiPageInDirectory(PVOID ImageBase, USHORT Directory)
Definition: except.c:180
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION
Definition: pedump.c:262
Definition: btrfs_drv.h:1876
PVOID DllBase
Definition: btrfs_drv.h:1880
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY InLoadOrderModuleList
Definition: ldrtypes.h:120
PPEB_LDR_DATA Ldr
Definition: btrfs_drv.h:1912
Definition: compat.h:836
PPEB ProcessEnvironmentBlock
Definition: ntddk_ex.h:337
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by KiDispatchException().

◆ KiSystemFatalException()

VOID DECLSPEC_NORETURN KiSystemFatalException ( IN ULONG  ExceptionCode,
IN PKTRAP_FRAME  TrapFrame 
)

Definition at line 422 of file except.c.

424{
425 /* Bugcheck the system */
426 KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
428 0,
429 0,
430 0,
431 TrapFrame);
432}
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774

◆ KiXmmExceptionHandler()

NTSTATUS NTAPI KiXmmExceptionHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 676 of file except.c.

678{
680
681 if ((TrapFrame->MxCsr & _MM_EXCEPT_INVALID) &&
682 !(TrapFrame->MxCsr & _MM_MASK_INVALID))
683 {
684 /* Invalid operation */
686 }
687 else if ((TrapFrame->MxCsr & _MM_EXCEPT_DENORM) &&
688 !(TrapFrame->MxCsr & _MM_MASK_DENORM))
689 {
690 /* Denormalized operand. Yes, this is what Windows returns. */
692 }
693 else if ((TrapFrame->MxCsr & _MM_EXCEPT_DIV_ZERO) &&
694 !(TrapFrame->MxCsr & _MM_MASK_DIV_ZERO))
695 {
696 /* Divide by zero */
698 }
699 else if ((TrapFrame->MxCsr & _MM_EXCEPT_OVERFLOW) &&
700 !(TrapFrame->MxCsr & _MM_MASK_OVERFLOW))
701 {
702 /* Overflow */
704 }
705 else if ((TrapFrame->MxCsr & _MM_EXCEPT_UNDERFLOW) &&
706 !(TrapFrame->MxCsr & _MM_MASK_UNDERFLOW))
707 {
708 /* Underflow */
710 }
711 else if ((TrapFrame->MxCsr & _MM_EXCEPT_INEXACT) &&
712 !(TrapFrame->MxCsr & _MM_MASK_INEXACT))
713 {
714 /* Precision */
716 }
717 else
718 {
719 /* Should not happen */
720 ASSERT(FALSE);
721 }
722
723 return ExceptionCode;
724}
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379
#define _MM_MASK_INVALID
Definition: xmmintrin.h:102
#define _MM_EXCEPT_DIV_ZERO
Definition: xmmintrin.h:96
#define _MM_MASK_DENORM
Definition: xmmintrin.h:103
#define _MM_EXCEPT_UNDERFLOW
Definition: xmmintrin.h:98
#define _MM_EXCEPT_INEXACT
Definition: xmmintrin.h:99
#define _MM_EXCEPT_OVERFLOW
Definition: xmmintrin.h:97
#define _MM_EXCEPT_INVALID
Definition: xmmintrin.h:94
#define _MM_MASK_DIV_ZERO
Definition: xmmintrin.h:104
#define _MM_EXCEPT_DENORM
Definition: xmmintrin.h:95
#define _MM_MASK_OVERFLOW
Definition: xmmintrin.h:105
#define _MM_MASK_INEXACT
Definition: xmmintrin.h:107
#define _MM_MASK_UNDERFLOW
Definition: xmmintrin.h:106

Variable Documentation

◆ KiIdt

KIDTENTRY64 KiIdt[256]

Definition at line 50 of file except.c.

Referenced by KeInitExceptions().

◆ KiIdtDescriptor

KDESCRIPTOR KiIdtDescriptor = {{0}, sizeof(KiIdt) - 1, KiIdt}

Definition at line 51 of file except.c.

Referenced by KeInitExceptions(), and KiSystemStartup().

◆ KiInterruptInitTable

KIDT_INIT KiInterruptInitTable[]
Initial value:
=
{
{0x00, 0x00, 0x00, KiDivideErrorFault},
{0x01, 0x00, 0x00, KiDebugTrapOrFault},
{0x02, 0x00, 0x03, KiNmiInterrupt},
{0x03, 0x03, 0x00, KiBreakpointTrap},
{0x04, 0x03, 0x00, KiOverflowTrap},
{0x05, 0x00, 0x00, KiBoundFault},
{0x06, 0x00, 0x00, KiInvalidOpcodeFault},
{0x07, 0x00, 0x00, KiNpxNotAvailableFault},
{0x08, 0x00, 0x01, KiDoubleFaultAbort},
{0x09, 0x00, 0x00, KiNpxSegmentOverrunAbort},
{0x0A, 0x00, 0x00, KiInvalidTssFault},
{0x0B, 0x00, 0x00, KiSegmentNotPresentFault},
{0x0C, 0x00, 0x00, KiStackFault},
{0x0D, 0x00, 0x00, KiGeneralProtectionFault},
{0x0E, 0x00, 0x00, KiPageFault},
{0x10, 0x00, 0x00, KiFloatingErrorFault},
{0x11, 0x00, 0x00, KiAlignmentFault},
{0x12, 0x00, 0x02, KiMcheckAbort},
{0x13, 0x00, 0x00, KiXmmException},
{0x1F, 0x00, 0x00, KiApcInterrupt},
{0x2C, 0x03, 0x00, KiRaiseAssertion},
{0x2D, 0x03, 0x00, KiDebugServiceTrap},
{0x2F, 0x00, 0x00, KiDpcInterrupt},
{0xE1, 0x00, 0x00, KiIpiInterrupt},
{0, 0, 0, 0}
}
VOID KiDebugServiceTrap(VOID)
VOID KiOverflowTrap(VOID)
VOID KiGeneralProtectionFault(VOID)
VOID KiInvalidOpcodeFault(VOID)
VOID KiXmmException(VOID)
VOID KiNpxSegmentOverrunAbort(VOID)
VOID KiInvalidTssFault(VOID)
VOID KiDebugTrapOrFault(VOID)
VOID KiDivideErrorFault(VOID)
VOID KiAlignmentFault(VOID)
VOID KiApcInterrupt(VOID)
Definition: trapc.c:229
VOID KiSegmentNotPresentFault(VOID)
VOID KiIpiInterrupt(VOID)
VOID KiBreakpointTrap(VOID)
VOID KiDoubleFaultAbort(VOID)
VOID KiNpxNotAvailableFault(VOID)
VOID KiBoundFault(VOID)
VOID KiStackFault(VOID)
VOID KiMcheckAbort(VOID)
VOID KiRaiseAssertion(VOID)
VOID KiDpcInterrupt(VOID)
VOID KiFloatingErrorFault(VOID)
VOID KiPageFault(VOID)
VOID KiNmiInterrupt(VOID)

Definition at line 20 of file except.c.

Referenced by KeInitExceptions().

◆ KiUnexpectedRange

KI_INTERRUPT_DISPATCH_ENTRY KiUnexpectedRange[256]
extern

Referenced by KeInitExceptions().