⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdapi.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 4 页
字号:
/*++

Copyright (c) 1990-2000 Microsoft Corporation.  All rights reserved.

Module Name:

    kdapi.c

Abstract:

    Implementation of Kernel Debugger portable remote APIs.


--*/

#include "kdp.h"

extern BOOL fDbgConnected;

//
// included to find the relocated kernel data section
//
extern ROMHDR * const volatile pTOC;

// This routine is called when it receives DbgKdTerminateApi
extern BOOLEAN (*KdpCleanup)(void);
//end

extern VOID KdTerminateTransport(VOID);
extern VOID KdInterruptsOff(VOID);
extern VOID KdInterruptsOn(VOID);

DWORD NkCEProcessorType; // Temp change [GH]: was CEProcessorType

#if defined(x86)
extern PTHREAD g_CurFPUOwner;
#endif


//
// Define external data.
//

extern PVOID KdpImageBase;

CHAR *socketReady;
DWORD packetsIndex;

BOOLEAN KdpSendContext = TRUE;
BOOL fDbgConnected;
BOOL fAtBreakState;

DBGKD_MANIPULATE_STATE ManipulateState;


#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGEKD, KdpSendWaitContinue)
#pragma alloc_text(PAGEKD, KdpReadVirtualMemory)
#pragma alloc_text(PAGEKD, KdpWriteVirtualMemory)
#pragma alloc_text(PAGEKD, KdpGetContext)
#pragma alloc_text(PAGEKD, KdpSetContext)
#pragma alloc_text(PAGEKD, KdpWriteBreakpoint)
#pragma alloc_text(PAGEKD, KdpRestoreBreakpoint)
#pragma alloc_text(PAGEKD, KdpReportExceptionStateChange)
#pragma alloc_text(PAGEKD, KdpReportLoadSymbolsStateChange)
#pragma alloc_text(PAGEKD, KdpReadPhysicalMemory)
#pragma alloc_text(PAGEKD, KdpWritePhysicalMemory)
#pragma alloc_text(PAGEKD, KdpGetVersion)
#pragma alloc_text(PAGEKD, KdpWriteBreakPointEx)
#pragma alloc_text(PAGEKD, KdpRestoreBreakPointEx)
#endif // ALLOC_PRAGMA


typedef struct {
    DBGKD_WAIT_STATE_CHANGE StateChange;
    USHORT AdditionalDataLength;
    CHAR AdditionalData[80];
} STATE_PACKET;

#define MAX_LOAD_NOTIFICATIONS 45 // wraps around after 45
STATE_PACKET SavedPackets[MAX_LOAD_NOTIFICATIONS];

VOID
SendSavedPackets(VOID)
{
    PSTRING AdditionalData = NULL;
    STRING MessageHeader;
    STRING MessageData;
    KCONTINUE_STATUS Status;
    CONTEXT ContextRecord;
    DWORD i;

    for (i = 0; i < (packetsIndex%MAX_LOAD_NOTIFICATIONS); i++) {
        do {
            MessageHeader.Length = sizeof(DBGKD_WAIT_STATE_CHANGE);
            MessageHeader.Buffer = (PCHAR)&SavedPackets[i].StateChange;

            if (SavedPackets[i].AdditionalDataLength) {
                MessageData.Length = SavedPackets[i].AdditionalDataLength;
                MessageData.Buffer = SavedPackets[i].AdditionalData;
                AdditionalData = &MessageData;
            }

            Status = KdpSendWaitContinue(
                PACKET_TYPE_KD_STATE_CHANGE,
                &MessageHeader,
                AdditionalData,
                &ContextRecord
                );

        } while (Status == ContinueProcessorReselected);
    }

    packetsIndex = 0;
}


KCONTINUE_STATUS
KdpSendWaitContinue (
    IN ULONG OutPacketType,
    IN PSTRING OutMessageHeader,
    IN PSTRING OutMessageData OPTIONAL,
    IN OUT CONTEXT * ContextRecord
    )

