Exemplo n.º 1
0
BOOLEAN
NTAPI
KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
                          IN PKEXCEPTION_FRAME ExceptionFrame,
                          IN PEXCEPTION_RECORD ExceptionRecord,
                          IN PCONTEXT Context,
                          IN KPROCESSOR_MODE PreviousMode,
                          IN BOOLEAN SecondChance)
{
    KD_CONTINUE_TYPE Return = kdHandleException;
    ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];

    /* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
        (ExceptionRecord->NumberParameters > 0) &&
        ((ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS) ||
         (ExceptionCommand == BREAKPOINT_UNLOAD_SYMBOLS) ||
         (ExceptionCommand == BREAKPOINT_COMMAND_STRING) ||
         (ExceptionCommand == BREAKPOINT_PRINT) ||
         (ExceptionCommand == BREAKPOINT_PROMPT)))
    {
        /* Check if this is a debug print */
        if (ExceptionCommand == BREAKPOINT_PRINT)
        {
            /* Print the string */
            KdpServiceDispatcher(BREAKPOINT_PRINT,
                                 (PVOID)ExceptionRecord->ExceptionInformation[1],
                                 ExceptionRecord->ExceptionInformation[2]);

            /* Return success */
            KeSetContextReturnRegister(Context, STATUS_SUCCESS);
        }
#ifdef KDBG
        else if (ExceptionCommand == BREAKPOINT_LOAD_SYMBOLS)
        {
            PLDR_DATA_TABLE_ENTRY LdrEntry;

            /* Load symbols. Currently implemented only for KDBG! */
            if(KdbpSymFindModule(((PKD_SYMBOLS_INFO)ExceptionRecord->ExceptionInformation[2])->BaseOfDll, NULL, -1, &LdrEntry))
                KdbSymProcessSymbols(LdrEntry);
        }
        else if (ExceptionCommand == BREAKPOINT_PROMPT)
        {
            ULONG ReturnValue;
            LPSTR OutString;
            USHORT OutStringLength;

            /* Get the response string  and length */
            OutString = (LPSTR)Context->Ebx;
            OutStringLength = (USHORT)Context->Edi;

            /* Call KDBG */
            ReturnValue = KdpPrompt((LPSTR)ExceptionRecord->
                                    ExceptionInformation[1],
                                    (USHORT)ExceptionRecord->
                                    ExceptionInformation[2],
                                    OutString,
                                    OutStringLength);

            /* Return the number of characters that we received */
            Context->Eax = ReturnValue;
        }
#endif

        /* This we can handle: simply bump the Program Counter */
        KeSetContextPc(Context, KeGetContextPc(Context) + KD_BREAKPOINT_SIZE);
        return TRUE;
    }

#ifdef KDBG
    /* Check if this is an assertion failure */
    if (ExceptionRecord->ExceptionCode == STATUS_ASSERTION_FAILURE)
    {
        /* Bump EIP to the instruction following the int 2C */
        Context->Eip += 2;
    }
#endif

    /* Get out of here if the Debugger isn't connected */
    if (KdDebuggerNotPresent) return FALSE;

#ifdef KDBG
    /* Call KDBG if available */
    Return = KdbEnterDebuggerException(ExceptionRecord,
                                       PreviousMode,
                                       Context,
                                       TrapFrame,
                                       !SecondChance);
#else /* not KDBG */
    if (WrapperInitRoutine)
    {
        /* Call GDB */
        Return = WrapperTable.KdpExceptionRoutine(ExceptionRecord,
                                                  Context,
                                                  TrapFrame);
    }
