19#define KDB_STACK_SIZE (4096*3)
21#define KDB_STACK_ALIGN 16
22#define KDB_STACK_RESERVE (5 * sizeof(PVOID))
24#define KDB_STACK_ALIGN 4
25#define KDB_STACK_RESERVE sizeof(ULONG)
27#define KDB_MAXIMUM_BREAKPOINT_COUNT 256
28#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT 4
29#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT 256
32#define _STRING(x) __STRING(x)
39static ULONG KdbBreakPointCount = 0;
98 "BOUND range exceeded",
100 "No Math Coprocessor",
104 "Segment Not Present",
105 "Stack Segment Fault",
106 "General Protection",
242 KdbPrintf(
"Couldn't access memory at 0x%p\n", Eip);
247 while ((
i <
sizeof (Mem)) && (Mem[
i] == 0x66 || Mem[
i] == 0x67))
250 if (
i ==
sizeof (Mem))
253 if (Mem[
i] == 0xE8 || Mem[
i] == 0x9A || Mem[
i] == 0xF2 || Mem[
i] == 0xF3 ||
254 (((
i + 1) <
sizeof (Mem)) && Mem[
i] == 0xFF && (Mem[
i+1] & 0x38) == 0x10))
320 else if (Mem[0] == 0xcd)
334 if (IntVect >= (Idtr.
Limit + 1) / 8)
348 if ((IntDesc[1] & (1 << 15)) == 0)
352 if ((IntDesc[1] & 0x1f00) == 0x0500)
357 else if (((IntDesc[1] & 0x1fe0) == 0x0e00) ||
358 ((IntDesc[1] & 0x1fe0) == 0x0f00))
361 TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
429 bp = KdbBreakPoints + BreakPointNr;
442 *AccessType = bp->
Data.
Hw.AccessType;
445 *DebugReg = bp->
Data.
Hw.DebugReg;
457 if (ConditionExpression)
489 PCHAR ConditionExpressionDup;
505 KdbPuts(
"Size must be 1 for execution breakpoints.\n");
516 if (ConditionExpression)
522 KdbPrintf(
"Couldn't parse expression: %s at character %d\n",
ErrMsg, ErrOffset);
529 i =
strlen(ConditionExpression) + 1;
536 ConditionExpressionDup =
NULL;
572 KdbBreakPoints[
i].
Data.
Hw.AccessType = AccessType;
575 KdbBreakPointCount++;
603 if (BreakPointNr < 0)
606 BreakPointNr = BreakPoint - KdbBreakPoints;
611 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
617 BreakPoint = KdbBreakPoints + BreakPointNr;
622 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
630 KdbPrintf(
"Breakpoint %d deleted.\n", BreakPointNr);
633 KdbBreakPointCount--;
710 if (BreakPointNr < 0)
713 BreakPointNr = BreakPoint - KdbBreakPoints;
718 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
724 BreakPoint = KdbBreakPoints + BreakPointNr;
729 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
733 if (BreakPoint->Enabled)
735 KdbPrintf(
"Breakpoint %d is already enabled.\n", BreakPointNr);
744 KdbPrintf(
"Maximum number of SW breakpoints (%d) used. "
745 "Disable another breakpoint in order to enable this one.\n",
751 0xCC, &BreakPoint->Data.SavedInstruction);
754 KdbPrintf(
"Couldn't access memory at 0x%p\n", BreakPoint->Address);
763 ASSERT(BreakPoint->Data.Hw.Size == 1);
765 ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
769 KdbPrintf(
"Maximum number of HW breakpoints (%d) already used. "
770 "Disable another breakpoint in order to enable this one.\n",
812 switch (BreakPoint->Data.Hw.AccessType)
846 BreakPoint->Data.Hw.DebugReg =
i;
852 KdbPrintf(
"Breakpoint %d enabled.\n", BreakPointNr);
875 if (BreakPointNr < 0)
878 BreakPointNr = BreakPoint - KdbBreakPoints;
883 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
889 BreakPoint = KdbBreakPoints + BreakPointNr;
894 KdbPrintf(
"Invalid breakpoint: %d\n", BreakPointNr);
898 if (BreakPoint->Enabled ==
FALSE)
900 KdbPrintf(
"Breakpoint %d is not enabled.\n", BreakPointNr);
909 BreakPoint->Data.SavedInstruction,
NULL);
913 KdbPuts(
"Couldn't restore original instruction.\n");
956 BreakPoint->Enabled =
FALSE;
958 KdbPrintf(
"Breakpoint %d disabled.\n", BreakPointNr);
1000 if (ExceptionNr < 0)
1004 if (ExceptionNr == 1 || ExceptionNr == 8 ||
1005 ExceptionNr == 9 || ExceptionNr == 15)
1016 ExceptionNr == 1 || ExceptionNr == 8 ||
1017 ExceptionNr == 9 || ExceptionNr == 15)
1052 KdbpPrint(
"Cannot attach to thread within another process while executing a DPC.\n");
1160 PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
1161 ULONG SavedStackLimit;
1299 EnterConditionMet =
FALSE;
1317 KdbPuts(
"Couldn't restore original instruction after INT3! Cannot continue execution.\n");
1358 goto continue_execution;
1379 goto continue_execution;
1395 goto continue_execution;
1401 KdbPrintf(
"\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
1406 KdbPrintf(
"\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
1432 KdbPrintf(
"Warning: Couldn't reenable breakpoint %d\n",
1433 BreakPoint - KdbBreakPoints);
1438 Context->EFlags &= ~EFLAGS_TF;
1442 goto continue_execution;
1458 Context->EFlags &= ~EFLAGS_TF;
1465 goto continue_execution;
1469 Context->EFlags &= ~EFLAGS_TF;
1475 if (!EnterConditionMet)
1480 KdbPuts(
"\nEntered debugger on unexpected debug trap!\n");
1488 EnterConditionMet =
FALSE;
1490 if (!EnterConditionMet)
1495 KdbPrintf(
"\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
1502 "Unknown/User defined exception";
1504 if (!EnterConditionMet)
1506 return ContinueType;
1509 KdbPrintf(
"\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
1510 FirstChance ?
"first" :
"last",
ExceptionCode, ExceptionString);
1513 ExceptionRecord && ExceptionRecord->NumberParameters != 0)
1516 KdbPrintf(
"Memory at 0x%p could not be accessed\n", TrapCr2);
1617 return ContinueType;
1624#define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
1629 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)
KDP_DEBUG_MODE KdpDebugMode
VOID KdpScreenRelease(VOID)
VOID KdpScreenAcquire(VOID)
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.
#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 ...
VOID KdbpGetCommandLineSettings(_In_ PCSTR p1)
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 _KD_CONTINUE_TYPE KD_CONTINUE_TYPE
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 KdbPuts(_In_ PCSTR String)
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
VOID __cdecl KdbPrintf(_In_ PCSTR Format,...)
enum _KDB_ACCESS_TYPE KDB_ACCESS_TYPE
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
enum _KDB_BREAKPOINT_TYPE KDB_BREAKPOINT_TYPE
VOID KbdDisableMouse(VOID)
VOID KbdEnableMouse(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 KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
static int ErrMsg(int Error)
PULONG MinorVersion OPTIONAL
base of all file and directory entries
LIST_ENTRY ThreadListHead
union _KDB_BREAKPOINT::@1817 Data
PCHAR ConditionExpression
struct _KDB_BREAKPOINT::@1817::@1818 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