ReactOS  0.4.15-dev-5452-g3c95c95
kdb.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for kdb.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define KDB_STACK_SIZE   (4096*3)
 
#define KDB_STACK_ALIGN   4
 
#define KDB_STACK_RESERVE   sizeof(ULONG) /* Return address */
 
#define KDB_MAXIMUM_BREAKPOINT_COUNT   256
 
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT   4
 
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT   256
 
#define __STRING(x)   #x
 
#define _STRING(x)   __STRING(x)
 
#define CONST_STR_LEN(x)   (sizeof(x)/sizeof(x[0]) - 1)
 

Functions

static DECLSPEC_ALIGN (KDB_STACK_ALIGN)
 
static VOID KdbpKdbTrapFrameFromKernelStack (PVOID KernelStack, PKDB_KTRAP_FRAME KdbTrapFrame)
 
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. More...
 
BOOLEAN KdbpShouldStepOverInstruction (ULONG_PTR Eip)
 Checks whether the given instruction can be single stepped or has to be stepped over using a temporary breakpoint. More...
 
BOOLEAN KdbpStepOverInstruction (ULONG_PTR Eip)
 Steps over an instruction. More...
 
BOOLEAN KdbpStepIntoInstruction (ULONG_PTR Eip)
 Steps into an instruction (interrupts) More...
 
LONG KdbpGetNextBreakPointNr (IN ULONG Start OPTIONAL)
 Gets the number of the next breakpoint >= Start. More...
 
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. More...
 
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. More...
 
BOOLEAN KdbpDeleteBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Deletes a breakpoint. More...
 
static LONG KdbpIsBreakPointOurs (IN NTSTATUS ExceptionCode, IN PCONTEXT Context)
 Checks if the breakpoint was set by the debugger. More...
 
BOOLEAN KdbpEnableBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Enables a breakpoint. More...
 
