|
|
//----------------------------------------------------------------------------
//
// Abstraction of target-specific information.
//
// Copyright (C) Microsoft Corporation, 1999-2001.
//
//----------------------------------------------------------------------------
#ifndef __TARGET_HPP__
#define __TARGET_HPP__
extern DBGKD_GET_VERSION64 g_KdVersion;
HRESULT EmulateNtSelDescriptor(class MachineInfo* Machine, ULONG Selector, PDESCRIPTOR64 Desc); ULONG NtBuildToSystemVersion(ULONG Build); ULONG Win9xBuildToSystemVersion(ULONG Build); void SetTargetSystemVersionAndBuild(ULONG Build, ULONG PlatformId); PCSTR SystemVersionName(ULONG Sver);
BOOL GetUserModuleListAddress( MachineInfo* Machine, ULONG64 Peb, BOOL Quiet, PULONG64 OrderModuleListStart, PULONG64 FirstEntry );
BOOL GetModNameFromLoaderList( MachineInfo* Machine, ULONG64 Peb, ULONG64 ModuleBase, PSTR NameBuffer, ULONG BufferSize, BOOL FullPath );
void InitSelCache(void);
void ConvertLoaderEntry32To64( PKLDR_DATA_TABLE_ENTRY32 b32, PKLDR_DATA_TABLE_ENTRY64 b64 );
void SetTargetNtCsdVersion(ULONG CsdVersion);
//----------------------------------------------------------------------------
//
// Module list abstraction.
//
//----------------------------------------------------------------------------
// If the image header is paged out the true values for
// certain fields cannot be retrieved. These placeholders
// are used instead.
#define UNKNOWN_CHECKSUM 0xffffffff
#define UNKNOWN_TIMESTAMP 0xfffffffe
typedef struct _MODULE_INFO_ENTRY { // NamePtr should include a path if one is available.
// It is the responsibility of callers to find the
// file tail if that's all they care about.
// If UnicodeNamePtr is false NameLength is ignored.
PSTR NamePtr; ULONG UnicodeNamePtr:1; ULONG ImageInfoValid:1; ULONG ImageInfoPartial:1; ULONG ImageDebugHeader:1; ULONG Unused:28; // Length in bytes not including the terminator.
ULONG NameLength; PSTR ModuleName; HANDLE File; ULONG64 Base; ULONG Size; ULONG SizeOfCode; ULONG SizeOfData; ULONG CheckSum; ULONG TimeDateStamp; PVOID DebugHeader; ULONG SizeOfDebugHeader; CHAR Buffer[MAX_IMAGE_PATH * sizeof(WCHAR)]; } MODULE_INFO_ENTRY, *PMODULE_INFO_ENTRY;
class ModuleInfo { public: virtual HRESULT Initialize(void) = 0; virtual HRESULT GetEntry(PMODULE_INFO_ENTRY Entry) = 0; // Base implementation does nothing.
// Updates the entry image info by reading the
// image header.
void ReadImageHeaderInfo(PMODULE_INFO_ENTRY Entry); };
class NtModuleInfo : public ModuleInfo { public: virtual HRESULT GetEntry(PMODULE_INFO_ENTRY Entry);
protected: MachineInfo* m_Machine; ULONG64 m_Head; ULONG64 m_Cur; };
class NtKernelModuleInfo : public NtModuleInfo { public: virtual HRESULT Initialize(void); };
extern NtKernelModuleInfo g_NtKernelModuleIterator;
class NtUserModuleInfo : public NtModuleInfo { public: virtual HRESULT Initialize(void);
protected: ULONG64 m_Peb; };
class NtTargetUserModuleInfo : public NtUserModuleInfo { public: virtual HRESULT Initialize(void); };
extern NtTargetUserModuleInfo g_NtTargetUserModuleIterator;
class NtWow64UserModuleInfo : public NtUserModuleInfo { public: virtual HRESULT Initialize(void);
private: HRESULT GetPeb32(PULONG64 Peb32); };
extern NtWow64UserModuleInfo g_NtWow64UserModuleIterator;
class DebuggerModuleInfo : public ModuleInfo { public: virtual HRESULT Initialize(void); virtual HRESULT GetEntry(PMODULE_INFO_ENTRY Entry);
private: PDEBUG_IMAGE_INFO m_Image; };
extern DebuggerModuleInfo g_DebuggerModuleIterator;
class UnloadedModuleInfo { public: virtual HRESULT Initialize(void) = 0; virtual HRESULT GetEntry(PSTR Name, PDEBUG_MODULE_PARAMETERS Params) = 0; };
class NtKernelUnloadedModuleInfo : public UnloadedModuleInfo { public: virtual HRESULT Initialize(void); virtual HRESULT GetEntry(PSTR Name, PDEBUG_MODULE_PARAMETERS Params);
protected: ULONG64 m_Base; ULONG m_Index; ULONG m_Count; };
extern NtKernelUnloadedModuleInfo g_NtKernelUnloadedModuleIterator;
class W9xModuleInfo : public ModuleInfo { public: virtual HRESULT Initialize(void); virtual HRESULT GetEntry(PMODULE_INFO_ENTRY Entry);
protected: HANDLE m_Snap; BOOL m_First; ULONG m_LastId; };
extern W9xModuleInfo g_W9xModuleIterator;
//----------------------------------------------------------------------------
//
// Target configuration information.
//
//----------------------------------------------------------------------------
#define IS_TARGET_SET() (g_TargetClass != DEBUG_CLASS_UNINITIALIZED)
#define IS_KERNEL_TARGET() (g_TargetClass == DEBUG_CLASS_KERNEL)
#define IS_USER_TARGET() (g_TargetClass == DEBUG_CLASS_USER_WINDOWS)
#define IS_CONN_KERNEL_TARGET() \
(IS_KERNEL_TARGET() && g_TargetClassQualifier == DEBUG_KERNEL_CONNECTION)
#define IS_LOCAL_KERNEL_TARGET() \
(IS_KERNEL_TARGET() && g_TargetClassQualifier == DEBUG_KERNEL_LOCAL)
#define IS_EXDI_KERNEL_TARGET() \
(IS_KERNEL_TARGET() && g_TargetClassQualifier == DEBUG_KERNEL_EXDI_DRIVER)
#define IS_LIVE_USER_TARGET() \
(IS_USER_TARGET() && !IS_DUMP_TARGET())
#define IS_LIVE_KERNEL_TARGET() \
(IS_KERNEL_TARGET() && !IS_DUMP_TARGET())
#define IS_REMOTE_USER_TARGET() \
(IS_USER_TARGET() && \ g_TargetClassQualifier == DEBUG_USER_WINDOWS_PROCESS_SERVER)
#define IS_LOCAL_USER_TARGET() \
(IS_USER_TARGET() && \ g_TargetClassQualifier != DEBUG_USER_WINDOWS_PROCESS_SERVER)
// Local kernels do not need caching. Anything else does.
#define IS_REMOTE_KERNEL_TARGET() \
(IS_LIVE_KERNEL_TARGET() && g_TargetClassQualifier != DEBUG_KERNEL_LOCAL)
// g_TargetMachineType is sometimes set before InitializeMachine
// is called so it can't be used as a direct check for
// initialization. Instead a separate, clean initialization
// variable is used.
// IS_MACHINE_SET == TRUE implies a target is set
// since it isn't possible to determine the machine type
// without knowing the target.
#define IS_MACHINE_SET() g_MachineInitialized
// Checks whether the debuggee is in a state where it
// can be examined. This requires that the debuggee is known
// and paused so that its state is available.
#define IS_MACHINE_ACCESSIBLE() \
(IS_MACHINE_SET() && !IS_RUNNING(g_CmdState) && \ g_CurrentProcess != NULL && g_CurrentProcess->CurrentThread != NULL)
// Further restricts the check to just context state as a
// local kernel session can examine memory and therefore is
// accessible but it does not have a context.
#define IS_CONTEXT_ACCESSIBLE() \
(IS_MACHINE_ACCESSIBLE() && !IS_LOCAL_KERNEL_TARGET())
// Simpler context check for code which may be on the suspend/
// resume path and therefore may be in the middle of initializing
// the variables that IS_CONTEXT_ACCESSIBLE checks. This
// macro just checks whether it's possible to get any
// context information.
#define IS_CONTEXT_POSSIBLE() \
(g_RegContextThread != NULL && !IS_LOCAL_KERNEL_TARGET())
// Dumps and local kernel sessions cannot ever support
// execution so disallow execution commands for them.
#define IS_EXECUTION_POSSIBLE() \
(!(IS_DUMP_TARGET() || IS_LOCAL_KERNEL_TARGET()))
//
// System version is an internal abstraction of build numbers
// and product types. The only requirement is that within
// a specific system family the numbers increase for newer
// systems.
//
// Most of the debugger code is built around NT system versions
// so there's a SystemVersion variable which is always an
// NT system version. The ActualSystemVersion contains the
// true system version which gets mapped into a compatible NT
// system version for SystemVersion.
//
enum { SVER_INVALID = 0, NT_SVER_START = 4 * 1024, NT_SVER_NT4, NT_SVER_W2K_RC3, NT_SVER_W2K, NT_SVER_W2K_WHISTLER, NT_SVER_END,
W9X_SVER_START = 8 * 1024, W9X_SVER_W95, W9X_SVER_W98, W9X_SVER_W98SE, W9X_SVER_WME, W9X_SVER_END, XBOX_SVER_START = 12 * 1024, XBOX_SVER_1, XBOX_SVER_END,
BIG_SVER_START = 16 * 1024, BIG_SVER_1, BIG_SVER_END,
EXDI_SVER_START = 20 * 1024, EXDI_SVER_1, EXDI_SVER_END,
NTBD_SVER_START = 24 * 1024, NTBD_SVER_W2K_WHISTLER, NTBD_SVER_END, EFI_SVER_START = 28 * 1024, EFI_SVER_1, EFI_SVER_END, };
// KD version MajorVersion high-byte identifiers.
enum { KD_MAJOR_NT, KD_MAJOR_XBOX, KD_MAJOR_BIG, KD_MAJOR_EXDI, KD_MAJOR_NTBD, KD_MAJOR_EFI, KD_MAJOR_COUNT };
extern ULONG g_SystemVersion; extern ULONG g_ActualSystemVersion;
extern ULONG g_TargetCheckedBuild; extern ULONG g_TargetBuildNumber; extern BOOL g_MachineInitialized; extern ULONG g_TargetMachineType; extern ULONG g_TargetExecMachine; extern ULONG g_TargetPlatformId; extern char g_TargetServicePackString[MAX_PATH]; extern ULONG g_TargetServicePackNumber; extern char g_TargetBuildLabName[272]; extern ULONG g_TargetNumberProcessors; extern ULONG g_TargetClass; extern ULONG g_TargetClassQualifier;
//----------------------------------------------------------------------------
//
// Convenience routines.
//
//----------------------------------------------------------------------------
extern ULONG g_TmpCount;
#define ReadVirt(Offset, Var) \
(g_Target->ReadVirtual(Offset, &(Var), sizeof(Var), \ &g_TmpCount) == S_OK && g_TmpCount == sizeof(Var)) #define WriteVirt(Offset, Var) \
(g_Target->WriteVirtual(Offset, &(Var), sizeof(Var), \ &g_TmpCount) == S_OK && g_TmpCount == sizeof(Var))
//----------------------------------------------------------------------------
//
// This class abstracts processing of target-class-dependent
// information. g_Target is set to the appropriate implementation
// once the class of target is known.
//
//----------------------------------------------------------------------------
class TargetInfo { public: //
// Pure abstraction methods.
// Unless otherwise indicated, base implementations give
// an error message and return E_UNEXPECTED.
//
virtual HRESULT Initialize(void); // Base implementation does nothing.
virtual void Uninitialize(void);
// Some targets, such as eXDI, require initialization
// per thread. In eXDI's case, it's calling CoInitialize.
// Base implementations do nothing.
virtual HRESULT ThreadInitialize(void); virtual void ThreadUninitialize(void);
// Determines the next byte offset and next page offset
// that might have different validity than the given offset.
virtual void NearestDifferentlyValidOffsets(ULONG64 Offset, PULONG64 NextOffset, PULONG64 NextPage); virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); // Base implementation layers on ReadVirtual.
virtual HRESULT SearchVirtual( IN ULONG64 Offset, IN ULONG64 Length, IN PVOID Pattern, IN ULONG PatternSize, IN ULONG PatternGranularity, OUT PULONG64 MatchOffset ); // Base implementations just call Read/WriteVirtual.
virtual HRESULT ReadVirtualUncached( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtualUncached( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadPhysical( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysical( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); // Base implementations just call Read/WritePhysical.
virtual HRESULT ReadPhysicalUncached( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysicalUncached( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadControl( IN ULONG Processor, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteControl( IN ULONG Processor, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadMsr( IN ULONG Msr, OUT PULONG64 Value ); virtual HRESULT WriteMsr( IN ULONG Msr, IN ULONG64 Value ); virtual HRESULT ReadBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT GetProcessorSystemDataOffset( IN ULONG Processor, IN ULONG Index, OUT PULONG64 Offset ); virtual HRESULT CheckLowMemory( ); virtual HRESULT ReadHandleData( IN ULONG64 Handle, IN ULONG DataType, OUT OPTIONAL PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG DataSize ); // Base implementations layer on WriteVirtual/Physical.
virtual HRESULT FillVirtual( THIS_ IN ULONG64 Start, IN ULONG Size, IN PVOID Pattern, IN ULONG PatternSize, OUT PULONG Filled ); virtual HRESULT FillPhysical( THIS_ IN ULONG64 Start, IN ULONG Size, IN PVOID Pattern, IN ULONG PatternSize, OUT PULONG Filled ); virtual HRESULT GetProcessorId (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id); // Base implementation silently fails as many targets do
// not support this.
virtual HRESULT ReadPageFile(ULONG PfIndex, ULONG64 PfOffset, PVOID Buffer, ULONG Size);
virtual HRESULT GetFunctionTableListHead(void); virtual PVOID FindDynamicFunctionEntry(MachineInfo* Machine, ULONG64 Address); virtual ULONG64 GetDynamicFunctionTableBase(MachineInfo* Machine, ULONG64 Address); virtual HRESULT ReadOutOfProcessDynamicFunctionTable(PWSTR Dll, ULONG64 Table, PULONG TableSize, PVOID* TableData); static PVOID CALLBACK DynamicFunctionTableCallback(HANDLE Process, ULONG64 Address, ULONG64 Context);
virtual HRESULT GetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT SetTargetContext( ULONG64 Thread, PVOID Context ); // Retrieves segment register descriptors if they are available
// directly. Invalid descriptors may be returned, indicating
// either segment registers aren't supported or that the
// descriptors must be looked up in descriptor tables.
// Base implementation returns invalid descriptors.
virtual HRESULT GetTargetSegRegDescriptors(ULONG64 Thread, ULONG Start, ULONG Count, PDESCRIPTOR64 Descs); // Base implementations call Read/WriteSpecialRegisters.
virtual HRESULT GetTargetSpecialRegisters (ULONG64 Thread, PCROSS_PLATFORM_KSPECIAL_REGISTERS Special); virtual HRESULT SetTargetSpecialRegisters (ULONG64 Thread, PCROSS_PLATFORM_KSPECIAL_REGISTERS Special); // Called when the current context state is being
// discarded so that caches can be flushed.
// Base implementation does nothing.
virtual void InvalidateTargetContext(void);
virtual HRESULT GetThreadIdByProcessor( IN ULONG Processor, OUT PULONG Id ); // This method takes both a PTHREAD_INFO and a "handle"
// to make things simpler for the kernel thread-to-processor
// mapping. If Thread is NULL processor must be a processor
// index in kernel mode or a thread handle in user mode.
virtual HRESULT GetThreadInfoDataOffset(PTHREAD_INFO Thread, ULONG64 ThreadHandle, PULONG64 Offset); // In theory this method should take a PPROCESS_INFO.
// Due to the current kernel process and thread structure
// where there's only a kernel process and threads per
// processor such a call would be useless in kernel mode.
// Instead it allows you to either get the process data
// for a thread of that process or get the process data
// from a thread data.
virtual HRESULT GetProcessInfoDataOffset(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetThreadInfoTeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetProcessInfoPeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset);
// This is on target rather than machine since it has
// both user and kernel variations and the implementations
// don't have much processor-specific code in them.
virtual HRESULT GetSelDescriptor(class MachineInfo* Machine, ULONG64 Thread, ULONG Selector, PDESCRIPTOR64 Desc);
virtual HRESULT GetTargetKdVersion(PDBGKD_GET_VERSION64 Version); virtual HRESULT ReadBugCheckData(PULONG Code, ULONG64 Args[4]); virtual HRESULT OutputVersion(void); virtual HRESULT OutputTime(void); virtual ModuleInfo* GetModuleInfo(BOOL UserMode); virtual UnloadedModuleInfo* GetUnloadedModuleInfo(void); // Image can be identified either by its path or base address.
virtual HRESULT GetImageVersionInformation(PCSTR ImagePath, ULONG64 ImageBase, PCSTR Item, PVOID Buffer, ULONG BufferSize, PULONG VerInfoSize); virtual HRESULT Reload(PCSTR Args);
virtual HRESULT GetExceptionContext(PCROSS_PLATFORM_CONTEXT Context); virtual ULONG64 GetCurrentTimeDateN(void); virtual ULONG64 GetCurrentSystemUpTimeN(void); virtual ULONG64 GetProcessUpTimeN(ULONG64 Process); virtual void InitializeWatchTrace(void); virtual void ProcessWatchTraceEvent(PDBGKD_TRACE_DATA TraceData, ADDR PcAddr);
virtual HRESULT WaitForEvent(ULONG Flags, ULONG Timeout); virtual HRESULT RequestBreakIn(void); virtual HRESULT Reboot(void);
virtual HRESULT InsertCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace); virtual HRESULT RemoveCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace);
// Returns information similar to VirtualQueryEx for
// user-mode targets. Used when writing dump files.
virtual HRESULT QueryMemoryRegion(PULONG64 Handle, BOOL HandleIsOffset, PMEMORY_BASIC_INFORMATION64 Info); // Returns information about the kind of memory the
// given address refers to.
// Base implementation returns rwx with process for
// user-mode and kernel for kernel mode. In other words,
// the least restrictive settings.
virtual HRESULT QueryAddressInformation(ULONG64 Address, ULONG InSpace, PULONG OutSpace, PULONG OutFlags); //
// Layered methods. These are usually common code that
// use pure methods to do their work.
//
HRESULT ReadAllVirtual(ULONG64 Address, PVOID Buffer, ULONG BufferSize) { HRESULT Status; ULONG Done;
if ((Status = ReadVirtual(Address, Buffer, BufferSize, &Done)) == S_OK && Done != BufferSize) { Status = HRESULT_FROM_WIN32(ERROR_READ_FAULT); } return Status; } HRESULT WriteAllVirtual(ULONG64 Address, PVOID Buffer, ULONG BufferSize) { HRESULT Status; ULONG Done;
if ((Status = WriteVirtual(Address, Buffer, BufferSize, &Done)) == S_OK && Done != BufferSize) { Status = HRESULT_FROM_WIN32(ERROR_WRITE_FAULT); } return Status; }
HRESULT ReadAllPhysical(ULONG64 Address, PVOID Buffer, ULONG BufferSize) { HRESULT Status; ULONG Done;
if ((Status = ReadPhysical(Address, Buffer, BufferSize, &Done)) == S_OK && Done != BufferSize) { Status = HRESULT_FROM_WIN32(ERROR_READ_FAULT); } return Status; } HRESULT WriteAllPhysical(ULONG64 Address, PVOID Buffer, ULONG BufferSize) { HRESULT Status; ULONG Done;
if ((Status = WritePhysical(Address, Buffer, BufferSize, &Done)) == S_OK && Done != BufferSize) { Status = HRESULT_FROM_WIN32(ERROR_WRITE_FAULT); } return Status; }
HRESULT ReadPointer(MachineInfo* Machine, ULONG64 Address, PULONG64 PointerValue); HRESULT WritePointer(MachineInfo* Machine, ULONG64 Address, ULONG64 PointerValue); HRESULT ReadListEntry(MachineInfo* Machine, ULONG64 Address, PLIST_ENTRY64 List); HRESULT ReadLoaderEntry(MachineInfo* Machine, ULONG64 Address, PKLDR_DATA_TABLE_ENTRY64 Entry); HRESULT ReadUnicodeString(MachineInfo* Machine, ULONG64 Address, PUNICODE_STRING64 String); HRESULT ReadDirectoryTableBase(PULONG64 DirBase); HRESULT ReadSharedUserTimeDateN(PULONG64 TimeDate); HRESULT ReadSharedUserUpTimeN(PULONG64 UpTime); HRESULT ReadImageVersionInfo(ULONG64 ImageBase, PCSTR Item, PVOID Buffer, ULONG BufferSize, PULONG VerInfoSize, PIMAGE_DATA_DIRECTORY ResDataDir);
HRESULT ReadImplicitThreadInfoPointer(ULONG Offset, PULONG64 Ptr); HRESULT ReadImplicitProcessInfoPointer(ULONG Offset, PULONG64 Ptr); // Internal routines which provide canonical context input
// and output, applying any necessary conversions before
// or after calling Get/SetTargetContext.
HRESULT GetContext( ULONG64 Thread, PCROSS_PLATFORM_CONTEXT Context ); HRESULT SetContext( ULONG64 Thread, PCROSS_PLATFORM_CONTEXT Context );
// Calls GetTargetKdVersion on g_KdVersion and outputs the content.
void GetKdVersion(void); // Internal implementations based on user or kernel
// registers and data. Placed here for sharing between
// live and dump sessions rather than using multiple
// inheritance.
HRESULT KdGetThreadInfoDataOffset(PTHREAD_INFO Thread, ULONG64 ThreadHandle, PULONG64 Offset); HRESULT KdGetProcessInfoDataOffset(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); HRESULT KdGetThreadInfoTeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); HRESULT KdGetProcessInfoPeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); HRESULT KdGetSelDescriptor(class MachineInfo* Machine, ULONG64 Thread, ULONG Selector, PDESCRIPTOR64 Desc); };
// Base failure behaviors for when a specific target isn't selected.
extern TargetInfo g_UnexpectedTarget;
extern TargetInfo* g_Target;
//----------------------------------------------------------------------------
//
// LiveKernelTargetInfo.
//
//----------------------------------------------------------------------------
class LiveKernelTargetInfo : public TargetInfo { public: // TargetInfo.
virtual HRESULT Initialize(void); virtual HRESULT GetProcessorId (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id); virtual HRESULT GetThreadIdByProcessor( IN ULONG Processor, OUT PULONG Id ); virtual HRESULT GetThreadInfoDataOffset(PTHREAD_INFO Thread, ULONG64 ThreadHandle, PULONG64 Offset); virtual HRESULT GetProcessInfoDataOffset(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetThreadInfoTeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetProcessInfoPeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset);
virtual HRESULT GetSelDescriptor(class MachineInfo* Machine, ULONG64 Thread, ULONG Selector, PDESCRIPTOR64 Desc); virtual HRESULT ReadBugCheckData(PULONG Code, ULONG64 Args[4]);
virtual ULONG64 GetCurrentTimeDateN(void); virtual ULONG64 GetCurrentSystemUpTimeN(void); // LiveKernelTargetInfo.
// Options are only valid in Initialize.
PCSTR m_ConnectOptions; };
//----------------------------------------------------------------------------
//
// ConnLiveKernelTargetInfo.
//
//----------------------------------------------------------------------------
class ConnLiveKernelTargetInfo : public LiveKernelTargetInfo { public: // TargetInfo.
virtual HRESULT Initialize(void); virtual void Uninitialize(void); virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT SearchVirtual( IN ULONG64 Offset, IN ULONG64 Length, IN PVOID Pattern, IN ULONG PatternSize, IN ULONG PatternGranularity, OUT PULONG64 MatchOffset ); virtual HRESULT ReadVirtualUncached( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtualUncached( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadPhysical( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysical( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadPhysicalUncached( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysicalUncached( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadControl( IN ULONG Processor, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteControl( IN ULONG Processor, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadMsr( IN ULONG Msr, OUT PULONG64 Value ); virtual HRESULT WriteMsr( IN ULONG Msr, IN ULONG64 Value ); virtual HRESULT ReadBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT CheckLowMemory( ); virtual HRESULT FillVirtual( THIS_ IN ULONG64 Start, IN ULONG Size, IN PVOID Pattern, IN ULONG PatternSize, OUT PULONG Filled ); virtual HRESULT FillPhysical( THIS_ IN ULONG64 Start, IN ULONG Size, IN PVOID Pattern, IN ULONG PatternSize, OUT PULONG Filled );
virtual HRESULT GetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT SetTargetContext( ULONG64 Thread, PVOID Context );
virtual HRESULT GetTargetKdVersion(PDBGKD_GET_VERSION64 Version);
virtual void InitializeWatchTrace(void); virtual void ProcessWatchTraceEvent(PDBGKD_TRACE_DATA TraceData, ADDR PcAddr); virtual HRESULT WaitForEvent(ULONG Flags, ULONG Timeout);
virtual HRESULT RequestBreakIn(void); virtual HRESULT Reboot(void);
virtual HRESULT InsertCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace); virtual HRESULT RemoveCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace);
virtual HRESULT QueryAddressInformation(ULONG64 Address, ULONG InSpace, PULONG OutSpace, PULONG OutFlags); };
extern ConnLiveKernelTargetInfo g_ConnLiveKernelTarget;
//----------------------------------------------------------------------------
//
// LocalLiveKernelTargetInfo.
//
//----------------------------------------------------------------------------
class LocalLiveKernelTargetInfo : public LiveKernelTargetInfo { public: // TargetInfo.
virtual HRESULT Initialize(void); virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadPhysical( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysical( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadControl( IN ULONG Processor, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteControl( IN ULONG Processor, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadMsr( IN ULONG Msr, OUT PULONG64 Value ); virtual HRESULT WriteMsr( IN ULONG Msr, IN ULONG64 Value ); virtual HRESULT ReadBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT CheckLowMemory( );
virtual HRESULT GetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT SetTargetContext( ULONG64 Thread, PVOID Context );
virtual HRESULT GetTargetKdVersion(PDBGKD_GET_VERSION64 Version);
virtual HRESULT WaitForEvent(ULONG Flags, ULONG Timeout); };
extern LocalLiveKernelTargetInfo g_LocalLiveKernelTarget;
//----------------------------------------------------------------------------
//
// ExdiLiveKernelTargetInfo.
//
//----------------------------------------------------------------------------
class ExdiNotifyRunChange : public IeXdiClientNotifyRunChg { public: HRESULT Initialize(void); void Uninitialize(void); // IUnknown.
STDMETHOD(QueryInterface)( THIS_ IN REFIID InterfaceId, OUT PVOID* Interface ); STDMETHOD_(ULONG, AddRef)( THIS ); STDMETHOD_(ULONG, Release)( THIS );
// IeXdiClientNotifyRunChg.
STDMETHOD(NotifyRunStateChange)(RUN_STATUS_TYPE ersCurrent, HALT_REASON_TYPE ehrCurrent, ADDRESS_TYPE CurrentExecAddress, DWORD dwExceptionCode);
// ExdiNotifyRunChange.
HANDLE m_Event; HALT_REASON_TYPE m_HaltReason; ADDRESS_TYPE m_ExecAddress; ULONG m_ExceptionCode; };
typedef union _EXDI_CONTEXT { CONTEXT_X86 X86Context; CONTEXT_X86_64 Amd64Context; } EXDI_CONTEXT, *PEXDI_CONTEXT;
enum EXDI_KD_SUPPORT { EXDI_KD_NONE, EXDI_KD_IOCTL, EXDI_KD_GS_PCR };
class ExdiLiveKernelTargetInfo : public LiveKernelTargetInfo { public: // TargetInfo.
virtual HRESULT Initialize(void); virtual void Uninitialize(void); virtual HRESULT ThreadInitialize(void); virtual void ThreadUninitialize(void); virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadPhysical( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WritePhysical( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadControl( IN ULONG Processor, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteControl( IN ULONG Processor, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteIo( IN ULONG InterfaceType, IN ULONG BusNumber, IN ULONG AddressSpace, IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadMsr( IN ULONG Msr, OUT PULONG64 Value ); virtual HRESULT WriteMsr( IN ULONG Msr, IN ULONG64 Value ); virtual HRESULT ReadBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteBusData( IN ULONG BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT GetProcessorSystemDataOffset( IN ULONG Processor, IN ULONG Index, OUT PULONG64 Offset ); virtual HRESULT CheckLowMemory( );
virtual HRESULT GetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT SetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT GetTargetSegRegDescriptors(ULONG64 Thread, ULONG Start, ULONG Count, PDESCRIPTOR64 Descs); virtual HRESULT GetTargetSpecialRegisters (ULONG64 Thread, PCROSS_PLATFORM_KSPECIAL_REGISTERS Special); virtual HRESULT SetTargetSpecialRegisters (ULONG64 Thread, PCROSS_PLATFORM_KSPECIAL_REGISTERS Special); virtual void InvalidateTargetContext(void);
virtual HRESULT GetTargetKdVersion(PDBGKD_GET_VERSION64 Version);
virtual HRESULT WaitForEvent(ULONG Flags, ULONG Timeout);
virtual HRESULT RequestBreakIn(void); virtual HRESULT Reboot(void);
virtual HRESULT InsertCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace); virtual HRESULT RemoveCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace);
// ExdiLiveKernelTargetInfo.
IeXdiServer* m_Server; IUnknown* m_Context; ULONG m_ContextValid; EXDI_CONTEXT m_ContextData; GLOBAL_TARGET_INFO_STRUCT m_GlobalInfo; EXDI_KD_SUPPORT m_KdSupport; BOOL m_ForceX86; ULONG m_ExpectedMachine; CBP_KIND m_CodeBpType; ExdiNotifyRunChange m_RunChange; };
extern ExdiLiveKernelTargetInfo g_ExdiLiveKernelTarget;
//----------------------------------------------------------------------------
//
// UserTargetInfo.
//
//----------------------------------------------------------------------------
class UserTargetInfo : public TargetInfo { public: // TargetInfo.
virtual HRESULT Initialize(void); virtual void Uninitialize(void); virtual HRESULT ReadVirtualUncached( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtualUncached( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); virtual HRESULT ReadHandleData( IN ULONG64 Handle, IN ULONG DataType, OUT OPTIONAL PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG DataSize ); virtual HRESULT GetProcessorId (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id);
virtual HRESULT GetFunctionTableListHead(void); virtual HRESULT ReadOutOfProcessDynamicFunctionTable(PWSTR Dll, ULONG64 Table, PULONG TableSize, PVOID* TableData);
virtual HRESULT GetTargetContext( ULONG64 Thread, PVOID Context ); virtual HRESULT SetTargetContext( ULONG64 Thread, PVOID Context );
virtual HRESULT GetThreadInfoDataOffset(PTHREAD_INFO Thread, ULONG64 ThreadHandle, PULONG64 Offset); virtual HRESULT GetProcessInfoDataOffset(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetThreadInfoTeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset); virtual HRESULT GetProcessInfoPeb(PTHREAD_INFO Thread, ULONG Processor, ULONG64 ThreadData, PULONG64 Offset);
virtual HRESULT GetSelDescriptor(class MachineInfo* Machine, ULONG64 Thread, ULONG Selector, PDESCRIPTOR64 Desc);
virtual HRESULT GetImageVersionInformation(PCSTR ImagePath, ULONG64 ImageBase, PCSTR Item, PVOID Buffer, ULONG BufferSize, PULONG VerInfoSize); virtual ULONG64 GetCurrentTimeDateN(void); virtual ULONG64 GetCurrentSystemUpTimeN(void); virtual ULONG64 GetProcessUpTimeN(ULONG64 Process);
virtual void InitializeWatchTrace(void); virtual void ProcessWatchTraceEvent(PDBGKD_TRACE_DATA TraceData, ADDR PcAddr); virtual HRESULT WaitForEvent(ULONG Flags, ULONG Timeout);
virtual HRESULT RequestBreakIn(void);
virtual HRESULT InsertCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace); virtual HRESULT RemoveCodeBreakpoint(PPROCESS_INFO Process, class MachineInfo* Machine, PADDR Addr, PUCHAR StorageSpace);
virtual HRESULT QueryMemoryRegion(PULONG64 Handle, BOOL HandleIsOffset, PMEMORY_BASIC_INFORMATION64 Info);
IUserDebugServices* m_Services; ULONG m_ServiceFlags; };
class LocalUserTargetInfo : public UserTargetInfo { public: // TargetInfo.
virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); };
extern LocalUserTargetInfo g_LocalUserTarget;
class RemoteUserTargetInfo : public UserTargetInfo { public: // TargetInfo.
virtual HRESULT ReadVirtual( IN ULONG64 Offset, OUT PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesRead ); virtual HRESULT WriteVirtual( IN ULONG64 Offset, IN PVOID Buffer, IN ULONG BufferSize, OUT OPTIONAL PULONG BytesWritten ); };
extern RemoteUserTargetInfo g_RemoteUserTarget;
//----------------------------------------------------------------------------
//
// DumpTargetInfo hierarchy is in dump.hpp.
//
//----------------------------------------------------------------------------
#endif // #ifndef __TARGET_HPP__
|