//---------------------------------------------------------------------------- // // 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__