BOOLEAN KdbpDisableBreakPoint (IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
 Disables a breakpoint. More...
 
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. More...
 
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. More...
 
BOOLEAN KdbpAttachToThread (PVOID ThreadId)
 Switches to another thread context. More...
 
BOOLEAN KdbpAttachToProcess (PVOID ProcessId)
 Switches to another process/thread context. More...
 
static VOID KdbpCallMainLoop (VOID)
 Calls the main loop ... More...
 
static VOID KdbpInternalEnter (VOID)
 Internal function to enter KDB. More...
 
static ULONG KdbpGetExceptionNumberFromStatus (IN NTSTATUS ExceptionCode)
 
KD_CONTINUE_TYPE KdbEnterDebuggerException (IN PEXCEPTION_RECORD64 ExceptionRecord, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT Context, IN BOOLEAN FirstChance)
 KDB Exception filter. More...
 
KD_CONTINUE_TYPE KdbEnterDebuggerFirstChanceException (IN OUT PKTRAP_FRAME TrapFrame)
 
VOID NTAPI KdbpGetCommandLineSettings (PCHAR p1)
 
NTSTATUS KdbpSafeReadMemory (OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
 
NTSTATUS KdbpSafeWriteMemory (OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
 

Variables

static LONG KdbEntryCount = 0
 
static ULONG KdbSwBreakPointCount = 0
 
static ULONG KdbHwBreakPointCount = 0
 
static PKDB_BREAKPOINT KdbSwBreakPoints [KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
 
static PKDB_BREAKPOINT KdbHwBreakPoints [KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
 
static PKDB_BREAKPOINT KdbBreakPointToReenable = NULL
 
static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
 
LONG KdbLastBreakPointNr = -1
 
ULONG KdbNumSingleSteps = 0
 
BOOLEAN KdbSingleStepOver = FALSE
 
ULONG KdbDebugState = 0
 
static BOOLEAN KdbEnteredOnSingleStep = FALSE
 
PEPROCESS KdbCurrentProcess = NULL
 
PEPROCESS KdbOriginalProcess = NULL
 
PETHREAD KdbCurrentThread = NULL
 
PETHREAD KdbOriginalThread = NULL
 
PKDB_KTRAP_FRAME KdbCurrentTrapFrame = NULL
 
static KDB_KTRAP_FRAME KdbTrapFrame = { 0 }
 
static KDB_KTRAP_FRAME KdbThreadTrapFrame = { 0 }
 
static KAPC_STATE KdbApcState
 
BOOLEAN KdbpBugCheckRequested
 
static KDB_ENTER_CONDITION KdbEnterConditions [][2]
 
static const CHARExceptionNrToString []
 

Macro Definition Documentation

◆ __STRING

#define __STRING (   x)    #x

Definition at line 32 of file kdb.c.

◆ _STRING

#define _STRING (   x)    __STRING(x)

Definition at line 33 of file kdb.c.

◆ CONST_STR_LEN

#define CONST_STR_LEN (   x)    (sizeof(x)/sizeof(x[0]) - 1)

◆ KDB_MAXIMUM_BREAKPOINT_COUNT

#define KDB_MAXIMUM_BREAKPOINT_COUNT   256

Definition at line 28 of file kdb.c.

◆ KDB_MAXIMUM_HW_BREAKPOINT_COUNT

#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT   4

Definition at line 29 of file kdb.c.

◆ KDB_MAXIMUM_SW_BREAKPOINT_COUNT

#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT   256

Definition at line 30 of file kdb.c.

◆ KDB_STACK_ALIGN

#define KDB_STACK_ALIGN   4

Definition at line 25 of file kdb.c.

◆ KDB_STACK_RESERVE

#define KDB_STACK_RESERVE   sizeof(ULONG) /* Return address */

Definition at line 26 of file kdb.c.

◆ KDB_STACK_SIZE

#define KDB_STACK_SIZE   (4096*3)

Definition at line 20 of file kdb.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file kdb.c.

Function Documentation

◆ DECLSPEC_ALIGN()

static DECLSPEC_ALIGN ( KDB_STACK_ALIGN  )
static

Definition at line 38 of file kdb.c.

41  {{0}}; /* Breakpoint array */

◆ KdbEnterDebuggerException()

KD_CONTINUE_TYPE KdbEnterDebuggerException ( IN PEXCEPTION_RECORD64  ExceptionRecord,
IN KPROCESSOR_MODE  PreviousMode,
IN PCONTEXT  Context,
IN BOOLEAN  FirstChance 
)

KDB Exception filter.

Called by the exception dispatcher.

Parameters
ExceptionRecordUnused.
PreviousModeUserMode if the exception was raised from umode, otherwise KernelMode.
ContextContext, IN/OUT parameter.
TrapFrameException TrapFrame.
FirstChanceTRUE when called before exception frames were serached, FALSE for the second call.
Returns
KD_CONTINUE_TYPE

Definition at line 1265 of file kdb.c.

1270 {
1271  KDB_ENTER_CONDITION EnterCondition;
1272  KD_CONTINUE_TYPE ContinueType = kdHandleException;
1273  PKDB_BREAKPOINT BreakPoint;
1274  ULONG ExpNr;
1275  ULONGLONG ull;
1276  BOOLEAN Resume = FALSE;
1277  BOOLEAN EnterConditionMet = TRUE;
1278  ULONG OldEflags;
1279  KIRQL OldIrql;
1281 
1282  ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);
1283 
1285 
1286  /* Set continue type to kdContinue for single steps and breakpoints */
1290  {
1291  ContinueType = kdContinue;
1292  }
1293 
1294  /* Check if we should handle the exception. */
1295  /* FIXME - won't get all exceptions here :( */
1297  EnterCondition = KdbEnterConditions[ExpNr][FirstChance ? 0 : 1];
1298  if (EnterCondition == KdbDoNotEnter ||
1299  (EnterCondition == KdbEnterFromUmode && PreviousMode == KernelMode) ||
1300  (EnterCondition == KdbEnterFromKmode && PreviousMode != KernelMode))
1301  {
1302  EnterConditionMet = FALSE;
1303  }
1304 
1305  /* If we stopped on one of our breakpoints then let the user know */
1306  KdbLastBreakPointNr = -1;
1308 
1309  if (FirstChance && (ExceptionCode == STATUS_SINGLE_STEP || ExceptionCode == STATUS_BREAKPOINT) &&
1311  {
1312  BreakPoint = KdbBreakPoints + KdbLastBreakPointNr;
1313 
1315  {
1316  /* ... and restore the original instruction */
1318  BreakPoint->Data.SavedInstruction, NULL)))
1319  {
1320  KdbpPrint("Couldn't restore original instruction after INT3! Cannot continue execution.\n");
1321  KeBugCheck(0); // FIXME: Proper bugcode!
1322  }
1323 
1324  /* Also since we are past the int3 now, decrement EIP in the
1325  TrapFrame. This is only needed because KDBG insists on working
1326  with the TrapFrame instead of with the Context, as it is supposed
1327  to do. The context has already EIP point to the int3, since
1328  KiDispatchException accounts for that. Whatever we do here with
1329  the TrapFrame does not matter anyway, since KiDispatchException
1330  will overwrite it with the values from the Context! */
1332  }
1333 
1334  if ((BreakPoint->Type == KdbBreakPointHardware) &&
1335  (BreakPoint->Data.Hw.AccessType == KdbAccessExec))
1336  {
1337  Resume = TRUE; /* Set the resume flag when continuing execution */
1338  }
1339 
1340  /*
1341  * When a temporary breakpoint is hit we have to make sure that we are
1342  * in the same context in which it was set, otherwise it could happen
1343  * that another process/thread hits it before and it gets deleted.
1344  */
1345  else if (BreakPoint->Type == KdbBreakPointTemporary &&
1346  BreakPoint->Process == KdbCurrentProcess)
1347  {
1348  ASSERT((Context->EFlags & EFLAGS_TF) == 0);
1349 
1350  /* Delete the temporary breakpoint which was used to step over or into the instruction */
1351  KdbpDeleteBreakPoint(-1, BreakPoint);
1352 
1353  if (--KdbNumSingleSteps > 0)
1354  {
1357  {
1358  Context->EFlags |= EFLAGS_TF;
1359  }
1360 
1361  goto continue_execution; /* return */
1362  }
1363 
1365  }
1366 
1367  /*
1368  * If we hit a breakpoint set by the debugger we set the single step flag,
1369  * ignore the next single step and reenable the breakpoint.
1370  */
1371  else if (BreakPoint->Type == KdbBreakPointSoftware ||
1372  BreakPoint->Type == KdbBreakPointTemporary)
1373  {
1375  Context->EFlags |= EFLAGS_TF;
1376  KdbBreakPointToReenable = BreakPoint;
1377  }
1378 
1379  /* Make sure that the breakpoint should be triggered in this context */
1380  if (!BreakPoint->Global && BreakPoint->Process != KdbCurrentProcess)
1381  {
1382  goto continue_execution; /* return */
1383  }
1384 
1385  /* Check if the condition for the breakpoint is met. */
1386  if (BreakPoint->Condition)
1387  {
1388  /* Setup the KDB trap frame */
1389  KdbTrapFrame = *Context;
1390 
1391  ull = 0;
1392  if (!KdbpRpnEvaluateParsedExpression(BreakPoint->Condition, &KdbTrapFrame, &ull, NULL, NULL))
1393  {
1394  /* FIXME: Print warning? */
1395  }
1396  else if (ull == 0) /* condition is not met */
1397  {
1398  goto continue_execution; /* return */
1399  }
1400  }
1401 
1402  if (BreakPoint->Type == KdbBreakPointSoftware)
1403  {
1404  KdbpPrint("\nEntered debugger on breakpoint #%d: EXEC 0x%04x:0x%p\n",
1405  KdbLastBreakPointNr, Context->SegCs & 0xffff, KeGetContextPc(Context));
1406  }
1407  else if (BreakPoint->Type == KdbBreakPointHardware)
1408  {
1409  KdbpPrint("\nEntered debugger on breakpoint #%d: %s 0x%08x\n",
1411  (BreakPoint->Data.Hw.AccessType == KdbAccessRead) ? "READ" :
1412  ((BreakPoint->Data.Hw.AccessType == KdbAccessWrite) ? "WRITE" :
1413  ((BreakPoint->Data.Hw.AccessType == KdbAccessReadWrite) ? "RDWR" : "EXEC")),
1414  BreakPoint->Address);
1415  }
1416  }
1417  else if (ExceptionCode == STATUS_SINGLE_STEP)
1418  {
1419  /* Silently ignore a debugger initiated single step. */
1420  if ((Context->Dr6 & 0xf) == 0 && KdbBreakPointToReenable)
1421  {
1422  /* FIXME: Make sure that the breakpoint was really hit (check bp->Address vs. tf->Eip) */
1423  BreakPoint = KdbBreakPointToReenable;
1425  ASSERT(BreakPoint->Type == KdbBreakPointSoftware ||
1426  BreakPoint->Type == KdbBreakPointTemporary);
1427 
1428  /*
1429  * Reenable the breakpoint we disabled to execute the breakpointed
1430  * instruction.
1431  */
1433  &BreakPoint->Data.SavedInstruction)))
1434  {
1435  KdbpPrint("Warning: Couldn't reenable breakpoint %d\n",
1436  BreakPoint - KdbBreakPoints);
1437  }
1438 
1439  /* Unset TF if we are no longer single stepping. */
1440  if (KdbNumSingleSteps == 0)
1441  Context->EFlags &= ~EFLAGS_TF;
1442 
1444  {
1445  goto continue_execution; /* return */
1446  }
1447  }
1448 
1449  /* Quoth the raven, 'Nevermore!' */
1451 
1452  /* Check if we expect a single step */
1453  if ((Context->Dr6 & 0xf) == 0 && KdbNumSingleSteps > 0)
1454  {
1455  /*ASSERT((Context->Eflags & EFLAGS_TF) != 0);*/
1456  if (--KdbNumSingleSteps > 0)
1457  {
1460  {
1461  Context->EFlags &= ~EFLAGS_TF;
1462  }
1463  else
1464  {
1465  Context->EFlags |= EFLAGS_TF;
1466  }
1467 
1468  goto continue_execution; /* return */
1469  }
1470  else
1471  {
1472  Context->EFlags &= ~EFLAGS_TF;
1474  }
1475  }
1476  else
1477  {
1478  if (!EnterConditionMet)
1479  {
1480  return kdHandleException;
1481  }
1482 
1483  KdbpPrint("\nEntered debugger on unexpected debug trap!\n");
1484  }
1485  }
1486  else if (ExceptionCode == STATUS_BREAKPOINT)
1487  {
1488  if (KdbInitFileBuffer)
1489  {
1491  EnterConditionMet = FALSE;
1492  }
1493  if (!EnterConditionMet)
1494  {
1495  return kdHandleException;
1496  }
1497 
1498  KdbpPrint("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
1499  Context->SegCs & 0xffff, KeGetContextPc(Context));
1500  }
1501  else
1502  {
1503  const CHAR *ExceptionString = (ExpNr < RTL_NUMBER_OF(ExceptionNrToString)) ?
1504  (ExceptionNrToString[ExpNr]) :
1505  ("Unknown/User defined exception");
1506 
1507  if (!EnterConditionMet)
1508  {
1509  return ContinueType;
1510  }
1511 
1512  KdbpPrint("\nEntered debugger on %s-chance exception (Exception Code: 0x%x) (%s)\n",
1513  FirstChance ? "first" : "last", ExceptionCode, ExceptionString);
1514 
1516  ExceptionRecord && ExceptionRecord->NumberParameters != 0)
1517  {
1518  ULONG_PTR TrapCr2;
1519 
1520  TrapCr2 = __readcr2();
1521 
1522  KdbpPrint("Memory at 0x%p could not be accessed\n", TrapCr2);
1523  }
1524  }
1525 
1526  /* Once we enter the debugger we do not expect any more single steps to happen */
1527  KdbNumSingleSteps = 0;
1528 
1529  /* Update the current process pointer */
1533 
1534  /* Setup the KDB trap frame */
1535  KdbTrapFrame = *Context;
1536 
1537  /* Enter critical section */
1538  OldEflags = __readeflags();
1539  _disable();
1540 
1541  /* HACK: Save the current IRQL and pretend we are at dispatch level */
1543  if (OldIrql > DISPATCH_LEVEL)
1545 
1546  /* Exception inside the debugger? Game over. */
1548  {
1549  __writeeflags(OldEflags);
1550  return kdHandleException;
1551  }
1552 
1553  /* Call the main loop */
1555 
1556  /* Check if we should single step */
1557  if (KdbNumSingleSteps > 0)
1558  {
1559  /* Variable explains itself! */
1561 
1564  {
1566  /*KdbCurrentTrapFrame->EFlags &= ~EFLAGS_TF;*/
1567  }
1568  else
1569  {
1571  }
1572  }
1573 
1574  /* We can't update the current thread's trapframe 'cause it might not have one */
1575 
1576  /* Detach from attached process */
1578  {
1580  }
1581 
1582  /* Update the exception Context */
1583  *Context = KdbTrapFrame;
1584 
1585  /* Decrement the entry count */
1587 
1588  /* HACK: Raise back to old IRQL */
1589  if (OldIrql > DISPATCH_LEVEL)
1591 
1592  /* Leave critical section */
1593  __writeeflags(OldEflags);
1594 
1595  /* Check if user requested a bugcheck */
1597  {
1598  /* Clear the flag and bugcheck the system */
1600  KeBugCheck(MANUALLY_INITIATED_CRASH);
1601  }
1602 
1603 continue_execution:
1604  /* Clear debug status */
1605  if (ExceptionCode == STATUS_BREAKPOINT) /* FIXME: Why clear DR6 on INT3? */
1606  {
1607  /* Set the RF flag so we don't trigger the same breakpoint again. */
1608  if (Resume)
1609  {
1610  Context->EFlags |= EFLAGS_RF;
1611  }
1612 
1613  /* Clear dr6 status flags. */
1614  Context->Dr6 &= ~0x0000e00f;
1615 
1617  {
1618  /* Skip the current instruction */
1620  }
1621  }
1622 
1623  return ContinueType;
1624 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
Definition: kdb.c:601
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
static PKDB_BREAKPOINT KdbBreakPointToReenable
Definition: kdb.c:46
__INTRIN_INLINE unsigned long __readcr2(void)
Definition: intrin_x86.h:1811
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
BOOLEAN Global
Definition: kdb.h:30
static VOID KdbpInternalEnter(VOID)
Internal function to enter KDB.
Definition: kdb.c:1160
BOOLEAN KdbpStepIntoInstruction(ULONG_PTR Eip)
Steps into an instruction (interrupts)
Definition: kdb.c:302
#define TRUE
Definition: types.h:120
PETHREAD KdbOriginalThread
Definition: kdb.c:57
PEPROCESS KdbCurrentProcess
Definition: kdb.c:54
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define KeGetContextPc(Context)
Definition: ke.h:31
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:185
BOOLEAN KdbpStepOverInstruction(ULONG_PTR Eip)
Steps over an instruction.
Definition: kdb.c:274
union _KDB_BREAKPOINT::@1771 Data
VOID KdbpCliInterpretInitFile(VOID)
This function is called by KdbEnterDebuggerException...
Definition: kdb_cli.c:3741
PEPROCESS KdbOriginalProcess
Definition: kdb.c:55
uint32_t ULONG_PTR
Definition: typedefs.h:65
static ULONG KdbpGetExceptionNumberFromStatus(IN NTSTATUS ExceptionCode)
Definition: kdb.c:1199
UCHAR KIRQL
Definition: env_spec_w32.h:591
static LONG KdbEntryCount
Definition: kdb.c:37
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:65
static const CHAR * ExceptionNrToString[]
Definition: kdb.c:93
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.
Definition: kdb.c:157
static BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
Definition: kdb.c:48
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
ULONG_PTR Address
Definition: kdb.h:29
PVOID Condition
Definition: kdb.h:33
ULONG EFlags
Definition: nt_native.h:1478
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:58
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:960
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
#define KeSetContextPc(Context, ProgramCounter)
Definition: ke.h:34
struct _KDB_BREAKPOINT::@1771::@1772 Hw
ULONG KdbNumSingleSteps
Definition: kdb.c:50
#define InterlockedDecrement
Definition: armddk.h:52
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
#define EFLAGS_RF
Definition: ketypes.h:131
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
BOOLEAN KdbSingleStepOver
Definition: kdb.c:51
#define EFLAGS_TF
Definition: ketypes.h:125
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:156
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.
Definition: kdb_expr.c:1196
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
PEPROCESS Process
Definition: kdb.h:31
UCHAR SavedInstruction
Definition: kdb.h:36
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
LONG KdbLastBreakPointNr
Definition: kdb.c:49
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
static KAPC_STATE KdbApcState
Definition: kdb.c:61
#define NULL
Definition: types.h:112
VOID NTAPI KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
Definition: spinlock.c:27
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:59
PETHREAD KdbCurrentThread
Definition: kdb.c:56
struct tagContext Context
Definition: acpixf.h:1038
void __cdecl _disable(void)
Definition: intrin_arm.h:365
unsigned int ULONG
Definition: retypes.h:1
#define KD_BREAKPOINT_SIZE
Definition: ke.h:122
static LONG KdbpIsBreakPointOurs(IN NTSTATUS ExceptionCode, IN PCONTEXT Context)
Checks if the breakpoint was set by the debugger.
Definition: kdb.c:651
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
KDB_BREAKPOINT_TYPE Type
Definition: kdb.h:27
static BOOLEAN KdbEnteredOnSingleStep
Definition: kdb.c:53
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224
PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:155