#endif /* not KDBG */

    /* Debugger didn't handle it, please handle! */
    if (Return == kdHandleException) return FALSE;

    /* Debugger handled it */
    return TRUE;
}
Exemplo n.º 2
0
BOOLEAN
NTAPI
KdpTrap(IN PKTRAP_FRAME TrapFrame,
        IN PKEXCEPTION_FRAME ExceptionFrame,
        IN PEXCEPTION_RECORD ExceptionRecord,
        IN PCONTEXT ContextRecord,
        IN KPROCESSOR_MODE PreviousMode,
        IN BOOLEAN SecondChanceException)
{
    BOOLEAN Unload = FALSE;
    ULONG_PTR ProgramCounter;
    BOOLEAN Handled;
    NTSTATUS ReturnStatus;
    USHORT ReturnLength;

    /*
     * Check if we got a STATUS_BREAKPOINT with a SubID for Print, Prompt or
     * Load/Unload symbols. Make sure it isn't a software breakpoints as those
     * are handled by KdpReport.
     */
    if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
            (ExceptionRecord->ExceptionInformation[0] != BREAKPOINT_BREAK))
    {
        /* Save Program Counter */
        ProgramCounter = KeGetContextPc(ContextRecord);

        /* Check what kind of operation was requested from us */
        switch (ExceptionRecord->ExceptionInformation[0])
        {
        /* DbgPrint */
        case BREAKPOINT_PRINT:

            /* Call the worker routine */
            ReturnStatus = KdpPrint((ULONG)KdpGetParameterThree(ContextRecord),
                                    (ULONG)KdpGetParameterFour(ContextRecord),
                                    (LPSTR)ExceptionRecord->
                                    ExceptionInformation[1],
                                    (USHORT)ExceptionRecord->
                                    ExceptionInformation[2],
                                    PreviousMode,
                                    TrapFrame,
                                    ExceptionFrame,
                                    &Handled);

            /* Update the return value for the caller */
            KeSetContextReturnRegister(ContextRecord, ReturnStatus);
            break;

        /* DbgPrompt */
        case BREAKPOINT_PROMPT:

            /* Call the worker routine */
            ReturnLength = KdpPrompt((LPSTR)ExceptionRecord->
                                     ExceptionInformation[1],
                                     (USHORT)ExceptionRecord->
                                     ExceptionInformation[2],
                                     (LPSTR)KdpGetParameterThree(ContextRecord),
                                     (USHORT)KdpGetParameterFour(ContextRecord),
                                     PreviousMode,
                                     TrapFrame,
                                     ExceptionFrame);
            Handled = TRUE;

            /* Update the return value for the caller */
            KeSetContextReturnRegister(ContextRecord, ReturnLength);
            break;

        /* DbgUnLoadImageSymbols */
        case BREAKPOINT_UNLOAD_SYMBOLS:

            /* Drop into the load case below, with the unload parameter */
            Unload = TRUE;

        /* DbgLoadImageSymbols */
        case BREAKPOINT_LOAD_SYMBOLS:

            /* Call the worker routine */
            KdpSymbol((PSTRING)ExceptionRecord->
                      ExceptionInformation[1],
                      (PKD_SYMBOLS_INFO)ExceptionRecord->
                      ExceptionInformation[2],
                      Unload,
                      PreviousMode,
                      ContextRecord,
                      TrapFrame,
                      ExceptionFrame);
            Handled = TRUE;
            break;

        /* DbgCommandString */
        case BREAKPOINT_COMMAND_STRING:

            /* Call the worker routine */
            KdpCommandString((PSTRING)ExceptionRecord->
                             ExceptionInformation[1],
                             (PSTRING)ExceptionRecord->
                             ExceptionInformation[2],
                             PreviousMode,
                             ContextRecord,
                             TrapFrame,
                             ExceptionFrame);
            Handled = TRUE;
            break;

        /* Anything else, do nothing */
        default:

            /* Invalid debug service! Don't handle this! */
            Handled = FALSE;
            break;
        }

        /*
         * If the PC was not updated, we'll increment it ourselves so execution
         * continues past the breakpoint.
         */
        if (ProgramCounter == KeGetContextPc(ContextRecord))
        {
            /* Update it */
            KeSetContextPc(ContextRecord,
                           ProgramCounter + KD_BREAKPOINT_SIZE);
        }
    }
    else
    {
        /* Call the worker routine */
        Handled = KdpReport(TrapFrame,
                            ExceptionFrame,
                            ExceptionRecord,
                            ContextRecord,
                            PreviousMode,
                            SecondChanceException);
    }

    /* Return TRUE or FALSE to caller */
    return Handled;
}