882 lines
23 KiB
C
882 lines
23 KiB
C
|
/*++ BUILD Version: 0063 // Increment this if a change has global effects
|
|||
|
|
|||
|
Copyright (c) 1990-1994 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
windbgkd.h
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module defines the 32-Bit Windows Kernel Debugger interface.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#ifndef _WINDBGKD_
|
|||
|
#define _WINDBGKD_
|
|||
|
|
|||
|
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
|
|||
|
|
|||
|
#ifdef _X86_
|
|||
|
|
|||
|
//
|
|||
|
// DBGKD_CONTROL_REPORT
|
|||
|
//
|
|||
|
// This structure contains machine specific data passed to the debugger
|
|||
|
// when a Wait_State_Change message is sent. Idea is to allow debugger
|
|||
|
// to do what it needes without reading any more packets.
|
|||
|
// Structure is filled in by KdpSetControlReport
|
|||
|
//
|
|||
|
|
|||
|
#define DBGKD_MAXSTREAM 16
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTROL_REPORT {
|
|||
|
DWORD Dr6;
|
|||
|
DWORD Dr7;
|
|||
|
WORD InstructionCount;
|
|||
|
WORD ReportFlags;
|
|||
|
BYTE InstructionStream[DBGKD_MAXSTREAM];
|
|||
|
WORD SegCs;
|
|||
|
WORD SegDs;
|
|||
|
WORD SegEs;
|
|||
|
WORD SegFs;
|
|||
|
DWORD EFlags;
|
|||
|
} DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
|
|||
|
|
|||
|
#define REPORT_INCLUDES_SEGS 0x0001 // this is for backward compatibility
|
|||
|
|
|||
|
//
|
|||
|
// DBGKD_CONTROL_SET
|
|||
|
//
|
|||
|
// This structure control value the debugger wants to set on every
|
|||
|
// continue, and thus sets here to avoid packet traffic.
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTROL_SET {
|
|||
|
DWORD TraceFlag; // WARNING: This must NOT be a BOOLEAN,
|
|||
|
// or host and target will end
|
|||
|
// up with different alignments!
|
|||
|
DWORD Dr7;
|
|||
|
DWORD CurrentSymbolStart; // Range in which to trace locally
|
|||
|
DWORD CurrentSymbolEnd;
|
|||
|
} DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
|
|||
|
|
|||
|
#endif //_X86_
|
|||
|
|
|||
|
|
|||
|
typedef struct _DESCRIPTOR_TABLE_ENTRY {
|
|||
|
DWORD Selector;
|
|||
|
LDT_ENTRY Descriptor;
|
|||
|
} DESCRIPTOR_TABLE_ENTRY, *PDESCRIPTOR_TABLE_ENTRY;
|
|||
|
|
|||
|
|
|||
|
#if defined(_MIPS_)
|
|||
|
|
|||
|
// end_ntddk end_nthal
|
|||
|
|
|||
|
//
|
|||
|
// Define MIPS specific kernel debugger information.
|
|||
|
//
|
|||
|
// The following structure contains machine specific data passed to
|
|||
|
// the host system kernel debugger in a wait state change message.
|
|||
|
//
|
|||
|
|
|||
|
#define DBGKD_MAXSTREAM 16
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTROL_REPORT {
|
|||
|
DWORD InstructionCount;
|
|||
|
BYTE InstructionStream[DBGKD_MAXSTREAM];
|
|||
|
} DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
|
|||
|
|
|||
|
//
|
|||
|
// The following structure contains information that the host system
|
|||
|
// kernel debugger wants to set on every continue operation and avoids
|
|||
|
// the need to send extra packets of information.
|
|||
|
//
|
|||
|
|
|||
|
typedef DWORD DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
|
|||
|
|
|||
|
#endif // ntddk nthal
|
|||
|
|
|||
|
#ifdef _ALPHA_
|
|||
|
|
|||
|
//
|
|||
|
// Define Alpha specific kernel debugger information.
|
|||
|
//
|
|||
|
// The following structure contains machine specific data passed to
|
|||
|
// the host system kernel debugger in a wait state change message.
|
|||
|
//
|
|||
|
|
|||
|
#define DBGKD_MAXSTREAM 16
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTROL_REPORT {
|
|||
|
DWORD InstructionCount;
|
|||
|
BYTE InstructionStream[DBGKD_MAXSTREAM];
|
|||
|
} DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
|
|||
|
|
|||
|
//
|
|||
|
// The following structure contains information that the host system
|
|||
|
// kernel debugger wants to set on every continue operation and avoids
|
|||
|
// the need to send extra packets of information.
|
|||
|
//
|
|||
|
|
|||
|
typedef DWORD DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
|
|||
|
|
|||
|
#endif // _ALPHA_
|
|||
|
|
|||
|
#if defined(_PPC_)
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Define PowerPC specific kernel debugger information.
|
|||
|
//
|
|||
|
// The following structure contains machine specific data passed to
|
|||
|
// the host system kernel debugger in a wait state change message.
|
|||
|
//
|
|||
|
// **FINISH** Copied without change from MIPS; may need modification
|
|||
|
|
|||
|
#define DBGKD_MAXSTREAM 16
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTROL_REPORT {
|
|||
|
DWORD InstructionCount;
|
|||
|
BYTE InstructionStream[DBGKD_MAXSTREAM];
|
|||
|
} DBGKD_CONTROL_REPORT, *PDBGKD_CONTROL_REPORT;
|
|||
|
|
|||
|
//
|
|||
|
// The following structure contains information that the host system
|
|||
|
// kernel debugger wants to set on every continue operation and avoids
|
|||
|
// the need to send extra packets of information.
|
|||
|
//
|
|||
|
|
|||
|
typedef DWORD DBGKD_CONTROL_SET, *PDBGKD_CONTROL_SET;
|
|||
|
|
|||
|
#endif // defined(_PPC_)
|
|||
|
|
|||
|
#ifdef _PPC_
|
|||
|
//
|
|||
|
// Special Registers for PowerPC
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _KSPECIAL_REGISTERS {
|
|||
|
DWORD KernelDr0;
|
|||
|
DWORD KernelDr1;
|
|||
|
DWORD KernelDr2;
|
|||
|
DWORD KernelDr3;
|
|||
|
DWORD KernelDr4;
|
|||
|
DWORD KernelDr5;
|
|||
|
DWORD KernelDr6;
|
|||
|
DWORD KernelDr7;
|
|||
|
DWORD Sprg0;
|
|||
|
DWORD Sprg1;
|
|||
|
DWORD Sr0;
|
|||
|
DWORD Sr1;
|
|||
|
DWORD Sr2;
|
|||
|
DWORD Sr3;
|
|||
|
DWORD Sr4;
|
|||
|
DWORD Sr5;
|
|||
|
DWORD Sr6;
|
|||
|
DWORD Sr7;
|
|||
|
DWORD Sr8;
|
|||
|
DWORD Sr9;
|
|||
|
DWORD Sr10;
|
|||
|
DWORD Sr11;
|
|||
|
DWORD Sr12;
|
|||
|
DWORD Sr13;
|
|||
|
DWORD Sr14;
|
|||
|
DWORD Sr15;
|
|||
|
DWORD DBAT0L;
|
|||
|
DWORD DBAT0U;
|
|||
|
DWORD DBAT1L;
|
|||
|
DWORD DBAT1U;
|
|||
|
DWORD DBAT2L;
|
|||
|
DWORD DBAT2U;
|
|||
|
DWORD DBAT3L;
|
|||
|
DWORD DBAT3U;
|
|||
|
DWORD IBAT0L;
|
|||
|
DWORD IBAT0U;
|
|||
|
DWORD IBAT1L;
|
|||
|
DWORD IBAT1U;
|
|||
|
DWORD IBAT2L;
|
|||
|
DWORD IBAT2U;
|
|||
|
DWORD IBAT3L;
|
|||
|
DWORD IBAT3U;
|
|||
|
DWORD Sdr1;
|
|||
|
DWORD Reserved[9];
|
|||
|
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
|||
|
|
|||
|
//
|
|||
|
// Processor State structure.
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _KPROCESSOR_STATE {
|
|||
|
struct _CONTEXT ContextFrame;
|
|||
|
struct _KSPECIAL_REGISTERS SpecialRegisters;
|
|||
|
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
|||
|
|
|||
|
#endif // _PPC_
|
|||
|
|
|||
|
#ifdef _X86_
|
|||
|
//
|
|||
|
// Special Registers for i386
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DESCRIPTOR {
|
|||
|
WORD Pad;
|
|||
|
WORD Limit;
|
|||
|
DWORD Base;
|
|||
|
} KDESCRIPTOR, *PKDESCRIPTOR;
|
|||
|
|
|||
|
typedef struct _KSPECIAL_REGISTERS {
|
|||
|
DWORD Cr0;
|
|||
|
DWORD Cr2;
|
|||
|
DWORD Cr3;
|
|||
|
DWORD Cr4;
|
|||
|
DWORD KernelDr0;
|
|||
|
DWORD KernelDr1;
|
|||
|
DWORD KernelDr2;
|
|||
|
DWORD KernelDr3;
|
|||
|
DWORD KernelDr6;
|
|||
|
DWORD KernelDr7;
|
|||
|
KDESCRIPTOR Gdtr;
|
|||
|
KDESCRIPTOR Idtr;
|
|||
|
WORD Tr;
|
|||
|
WORD Ldtr;
|
|||
|
DWORD Reserved[6];
|
|||
|
} KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
|
|||
|
|
|||
|
//
|
|||
|
// Processor State frame: Before a processor freezes itself, it
|
|||
|
// dumps the processor state to the processor state frame for
|
|||
|
// debugger to examine.
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _KPROCESSOR_STATE {
|
|||
|
struct _CONTEXT ContextFrame;
|
|||
|
struct _KSPECIAL_REGISTERS SpecialRegisters;
|
|||
|
} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
|
|||
|
#endif // _X86_
|
|||
|
|
|||
|
typedef struct _DBGKM_EXCEPTION {
|
|||
|
EXCEPTION_RECORD ExceptionRecord;
|
|||
|
DWORD FirstChance;
|
|||
|
} DBGKM_EXCEPTION, *PDBGKM_EXCEPTION;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// DbgKd APIs are for the portable kernel debugger
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// KD_PACKETS are the low level data format used in KD. All packets
|
|||
|
// begin with a packet leader, byte count, packet type. The sequence
|
|||
|
// for accepting a packet is:
|
|||
|
//
|
|||
|
// - read 4 bytes to get packet leader. If read times out (10 seconds)
|
|||
|
// with a short read, or if packet leader is incorrect, then retry
|
|||
|
// the read.
|
|||
|
//
|
|||
|
// - next read 2 byte packet type. If read times out (10 seconds) with
|
|||
|
// a short read, or if packet type is bad, then start again looking
|
|||
|
// for a packet leader.
|
|||
|
//
|
|||
|
// - next read 4 byte packet Id. If read times out (10 seconds)
|
|||
|
// with a short read, or if packet Id is not what we expect, then
|
|||
|
// ask for resend and restart again looking for a packet leader.
|
|||
|
//
|
|||
|
// - next read 2 byte byte count. If read times out (10 seconds) with
|
|||
|
// a short read, or if byte count is greater than PACKET_MAX_SIZE,
|
|||
|
// then start again looking for a packet leader.
|
|||
|
//
|
|||
|
// - next read 4 byte packet data checksum.
|
|||
|
//
|
|||
|
// - The packet data immediately follows the packet. There should be
|
|||
|
// ByteCount bytes following the packet header. Read the packet
|
|||
|
// data, if read times out (10 seconds) then start again looking for
|
|||
|
// a packet leader.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
typedef struct _KD_PACKET {
|
|||
|
DWORD PacketLeader;
|
|||
|
WORD PacketType;
|
|||
|
WORD ByteCount;
|
|||
|
DWORD PacketId;
|
|||
|
DWORD Checksum;
|
|||
|
} KD_PACKET, *PKD_PACKET;
|
|||
|
|
|||
|
|
|||
|
#define PACKET_MAX_SIZE 4000
|
|||
|
#define INITIAL_PACKET_ID 0x80800000 // DON't use 0
|
|||
|
#define SYNC_PACKET_ID 0x00000800 // Or in with INITIAL_PACKET_ID
|
|||
|
// to force a packet ID reset.
|
|||
|
|
|||
|
//
|
|||
|
// BreakIn packet
|
|||
|
//
|
|||
|
|
|||
|
#define BREAKIN_PACKET 0x62626262
|
|||
|
#define BREAKIN_PACKET_BYTE 0x62
|
|||
|
|
|||
|
//
|
|||
|
// Packet lead in sequence
|
|||
|
//
|
|||
|
|
|||
|
#define PACKET_LEADER 0x30303030 //0x77000077
|
|||
|
#define PACKET_LEADER_BYTE 0x30
|
|||
|
|
|||
|
#define CONTROL_PACKET_LEADER 0x69696969
|
|||
|
#define CONTROL_PACKET_LEADER_BYTE 0x69
|
|||
|
|
|||
|
//
|
|||
|
// Packet Trailing Byte
|
|||
|
//
|
|||
|
|
|||
|
#define PACKET_TRAILING_BYTE 0xAA
|
|||
|
|
|||
|
//
|
|||
|
// Packet Types
|
|||
|
//
|
|||
|
|
|||
|
#define PACKET_TYPE_UNUSED 0
|
|||
|
#define PACKET_TYPE_KD_STATE_CHANGE 1
|
|||
|
#define PACKET_TYPE_KD_STATE_MANIPULATE 2
|
|||
|
#define PACKET_TYPE_KD_DEBUG_IO 3
|
|||
|
#define PACKET_TYPE_KD_ACKNOWLEDGE 4 // Packet-control type
|
|||
|
#define PACKET_TYPE_KD_RESEND 5 // Packet-control type
|
|||
|
#define PACKET_TYPE_KD_RESET 6 // Packet-control type
|
|||
|
#define PACKET_TYPE_MAX 7
|
|||
|
|
|||
|
//
|
|||
|
// If the packet type is PACKET_TYPE_KD_STATE_CHANGE, then
|
|||
|
// the format of the packet data is as follows:
|
|||
|
//
|
|||
|
|
|||
|
#define DbgKdExceptionStateChange 0x00003030L
|
|||
|
#define DbgKdLoadSymbolsStateChange 0x00003031L
|
|||
|
|
|||
|
//
|
|||
|
// Pathname Data follows directly
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_LOAD_SYMBOLS {
|
|||
|
DWORD PathNameLength;
|
|||
|
PVOID BaseOfDll;
|
|||
|
DWORD ProcessId;
|
|||
|
DWORD CheckSum;
|
|||
|
DWORD SizeOfImage;
|
|||
|
BOOLEAN UnloadSymbols;
|
|||
|
} DBGKD_LOAD_SYMBOLS, *PDBGKD_LOAD_SYMBOLS;
|
|||
|
|
|||
|
typedef struct _DBGKD_WAIT_STATE_CHANGE {
|
|||
|
DWORD NewState;
|
|||
|
WORD ProcessorLevel;
|
|||
|
WORD Processor;
|
|||
|
DWORD NumberProcessors;
|
|||
|
PVOID Thread;
|
|||
|
PVOID ProgramCounter;
|
|||
|
union {
|
|||
|
DBGKM_EXCEPTION Exception;
|
|||
|
DBGKD_LOAD_SYMBOLS LoadSymbols;
|
|||
|
} u;
|
|||
|
DBGKD_CONTROL_REPORT ControlReport;
|
|||
|
CONTEXT Context;
|
|||
|
} DBGKD_WAIT_STATE_CHANGE, *PDBGKD_WAIT_STATE_CHANGE;
|
|||
|
|
|||
|
//
|
|||
|
// If the packet type is PACKET_TYPE_KD_STATE_MANIPULATE, then
|
|||
|
// the format of the packet data is as follows:
|
|||
|
//
|
|||
|
// Api Numbers for state manipulation
|
|||
|
//
|
|||
|
|
|||
|
#define DbgKdReadVirtualMemoryApi 0x00003130L
|
|||
|
#define DbgKdWriteVirtualMemoryApi 0x00003131L
|
|||
|
#define DbgKdGetContextApi 0x00003132L
|
|||
|
#define DbgKdSetContextApi 0x00003133L
|
|||
|
#define DbgKdWriteBreakPointApi 0x00003134L
|
|||
|
#define DbgKdRestoreBreakPointApi 0x00003135L
|
|||
|
#define DbgKdContinueApi 0x00003136L
|
|||
|
#define DbgKdReadControlSpaceApi 0x00003137L
|
|||
|
#define DbgKdWriteControlSpaceApi 0x00003138L
|
|||
|
#define DbgKdReadIoSpaceApi 0x00003139L
|
|||
|
#define DbgKdWriteIoSpaceApi 0x0000313AL
|
|||
|
#define DbgKdRebootApi 0x0000313BL
|
|||
|
#define DbgKdContinueApi2 0x0000313CL
|
|||
|
#define DbgKdReadPhysicalMemoryApi 0x0000313DL
|
|||
|
#define DbgKdWritePhysicalMemoryApi 0x0000313EL
|
|||
|
#define DbgKdQuerySpecialCallsApi 0x0000313FL
|
|||
|
#define DbgKdSetSpecialCallApi 0x00003140L
|
|||
|
#define DbgKdClearSpecialCallsApi 0x00003141L
|
|||
|
#define DbgKdSetInternalBreakPointApi 0x00003142L
|
|||
|
#define DbgKdGetInternalBreakPointApi 0x00003143L
|
|||
|
#define DbgKdReadIoSpaceExtendedApi 0x00003144L
|
|||
|
#define DbgKdWriteIoSpaceExtendedApi 0x00003145L
|
|||
|
#define DbgKdGetVersionApi 0x00003146L
|
|||
|
#define DbgKdWriteBreakPointExApi 0x00003147L
|
|||
|
#define DbgKdRestoreBreakPointExApi 0x00003148L
|
|||
|
#define DbgKdCauseBugCheckApi 0x00003149L
|
|||
|
#define DbgKdSwitchProcessor 0x00003150L
|
|||
|
#define DbgKdPageInApi 0x00003151L
|
|||
|
#define DbgKdReadMachineSpecificRegister 0x00003152L
|
|||
|
#define DbgKdWriteMachineSpecificRegister 0x00003153L
|
|||
|
|
|||
|
//
|
|||
|
// Response is a read memory message with data following
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_READ_MEMORY {
|
|||
|
PVOID TargetBaseAddress;
|
|||
|
DWORD TransferCount;
|
|||
|
DWORD ActualBytesRead;
|
|||
|
} DBGKD_READ_MEMORY, *PDBGKD_READ_MEMORY;
|
|||
|
|
|||
|
//
|
|||
|
// Data follows directly
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_WRITE_MEMORY {
|
|||
|
PVOID TargetBaseAddress;
|
|||
|
DWORD TransferCount;
|
|||
|
DWORD ActualBytesWritten;
|
|||
|
} DBGKD_WRITE_MEMORY, *PDBGKD_WRITE_MEMORY;
|
|||
|
|
|||
|
//
|
|||
|
// Response is a get context message with a full context record following
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_GET_CONTEXT {
|
|||
|
DWORD ContextFlags;
|
|||
|
} DBGKD_GET_CONTEXT, *PDBGKD_GET_CONTEXT;
|
|||
|
|
|||
|
//
|
|||
|
// Full Context record follows
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _DBGKD_SET_CONTEXT {
|
|||
|
DWORD ContextFlags;
|
|||
|
} DBGKD_SET_CONTEXT, *PDBGKD_SET_CONTEXT;
|
|||
|
|
|||
|
#define BREAKPOINT_TABLE_SIZE 32 // max number supported by kernel
|
|||
|
|
|||
|
typedef struct _DBGKD_WRITE_BREAKPOINT {
|
|||
|
PVOID BreakPointAddress;
|
|||
|
DWORD BreakPointHandle;
|
|||
|
} DBGKD_WRITE_BREAKPOINT, *PDBGKD_WRITE_BREAKPOINT;
|
|||
|
|
|||
|
typedef struct _DBGKD_RESTORE_BREAKPOINT {
|
|||
|
DWORD BreakPointHandle;
|
|||
|
} DBGKD_RESTORE_BREAKPOINT, *PDBGKD_RESTORE_BREAKPOINT;
|
|||
|
|
|||
|
typedef struct _DBGKD_BREAKPOINTEX {
|
|||
|
DWORD BreakPointCount;
|
|||
|
DWORD ContinueStatus;
|
|||
|
} DBGKD_BREAKPOINTEX, *PDBGKD_BREAKPOINTEX;
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTINUE {
|
|||
|
DWORD ContinueStatus;
|
|||
|
} DBGKD_CONTINUE, *PDBGKD_CONTINUE;
|
|||
|
|
|||
|
typedef struct _DBGKD_CONTINUE2 {
|
|||
|
DWORD ContinueStatus;
|
|||
|
DBGKD_CONTROL_SET ControlSet;
|
|||
|
} DBGKD_CONTINUE2, *PDBGKD_CONTINUE2;
|
|||
|
|
|||
|
typedef struct _DBGKD_READ_WRITE_IO {
|
|||
|
DWORD DataSize; // 1, 2, 4
|
|||
|
PVOID IoAddress;
|
|||
|
DWORD DataValue;
|
|||
|
} DBGKD_READ_WRITE_IO, *PDBGKD_READ_WRITE_IO;
|
|||
|
|
|||
|
typedef struct _DBGKD_READ_WRITE_IO_EXTENDED {
|
|||
|
DWORD DataSize; // 1, 2, 4
|
|||
|
DWORD InterfaceType;
|
|||
|
DWORD BusNumber;
|
|||
|
DWORD AddressSpace;
|
|||
|
PVOID IoAddress;
|
|||
|
DWORD DataValue;
|
|||
|
} DBGKD_READ_WRITE_IO_EXTENDED, *PDBGKD_READ_WRITE_IO_EXTENDED;
|
|||
|
|
|||
|
typedef struct _DBGKD_READ_WRITE_MSR {
|
|||
|
DWORD Msr;
|
|||
|
DWORD DataValueLow;
|
|||
|
DWORD DataValueHigh;
|
|||
|
} DBGKD_READ_WRITE_MSR, *PDBGKD_READ_WRITE_MSR;
|
|||
|
|
|||
|
|
|||
|
typedef struct _DBGKD_QUERY_SPECIAL_CALLS {
|
|||
|
DWORD NumberOfSpecialCalls;
|
|||
|
// DWORD SpecialCalls[];
|
|||
|
} DBGKD_QUERY_SPECIAL_CALLS, *PDBGKD_QUERY_SPECIAL_CALLS;
|
|||
|
|
|||
|
typedef struct _DBGKD_SET_SPECIAL_CALL {
|
|||
|
DWORD SpecialCall;
|
|||
|
} DBGKD_SET_SPECIAL_CALL, *PDBGKD_SET_SPECIAL_CALL;
|
|||
|
|
|||
|
typedef struct _DBGKD_SET_INTERNAL_BREAKPOINT {
|
|||
|
DWORD BreakpointAddress;
|
|||
|
DWORD Flags;
|
|||
|
} DBGKD_SET_INTERNAL_BREAKPOINT, *PDBGKD_SET_INTERNAL_BREAKPOINT;
|
|||
|
|
|||
|
typedef struct _DBGKD_GET_INTERNAL_BREAKPOINT {
|
|||
|
DWORD BreakpointAddress;
|
|||
|
DWORD Flags;
|
|||
|
DWORD Calls;
|
|||
|
DWORD MaxCallsPerPeriod;
|
|||
|
DWORD MinInstructions;
|
|||
|
DWORD MaxInstructions;
|
|||
|
DWORD TotalInstructions;
|
|||
|
} DBGKD_GET_INTERNAL_BREAKPOINT, *PDBGKD_GET_INTERNAL_BREAKPOINT;
|
|||
|
|
|||
|
#define DBGKD_INTERNAL_BP_FLAG_COUNTONLY 0x00000001 // don't count instructions
|
|||
|
#define DBGKD_INTERNAL_BP_FLAG_INVALID 0x00000002 // disabled BP
|
|||
|
#define DBGKD_INTERNAL_BP_FLAG_SUSPENDED 0x00000004 // temporarily suspended
|
|||
|
#define DBGKD_INTERNAL_BP_FLAG_DYING 0x00000008 // kill on exit
|
|||
|
|
|||
|
typedef struct _DBGKD_GET_VERSION {
|
|||
|
WORD MajorVersion;
|
|||
|
WORD MinorVersion;
|
|||
|
WORD ProtocolVersion;
|
|||
|
WORD Flags;
|
|||
|
DWORD KernBase;
|
|||
|
DWORD PsLoadedModuleList;
|
|||
|
WORD MachineType;
|
|||
|
|
|||
|
//
|
|||
|
// help for walking stacks with user callbacks:
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// The address of the thread structure is provided in the
|
|||
|
// WAIT_STATE_CHANGE packet. This is the offset from the base of
|
|||
|
// the thread structure to the pointer to the kernel stack frame
|
|||
|
// for the currently active usermode callback.
|
|||
|
//
|
|||
|
|
|||
|
WORD ThCallbackStack; // offset in thread data
|
|||
|
|
|||
|
//
|
|||
|
// these values are offsets into that frame:
|
|||
|
//
|
|||
|
|
|||
|
WORD NextCallback; // saved pointer to next callback frame
|
|||
|
WORD FramePointer; // saved frame pointer
|
|||
|
|
|||
|
//
|
|||
|
// Address of the kernel callout routine.
|
|||
|
//
|
|||
|
|
|||
|
DWORD KiCallUserMode; // kernel routine
|
|||
|
|
|||
|
//
|
|||
|
// Address of the usermode entry point for callbacks.
|
|||
|
//
|
|||
|
|
|||
|
DWORD KeUserCallbackDispatcher; // address in ntdll
|
|||
|
|
|||
|
//
|
|||
|
// DbgBreakPointWithStatus is a function which takes an argument
|
|||
|
// and hits a breakpoint. This field contains the address of the
|
|||
|
// breakpoint instruction. When the debugger sees a breakpoint
|
|||
|
// at this address, it may retrieve the argument from the first
|
|||
|
// argument register, or on x86 the eax register.
|
|||
|
//
|
|||
|
|
|||
|
DWORD BreakpointWithStatus; // address of breakpoint
|
|||
|
|
|||
|
DWORD Reserved4;
|
|||
|
} DBGKD_GET_VERSION, *PDBGKD_GET_VERSION;
|
|||
|
|
|||
|
#define DBGKD_VERS_FLAG_MP 0x0001 // kernel is MP built
|
|||
|
|
|||
|
typedef struct _DBGKD_PAGEIN {
|
|||
|
DWORD Address;
|
|||
|
DWORD ContinueStatus;
|
|||
|
} DBGKD_PAGEIN, *PDBGKD_PAGEIN;
|
|||
|
|
|||
|
typedef struct _DBGKD_MANIPULATE_STATE {
|
|||
|
DWORD ApiNumber;
|
|||
|
WORD ProcessorLevel;
|
|||
|
WORD Processor;
|
|||
|
DWORD ReturnStatus;
|
|||
|
union {
|
|||
|
DBGKD_READ_MEMORY ReadMemory;
|
|||
|
DBGKD_WRITE_MEMORY WriteMemory;
|
|||
|
DBGKD_GET_CONTEXT GetContext;
|
|||
|
DBGKD_SET_CONTEXT SetContext;
|
|||
|
DBGKD_WRITE_BREAKPOINT WriteBreakPoint;
|
|||
|
DBGKD_RESTORE_BREAKPOINT RestoreBreakPoint;
|
|||
|
DBGKD_CONTINUE Continue;
|
|||
|
DBGKD_CONTINUE2 Continue2;
|
|||
|
DBGKD_READ_WRITE_IO ReadWriteIo;
|
|||
|
DBGKD_READ_WRITE_IO_EXTENDED ReadWriteIoExtended;
|
|||
|
DBGKD_QUERY_SPECIAL_CALLS QuerySpecialCalls;
|
|||
|
DBGKD_SET_SPECIAL_CALL SetSpecialCall;
|
|||
|
DBGKD_SET_INTERNAL_BREAKPOINT SetInternalBreakpoint;
|
|||
|
DBGKD_GET_INTERNAL_BREAKPOINT GetInternalBreakpoint;
|
|||
|
DBGKD_GET_VERSION GetVersion;
|
|||
|
DBGKD_BREAKPOINTEX BreakPointEx;
|
|||
|
DBGKD_PAGEIN PageIn;
|
|||
|
DBGKD_READ_WRITE_MSR ReadWriteMsr;
|
|||
|
} u;
|
|||
|
} DBGKD_MANIPULATE_STATE, *PDBGKD_MANIPULATE_STATE;
|
|||
|
|
|||
|
//
|
|||
|
// This is the format for the trace data passed back from the kernel to
|
|||
|
// the debugger to describe multiple calls that have returned since the
|
|||
|
// last trip back. The basic format is that there are a bunch of these
|
|||
|
// (4 byte) unions stuck together. Each union is of one of two types: a
|
|||
|
// 4 byte unsigned long interger, or a three field struct, describing a
|
|||
|
// call (where "call" is delimited by returning or exiting the symbol
|
|||
|
// scope). If the number of instructions executed is too big to fit
|
|||
|
// into a WORD -1, then the Instructions field has
|
|||
|
// TRACE_DATA_INSTRUCTIONS_BIG and the next union is a LongNumber
|
|||
|
// containing the real number of instructions executed.
|
|||
|
//
|
|||
|
// The very first union returned in each callback is a LongNumber
|
|||
|
// containing the number of unions returned (including the "size"
|
|||
|
// record, os it's always at least 1 even if there's no data to return).
|
|||
|
//
|
|||
|
// This is all returned to the debugger when one of two things
|
|||
|
// happens:
|
|||
|
//
|
|||
|
// 1) The pc moves out of all defined symbol ranges
|
|||
|
// 2) The buffer of trace data entries is filled.
|
|||
|
//
|
|||
|
// The "trace done" case is hacked around on the debugger side. It
|
|||
|
// guarantees that the pc address that indicates a trace exit never
|
|||
|
// winds up in a defined symbol range.
|
|||
|
//
|
|||
|
// The only other complexity in this system is handling the SymbolNumber
|
|||
|
// table. This table is kept in parallel by the kernel and the
|
|||
|
// debugger. When the PC exits a known symbol range, the Begin and End
|
|||
|
// symbol ranges are set by the debugger and are allocated to the next
|
|||
|
// symbol slot upon return. "The next symbol slot" means the numerical
|
|||
|
// next slot number, unless we've filled all slots, in which case it is
|
|||
|
// #0. (ie., allocation is cyclic and not LRU or something). The
|
|||
|
// SymbolNumber table is flushed when a SpecialCalls call is made (ie.,
|
|||
|
// at the beginning of the WatchTrace).
|
|||
|
//
|
|||
|
|
|||
|
typedef union _DBGKD_TRACE_DATA {
|
|||
|
struct {
|
|||
|
BYTE SymbolNumber;
|
|||
|
CHAR LevelChange;
|
|||
|
WORD Instructions;
|
|||
|
} s;
|
|||
|
DWORD LongNumber;
|
|||
|
} DBGKD_TRACE_DATA, *PDBGKD_TRACE_DATA;
|
|||
|
|
|||
|
#define TRACE_DATA_INSTRUCTIONS_BIG 0xffff
|
|||
|
|
|||
|
#define TRACE_DATA_BUFFER_MAX_SIZE 40
|
|||
|
|
|||
|
//
|
|||
|
// If the packet type is PACKET_TYPE_KD_DEBUG_IO, then
|
|||
|
// the format of the packet data is as follows:
|
|||
|
//
|
|||
|
|
|||
|
#define DbgKdPrintStringApi 0x00003230L
|
|||
|
#define DbgKdGetStringApi 0x00003231L
|
|||
|
|
|||
|
//
|
|||
|
// For print string, the Null terminated string to print
|
|||
|
// immediately follows the message
|
|||
|
//
|
|||
|
typedef struct _DBGKD_PRINT_STRING {
|
|||
|
DWORD LengthOfString;
|
|||
|
} DBGKD_PRINT_STRING, *PDBGKD_PRINT_STRING;
|
|||
|
|
|||
|
//
|
|||
|
// For get string, the Null terminated promt string
|
|||
|
// immediately follows the message. The LengthOfStringRead
|
|||
|
// field initially contains the maximum number of characters
|
|||
|
// to read. Upon reply, this contains the number of bytes actually
|
|||
|
// read. The data read immediately follows the message.
|
|||
|
//
|
|||
|
//
|
|||
|
typedef struct _DBGKD_GET_STRING {
|
|||
|
DWORD LengthOfPromptString;
|
|||
|
DWORD LengthOfStringRead;
|
|||
|
} DBGKD_GET_STRING, *PDBGKD_GET_STRING;
|
|||
|
|
|||
|
typedef struct _DBGKD_DEBUG_IO {
|
|||
|
DWORD ApiNumber;
|
|||
|
WORD ProcessorLevel;
|
|||
|
WORD Processor;
|
|||
|
union {
|
|||
|
DBGKD_PRINT_STRING PrintString;
|
|||
|
DBGKD_GET_STRING GetString;
|
|||
|
} u;
|
|||
|
} DBGKD_DEBUG_IO, *PDBGKD_DEBUG_IO;
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
NTAPI
|
|||
|
DbgKdSendBreakIn(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
PBYTE
|
|||
|
NTAPI
|
|||
|
DbgKdGets(
|
|||
|
PBYTE Buffer,
|
|||
|
WORD Length
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWaitStateChange(
|
|||
|
OUT PDBGKD_WAIT_STATE_CHANGE StateChange,
|
|||
|
OUT PVOID Buffer,
|
|||
|
IN DWORD BufferLength
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdContinue (
|
|||
|
IN DWORD ContinueStatus
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdContinue2 (
|
|||
|
IN DWORD ContinueStatus,
|
|||
|
IN DBGKD_CONTROL_SET ControlSet
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReadVirtualMemory(
|
|||
|
IN PVOID TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesRead OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWriteVirtualMemory(
|
|||
|
IN PVOID TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesWritten OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReadPhysicalMemory(
|
|||
|
IN PHYSICAL_ADDRESS TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesRead OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWritePhysicalMemory(
|
|||
|
IN PHYSICAL_ADDRESS TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesWritten OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReadControlSpace(
|
|||
|
IN WORD Processor,
|
|||
|
IN PVOID TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesRead OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWriteControlSpace(
|
|||
|
IN WORD Processor,
|
|||
|
IN PVOID TargetBaseAddress,
|
|||
|
OUT PVOID UserInterfaceBuffer,
|
|||
|
IN DWORD TransferCount,
|
|||
|
OUT PDWORD ActualBytesWritten OPTIONAL
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReadIoSpace(
|
|||
|
IN PVOID IoAddress,
|
|||
|
OUT PVOID ReturnedData,
|
|||
|
IN DWORD DataSize
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWriteIoSpace(
|
|||
|
IN PVOID IoAddress,
|
|||
|
IN DWORD DataValue,
|
|||
|
IN DWORD DataSize
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReadMsr(
|
|||
|
IN DWORD MsrReg,
|
|||
|
OUT PDWORDLONG MsrValue
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWriteMsr(
|
|||
|
IN DWORD MsrReg,
|
|||
|
IN DWORDLONG MsrValue
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdGetContext(
|
|||
|
IN WORD Processor,
|
|||
|
IN OUT PCONTEXT Context
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdSetContext(
|
|||
|
IN WORD Processor,
|
|||
|
IN PCONTEXT Context
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdWriteBreakPoint(
|
|||
|
IN PVOID BreakPointAddress,
|
|||
|
OUT PDWORD BreakPointHandle
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdRestoreBreakPoint(
|
|||
|
IN DWORD BreakPointHandle
|
|||
|
);
|
|||
|
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdReboot(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
#ifdef _X86_
|
|||
|
DWORD
|
|||
|
NTAPI
|
|||
|
DbgKdLookupSelector(
|
|||
|
IN WORD Processor,
|
|||
|
IN OUT PDESCRIPTOR_TABLE_ENTRY pDescriptorTableEntry
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
#define DBG_EXCEPTION_HANDLED ((DWORD )0x00010001L)
|
|||
|
|
|||
|
#endif // _WINDBGKD_
|
|||
|
|