Referenced by KdbEnterDebuggerFirstChanceException(), and KdSendPacket().

◆ KdbEnterDebuggerFirstChanceException()

KD_CONTINUE_TYPE KdbEnterDebuggerFirstChanceException ( IN OUT PKTRAP_FRAME  TrapFrame)

Definition at line 1627 of file kdb.c.

1629 {
1630  EXCEPTION_RECORD64 ExceptionRecord;
1631  KD_CONTINUE_TYPE Return;
1632  CONTEXT Context;
1633 
1634  /* Copy TrapFrame to Context */
1635  RtlZeroMemory(&Context, sizeof(CONTEXT));
1637 #ifdef CONTEXT_EXTENDED_REGISTERS
1638  Context.ContextFlags |= CONTEXT_EXTENDED_REGISTERS;
1639 #endif
1640  KeTrapFrameToContext(TrapFrame, NULL, &Context);
1641 
1642  /* Create ExceptionRecord (assume breakpoint) */
1643  RtlZeroMemory(&ExceptionRecord, sizeof(EXCEPTION_RECORD64));
1644  ExceptionRecord.ExceptionCode = STATUS_BREAKPOINT;
1645 
1646  /* Call real function */
1647  Return = KdbEnterDebuggerException(&ExceptionRecord,
1648  KernelMode,
1649  &Context,
1650  TRUE);
1651 
1652  /* Copy back Context to TrapFrame */
1653  KeContextToTrapFrame(&Context, NULL, TrapFrame, Context.ContextFlags, KernelMode);
1654 
1655  return Return;
1656 }
VOID NTAPI KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame, ULONG ContextFlags, KPROCESSOR_MODE PreviousMode)
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define CONTEXT_EXTENDED_REGISTERS
#define TRUE
Definition: types.h:120
#define CONTEXT_FLOATING_POINT
Definition: nt_native.h:1372
NTSTATUS ExceptionCode
Definition: rtltypes.h:190
#define CONTEXT_SEGMENTS
Definition: nt_native.h:1371
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
VOID NTAPI KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame, IN OUT PCONTEXT Context)
Definition: context.c:169
#define CONTEXT_DEBUG_REGISTERS
Definition: nt_native.h:1373
#define NULL
Definition: types.h:112
struct tagContext Context
Definition: acpixf.h:1038
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONTEXT_INTEGER
Definition: nt_native.h:1370
KD_CONTINUE_TYPE KdbEnterDebuggerException(IN PEXCEPTION_RECORD64 ExceptionRecord, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT Context, IN BOOLEAN FirstChance)
KDB Exception filter.
Definition: kdb.c:1265

◆ KdbpAttachToProcess()

BOOLEAN KdbpAttachToProcess ( PVOID  ProcessId)

Switches to another process/thread context.

This function switches to the first thread in the specified process.

Parameters
ProcessIdId of the process to switch to.
Return values
TRUESuccess.
FALSEFailure (i.e. invalid process id)

Definition at line 1120 of file kdb.c.

1122 {
1124  PETHREAD Thread;
1126 
1127  /* Get a pointer to the process */
1129  {
1130  KdbpPrint("Invalid process id: 0x%08x\n", (ULONG_PTR)ProcessId);
1131  return FALSE;
1132  }
1133 
1134  Entry = Process->ThreadListHead.Flink;
1137  {
1138  KdbpPrint("No threads in process 0x%p, cannot attach to process!\n", ProcessId);
1139  return FALSE;
1140  }
1141 
1142  Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1143 
1145 }
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2709
struct _Entry Entry
Definition: kefuncs.h:629
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
Definition: kdb.c:1039
PEPROCESS KdbCurrentProcess
Definition: kdb.c:54
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
LIST_ENTRY ThreadListHead
Definition: pstypes.h:1329
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
CLIENT_ID Cid
Definition: pstypes.h:1128
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
HANDLE UniqueThread
Definition: compat.h:826
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224
base of all file and directory entries
Definition: entries.h:82

Referenced by KdbpCmdProc().

◆ KdbpAttachToThread()

BOOLEAN KdbpAttachToThread ( PVOID  ThreadId)

Switches to another thread context.

Parameters
ThreadIdId of the thread to switch to.
Return values
TRUESuccess.
FALSEFailure (i.e. invalid thread id)

Definition at line 1039 of file kdb.c.

1041 {
1042  PETHREAD Thread = NULL;
1044 
1045  /* Get a pointer to the thread */
1046  if (!NT_SUCCESS(PsLookupThreadByThreadId(ThreadId, &Thread)))
1047  {
1048  KdbpPrint("Invalid thread id: 0x%08x\n", (ULONG_PTR)ThreadId);
1049  return FALSE;
1050  }
1051  Process = Thread->ThreadsProcess;
1052 
1054  {
1055  KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
1057  return FALSE;
1058  }
1059 
1060  /* Save the current thread's context (if we previously attached to a thread) */
1062  {
1064  /* Actually, we can't save the context, there's no guarantee that there was a trap frame */
1065  }
1066  else
1067  {
1069  }
1070 
1071  /* Switch to the thread's context */
1072  if (Thread != KdbOriginalThread)
1073  {
1074  /* The thread we're attaching to isn't the thread on which we entered
1075  * kdb and so the thread we're attaching to is not running. There
1076  * is no guarantee that it actually has a trap frame. So we have to
1077  * peek directly at the registers which were saved on the stack when the
1078  * thread was preempted in the scheduler */
1082  }
1083  else /* Switching back to original thread */
1084  {
1086  }
1088 
1089  /* Attach to the thread's process */
1091  if (KdbCurrentProcess != Process)
1092  {
1093  if (KdbCurrentProcess != KdbOriginalProcess) /* detach from previously attached process */
1094  {
1096  }
1097 
1098  if (KdbOriginalProcess != Process)
1099  {
1101  }
1102 
1104  }
1105 
1107  return TRUE;
1108 }
#define TRUE
Definition: types.h:120
PETHREAD KdbOriginalThread
Definition: kdb.c:57
PEPROCESS KdbCurrentProcess
Definition: kdb.c:54
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
KTHREAD Tcb
Definition: pstypes.h:1103
static VOID KdbpKdbTrapFrameFromKernelStack(PVOID KernelStack, PKDB_KTRAP_FRAME KdbTrapFrame)
Definition: kdb.c:121
BOOLEAN NTAPI KeIsExecutingDpc(VOID)
Definition: dpc.c:947
static KDB_KTRAP_FRAME KdbThreadTrapFrame
Definition: kdb.c:60
PEPROCESS KdbOriginalProcess
Definition: kdb.c:55
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID KernelStack
Definition: ketypes.h:1615
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:58
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
static KAPC_STATE KdbApcState
Definition: kdb.c:61
#define NULL
Definition: types.h:112
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:59
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
PETHREAD KdbCurrentThread
Definition: kdb.c:56
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224

