ReactOS 0.4.15-dev-7660-g0086d05
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 VOID 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
_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
#define KeGetPcr()
Definition: ke.h:26
USHORT Limit
Definition: ketypes.h:555
UCHAR Dpl
Definition: ke.h:96
UCHAR IstIndex
Definition: ke.h:97
ULONG OffsetHigh
Definition: ketypes.h:544
USHORT Reserved0
Definition: ketypes.h:539
USHORT IstIndex
Definition: ketypes.h:538
USHORT OffsetMiddle
Definition: ketypes.h:543
USHORT OffsetLow
Definition: ketypes.h:536
ULONG Reserved1
Definition: ketypes.h:545
USHORT Dpl
Definition: ketypes.h:541
USHORT Present
Definition: ketypes.h:542
USHORT Selector
Definition: ketypes.h:537
USHORT Type
Definition: ketypes.h:540
_In_ PKSERVICE_ROUTINE ServiceRoutine
Definition: iofuncs.h:800

◆ KeRaiseUserException()

NTSTATUS NTAPI KeRaiseUserException ( IN NTSTATUS  ExceptionCode)

Definition at line 409 of file except.c.

410{
412 return STATUS_UNSUCCESSFUL;
413}
#define UNIMPLEMENTED
Definition: debug.h:115
#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 (does not return, if successful) */
365 KiDispatchExceptionToUser(TrapFrame, &Context, ExceptionRecord);
366
367 /* Failed to dispatch, fall through for second chance handling */
368 }
369
370 /* Try second chance */
371 if (DbgkForwardException(ExceptionRecord, TRUE, TRUE))
372 {
373 /* Handled, get out */
374 return;
375 }
376 else if (DbgkForwardException(ExceptionRecord, FALSE, TRUE))
377 {
378 /* Handled, get out */
379 return;
380 }
381
382 /* 3rd strike, kill the process */
383 DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %lx, BaseAddress: %lx\n",
384 PsGetCurrentProcess()->ImageFileName,
385 ExceptionRecord->ExceptionCode,
386 ExceptionRecord->ExceptionAddress,
387 PsGetCurrentProcess()->SectionBaseAddress);
388
389 ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
390 KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,
391 ExceptionRecord->ExceptionCode,
392 (ULONG_PTR)ExceptionRecord->ExceptionAddress,
393 (ULONG_PTR)TrapFrame,
394 0);
395 }
396
397Handled:
398 /* Convert the context back into Trap/Exception Frames */
400 ExceptionFrame,
401 TrapFrame,
402 Context.ContextFlags,
404 return;
405}
#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:86
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:1148
#define KI_EXCEPTION_ACCESS_VIOLATION
Definition: ketypes.h:144
NTSYSAPI BOOLEAN NTAPI RtlDispatchException(_In_ PEXCEPTION_RECORD ExceptionRecord, _In_ PCONTEXT Context)
Definition: except.c:87
#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 VOID 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 VOID 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 _SEH2_YIELD(return);
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 KiServiceExit2(TrapFrame);
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
#define KiServiceExit2
Definition: ke.h:5
PVOID KeUserExceptionDispatcher
Definition: ke.h:143
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
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:1083
EXCEPTION_RECORD ExceptionRecord
Definition: ketypes.h:1081
USHORT SegSs
Definition: ketypes.h:1050
ULONG EFlags
Definition: ketypes.h:1047
ULONG64 Rsp
Definition: ketypes.h:1049
ULONG64 Rip
Definition: ketypes.h:1044
USHORT SegCs
Definition: ketypes.h:1045

Referenced by KiDispatchException().

◆ KiGeneralProtectionFaultHandler()

NTSTATUS NTAPI KiGeneralProtectionFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 621 of file except.c.

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

587{
588 BOOLEAN Wow64 = TrapFrame->SegCs == KGDT64_R3_CMCODE;
589 PUCHAR InstructionPointer;
591
592 /* We need to decode the instruction at RIP */
593 InstructionPointer = (PUCHAR)TrapFrame->Rip;
594
596 {
597 /* Probe the instruction address */
598 ProbeForRead(InstructionPointer, 64, 1);
599
600 /* Check if it's a privileged instruction */
601 if (KiIsPrivilegedInstruction(InstructionPointer, Wow64))
602 {
604 }
605 else
606 {
608 }
609 }
611 {
613 }
615
616 return Status;
617}
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:442
#define STATUS_PRIVILEGED_INSTRUCTION
Definition: ntstatus.h:386
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159

Referenced by KiGeneralProtectionFaultHandler().

◆ KiIsPrivilegedInstruction()

static BOOLEAN KiIsPrivilegedInstruction ( PUCHAR  Ip,
BOOLEAN  Wow64 
)
static

Definition at line 442 of file except.c.

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

Referenced by KiGeneralProtectionFaultUserMode().

◆ KiNpxNotAvailableFaultHandler()

NTSTATUS NTAPI KiNpxNotAvailableFaultHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 432 of file except.c.

434{
436 KeBugCheckWithTf(TRAP_CAUSE_UNKNOWN, 13, 0, 0, 1, TrapFrame);
437 return -1;
438}
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 418 of file except.c.

420{
421 /* Bugcheck the system */
422 KeBugCheckWithTf(UNEXPECTED_KERNEL_MODE_TRAP,
424 0,
425 0,
426 0,
427 TrapFrame);
428}
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774

◆ KiXmmExceptionHandler()

NTSTATUS NTAPI KiXmmExceptionHandler ( IN PKTRAP_FRAME  TrapFrame)

Definition at line 672 of file except.c.

674{
676
677 if ((TrapFrame->MxCsr & _MM_EXCEPT_INVALID) &&
678 !(TrapFrame->MxCsr & _MM_MASK_INVALID))
679 {
680 /* Invalid operation */
682 }
683 else if ((TrapFrame->MxCsr & _MM_EXCEPT_DENORM) &&
684 !(TrapFrame->MxCsr & _MM_MASK_DENORM))
685 {
686 /* Denormalized operand. Yes, this is what Windows returns. */
688 }
689 else if ((TrapFrame->MxCsr & _MM_EXCEPT_DIV_ZERO) &&
690 !(TrapFrame->MxCsr & _MM_MASK_DIV_ZERO))
691 {
692 /* Divide by zero */
694 }
695 else if ((TrapFrame->MxCsr & _MM_EXCEPT_OVERFLOW) &&
696 !(TrapFrame->MxCsr & _MM_MASK_OVERFLOW))
697 {
698 /* Overflow */
700 }
701 else if ((TrapFrame->MxCsr & _MM_EXCEPT_UNDERFLOW) &&
702 !(TrapFrame->MxCsr & _MM_MASK_UNDERFLOW))
703 {
704 /* Underflow */
706 }
707 else if ((TrapFrame->MxCsr & _MM_EXCEPT_INEXACT) &&
708 !(TrapFrame->MxCsr & _MM_MASK_INEXACT))
709 {
710 /* Precision */
712 }
713 else
714 {
715 /* Should not happen */
716 ASSERT(FALSE);
717 }
718
719 return ExceptionCode;
720}
#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().