20#define KDB_STACK_SIZE (4096*3)
22#define KDB_STACK_ALIGN 16
23#define KDB_STACK_RESERVE (5 * sizeof(PVOID))
25#define KDB_STACK_ALIGN 4
26#define KDB_STACK_RESERVE sizeof(ULONG)
28#define KDB_MAXIMUM_BREAKPOINT_COUNT 256
29#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT 4
30#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT 256
33#define _STRING(x) __STRING(x)
40static ULONG KdbBreakPointCount = 0;
100 "BOUND range exceeded",
102 "No Math Coprocessor",
106 "Segment Not Present",
107 "Stack Segment Fault",
108 "General Protection",
244 KdbpPrint(
"Couldn't access memory at 0x%p\n", Eip);
249 while ((
i <
sizeof (Mem)) && (Mem[
i] == 0x66 || Mem[
i] == 0x67))
252 if (
i ==
sizeof (Mem))
255 if (Mem[
i] == 0xE8 || Mem[
i] == 0x9A || Mem[
i] == 0xF2 || Mem[
i] == 0xF3 ||
256 (((
i + 1) <
sizeof (Mem)) && Mem[
i] == 0xFF && (Mem[
i+1] & 0x38) == 0x10))
322 else if (Mem[0] == 0xcd)
336 if (IntVect >= (Idtr.
Limit + 1) / 8)
350 if ((IntDesc[1] & (1 << 15)) == 0)
354 if ((IntDesc[1] & 0x1f00) == 0x0500)
359 else if (((IntDesc[1] & 0x1fe0) == 0x0e00) ||
360 ((IntDesc[1] & 0x1fe0) == 0x0f00))
363 TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
431 bp = KdbBreakPoints + BreakPointNr;
444 *AccessType = bp->
Data.
Hw.AccessType;
447 *DebugReg = bp->
Data.
Hw.DebugReg;
459 if (ConditionExpression)
491 PCHAR ConditionExpressionDup;
507 KdbpPrint(
"Size must be 1 for execution breakpoints.\n");
518 if (ConditionExpression)
524 KdbpPrint(
"Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
526 KdbpPrint(
"Couldn't parse expression: %s", ErrMsg);
531 i =
strlen(ConditionExpression) + 1;
538 ConditionExpressionDup =
NULL;
574 KdbBreakPoints[
i].
Data.
Hw.AccessType = AccessType;
577 KdbBreakPointCount++;
605 if (BreakPointNr < 0)
608 BreakPointNr = BreakPoint - KdbBreakPoints;
613 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
619 BreakPoint = KdbBreakPoints + BreakPointNr;
624 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
632 KdbpPrint(
"Breakpoint %d deleted.\n", BreakPointNr);
635 KdbBreakPointCount--;
712 if (BreakPointNr < 0)
715 BreakPointNr = BreakPoint - KdbBreakPoints;
720 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
726 BreakPoint = KdbBreakPoints + BreakPointNr;
731 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
735 if (BreakPoint->Enabled)
737 KdbpPrint(
"Breakpoint %d is already enabled.\n", BreakPointNr);
746 KdbpPrint(
"Maximum number of SW breakpoints (%d) used. "
747 "Disable another breakpoint in order to enable this one.\n",
753 0xCC, &BreakPoint->Data.SavedInstruction);
756 KdbpPrint(
"Couldn't access memory at 0x%p\n", BreakPoint->Address);
765 ASSERT(BreakPoint->Data.Hw.Size == 1);
767 ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
771 KdbpPrint(
"Maximum number of HW breakpoints (%d) already used. "
772 "Disable another breakpoint in order to enable this one.\n",
815 switch (BreakPoint->Data.Hw.AccessType)
849 BreakPoint->Data.Hw.DebugReg =
i;
855 KdbpPrint(
"Breakpoint %d enabled.\n", BreakPointNr);
878 if (BreakPointNr < 0)
881 BreakPointNr = BreakPoint - KdbBreakPoints;
886 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
892 BreakPoint = KdbBreakPoints + BreakPointNr;
897 KdbpPrint(
"Invalid breakpoint: %d\n", BreakPointNr);
901 if (BreakPoint->Enabled ==
FALSE)
903 KdbpPrint(
"Breakpoint %d is not enabled.\n", BreakPointNr);
912 BreakPoint->Data.SavedInstruction,
NULL);
916 KdbpPrint(
"Couldn't restore original instruction.\n");
959 BreakPoint->Enabled =
FALSE;
961 KdbpPrint(
"Breakpoint %d disabled.\n", BreakPointNr);
1003 if (ExceptionNr < 0)
1007 if (ExceptionNr == 1 || ExceptionNr == 8 ||
1008 ExceptionNr == 9 || ExceptionNr == 15)
1019 ExceptionNr == 1 || ExceptionNr == 8 ||
1020 ExceptionNr == 9 || ExceptionNr == 15)
1055 KdbpPrint(
"Cannot attach to thread within another process while executing a DPC.\n");
1163 PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
1164 ULONG SavedStackLimit;
1272 KD_CONTINUE_TYPE ContinueType = kdHandleException;
1291 ContinueType = kdContinue;
1302 EnterConditionMet =
FALSE;
1320 KdbpPrint(
"Couldn't restore original instruction after INT3! Cannot continue execution.\n");
1361 goto continue_execution;
1382 goto continue_execution;
1398 goto continue_execution;
1404 KdbpPrint(
"\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
1409 KdbpPrint(
"\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
1435 KdbpPrint(
"Warning: Couldn't reenable breakpoint %d\n",
1436 BreakPoint - KdbBreakPoints);
1441 Context->EFlags &= ~EFLAGS_TF;
1445 goto continue_execution;
1461 Context->EFlags &= ~EFLAGS_TF;
1468 goto continue_execution;
1472 Context->EFlags &= ~EFLAGS_TF;
1478 if (!EnterConditionMet)
1480 return kdHandleException;
1483 KdbpPrint(
"\nEntered debugger on unexpected debug trap!\n");
1491 EnterConditionMet =
FALSE;
1493 if (!EnterConditionMet)
1495 return kdHandleException;
1498 KdbpPrint(
"\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
1505 (
"Unknown/User defined exception");
1507 if (!EnterConditionMet)
1509 return ContinueType;
1512 KdbpPrint(
"\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
1513 FirstChance ?
"first" :
"last",
ExceptionCode, ExceptionString);
1516 ExceptionRecord && ExceptionRecord->NumberParameters != 0)
1522 KdbpPrint(
"Memory at 0x%p could not be accessed\n", TrapCr2);
1550 return kdHandleException;
1623 return ContinueType;
1631#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
1633 while (p1 && (p1 =
strchr(p1,
' ')))
1636 while (*p1 ==
' ') ++p1;
ACPI_SIZE strlen(const char *String)
char * strchr(const char *String, int ch)
#define InterlockedIncrement
#define InterlockedDecrement
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
#define NT_SUCCESS(StatCode)
#define _strnicmp(_String1, _String2, _MaxCount)
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
#define ExAllocatePoolWithTag(hernya, size, tag)
#define PsGetCurrentThread()
#define KeRaiseIrql(irql, oldIrql)
#define KeLowerIrql(oldIrql)
#define KeGetCurrentIrql()
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
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
LONG KdbpGetInstLength(IN ULONG_PTR Address)
void __cdecl _disable(void)
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
__INTRIN_INLINE uintptr_t __readeflags(void)
__INTRIN_INLINE unsigned long __readcr2(void)
__INTRIN_INLINE void __sidt(void *Destination)
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
PEPROCESS KdbCurrentProcess
LONG KdbpGetNextBreakPointNr(IN ULONG Start OPTIONAL)
Gets the number of the next breakpoint >= Start.
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
PETHREAD KdbCurrentThread
KD_CONTINUE_TYPE KdbEnterDebuggerException(IN PEXCEPTION_RECORD64 ExceptionRecord, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT Context, IN BOOLEAN FirstChance)
KDB Exception filter.
PETHREAD KdbOriginalThread
static PKDB_BREAKPOINT KdbBreakPointToReenable
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
static LONG KdbpIsBreakPointOurs(IN NTSTATUS ExceptionCode, IN PCONTEXT Context)
Checks if the breakpoint was set by the debugger.
static KDB_KTRAP_FRAME KdbThreadTrapFrame
static KDB_KTRAP_FRAME KdbTrapFrame
static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
BOOLEAN KdbpSetEnterCondition(IN LONG ExceptionNr, IN BOOLEAN FirstChance, IN KDB_ENTER_CONDITION Condition)
Sets the first or last chance enter-condition for exception nr. ExceptionNr.
PEPROCESS KdbOriginalProcess
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
VOID NTAPI KdbpGetCommandLineSettings(PCHAR p1)
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT
BOOLEAN KdbpBugCheckRequested
BOOLEAN KdbpStepIntoInstruction(ULONG_PTR Eip)
Steps into an instruction (interrupts)
static NTSTATUS KdbpOverwriteInstruction(IN PEPROCESS Process, IN ULONG_PTR Address, IN UCHAR NewInst, OUT PUCHAR OldInst OPTIONAL)
Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.
BOOLEAN KdbpGetEnterCondition(IN LONG ExceptionNr, IN BOOLEAN FirstChance, OUT KDB_ENTER_CONDITION *Condition)
Gets the first or last chance enter-condition for exception nr. ExceptionNr.
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
static VOID KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack, PKDB_KTRAP_FRAME KdbTrapFrame)
BOOLEAN KdbpAttachToProcess(PVOID ProcessId)
Switches to another process/thread context.
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT
static BOOLEAN KdbEnteredOnSingleStep
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
#define KDB_STACK_RESERVE
static VOID KdbpInternalEnter(VOID)
Internal function to enter KDB.
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
NTSTATUS KdbpSafeWriteMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
#define KDB_MAXIMUM_BREAKPOINT_COUNT
BOOLEAN KdbpShouldStepOverInstruction(ULONG_PTR Eip)
Checks whether the given instruction can be single stepped or has to be stepped over using a temporar...
static LONG KdbEntryCount
BOOLEAN KdbSingleStepOver
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
NTSTATUS KdbpInsertBreakPoint(IN ULONG_PTR Address, IN KDB_BREAKPOINT_TYPE Type, IN UCHAR Size OPTIONAL, IN KDB_ACCESS_TYPE AccessType OPTIONAL, IN PCHAR ConditionExpression OPTIONAL, IN BOOLEAN Global, OUT PLONG BreakPointNr OPTIONAL)
Inserts a breakpoint into the breakpoint array.
static const CHAR * ExceptionNrToString[]
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
BOOLEAN KdbpStepOverInstruction(ULONG_PTR Eip)
Steps over an instruction.
static VOID KdbpCallMainLoop(VOID)
Calls the main loop ...
static ULONG KdbSwBreakPointCount
static ULONG KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode)
static KAPC_STATE KdbApcState
BOOLEAN KdbpGetBreakPointInfo(IN ULONG BreakPointNr, OUT ULONG_PTR *Address OPTIONAL, OUT KDB_BREAKPOINT_TYPE *Type OPTIONAL, OUT UCHAR *Size OPTIONAL, OUT KDB_ACCESS_TYPE *AccessType OPTIONAL, OUT UCHAR *DebugReg OPTIONAL, OUT BOOLEAN *Enabled OPTIONAL, OUT BOOLEAN *Global OPTIONAL, OUT PEPROCESS *Process OPTIONAL, OUT PCHAR *ConditionExpression OPTIONAL)
Returns information of the specified breakpoint.
static ULONG KdbHwBreakPointCount
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
VOID KdbpCliInterpretInitFile(VOID)
This function is called by KdbEnterDebuggerException...
PVOID KdbpRpnParseExpression(IN PCHAR Expression, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Parses the given expression and returns a "handle" to it.
BOOLEAN KdbpRpnEvaluateParsedExpression(IN PVOID Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression and returns the result.
VOID NTAPI KdbpStackSwitchAndCall(IN PVOID NewStack, IN VOID(*Function)(VOID))
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
VOID KbdDisableMouse(VOID)
VOID KbdEnableMouse(VOID)
enum _KDB_ACCESS_TYPE KDB_ACCESS_TYPE
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
enum _KDB_BREAKPOINT_TYPE KDB_BREAKPOINT_TYPE
KDP_DEBUG_MODE KdpDebugMode
VOID KdpScreenRelease(VOID)
VOID KdpScreenAcquire(VOID)
#define PAGE_ROUND_DOWN(x)
#define PAGE_EXECUTE_READ
#define DECLSPEC_ALIGN(x)
IN ULONG IN UCHAR Condition
#define KD_BREAKPOINT_SIZE
#define KeSetContextPc(Context, ProgramCounter)
#define KeGetContextPc(Context)
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
#define MMDBG_COPY_UNSAFE
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
_Out_ PKAPC_STATE ApcState
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
#define STATUS_ILLEGAL_INSTRUCTION
#define STATUS_ARRAY_BOUNDS_EXCEEDED
#define STATUS_ASSERTION_FAILURE
#define STATUS_MEMORY_NOT_ALLOCATED
#define STATUS_STACK_OVERFLOW
#define STATUS_SINGLE_STEP
#define STATUS_BREAKPOINT
#define STATUS_FLOAT_MULTIPLE_TRAPS
#define STATUS_ACCESS_VIOLATION
#define STATUS_FLOAT_INVALID_OPERATION
#define STATUS_DATATYPE_MISALIGNMENT
#define STATUS_INTEGER_OVERFLOW
#define STATUS_INTEGER_DIVIDE_BY_ZERO
VOID NTAPI KeDetachProcess(VOID)
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
PULONG MinorVersion OPTIONAL
base of all file and directory entries
LIST_ENTRY ThreadListHead
union _KDB_BREAKPOINT::@1786 Data
PCHAR ConditionExpression
struct _KDB_BREAKPOINT::@1786::@1787 Hw
volatile VOID * StackLimit
#define RtlCopyMemory(Destination, Source, Length)
#define RtlZeroMemory(Destination, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_UNSUCCESSFUL
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
#define ObDereferenceObject
#define PsGetCurrentProcess
_In_ KPROCESSOR_MODE PreviousMode
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect