Skip to content

Commit

Permalink
** wip ** New improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
HBelusca committed Oct 13, 2024
1 parent 96f89c3 commit f06979d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 42 deletions.
43 changes: 26 additions & 17 deletions ntoskrnl/kdbg/kdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1141,20 +1141,29 @@ KdbpAttachToProcess(
return KdbpAttachToThread(Thread->Cid.UniqueThread);
}

/*!\brief Calls the main loop ...
*/
/**
* @brief Calls the main interactive debugger loop.
**/
static VOID
KdbpCallMainLoop(VOID)
{
KdbpCliMainLoop(KdbEnteredOnSingleStep);
}

/*!\brief Internal function to enter KDB.
/**
* @brief
* Internal function to enter KDBG and run the specified procedure.
*
* Disables interrupts, releases display ownership, ...
*/
*
* @param[in] Function
* The procedure to execute under the KDBG environment.
* Either execute the the main interactive debugger loop (KdbpCallMainLoop)
* or run the KDBinit file (KdbpCliInterpretInitFile).
**/
static VOID
KdbpInternalEnter(VOID)
KdbpInternalEnter(
_In_ VOID (*Function)(VOID))
{
PETHREAD Thread;
PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
Expand All @@ -1178,7 +1187,7 @@ KdbpInternalEnter(VOID)

// KdbPrintf("Switching to KDB stack 0x%08x-0x%08x (Current Stack is 0x%08x)\n", Thread->Tcb.StackLimit, Thread->Tcb.StackBase, Esp);

KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - KDB_STACK_RESERVE, KdbpCallMainLoop);
KdbpStackSwitchAndCall(KdbStack + KDB_STACK_SIZE - KDB_STACK_RESERVE, Function);

Thread->Tcb.InitialStack = SavedInitialStack;
Thread->Tcb.StackBase = SavedStackBase;
Expand Down Expand Up @@ -1275,6 +1284,7 @@ KdbEnterDebuggerException(
ULONG OldEflags;
KIRQL OldIrql;
NTSTATUS ExceptionCode;
VOID (*EnterFunction)(VOID) = KdbpCallMainLoop;

ExceptionCode = (ExceptionRecord ? ExceptionRecord->ExceptionCode : STATUS_BREAKPOINT);

Expand Down Expand Up @@ -1333,7 +1343,6 @@ KdbEnterDebuggerException(
{
Resume = TRUE; /* Set the resume flag when continuing execution */
}

/*
* When a temporary breakpoint is hit we have to make sure that we are
* in the same context in which it was set, otherwise it could happen
Expand All @@ -1360,7 +1369,6 @@ KdbEnterDebuggerException(

KdbEnteredOnSingleStep = TRUE;
}

/*
* If we hit a breakpoint set by the debugger we set the single step flag,
* ignore the next single step and reenable the breakpoint.
Expand Down Expand Up @@ -1482,23 +1490,24 @@ KdbEnterDebuggerException(
}
else if (ExceptionCode == STATUS_BREAKPOINT)
{
/* Do the condition check and banner display only if we are entering
* because of a true code breakpoint. Running the KDBinit file is also
* done via a breakpoint, but it is artificial, so we skip the check
* and the banner in this case. */
if (KdbInitFileBuffer)
{
// FIXME? Should we do that call at the same place
// where we currently call KdbpInternalEnter?
// InterlockedIncrement(&KdbEntryCount);
KdbpCliInterpretInitFile();
// InterlockedDecrement(&KdbEntryCount);
EnterConditionMet = FALSE;
goto continue_execution; /* return */
EnterFunction = KdbpCliInterpretInitFile;
goto EnterKdbg;
}

if (!EnterConditionMet)
{
return kdHandleException;
}

KdbPrintf("\nEntered debugger on embedded INT3 at 0x%04x:0x%p.\n",
Context->SegCs & 0xffff, KeGetContextPc(Context));
EnterKdbg:;
}
else
{
Expand Down Expand Up @@ -1549,8 +1558,8 @@ KdbEnterDebuggerException(
return kdHandleException;
}

/* Call the main loop */
KdbpInternalEnter();
/* Enter KDBG proper and either run the KDBinit file or call the main loop */
KdbpInternalEnter(EnterFunction);

/* Check if we should single step */
if (KdbNumSingleSteps > 0)
Expand Down
2 changes: 1 addition & 1 deletion ntoskrnl/kdbg/kdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef enum _KD_CONTINUE_TYPE

/* GLOBALS *******************************************************************/

extern PCHAR KdbInitFileBuffer;
extern volatile PCHAR KdbInitFileBuffer;

extern PEPROCESS KdbCurrentProcess;
extern PETHREAD KdbCurrentThread;
Expand Down
46 changes: 22 additions & 24 deletions ntoskrnl/kdbg/kdb_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static ULONG KdbNumberOfColsPrinted = 0;
static BOOLEAN KdbOutputAborted = FALSE;
static BOOLEAN KdbRepeatLastCommand = FALSE;

PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
volatile PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
BOOLEAN KdbpBugCheckRequested = FALSE;

/* Variables for Dmesg */
Expand Down Expand Up @@ -3339,7 +3339,7 @@ KdbpCliMainLoop(

/**
* @brief
* Interprets the KDBinit file from the SystemRoot\System32\drivers\etc
* Interprets the KDBinit file from the \SystemRoot\System32\drivers\etc
* directory, that has been loaded by KdbpCliInit().
*
* This function is used to interpret the init file in the debugger context
Expand All @@ -3352,21 +3352,19 @@ VOID
KdbpCliInterpretInitFile(VOID)
{
PCHAR p1, p2;
INT_PTR i;
CHAR c;

if (!KdbInitFileBuffer)
p1 = InterlockedExchangePointer((PVOID*)&KdbInitFileBuffer, NULL);
if (!p1)
return;

/* Execute the commands in the init file */
KdpDprintf("KDB: Executing KDBinit file...\n");
p1 = KdbInitFileBuffer;
KdbPuts("KDB: Executing KDBinit file...\n");
while (p1[0] != '\0')
{
i = strcspn(p1, "\r\n");
INT_PTR i = strcspn(p1, "\r\n");
if (i > 0)
{
c = p1[i];
CHAR c = p1[i];
p1[i] = '\0';

/* Look for "break" command and comments */
Expand All @@ -3378,8 +3376,8 @@ KdbpCliInterpretInitFile(VOID)
if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
(p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
{
/* Break into the debugger */
KdbpCliMainLoop(FALSE); // KdbpInternalEnter();
/* Run the debugger loop (we have already broken into the debugger) */
KdbpCliMainLoop(FALSE);
}
else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
{
Expand All @@ -3393,15 +3391,14 @@ KdbpCliInterpretInitFile(VOID)
while (p1[0] == '\r' || p1[0] == '\n')
p1++;
}
KdpDprintf("KDB: KDBinit executed\n");
KdbInitFileBuffer = NULL;
KdbPuts("KDB: KDBinit executed\n");
}

/**
* @brief Called when KDB is initialized.
*
* Reads the KDBinit file from the SystemRoot\System32\drivers\etc directory
* and executes it, by calling back into the debugger.
* Loads the KDBinit file from the \SystemRoot\System32\drivers\etc
* directory and interprets it, by calling back into the debugger.
**/
NTSTATUS
KdbpCliInit(VOID)
Expand All @@ -3412,7 +3409,7 @@ KdbpCliInit(VOID)
IO_STATUS_BLOCK Iosb;
FILE_STANDARD_INFORMATION FileStdInfo;
HANDLE hFile = NULL;
INT FileSize;
ULONG FileSize;
PCHAR FileBuffer;

/* Don't load the KDBinit file if its buffer is already lying around */
Expand All @@ -3434,7 +3431,7 @@ KdbpCliInit(VOID)
FILE_NO_INTERMEDIATE_BUFFERING);
if (!NT_SUCCESS(Status))
{
DPRINT1("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%lx)\n", Status);
DPRINT("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%lx)\n", Status);
return Status;
}

Expand All @@ -3451,16 +3448,17 @@ KdbpCliInit(VOID)
FileSize = FileStdInfo.EndOfFile.u.LowPart;

/* Allocate memory for the file */
FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
FileBuffer = ExAllocatePool(NonPagedPool, FileSize + 1); /* Add 1 byte for terminating NUL */
if (!FileBuffer)
{
ZwClose(hFile);
DPRINT1("Could not allocate %d bytes for KDBinit file\n", FileSize);
DPRINT1("Could not allocate %lu bytes for KDBinit file\n", FileSize);
return Status;
}

/* Load file into memory */
Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb, FileBuffer, FileSize, NULL, NULL);
Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb,
FileBuffer, FileSize, NULL, NULL);
ZwClose(hFile);

if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
Expand All @@ -3473,10 +3471,10 @@ KdbpCliInit(VOID)
FileSize = min(FileSize, (INT)Iosb.Information);
FileBuffer[FileSize] = '\0';

/* Interpret the init file by calling back into the debugger */
KdbInitFileBuffer = FileBuffer;
/* Interpret the KDBinit file by calling back into the debugger */
InterlockedExchangePointer((PVOID*)&KdbInitFileBuffer, FileBuffer);
DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
KdbInitFileBuffer = NULL;
InterlockedExchangePointer((PVOID*)&KdbInitFileBuffer, NULL);

ExFreePool(FileBuffer);

Expand Down Expand Up @@ -3618,7 +3616,7 @@ KdbInitialize(

if (BootPhase >= 2)
{
/* I/O is now set up for disk access: Read KDB Data */
/* I/O is now set up for disk access: load the KDBinit file */
NTSTATUS Status = KdbpCliInit();

/* Schedule an I/O reinitialization if needed */
Expand Down

0 comments on commit f06979d

Please sign in to comment.