Referenced by KdbpAttachToProcess(), and KdbpCmdThread().

◆ KdbpCallMainLoop()

static VOID KdbpCallMainLoop ( VOID  )
static

Calls the main loop ...

Definition at line 1150 of file kdb.c.

1151 {
1153 }
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3678
static BOOLEAN KdbEnteredOnSingleStep
Definition: kdb.c:53

Referenced by KdbpInternalEnter().

◆ KdbpDeleteBreakPoint()

BOOLEAN KdbpDeleteBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Deletes a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to delete. Can be -1
BreakPointBreakpoint to delete. Can be NULL.
Return values
TRUESuccess.
FALSEFailure (invalid breakpoint number)

Definition at line 601 of file kdb.c.

604 {
605  if (BreakPointNr < 0)
606  {
607  ASSERT(BreakPoint);
608  BreakPointNr = BreakPoint - KdbBreakPoints;
609  }
610 
611  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
612  {
613  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
614  return FALSE;
615  }
616 
617  if (!BreakPoint)
618  {
619  BreakPoint = KdbBreakPoints + BreakPointNr;
620  }
621 
622  if (BreakPoint->Type == KdbBreakPointNone)
623  {
624  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
625  return FALSE;
626  }
627 
628  if (BreakPoint->Enabled && !KdbpDisableBreakPoint(-1, BreakPoint))
629  return FALSE;
630 
631  if (BreakPoint->Type != KdbBreakPointTemporary)
632  KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
633 
634  BreakPoint->Type = KdbBreakPointNone;
635  KdbBreakPointCount--;
636 
637  return TRUE;
638 }
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:28
#define TRUE
Definition: types.h:120
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
Definition: kdb.c:871
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224

Referenced by KdbEnterDebuggerException(), and KdbpCmdEnableDisableClearBreakPoint().

◆ KdbpDisableBreakPoint()

BOOLEAN KdbpDisableBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Disables a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to disable. Can be -1
BreakPointBreakpoint to disable. Can be NULL.
Return values
TRUESuccess.
FALSEFailure.
See also
KdbpEnableBreakPoint

Definition at line 871 of file kdb.c.

874 {
875  ULONG i;
877 
878  if (BreakPointNr < 0)
879  {
880  ASSERT(BreakPoint);
881  BreakPointNr = BreakPoint - KdbBreakPoints;
882  }
883 
884  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
885  {
886  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
887  return FALSE;
888  }
889 
890  if (!BreakPoint)
891  {
892  BreakPoint = KdbBreakPoints + BreakPointNr;
893  }
894 
895  if (BreakPoint->Type == KdbBreakPointNone)
896  {
897  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
898  return FALSE;
899  }
900 
901  if (BreakPoint->Enabled == FALSE)
902  {
903  KdbpPrint("Breakpoint %d is not enabled.\n", BreakPointNr);
904  return TRUE;
905  }
906 
907  if (BreakPoint->Type == KdbBreakPointSoftware ||
908  BreakPoint->Type == KdbBreakPointTemporary)
909  {
911  Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
912  BreakPoint->Data.SavedInstruction, NULL);
913 
914  if (!NT_SUCCESS(Status))
915  {
916  KdbpPrint("Couldn't restore original instruction.\n");
917  return FALSE;
918  }
919 
920  for (i = 0; i < KdbSwBreakPointCount; i++)
921  {
922  if (KdbSwBreakPoints[i] == BreakPoint)
923  {
925  i = -1; /* if the last breakpoint is disabled dont break with i >= KdbSwBreakPointCount */
926  break;
927  }
928  }
929 
930  if (i != MAXULONG) /* not found */
931  ASSERT(0);
932  }
933  else
934  {
935  ASSERT(BreakPoint->Type == KdbBreakPointHardware);
936 
937  /* Clear the breakpoint. */
938  KdbTrapFrame.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
939  if ((KdbTrapFrame.Dr7 & 0xFF) == 0)
940  {
941  /* If no breakpoints are enabled then clear the exact match flags. */
942  KdbTrapFrame.Dr7 &= 0xFFFFFCFF;
943  }
944 
945  for (i = 0; i < KdbHwBreakPointCount; i++)
946  {
947  if (KdbHwBreakPoints[i] == BreakPoint)
948  {
950  i = -1; /* if the last breakpoint is disabled dont break with i >= KdbHwBreakPointCount */
951  break;
952  }
953  }
954 
955  if (i != MAXULONG) /* not found */
956  ASSERT(0);
957  }
958 
959  BreakPoint->Enabled = FALSE;
960  if (BreakPoint->Type != KdbBreakPointTemporary)
961  KdbpPrint("Breakpoint %d disabled.\n", BreakPointNr);
962 
963  return TRUE;
964 }
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:28
#define TRUE
Definition: types.h:120
static ULONG KdbSwBreakPointCount
Definition: kdb.c:42
LONG NTSTATUS
Definition: precomp.h:26
ULONG Dr7
Definition: nt_native.h:1439
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:45
#define FALSE
Definition: types.h:117
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.
Definition: kdb.c:157
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:44
#define MAXULONG
Definition: typedefs.h:251
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
#define NULL
Definition: types.h:112
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:59
unsigned int ULONG
Definition: retypes.h:1
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224
static ULONG KdbHwBreakPointCount
Definition: kdb.c:43

Referenced by KdbpCmdEnableDisableClearBreakPoint(), and KdbpDeleteBreakPoint().

◆ KdbpEnableBreakPoint()

BOOLEAN KdbpEnableBreakPoint ( IN LONG BreakPointNr  OPTIONAL,
IN OUT PKDB_BREAKPOINT BreakPoint  OPTIONAL 
)

Enables a breakpoint.

Parameters
BreakPointNrNumber of the breakpoint to enable Can be -1.
BreakPointBreakpoint to enable. Can be NULL.
Return values
TRUESuccess.
FALSEFailure.
See also
KdbpDisableBreakPoint

Definition at line 704 of file kdb.c.