/*++

Routine Description:

    This function sends a packet, and then waits for a continue message.
    BreakIns received while waiting will always cause a resend of the
    packet originally sent out.  While waiting, manipulate messages
    will be serviced.

    A resend always resends the original event sent to the debugger,
    not the last response to some debugger command.

Arguments:

    OutPacketType - Supplies the type of packet to send.

    OutMessageHeader - Supplies a pointer to a string descriptor that describes
        the message information.

    OutMessageData - Supplies a pointer to a string descriptor that describes
        the optional message data.

    ContextRecord - Exception context

Return Value:

    A value of TRUE is returned if the continue message indicates
    success, Otherwise, a value of FALSE is returned.

--*/

{

    ULONG Length;
    STRING MessageData;
    STRING MessageHeader;
    USHORT ReturnCode;
    NTSTATUS Status;

    //
    // Loop servicing state manipulation message until a continue message
    // is received.
    //

    MessageHeader.MaximumLength = sizeof(DBGKD_MANIPULATE_STATE);
    MessageHeader.Buffer = (PCHAR)&ManipulateState;
    MessageData.MaximumLength = KDP_MESSAGE_BUFFER_SIZE;
    MessageData.Buffer = (PCHAR)KdpMessageBuffer;

    KdInterruptsOff();
ResendPacket:

    //
    // Send event notification packet to debugger on host.  Come back
    // here any time we see a breakin sequence.
    //
   //DEBUGGERMSG(KDZONE_API, (L"SendPacket\n"));

    KdpSendPacket(
                  OutPacketType,
                  OutMessageHeader,
                  OutMessageData
                  );
    //
    // After sending packet, if there is no response from debugger
    // AND the packet is for reporting symbol (un)load, the debugger
    // will be decalred to be not present.  Note If the packet is for
    // reporting exception, the KdpSendPacket will never stop.
    //

    if (KdDebuggerNotPresent) {
        DEBUGGERMSG(KDZONE_API, (L"Debugger dead\r\n"));
        fDbgConnected=FALSE;
        KdInterruptsOn();
        return ContinueSuccess;
    }

    fAtBreakState = TRUE;
    while (TRUE) {

        //
        // Wait for State Manipulate Packet without timeout.
        //

        do {
            ReturnCode = KdpReceivePacket(
                            PACKET_TYPE_KD_STATE_MANIPULATE,
                            &MessageHeader,
                            &MessageData,
                            &Length
                            );
            if (ReturnCode == (USHORT)KDP_PACKET_RESEND) {
                goto ResendPacket;
            }
        } while (ReturnCode == KDP_PACKET_TIMEOUT);

        //
        // Switch on the return message API number.
        //

		DEBUGGERMSG(KDZONE_API, (L"Got Api %8.8lx\r\n", ManipulateState.ApiNumber));

        switch (ManipulateState.ApiNumber) {

        case DbgKdReadVirtualMemoryApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdReadVirtualMemoryApi\r\n"));
            KdpReadVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdWriteVirtualMemoryApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteVirtualMemoryApi\r\n"));
            KdpWriteVirtualMemory(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdReadPhysicalMemoryApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdReadPhysicalMemoryApi\r\n"));
            KdpReadPhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdWritePhysicalMemoryApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWritePhysicalMemoryApi\r\n"));
            KdpWritePhysicalMemory(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdGetContextApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdGetContextApi\r\n"));
            KdpGetContext(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdSetContextApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdSetContextApi\r\n"));
            KdpSetContext(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdWriteBreakPointApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteBreakPointApi\r\n"));
            KdpWriteBreakpoint(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdRestoreBreakPointApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdRestoreBreakPointApi\r\n"));
            KdpRestoreBreakpoint(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdReadControlSpaceApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdReadControlSpaceApi\r\n"));
            KdpReadControlSpace(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdWriteControlSpaceApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteControlSpaceApi\r\n"));
            KdpWriteControlSpace(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdReadIoSpaceApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdReadIoSpaceApi\r\n"));
            KdpReadIoSpace(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdWriteIoSpaceApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteIoSpaceApi\r\n"));
            KdpWriteIoSpace(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdContinueApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdContinueApi\r\n"));
            fAtBreakState = FALSE;
			DEBUGGERMSG(KDZONE_API, (L"Continuing target system %8.8lx\r\n", ManipulateState.u.Continue.ContinueStatus));
            if (NT_SUCCESS(ManipulateState.u.Continue.ContinueStatus) != FALSE) {
                KdInterruptsOn();
                return ContinueSuccess;
            } else {
                KdInterruptsOn();
                return ContinueError;
            }
            break;

        case DbgKdTerminateApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdTerminateApi\r\n"));
            KdpCleanup();
            fDbgConnected=FALSE;
            fAtBreakState = FALSE;
            KdTerminateTransport();
            KdInterruptsOn();
            return ContinueSuccess;

        case DbgKdContinueApi2:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdContinueApi2\r\n"));
            fAtBreakState = FALSE;
            if (NT_SUCCESS(ManipulateState.u.Continue2.ContinueStatus) != FALSE) {
                KdpGetStateChange(&ManipulateState,ContextRecord);
                KdInterruptsOn();
                return ContinueSuccess;
            } else {
                KdInterruptsOn();
                return ContinueError;
            }
            break;

        case DbgKdRebootApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdRebootApi\r\n"));
			if (pKDIoControl) {
				pKDIoControl( KD_IOCTL_RESET, NULL, 0);
			}
            break;

        case DbgKdGetVersionApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdGetVersionApi\r\n"));
            KdpGetVersion(&ManipulateState);
            break;

        case DbgKdCauseBugCheckApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdCauseBugCheckApi\r\n"));
            MessageData.Length = 0;
            ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
            KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData);
            break;

        case DbgKdWriteBreakPointExApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdWriteBreakPointExApi\r\n"));
            Status = KdpWriteBreakPointEx(&ManipulateState,
                                                  &MessageData,
                                                  ContextRecord);
            if (Status) {
                ManipulateState.ApiNumber = DbgKdContinueApi;
                ManipulateState.u.Continue.ContinueStatus = Status;
                KdInterruptsOn();
                return ContinueError;
            }
            break;

        case DbgKdRestoreBreakPointExApi:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdRestoreBreakPointExApi\r\n"));
            KdpRestoreBreakPointEx(&ManipulateState,&MessageData,ContextRecord);
            break;

        case DbgKdManipulateBreakpoint:
			DEBUGGERMSG( KDZONE_API, (L"DbgKdManipulateBreakpoint\r\n"));
            Status = KdpManipulateBreakPoint(&ManipulateState,
                                                  &MessageData,
                                                  ContextRecord);
            if (Status) {
                ManipulateState.ApiNumber = DbgKdContinueApi;
                ManipulateState.u.Continue.ContinueStatus = Status;
                KdInterruptsOn();
                return ContinueError;
            }
            break;
            //
            // Invalid message.
            //

        default:
			DEBUGGERMSG( KDZONE_API, (L"Unknown API ??\r\n"));
            MessageData.Length = 0;
            ManipulateState.ReturnStatus = STATUS_UNSUCCESSFUL;
            KdpSendPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &MessageHeader, &MessageData);
            break;
        }

    }
    KdInterruptsOn();
}

VOID
KdpReadVirtualMemory(
    IN PDBGKD_MANIPULATE_STATE m,
    IN PSTRING AdditionalData,
    IN CONTEXT * Context
    )

/*++

Routine Description:

    This function is called in response of a read virtual memory
    state manipulation message. Its function is to read virtual memory
    and return.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_MEMORY a = &m->u.ReadMemory;
    ULONG Length;
    STRING MessageHeader;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    //
    // make sure that nothing but a read memory message was transmitted
    //

    KD_ASSERT(AdditionalData->Length == 0);

    //
    // Trim transfer count to fit in a single message
    //

    if (a->TransferCount > (PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE))) {
        Length = PACKET_MAX_SIZE - sizeof(DBGKD_MANIPULATE_STATE);
    } else {
        Length = a->TransferCount;
    }

    AdditionalData->Length = (USHORT)KdpMoveMemory(
                                        AdditionalData->Buffer,
                                        a->TargetBaseAddress,
                                        Length
                                        );

    if (Length == AdditionalData->Length) {
        m->ReturnStatus = STATUS_SUCCESS;
    } else {
        m->ReturnStatus = STATUS_UNSUCCESSFUL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -