📄 kdapi.c
字号:
/*++Copyright (c) 1990-2000 Microsoft Corporation. All rights reserved.Module Name: kdapi.cAbstract: 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 DbgKdTerminateApiextern BOOLEAN (*KdpCleanup)(void);//endextern 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_PRAGMAtypedef struct { DBGKD_WAIT_STATE_CHANGE StateChange; USHORT AdditionalDataLength; CHAR AdditionalData[80];} STATE_PACKET;#define MAX_LOAD_NOTIFICATIONS 45 // wraps around after 45STATE_PACKET SavedPackets[MAX_LOAD_NOTIFICATIONS];VOIDSendSavedPackets(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_STATUSKdpSendWaitContinue ( 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 contextReturn 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();}VOIDKdpReadVirtualMemory( 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 + -