707 {
709  INT i;
710  ULONG ul;
711 
712  if (BreakPointNr < 0)
713  {
714  ASSERT(BreakPoint);
715  BreakPointNr = BreakPoint - KdbBreakPoints;
716  }
717 
718  if (BreakPointNr < 0 || BreakPointNr >= KDB_MAXIMUM_BREAKPOINT_COUNT)
719  {
720  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
721  return FALSE;
722  }
723 
724  if (!BreakPoint)
725  {
726  BreakPoint = KdbBreakPoints + BreakPointNr;
727  }
728 
729  if (BreakPoint->Type == KdbBreakPointNone)
730  {
731  KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
732  return FALSE;
733  }
734 
735  if (BreakPoint->Enabled)
736  {
737  KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
738  return TRUE;
739  }
740 
741  if (BreakPoint->Type == KdbBreakPointSoftware ||
742  BreakPoint->Type == KdbBreakPointTemporary)
743  {
745  {
746  KdbpPrint("Maximum number of SW breakpoints (%d) used. "
747  "Disable another breakpoint in order to enable this one.\n",
749  return FALSE;
750  }
751 
752  Status = KdbpOverwriteInstruction(BreakPoint->Process, BreakPoint->Address,
753  0xCC, &BreakPoint->Data.SavedInstruction);
754  if (!NT_SUCCESS(Status))
755  {
756  KdbpPrint("Couldn't access memory at 0x%p\n", BreakPoint->Address);
757  return FALSE;
758  }
759 
760  KdbSwBreakPoints[KdbSwBreakPointCount++] = BreakPoint;
761  }
762  else
763  {
764  if (BreakPoint->Data.Hw.AccessType == KdbAccessExec)
765  ASSERT(BreakPoint->Data.Hw.Size == 1);
766 
767  ASSERT((BreakPoint->Address % BreakPoint->Data.Hw.Size) == 0);
768 
770  {
771  KdbpPrint("Maximum number of HW breakpoints (%d) already used. "
772  "Disable another breakpoint in order to enable this one.\n",
774 
775  return FALSE;
776  }
777 
778  /* Find unused hw breakpoint */
780  for (i = 0; i < KDB_MAXIMUM_HW_BREAKPOINT_COUNT; i++)
781  {
782  if ((KdbTrapFrame.Dr7 & (0x3 << (i * 2))) == 0)
783  break;
784  }
785 
787 
788  /* Set the breakpoint address. */
789  switch (i)
790  {
791  case 0:
792  KdbTrapFrame.Dr0 = BreakPoint->Address;
793  break;
794  case 1:
795  KdbTrapFrame.Dr1 = BreakPoint->Address;
796  break;
797  case 2:
798  KdbTrapFrame.Dr2 = BreakPoint->Address;
799  break;
800  case 3:
801  KdbTrapFrame.Dr3 = BreakPoint->Address;
802  break;
803  }
804 
805  /* Enable the global breakpoint */
806  KdbTrapFrame.Dr7 |= (0x2 << (i * 2));
807 
808  /* Enable the exact match bits. */
809  KdbTrapFrame.Dr7 |= 0x00000300;
810 
811  /* Clear existing state. */
812  KdbTrapFrame.Dr7 &= ~(0xF << (16 + (i * 4)));
813 
814  /* Set the breakpoint type. */
815  switch (BreakPoint->Data.Hw.AccessType)
816  {
817  case KdbAccessExec:
818  ul = 0;
819  break;
820  case KdbAccessWrite:
821  ul = 1;
822  break;
823  case KdbAccessRead:
824  case KdbAccessReadWrite:
825  ul = 3;
826  break;
827  default:
828  ASSERT(0);
829  return TRUE;
830  break;
831  }
832 
833  KdbTrapFrame.Dr7 |= (ul << (16 + (i * 4)));
834 
835  /* Set the breakpoint length. */
836  KdbTrapFrame.Dr7 |= ((BreakPoint->Data.Hw.Size - 1) << (18 + (i * 4)));
837 
838  /* Update KdbCurrentTrapFrame - values are taken from there by the CLI */
840  {
847  }
848 
849  BreakPoint->Data.Hw.DebugReg = i;
850  KdbHwBreakPoints[KdbHwBreakPointCount++] = BreakPoint;
851  }
852 
853  BreakPoint->Enabled = TRUE;
854  if (BreakPoint->Type != KdbBreakPointTemporary)
855  KdbpPrint("Breakpoint %d enabled.\n", BreakPointNr);
856 
857  return TRUE;
858 }
#define KDB_MAXIMUM_SW_BREAKPOINT_COUNT
Definition: kdb.c:30
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:28
#define TRUE
Definition: types.h:120
static ULONG KdbSwBreakPointCount
Definition: kdb.c:42
LONG NTSTATUS
Definition: precomp.h:26
int32_t INT
Definition: typedefs.h:58
ULONG Dr7
Definition: nt_native.h:1439
ULONG Dr3
Definition: nt_native.h:1437
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:45
#define FALSE
Definition: types.h:117
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.
Definition: kdb.c:157
ULONG Dr1
Definition: nt_native.h:1435
ULONG Dr2
Definition: nt_native.h:1436
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:58
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:44
#define KDB_MAXIMUM_HW_BREAKPOINT_COUNT
Definition: kdb.c:29
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
ULONG Dr6
Definition: nt_native.h:1438
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:59
ULONG Dr0
Definition: nt_native.h:1434
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN Enabled
Definition: kdb.h:28
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224
static ULONG KdbHwBreakPointCount
Definition: kdb.c:43

Referenced by KdbpCmdEnableDisableClearBreakPoint(), and KdbpInsertBreakPoint().

◆ KdbpGetBreakPointInfo()

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.

Parameters
BreakPointNrNumber of the breakpoint to return information of.
AddressReceives the address of the breakpoint.
TypeReceives the type of the breakpoint (hardware or software)
SizeSize - for memory breakpoints.
AccessTypeAccess type - for hardware breakpoints.
DebugRegDebug register - for enabled hardware breakpoints.
EnabledWhether the breakpoint is enabled or not.
ProcessThe owning process of the breakpoint.
ConditionExpressionThe expression which was given as condition for the bp.
Returns
NULL on failure, pointer to a KDB_BREAKPOINT struct on success.

Definition at line 411 of file kdb.c.

422 {
423  PKDB_BREAKPOINT bp;
424 
425  if (BreakPointNr >= RTL_NUMBER_OF(KdbBreakPoints) ||
426  KdbBreakPoints[BreakPointNr].Type == KdbBreakPointNone)
427  {
428  return FALSE;
429  }
430 
431  bp = KdbBreakPoints + BreakPointNr;
432  if (Address)
433  *Address = bp->Address;
434 
435  if (Type)
436  *Type = bp->Type;
437 
438  if (bp->Type == KdbBreakPointHardware)
439  {
440  if (Size)
441  *Size = bp->Data.Hw.Size;
442 
443  if (AccessType)
444  *AccessType = bp->Data.Hw.AccessType;
445 
446  if (DebugReg && bp->Enabled)
447  *DebugReg = bp->Data.Hw.DebugReg;
448  }
449 
450  if (Enabled)
451  *Enabled = bp->Enabled;
452 
453  if (Global)
454  *Global = bp->Global;
455 
456  if (Process)
457  *Process = bp->Process;
458 
459  if (ConditionExpression)
460  *ConditionExpression = bp->ConditionExpression;
461 
462  return TRUE;
463 }
BOOLEAN Global
Definition: kdb.h:30
#define TRUE
Definition: types.h:120
PCHAR ConditionExpression
Definition: kdb.h:32
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
union _KDB_BREAKPOINT::@1771 Data
UNICODE_STRING Global
Definition: symlink.c:37
#define FALSE
Definition: types.h:117
static WCHAR Address[46]
Definition: ping.c:68
ULONG_PTR Address
Definition: kdb.h:29
Type
Definition: Type.h:6
struct _KDB_BREAKPOINT::@1771::@1772 Hw
PEPROCESS Process
Definition: kdb.h:31
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
BOOLEAN Enabled
Definition: kdb.h:28
KDB_BREAKPOINT_TYPE Type
Definition: kdb.h:27

Referenced by KdbpCmdBreakPointList().

◆ KdbpGetCommandLineSettings()

VOID NTAPI KdbpGetCommandLineSettings ( PCHAR  p1)

Definition at line 1660 of file kdb.c.

1662 {
1663 #define CONST_STR_LEN(x) (sizeof(x)/sizeof(x[0]) - 1)
1664 
1665  while (p1 && (p1 = strchr(p1, ' ')))
1666  {
1667  /* Skip other spaces */
1668  while (*p1 == ' ') ++p1;
1669 
1670  if (!_strnicmp(p1, "KDSERIAL", CONST_STR_LEN("KDSERIAL")))
1671  {
1672  p1 += CONST_STR_LEN("KDSERIAL");
1674  KdpDebugMode.Serial = TRUE;
1675  }
1676  else if (!_strnicmp(p1, "KDNOECHO", CONST_STR_LEN("KDNOECHO")))
1677  {
1678  p1 += CONST_STR_LEN("KDNOECHO");
1680  }
1681  else if (!_strnicmp(p1, "FIRSTCHANCE", CONST_STR_LEN("FIRSTCHANCE")))
1682  {
1683  p1 += CONST_STR_LEN("FIRSTCHANCE");
1685  }
1686  }
1687 }
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.
Definition: kdb.c:998
ULONG KdbDebugState
Definition: kdb.c:52
#define TRUE
Definition: types.h:120
KDP_DEBUG_MODE KdpDebugMode
Definition: kdio.c:48
#define CONST_STR_LEN(x)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
char * strchr(const char *String, int ch)
Definition: utclib.c:501

Referenced by KdDebuggerInitialize0().

◆ KdbpGetEnterCondition()

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.

Parameters
ExceptionNrNumber of the exception to get condition of.
FirstChanceWhether to get first or last chance condition.
ConditionReceives the condition setting.
Return values
TRUESuccess.
FALSEFailure (invalid exception nr)

Definition at line 976 of file kdb.c.

980 {
981  if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions))
982  return FALSE;
983 
984  *Condition = KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1];
985  return TRUE;
986 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:65
long LONG
Definition: pedump.c:60
IN ULONG IN UCHAR Condition
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

Referenced by KdbpCmdSet().

◆ KdbpGetExceptionNumberFromStatus()

static ULONG KdbpGetExceptionNumberFromStatus ( IN NTSTATUS  ExceptionCode)
static

Definition at line 1199 of file kdb.c.

1201 {
1202  ULONG Ret;
1203 
1204  switch (ExceptionCode)
1205  {
1207  Ret = 0;
1208  break;
1209  case STATUS_SINGLE_STEP:
1210  Ret = 1;
1211  break;
1212  case STATUS_BREAKPOINT:
1213  Ret = 3;
1214  break;
1216  Ret = 4;
1217  break;
1219  Ret = 5;
1220  break;
1222  Ret = 6;
1223  break;
1225  Ret = 7;
1226  break;
1227  case STATUS_STACK_OVERFLOW:
1228  Ret = 12;
1229  break;
1231  Ret = 14;
1232  break;
1234  Ret = 17;
1235  break;
1237  Ret = 18;
1238  break;
1240  Ret = 20;
1241  break;
1242 
1243  default:
1244  Ret = RTL_NUMBER_OF(KdbEnterConditions) - 1;
1245  break;
1246  }
1247 
1248  return Ret;
1249 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
#define STATUS_ILLEGAL_INSTRUCTION
Definition: ntstatus.h:266
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:185
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:65
#define STATUS_INTEGER_DIVIDE_BY_ZERO
Definition: ntstatus.h:384
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
#define STATUS_ASSERTION_FAILURE
Definition: ntstatus.h:960
#define STATUS_FLOAT_MULTIPLE_TRAPS
Definition: ntstatus.h:808
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:489
#define STATUS_DATATYPE_MISALIGNMENT
Definition: ntstatus.h:183
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_ARRAY_BOUNDS_EXCEEDED
Definition: ntstatus.h:376

Referenced by KdbEnterDebuggerException().

◆ KdbpGetNextBreakPointNr()

LONG KdbpGetNextBreakPointNr ( IN ULONG Start  OPTIONAL)

Gets the number of the next breakpoint >= Start.

Parameters
StartBreakpoint number to start searching at. -1 if no more breakpoints are found.
Returns
Breakpoint number (-1 if no more breakpoints are found)

Definition at line 384 of file kdb.c.

386 {
387  for (; Start < RTL_NUMBER_OF(KdbBreakPoints); Start++)
388  {
389  if (KdbBreakPoints[Start].Type != KdbBreakPointNone)
390  return Start;
391  }
392 
393  return -1;
394 }
Type
Definition: Type.h:6
Definition: partlist.h:33
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

Referenced by KdbpCmdBreakPointList().

◆ KdbpInsertBreakPoint()

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.

The Process of the breakpoint is set to KdbCurrentProcess

Parameters
AddressAddress at which to set the breakpoint.
TypeType of breakpoint (hardware or software)
SizeSize of breakpoint (for hardware/memory breakpoints)
AccessTypeAccess type (for hardware breakpoins)
ConditionExpressionExpression which must evaluate to true for conditional breakpoints.
GlobalWether the breakpoint is global or local to a process.
BreakPointNumberReceives the breakpoint number on success
Returns
NTSTATUS

Definition at line 480 of file kdb.c.

488 {
489  LONG_PTR i;
491  PCHAR ConditionExpressionDup;
492  LONG ErrOffset;
493  CHAR ErrMsg[128];
494 
496 
498  {
499  if ((Address % Size) != 0)
500  {
501  KdbpPrint("Address (0x%p) must be aligned to a multiple of the size (%d)\n", Address, Size);
502  return STATUS_UNSUCCESSFUL;
503  }
504 
505  if (AccessType == KdbAccessExec && Size != 1)
506  {
507  KdbpPrint("Size must be 1 for execution breakpoints.\n");
508  return STATUS_UNSUCCESSFUL;
509  }
510  }
511 
512  if (KdbBreakPointCount == KDB_MAXIMUM_BREAKPOINT_COUNT)
513  {
514  return STATUS_UNSUCCESSFUL;
515  }
516 
517  /* Parse conditon expression string and duplicate it */
518  if (ConditionExpression)
519  {
520  Condition = KdbpRpnParseExpression(ConditionExpression, &ErrOffset, ErrMsg);
521  if (!Condition)
522  {
523  if (ErrOffset >= 0)
524  KdbpPrint("Couldn't parse expression: %s at character %d\n", ErrMsg, ErrOffset);
525  else
526  KdbpPrint("Couldn't parse expression: %s", ErrMsg);
527 
528  return STATUS_UNSUCCESSFUL;
529  }
530 
531  i = strlen(ConditionExpression) + 1;
532  ConditionExpressionDup = ExAllocatePoolWithTag(NonPagedPool, i, TAG_KDBG);
533  RtlCopyMemory(ConditionExpressionDup, ConditionExpression, i);
534  }
535  else
536  {
537  Condition = NULL;
538  ConditionExpressionDup = NULL;
539  }
540 
541  /* Find unused breakpoint */
543  {
544  for (i = RTL_NUMBER_OF(KdbBreakPoints) - 1; i >= 0; i--)
545  {
546  if (KdbBreakPoints[i].Type == KdbBreakPointNone)
547  break;
548  }
549  }
550  else
551  {
552  for (i = 0; i < (LONG)RTL_NUMBER_OF(KdbBreakPoints); i++)
553  {
554  if (KdbBreakPoints[i].Type == KdbBreakPointNone)
555  break;
556  }
557  }
558 
559  ASSERT(i < (LONG)RTL_NUMBER_OF(KdbBreakPoints));
560 
561  /* Set the breakpoint */
563  KdbBreakPoints[i].Type = Type;
564  KdbBreakPoints[i].Address = Address;
565  KdbBreakPoints[i].Enabled = FALSE;
566  KdbBreakPoints[i].Global = Global;
567  KdbBreakPoints[i].Process = KdbCurrentProcess;
568  KdbBreakPoints[i].ConditionExpression = ConditionExpressionDup;
569  KdbBreakPoints[i].Condition = Condition;
570 
572  {
573  KdbBreakPoints[i].Data.Hw.Size = Size;
574  KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
575  }
576 
577  KdbBreakPointCount++;
578 
580  KdbpPrint("Breakpoint %d inserted.\n", i);
581 
582  /* Try to enable the breakpoint */
584 
585  /* Return the breakpoint number */
586  if (BreakPointNr)
587  *BreakPointNr = i;
588 
589  return STATUS_SUCCESS;
590 }
signed char * PCHAR
Definition: retypes.h:7
#define TAG_KDBG
Definition: tag.h:38
PVOID KdbpRpnParseExpression(IN PCHAR Expression, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Parses the given expression and returns a "handle" to it.
Definition: kdb_expr.c:1142
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define KDB_MAXIMUM_BREAKPOINT_COUNT
Definition: kdb.c:28
PEPROCESS KdbCurrentProcess
Definition: kdb.c:54
char CHAR
Definition: xmlstorage.h:175
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
UNICODE_STRING Global
Definition: symlink.c:37
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
IN ULONG IN UCHAR Condition
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
Definition: kdb.c:704
#define ASSERT(a)
Definition: mode.c:44
Type
Definition: Type.h:6
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
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
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define NULL
Definition: types.h:112
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224

Referenced by KdbpCmdBreakPoint(), KdbpStepIntoInstruction(), and KdbpStepOverInstruction().

◆ KdbpInternalEnter()

static VOID KdbpInternalEnter ( VOID  )
static

Internal function to enter KDB.

Disables interrupts, releases display ownership, ...

Definition at line 1160 of file kdb.c.

1161 {
1162  PETHREAD Thread;
1163  PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
1164  ULONG SavedStackLimit;
1165 
1166  KbdDisableMouse();
1167 
1168  /* Take control of the display */
1169  if (KdpDebugMode.Screen)
1170  KdpScreenAcquire();
1171 
1172  /* Call the interface's main loop on a different stack */
1174  SavedInitialStack = Thread->Tcb.InitialStack;
1175  SavedStackBase = Thread->Tcb.StackBase;
1176  SavedStackLimit = Thread->Tcb.StackLimit;
1177  SavedKernelStack = Thread->Tcb.KernelStack;
1178  Thread->Tcb.InitialStack = Thread->Tcb.StackBase = (char*)KdbStack + KDB_STACK_SIZE;
1179  Thread->Tcb.StackLimit = (ULONG_PTR)KdbStack;
1180  Thread->Tcb.KernelStack = (char*)KdbStack + KDB_STACK_SIZE;
1181 
1182  // KdbpPrint("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);
1183 
1185 
1186  Thread->Tcb.InitialStack = SavedInitialStack;
1187  Thread->Tcb.StackBase = SavedStackBase;
1188  Thread->Tcb.StackLimit = SavedStackLimit;
1189  Thread->Tcb.KernelStack = SavedKernelStack;
1190 
1191  /* Release the display */
1192  if (KdpDebugMode.Screen)
1193  KdpScreenRelease();
1194 
1195  KbdEnableMouse();
1196 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KDB_STACK_RESERVE
Definition: kdb.c:26
KTHREAD Tcb
Definition: pstypes.h:1103
KDP_DEBUG_MODE KdpDebugMode
Definition: kdio.c:48
VOID NTAPI KdbpStackSwitchAndCall(IN PVOID NewStack, IN VOID(*Function)(VOID))
VOID KdpScreenRelease(VOID)
Definition: kdio.c:399
VOID KbdEnableMouse(VOID)
PVOID KernelStack
Definition: ketypes.h:1615
VOID KdpScreenAcquire(VOID)
Definition: kdio.c:380
#define KDB_STACK_SIZE
Definition: kdb.c:20
volatile VOID * StackLimit
Definition: ketypes.h:1605
VOID KbdDisableMouse(VOID)
static VOID KdbpCallMainLoop(VOID)
Calls the main loop ...
Definition: kdb.c:1150
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
PVOID StackBase
Definition: ketypes.h:1606
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
PVOID InitialStack
Definition: ketypes.h:1604

Referenced by KdbEnterDebuggerException().

◆ KdbpIsBreakPointOurs()

static LONG KdbpIsBreakPointOurs ( IN NTSTATUS  ExceptionCode,
IN PCONTEXT  Context 
)
static

Checks if the breakpoint was set by the debugger.

Tries to find a breakpoint in the breakpoint array which caused the debug exception to happen.

Parameters
ExpNrException Number (1 or 3)
TrapFrameException trapframe
Returns
Breakpoint number, -1 on error.

Definition at line 651 of file kdb.c.

654 {
655  ULONG i;
657 
658  if (ExceptionCode == STATUS_BREAKPOINT) /* Software interrupt */
659  {
660  ULONG_PTR BpPc = KeGetContextPc(Context) - 1; /* Get EIP of INT3 instruction */
661  for (i = 0; i < KdbSwBreakPointCount; i++)
662  {
666 
667  if (KdbSwBreakPoints[i]->Address == BpPc)
668  {
669  return KdbSwBreakPoints[i] - KdbBreakPoints;
670  }
671  }
672  }
673  else if (ExceptionCode == STATUS_SINGLE_STEP) /* Hardware interrupt */
674  {
675  UCHAR DebugReg;
676 
677  for (i = 0; i < KdbHwBreakPointCount; i++)
678  {
681  DebugReg = KdbHwBreakPoints[i]->Data.Hw.DebugReg;
682 
683  if ((Context->Dr6 & ((ULONG_PTR)1 << DebugReg)) != 0)
684  {
685  return KdbHwBreakPoints[i] - KdbBreakPoints;
686  }
687  }
688  }
689 
690  return -1;
691 }
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1772
static ULONG KdbSwBreakPointCount
Definition: kdb.c:42
#define KeGetContextPc(Context)
Definition: ke.h:31
#define STATUS_SINGLE_STEP
Definition: ntstatus.h:185
union _KDB_BREAKPOINT::@1771 Data
uint32_t ULONG_PTR
Definition: typedefs.h:65
static PKDB_BREAKPOINT KdbHwBreakPoints[KDB_MAXIMUM_HW_BREAKPOINT_COUNT]
Definition: kdb.c:45
static WCHAR Address[46]
Definition: ping.c:68
#define STATUS_BREAKPOINT
Definition: ntstatus.h:184
#define ASSERT(a)
Definition: mode.c:44
static PKDB_BREAKPOINT KdbSwBreakPoints[KDB_MAXIMUM_SW_BREAKPOINT_COUNT]
Definition: kdb.c:44
Type
Definition: Type.h:6
struct _KDB_BREAKPOINT::@1771::@1772 Hw
unsigned char UCHAR
Definition: xmlstorage.h:181
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
unsigned int ULONG
Definition: retypes.h:1
static ULONG KdbHwBreakPointCount
Definition: kdb.c:43

Referenced by KdbEnterDebuggerException().

◆ KdbpKdbTrapFrameFromKernelStack()

static VOID KdbpKdbTrapFrameFromKernelStack ( PVOID  KernelStack,
PKDB_KTRAP_FRAME  KdbTrapFrame 
)
static

Definition at line 121 of file kdb.c.

124 {
125  ULONG_PTR *StackPtr;
126 
128  StackPtr = (ULONG_PTR *) KernelStack;
129 #ifdef _M_IX86
130  KdbTrapFrame->Ebp = StackPtr[3];
131  KdbTrapFrame->Edi = StackPtr[4];
132  KdbTrapFrame->Esi = StackPtr[5];
133  KdbTrapFrame->Ebx = StackPtr[6];
134  KdbTrapFrame->Eip = StackPtr[7];
135  KdbTrapFrame->Esp = (ULONG) (StackPtr + 8);
141 #endif
142 
143  /* FIXME: what about the other registers??? */
144 }
ULONG Esp
Definition: nt_native.h:1479
ULONG Eip
Definition: nt_native.h:1476
#define KGDT_R0_CODE
Definition: ketypes.h:75
ULONG SegGs
Definition: nt_native.h:1453
ULONG SegDs
Definition: nt_native.h:1456
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG SegEs
Definition: nt_native.h:1455
ULONG Esi
Definition: nt_native.h:1464
ULONG SegCs
Definition: nt_native.h:1477
ULONG Ebx
Definition: nt_native.h:1465
#define KGDT_R0_DATA
Definition: ketypes.h:76
ULONG SegSs
Definition: nt_native.h:1480
static KDB_KTRAP_FRAME KdbTrapFrame
Definition: kdb.c:59
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
ULONG Ebp
Definition: nt_native.h:1475
ULONG Edi
Definition: nt_native.h:1463

Referenced by KdbpAttachToThread().

◆ KdbpOverwriteInstruction()

static NTSTATUS KdbpOverwriteInstruction ( IN PEPROCESS  Process,
IN ULONG_PTR  Address,
IN UCHAR  NewInst,
OUT PUCHAR OldInst  OPTIONAL 
)
static

Overwrites the instruction at Address with NewInst and stores the old instruction in *OldInst.

Parameters
ProcessProcess in which's context to overwrite the instruction.
AddressAddress at which to overwrite the instruction.
NewInstNew instruction (written to Address)
OldInstOld instruction (read from Address)
Returns
NTSTATUS

Definition at line 157 of file kdb.c.

162 {
164  ULONG Protect;
167 
168  /* Get the protection for the address. */
170 
171  /* Return if that page isn't present. */
172  if (Protect & PAGE_NOACCESS)
173  {
175  }
176 
177  /* Attach to the process */
178  if (CurrentProcess != Process)
179  {
181  }
182 
183  /* Make the page writeable if it is read only. */
185  {
188  }
189 
190  /* Copy the old instruction back to the caller. */
191  if (OldInst)
192  {
193  Status = KdbpSafeReadMemory(OldInst, (PUCHAR)Address, 1);
194  if (!NT_SUCCESS(Status))
195  {
197  {
199  }
200 
201  /* Detach from process */
202  if (CurrentProcess != Process)
203  {
204  KeDetachProcess();
205  }
206 
207  return Status;
208  }
209  }
210 
211  /* Copy the new instruction in its place. */
212  Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
213 
214  /* Restore the page protection. */
216  {
218  }
219 
220  /* Detach from process */
221  if (CurrentProcess != Process)
222  {
224  }
225 
226  return Status;
227 }
KAPC_STATE
Definition: ketypes.h:1285
_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
Definition: zwfuncs.h:214
ULONG NTAPI MmGetPageProtect(struct _EPROCESS *Process, PVOID Address)
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define PAGE_NOACCESS
Definition: nt_native.h:1302
static WCHAR Address[46]
Definition: ping.c:68
#define PAGE_EXECUTE
Definition: nt_native.h:1306
Status
Definition: gdiplustypes.h:24
ULONG CurrentProcess
Definition: shell.c:125
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS KdbpSafeWriteMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1704
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1690
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:396
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1727
#define PAGE_READONLY
Definition: compat.h:138
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by KdbEnterDebuggerException(), KdbpDisableBreakPoint(), and KdbpEnableBreakPoint().

◆ KdbpSafeReadMemory()

NTSTATUS KdbpSafeReadMemory ( OUT PVOID  Dest,
IN PVOID  Src,
IN ULONG  Bytes 
)

Definition at line 1690 of file kdb.c.

1694 {
1695  return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Src,
1696  Dest,
1697  Bytes,
1698  0,
1700  NULL);
1701 }
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
Definition: kdapi.c:50
_In_ UINT Bytes
Definition: mmcopy.h:9
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned __int64 ULONG64
Definition: imports.h:198
#define MMDBG_COPY_UNSAFE
Definition: mm.h:77
#define NULL
Definition: types.h:112

Referenced by KdbpCmdBackTrace(), KdbpCmdDisassembleX(), KdbpCmdGdtLdtIdt(), KdbpCmdThread(), KdbpOverwriteInstruction(), KdbpReadMemory(), KdbpShouldStepOverInstruction(), KdbpStepIntoInstruction(), and RpnpEvaluateStack().

◆ KdbpSafeWriteMemory()

NTSTATUS KdbpSafeWriteMemory ( OUT PVOID  Dest,
IN PVOID  Src,
IN ULONG  Bytes 
)

Definition at line 1704 of file kdb.c.

1708 {
1709  return KdpCopyMemoryChunks((ULONG64)(ULONG_PTR)Dest,
1710  Src,
1711  Bytes,
1712  0,
1714  NULL);
1715 }
NTSTATUS NTAPI KdpCopyMemoryChunks(_In_ ULONG64 Address, _In_ PVOID Buffer, _In_ ULONG TotalSize, _In_ ULONG ChunkSize, _In_ ULONG Flags, _Out_opt_ PULONG ActualSize)
Definition: kdapi.c:50
_In_ UINT Bytes
Definition: mmcopy.h:9
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MMDBG_COPY_WRITE
Definition: mm.h:75
unsigned __int64 ULONG64
Definition: imports.h:198
#define MMDBG_COPY_UNSAFE
Definition: mm.h:77
#define NULL
Definition: types.h:112

Referenced by KdbpOverwriteInstruction().

◆ KdbpSetEnterCondition()

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.

Parameters
ExceptionNrNumber of the exception to set condition of (-1 for all)
FirstChanceWhether to set first or last chance condition.
ConditionThe new condition setting.
Return values
TRUESuccess.
FALSEFailure (invalid exception nr)

Definition at line 998 of file kdb.c.

1002 {
1003  if (ExceptionNr < 0)
1004  {
1005  for (ExceptionNr = 0; ExceptionNr < (LONG)RTL_NUMBER_OF(KdbEnterConditions); ExceptionNr++)
1006  {
1007  if (ExceptionNr == 1 || ExceptionNr == 8 ||
1008  ExceptionNr == 9 || ExceptionNr == 15) /* Reserved exceptions */
1009  {
1010  continue;
1011  }
1012 
1013  KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
1014  }
1015  }
1016  else
1017  {
1018  if (ExceptionNr >= (LONG)RTL_NUMBER_OF(KdbEnterConditions) ||
1019  ExceptionNr == 1 || ExceptionNr == 8 || /* Do not allow changing of the debug */
1020  ExceptionNr == 9 || ExceptionNr == 15) /* trap or reserved exceptions */
1021  {
1022  return FALSE;
1023  }
1024 
1025  KdbEnterConditions[ExceptionNr][FirstChance ? 0 : 1] = Condition;
1026  }
1027 
1028  return TRUE;
1029 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static KDB_ENTER_CONDITION KdbEnterConditions[][2]
Definition: kdb.c:65
long LONG
Definition: pedump.c:60
IN ULONG IN UCHAR Condition
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12

Referenced by KdbpCmdSet(), and KdbpGetCommandLineSettings().

◆ KdbpShouldStepOverInstruction()

BOOLEAN KdbpShouldStepOverInstruction ( ULONG_PTR  Eip)

Checks whether the given instruction can be single stepped or has to be stepped over using a temporary breakpoint.

Return values
TRUEInstruction is a call.
FALSEInstruction is not a call.

Definition at line 236 of file kdb.c.

238 {
239  UCHAR Mem[3];
240  ULONG i = 0;
241 
242  if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
243  {
244  KdbpPrint("Couldn't access memory at 0x%p\n", Eip);
245  return FALSE;
246  }
247 
248  /* Check if the current instruction is a call. */
249  while ((i < sizeof (Mem)) && (Mem[i] == 0x66 || Mem[i] == 0x67))
250  i++;
251 
252  if (i == sizeof (Mem))
253  return FALSE;
254 
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))
257  {
258  return TRUE;
259  }
260 
261  return FALSE;
262 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1690
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
unsigned int ULONG
Definition: retypes.h:1
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3224

Referenced by KdbpStepOverInstruction().

◆ KdbpStepIntoInstruction()

BOOLEAN KdbpStepIntoInstruction ( ULONG_PTR  Eip)

Steps into an instruction (interrupts)

If the given instruction should be stepped into, this function inserts a temporary breakpoint at the target instruction and returns TRUE, otherwise it returns FALSE.

Return values
TRUETemporary breakpoint set at target instruction.
FALSENo breakpoint was set.

Definition at line 302 of file kdb.c.

304 {
305  KDESCRIPTOR Idtr = {0};
306  UCHAR Mem[2];
307  INT IntVect;
308  ULONG IntDesc[2];
309  ULONG_PTR TargetEip;
310 
311  /* Read memory */
312  if (!NT_SUCCESS(KdbpSafeReadMemory(Mem, (PVOID)Eip, sizeof (Mem))))
313  {
314  /*KdbpPrint("Couldn't access memory at 0x%p\n", Eip);*/
315  return FALSE;
316  }
317 
318  /* Check for INT instruction */
319  /* FIXME: Check for iret */
320  if (Mem[0] == 0xcc)
321  IntVect = 3;
322  else if (Mem[0] == 0xcd)
323  IntVect = Mem[1];
324  else if (Mem[0] == 0xce && KdbCurrentTrapFrame->EFlags & (1<<11)) /* 1 << 11 is the overflow flag */
325  IntVect = 4;
326  else
327  return FALSE;
328 
329  if (IntVect < 32) /* We should be informed about interrupts < 32 by the kernel, no need to breakpoint them */
330  {
331  return FALSE;
332  }
333 
334  /* Read the interrupt descriptor table register */
335  __sidt(&Idtr.Limit);
336  if (IntVect >= (Idtr.Limit + 1) / 8)
337  {
338  /*KdbpPrint("IDT does not contain interrupt vector %d.\n", IntVect);*/
339  return TRUE;
340  }
341 
342  /* Get the interrupt descriptor */
343  if (!NT_SUCCESS(KdbpSafeReadMemory(IntDesc, (PVOID)((ULONG_PTR)Idtr.Base + (IntVect * 8)), sizeof(IntDesc))))
344  {
345  /*KdbpPrint("Couldn't access memory at 0x%p\n", (ULONG_PTR)Idtr.Base + (IntVect * 8));*/
346  return FALSE;
347  }
348 
349  /* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
350  if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
351  {
352  return FALSE;
353  }
354  if ((IntDesc[1] & 0x1f00) == 0x0500) /* Task gate */
355  {
356  /* FIXME: Task gates not supported */
357  return FALSE;
358  }
359  else if (((IntDesc[1] & 0x1fe0) == 0x0e00) || /* 32 bit Interrupt gate */
360  ((IntDesc[1] & 0x1fe0) == 0x0f00)) /* 32 bit Trap gate */
361  {
362  /* FIXME: Should the segment selector of the interrupt gate be checked? */
363  TargetEip = (IntDesc[1] & 0xffff0000) | (IntDesc[0] & 0x0000ffff);
364  }
365  else
366  {
367  return FALSE;
368  }
369 
370  /* Insert breakpoint */
372  return FALSE;
373 
374  return TRUE;
375 }
#define TRUE
Definition: types.h:120
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.
Definition: kdb.c:480
int32_t INT
Definition: typedefs.h:58
PVOID Base
Definition: ketypes.h:491
USHORT Limit
Definition: ketypes.h:490
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
ULONG EFlags
Definition: nt_native.h:1478
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:58
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1690
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by KdbEnterDebuggerException().

◆ KdbpStepOverInstruction()

BOOLEAN KdbpStepOverInstruction ( ULONG_PTR  Eip)

Steps over an instruction.

If the given instruction should be stepped over, this function inserts a temporary breakpoint after the instruction and returns TRUE, otherwise it returns FALSE.

Return values
TRUETemporary breakpoint set after instruction.
FALSENo breakpoint was set.

Definition at line 274 of file kdb.c.

276 {
277  LONG InstLen;
278 
280  return FALSE;
281 
282  InstLen = KdbpGetInstLength(Eip);
283  if (InstLen < 1)
284  return FALSE;
285 
286  if (!NT_SUCCESS(KdbpInsertBreakPoint(Eip + InstLen, KdbBreakPointTemporary, 0, 0, NULL, FALSE, NULL)))
287  return FALSE;
288 
289  return TRUE;
290 }
#define TRUE
Definition: types.h:120
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.
Definition: kdb.c:480
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
LONG KdbpGetInstLength(IN ULONG_PTR Address)
Definition: i386-dis.c:95
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NULL
Definition: types.h:112
BOOLEAN KdbpShouldStepOverInstruction(ULONG_PTR Eip)
Checks whether the given instruction can be single stepped or has to be stepped over using a temporar...
Definition: kdb.c:236

Referenced by KdbEnterDebuggerException().

Variable Documentation

◆ ExceptionNrToString

const CHAR* ExceptionNrToString[]
static
Initial value:
=
{
"Divide Error",
"Debug Trap",
"NMI",
"Breakpoint",
"Overflow",
"BOUND range exceeded",
"Invalid Opcode",
"No Math Coprocessor",
"Double Fault",
"Unknown(9)",
"Invalid TSS",
"Segment Not Present",
"Stack Segment Fault",
"General Protection",
"Page Fault",
"Reserved(15)",
"Math Fault",
"Alignment Check",
"Machine Check",
"SIMD Fault",
"Assertion Failure"
}

Definition at line 93 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbApcState

KAPC_STATE KdbApcState
static

Definition at line 61 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbBreakPointToReenable

PKDB_BREAKPOINT KdbBreakPointToReenable = NULL
static

Definition at line 46 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbCurrentProcess

◆ KdbCurrentThread

PETHREAD KdbCurrentThread = NULL

Definition at line 56 of file kdb.c.

Referenced by KdbEnterDebuggerException(), KdbpAttachToThread(), KdbpCmdProc(), and KdbpCmdThread().

◆ KdbCurrentTrapFrame

◆ KdbDebugState

ULONG KdbDebugState = 0

◆ KdbEnterConditions

◆ KdbEnteredOnSingleStep

BOOLEAN KdbEnteredOnSingleStep = FALSE
static

Definition at line 53 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCallMainLoop().

◆ KdbEntryCount

LONG KdbEntryCount = 0
static

Definition at line 37 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbHwBreakPointCount

ULONG KdbHwBreakPointCount = 0
static

Definition at line 43 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbHwBreakPoints

Definition at line 45 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbLastBreakPointNr

LONG KdbLastBreakPointNr = -1

Definition at line 49 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBreakPointList().

◆ KdbNumSingleSteps

ULONG KdbNumSingleSteps = 0

Definition at line 50 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdStep().

◆ KdbOriginalProcess

PEPROCESS KdbOriginalProcess = NULL

Definition at line 55 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbOriginalThread

PETHREAD KdbOriginalThread = NULL

Definition at line 57 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpAttachToThread().

◆ KdbpBugCheckRequested

BOOLEAN KdbpBugCheckRequested

Definition at line 156 of file kdb_cli.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdBugCheck().

◆ KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep

BOOLEAN KdbpEvenThoughWeHaveABreakPointToReenableWeAlsoHaveARealSingleStep
static

Definition at line 48 of file kdb.c.

Referenced by KdbEnterDebuggerException().

◆ KdbSingleStepOver

BOOLEAN KdbSingleStepOver = FALSE

Definition at line 51 of file kdb.c.

Referenced by KdbEnterDebuggerException(), and KdbpCmdStep().

◆ KdbSwBreakPointCount

ULONG KdbSwBreakPointCount = 0
static

Definition at line 42 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbSwBreakPoints

Definition at line 44 of file kdb.c.

Referenced by KdbpDisableBreakPoint(), KdbpEnableBreakPoint(), and KdbpIsBreakPointOurs().

◆ KdbThreadTrapFrame

KDB_KTRAP_FRAME KdbThreadTrapFrame = { 0 }
static

Definition at line 60 of file kdb.c.

Referenced by KdbpAttachToThread().

◆ KdbTrapFrame