diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/build.gradle b/Ghidra/Debug/Debugger-agent-dbgeng/build.gradle index 35fc966118..4f218b4165 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/build.gradle +++ b/Ghidra/Debug/Debugger-agent-dbgeng/build.gradle @@ -21,6 +21,7 @@ apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle" apply from: "$rootProject.projectDir/gradle/debugger/hasNodepJar.gradle" apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle" +apply from: "buildNatives.gradle" apply plugin: 'eclipse' eclipse.project.name = 'Debug Debugger-agent-dbgeng' @@ -36,6 +37,14 @@ dependencies { testImplementation project(path: ":Debugger-gadp", configuration: 'testArtifacts') } +// Include buildable native source in distribution +rootProject.assembleDistribution { + from (this.project.projectDir.toString()) { + include "src/**" + into { getZipPath(this.project) } + } +} + tasks.nodepJar { manifest { attributes['Main-Class'] = 'agent.dbgeng.gadp.DbgEngGadpServer' diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/buildNatives.gradle b/Ghidra/Debug/Debugger-agent-dbgeng/buildNatives.gradle new file mode 100644 index 0000000000..38a8306d5d --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/buildNatives.gradle @@ -0,0 +1,49 @@ +/* ### + * IP: GHIDRA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +if ("win_x86_64".equals(getCurrentPlatformName())) { + + String makeName = "win_x86_64TlbMake" + task(type: Exec, makeName) { + + def projectPath = projectDir.toString() + def solutionBatchFilePath = projectPath + "/build/buildSolution.bat" + def projectPathWindows = projectPath.replace("/", File.separator) + + doFirst { + file("build/os/win_x86_64").mkdirs() + + def srcdir = "src/main/py/src/dbgmodel" + def msbuildCmd = "midl /tlb build/os/win_x86_64/dbgmodel.tlb ${srcdir}/DbgModel.idl" + + println "Executing: " + msbuildCmd + + new File(solutionBatchFilePath).withWriter { out -> + out.println "call " + VISUAL_STUDIO_VCVARS_CMD + out.println msbuildCmd + } + } + + doLast { + assert file("build/os/win_x86_64/dbgmodel.tlb").exists() : "Failed to build dbgmodel.tlb" + } + + executable "cmd" + + args "/c" + args solutionBatchFilePath.replace("/", File.separator) + } +} diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest b/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest index fc57b11e64..caa6d946db 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest +++ b/Ghidra/Debug/Debugger-agent-dbgeng/certification.manifest @@ -5,4 +5,5 @@ data/debugger-launchers/local-dbgeng.bat||GHIDRA||||END| src/main/py/LICENSE||GHIDRA||||END| src/main/py/README.md||GHIDRA||||END| src/main/py/pyproject.toml||GHIDRA||||END| +src/main/py/src/dbgmodel/DbgModel.idl||GHIDRA||||END| src/main/py/src/ghidradbg/schema.xml||GHIDRA||||END| diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat index d836cde2ea..c0f60ff116 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat +++ b/Ghidra/Debug/Debugger-agent-dbgeng/data/debugger-launchers/local-dbgeng.bat @@ -14,6 +14,8 @@ :: Use env instead of args, because "all args except first" is terrible to implement in batch ::@env OPT_TARGET_IMG:str="" "Image" "The target binary executable image" ::@env OPT_TARGET_ARGS:str="" "Arguments" "Command-line arguments to pass to the target" +::@env OPT_USE_DBGMODEL:bool=true "Use dbgmodel" "Load and use dbgmodel.dll if it is available." +::@env OPT_DBGMODEL_PATH:str="" "Path to dbgeng" "Path to dbgeng and associated DLLS (if not Windows Kits)." @echo off diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/DbgModel.idl b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/DbgModel.idl new file mode 100644 index 0000000000..eea67cdce2 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/DbgModel.idl @@ -0,0 +1,1208 @@ +import "oaidl.idl"; +import "ocidl.idl"; + +[ + uuid(95F974F5-B0AE-44A4-8EB9-FEC4E8136427), + helpstring("DbgMod Type Library") +] +library DbgMod +{ + importlib("stdole32.tlb"); + importlib("stdole2.tlb"); + + /////////////////////////////////////////////////////////// + // interface forward declaration + interface IHostDataModelAccess; + interface IKeyStore; + interface IModelObject; + interface IDataModelManager; + interface IModelKeyReference; + interface IModelPropertyAccessor; + interface IModelMethod; + interface IKeyEnumerator; + interface IRawEnumerator; + interface IDataModelConcept; + interface IStringDisplayableConcept; + interface ICodeAddressConcept; + interface IModelIterator; + interface IIterableConcept; + interface IIndexableConcept; + interface IPreferredRuntimeTypeConcept; + interface IDebugHost; + interface IDebugHostContext; + interface IDebugHostSymbols; + interface IDebugHostModuleSignature; + interface IDebugHostTypeSignature; + interface IDebugHostMemory; + interface IDebugHostErrorSink; + interface IDebugHostEvaluator; + interface IDebugHostSymbolEnumerator; + interface IDebugHostSymbol; + interface IDebugHostModule; + interface IDebugHostType; + interface IDebugHostConstant; + interface IDebugHostField; + interface IDebugHostData; + interface IDebugHostBaseClass; + interface IDebugHostPublic; + interface IDebugHostType2; + interface IDebugHostStatus; + interface IDataModelScriptClient; + interface IDataModelScriptTemplate; + interface IDataModelScript; + interface IDataModelScriptProvider; + interface IDataModelScriptManager; + interface IDataModelScriptProviderEnumerator; + interface IDebugHostScriptHost; + interface IDataModelScriptHostContext; + interface IDataModelNameBinder; + interface IDataModelScriptTemplateEnumerator; + interface IDynamicKeyProviderConcept; + interface IDynamicConceptProviderConcept; + interface IModelKeyReference2; + interface IDebugHostEvaluator2; + interface IDebugHostSymbol2; + interface IDataModelManager2; + interface IDebugHostMemory2; + interface IDebugHostExtensibility; + interface IDataModelScriptDebug; + interface IDataModelScriptDebugClient; + interface IDataModelScriptDebugStack; + interface IDataModelScriptDebugStackFrame; + interface IDataModelScriptDebugVariableSetEnumerator; + interface IDataModelScriptDebugBreakpoint; + interface IDataModelScriptDebugBreakpointEnumerator; + interface IDataModelScriptDebug2; + interface IComparableConcept; + interface IEquatableConcept; + interface IDebugHostModule2; + + /////////////////////////////////////////////////////////// + // missing structs + enum {EXCEPTION_MAXIMUM_PARAMETERS = 15}; // maximum number of exception parameters + + typedef struct _EXCEPTION_RECORD64 { + DWORD ExceptionCode; + DWORD ExceptionFlags; + LONGLONG ExceptionRecord; + LONGLONG ExceptionAddress; + DWORD NumberParameters; + DWORD __unusedAlignment; + LONGLONG ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; + } EXCEPTION_RECORD64, *PEXCEPTION_RECORD64; + + typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; + } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + + typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; + } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + + enum { IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16}; + + typedef struct _IMAGE_OPTIONAL_HEADER64 { + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; + } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + + typedef struct _IMAGE_NT_HEADERS64 { + DWORD Signature; + IMAGE_FILE_HEADER FileHeader; + IMAGE_OPTIONAL_HEADER64 OptionalHeader; + } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + + struct _WINDBG_EXTENSION_APIS32 { + DWORD NotSupported; + }; + + struct _WINDBG_EXTENSION_APIS64 { + DWORD NotSupported; + }; + +/* + struct _MEMORY_BASIC_INFORMATION64 { + ULONGLONG BaseAddress; + ULONGLONG AllocationBase; + DWORD AllocationProtect; + DWORD __alignment1; + ULONGLONG RegionSize; + DWORD State; + DWORD Protect; + DWORD Type; + DWORD __alignment2; + }; +*/ + + typedef struct _Location { + ULONG64 HostDefined; + ULONG64 Offset; + } Location, *PLocation; + + typedef struct _ArrayDimension { + LONG64 LowerBound; + ULONG64 Length; + ULONG64 Stride; + } ArrayDimension, *PArrayDimension; + + typedef struct _SymbolSearchInfo { + ULONG HeaderSize; // sizeof(SymbolSearchInfo) + ULONG InfoSize; // sizeof(* by int *) + ULONG SearchOptions; + } SymbolSearchInfo, *PSymbolSearchInfo; + + typedef struct _TypeSearchInfo { + int SearchType; + } TypeSearchInfo, *PTypeSearchInfo; + + typedef struct _ScriptDebugPosition { + ULONG Line; + ULONG Column; + } ScriptDebugPosition, *PScriptDebugPosition; + + typedef struct _ScriptDebugEventInformation { + int DebugEvent; + ScriptDebugPosition EventPosition; // The line/column of script at which the debug event occurred (0 values : cannot determine) + ScriptDebugPosition EventSpanEnd; // The ending line/column of script at which the debug event occurred (0 values : cannot determine) + + union + { + struct + { + bool IsUncaught; + } ExceptionInformation; + + struct + { + ULONG64 BreakpointId; + } BreakpointInformation; + + } u; + } ScriptDebugEventInformation, *PScriptDebugEventInformation; + + + /////////////////////////////////////////////////////////// + // missing defines + + // + // dwCreationFlag values + // + + enum {DEBUG_PROCESS =0x00000001}; + enum {DEBUG_ONLY_THIS_PROCESS =0x00000002}; + + enum {CREATE_SUSPENDED =0x00000004}; + + enum {DETACHED_PROCESS =0x00000008}; + + enum {CREATE_NEW_CONSOLE =0x00000010}; + + enum {NORMAL_PRIORITY_CLASS =0x00000020}; + enum {IDLE_PRIORITY_CLASS =0x00000040}; + enum {HIGH_PRIORITY_CLASS =0x00000080}; + enum {REALTIME_PRIORITY_CLASS =0x00000100}; + + enum {CREATE_NEW_PROCESS_GROUP =0x00000200}; + enum {CREATE_UNICODE_ENVIRONMENT =0x00000400}; + + enum {CREATE_SEPARATE_WOW_VDM =0x00000800}; + enum {CREATE_SHARED_WOW_VDM =0x00001000}; + enum {CREATE_FORCEDOS =0x00002000}; + + enum {BELOW_NORMAL_PRIORITY_CLASS =0x00004000}; + enum {ABOVE_NORMAL_PRIORITY_CLASS =0x00008000}; + enum {STACK_SIZE_PARAM_IS_A_RESERVATION =0x00010000}; + + enum {CREATE_BREAKAWAY_FROM_JOB =0x01000000}; + enum {CREATE_PRESERVE_CODE_AUTHZ_LEVEL =0x02000000}; + + enum {CREATE_DEFAULT_ERROR_MODE =0x04000000}; + enum {CREATE_NO_WINDOW =0x08000000}; + + enum {PROFILE_USER =0x10000000}; + enum {PROFILE_KERNEL =0x20000000}; + enum {PROFILE_SERVER =0x40000000}; + + enum {CREATE_IGNORE_SYSTEM_DEFAULT =0x80000000}; + + + /////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////// +[ + object, + uuid(F2BCE54E-4835-4f8a-836E-7981E29904D1), + helpstring("IHostDataModelAccess") +] +interface IHostDataModelAccess : IUnknown { + HRESULT GetDataModel( IDataModelManager** manager, IDebugHost** host ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(0FC7557D-401D-4fca-9365-DA1E9850697C), + helpstring("IKeyStore") +] +interface IKeyStore : IUnknown { + HRESULT GetKey( const wchar_t* key, IModelObject** object, IKeyStore** metadata ); + HRESULT SetKey( const wchar_t* key, IModelObject* object, IKeyStore* metadata ); + HRESULT GetKeyValue( const wchar_t* key, IModelObject** object, IKeyStore** metadata ); + HRESULT SetKeyValue( const wchar_t* key, IModelObject* object ); + HRESULT ClearKeys( ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(E28C7893-3F4B-4b96-BACA-293CDC55F45D), + helpstring("IModelObject") +] +interface IModelObject : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT GetKind( int *kind ); + HRESULT GetIntrinsicValue( VARIANT* intrinsicData ); + HRESULT GetIntrinsicValueAs( VARTYPE vt, VARIANT* intrinsicData ); + HRESULT GetKeyValue( const wchar_t* key, IModelObject** object, IKeyStore** metadata ); + HRESULT SetKeyValue( const wchar_t* key, IModelObject* object ); + HRESULT EnumerateKeyValues( IKeyEnumerator** enumerator ); + HRESULT GetRawValue( int kind, const wchar_t* name, unsigned long searchFlags, IModelObject** object ); + HRESULT EnumerateRawValues( int kind, unsigned long searchFlags, IRawEnumerator** enumerator ); + HRESULT Dereference( IModelObject** object ); + HRESULT TryCastToRuntimeType( IModelObject** runtimeTypedObject ); + HRESULT GetConcept( REFIID conceptId, IUnknown** conceptInterface, IKeyStore** conceptMetadata ); + HRESULT GetLocation( Location* location ); + HRESULT GetTypeInfo( IDebugHostType** type ); + HRESULT GetTargetInfo( Location* location, IDebugHostType** type ); + HRESULT GetNumberOfParentModels( ULONG64* numModels ); + HRESULT GetParentModel( unsigned __int64 i, IModelObject **model, IModelObject **contextObject ); + HRESULT AddParentModel( IModelObject* model, IModelObject* contextObject, bool override); + HRESULT RemoveParentModel( IModelObject* model ); + HRESULT GetKey( const wchar_t* key, IModelObject** object, IKeyStore** metadata ); + HRESULT GetKeyReference( const wchar_t* key, IModelObject** objectReference, IKeyStore** metadata ); + HRESULT SetKey( const wchar_t* key, IModelObject* object, IKeyStore* metadata ); + HRESULT ClearKeys( ); + HRESULT EnumerateKeys( IKeyEnumerator** enumerator ); + HRESULT EnumerateKeyReferences( IKeyEnumerator** enumerator ); + HRESULT SetConcept( REFIID conceptId, IUnknown* conceptInterface, IKeyStore* conceptMetadata ); + HRESULT ClearConcepts( ); + HRESULT GetRawReference( int kind, const wchar_t* name, unsigned long searchFlags, IModelObject** object ); + HRESULT EnumerateRawReferences( int kind, unsigned long searchFlags, IRawEnumerator** enumerator ); + HRESULT SetContextForDataModel( IModelObject* dataModelObject, IUnknown* context ); + HRESULT GetContextForDataModel( IModelObject* dataModelObject, IUnknown** context ); + HRESULT Compare( IModelObject* other, IModelObject **ppResult ); + HRESULT IsEqualTo( IModelObject* other, bool* equal ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(73FE19F4-A110-4500-8ED9-3C28896F508C), + helpstring("IDataModelManager") +] +interface IDataModelManager : IUnknown { + HRESULT Close( ); + HRESULT CreateNoValue( IModelObject** object ); + HRESULT CreateErrorObject( HRESULT hrError, const wchar_t* pwszMessage, IModelObject** object ); + HRESULT CreateTypedObject( IDebugHostContext* context, Location objectLocation, IDebugHostType* objectType, IModelObject** object ); + HRESULT CreateTypedObjectReference( IDebugHostContext* context, Location objectLocation, IDebugHostType* objectType, IModelObject** object ); + HRESULT CreateSyntheticObject( IDebugHostContext* context, IModelObject** object ); + HRESULT CreateDataModelObject( IDataModelConcept* dataModel, IModelObject** object ); + HRESULT CreateIntrinsicObject( int objectKind, VARIANT* intrinsicData, IModelObject** object ); + HRESULT CreateTypedIntrinsicObject( VARIANT* intrinsicData, IDebugHostType* type, IModelObject** object ); + HRESULT GetModelForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject** dataModel ); + HRESULT GetModelForType( IDebugHostType* type, IModelObject** dataModel, IDebugHostTypeSignature** typeSignature, IDebugHostSymbolEnumerator** wildcardMatches ); + HRESULT RegisterModelForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject* dataModel ); + HRESULT UnregisterModelForTypeSignature( IModelObject* dataModel, IDebugHostTypeSignature* typeSignature ); + HRESULT RegisterExtensionForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject* dataModel ); + HRESULT UnregisterExtensionForTypeSignature( IModelObject* dataModel, IDebugHostTypeSignature* typeSignature ); + HRESULT CreateMetadataStore( IKeyStore* parentStore, IKeyStore** metadataStore ); + HRESULT GetRootNamespace( IModelObject** rootNamespace ); + HRESULT RegisterNamedModel( const wchar_t* modelName, IModelObject *modeObject ); + HRESULT UnregisterNamedModel( const wchar_t* modelName ); + HRESULT AcquireNamedModel( const wchar_t* modelName, IModelObject **modelObject ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(5253DCF8-5AFF-4c62-B302-56A289E00998), + helpstring("IModelKeyReference") +] +interface IModelKeyReference : IUnknown { + HRESULT GetKeyName( BSTR* keyName ); + HRESULT GetOriginalObject( IModelObject** originalObject ); + HRESULT GetContextObject( IModelObject** containingObject ); + HRESULT GetKey( IModelObject** object, IKeyStore** metadata ); + HRESULT GetKeyValue( IModelObject** object, IKeyStore** metadata ); + HRESULT SetKey( IModelObject* object, IKeyStore* metadata ); + HRESULT SetKeyValue( IModelObject* object ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(5A0C63D9-0526-42b8-960C-9516A3254C85), + helpstring("IModelPropertyAccessor") +] +interface IModelPropertyAccessor : IUnknown { + HRESULT GetValue( const wchar_t* key, IModelObject* contextObject, IModelObject** value ); + HRESULT SetValue( const wchar_t* key, IModelObject* contextObject, IModelObject* value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(80600C1F-B90B-4896-82AD-1C00207909E8), + helpstring("IModelMethod") +] +interface IModelMethod : IUnknown { + HRESULT Call( IModelObject *pContextObject, unsigned __int64 argCount, IModelObject **ppArguments, IModelObject **ppResult, IKeyStore **ppMetadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(345FA92E-5E00-4319-9CAE-971F7601CDCF), + helpstring("IKeyEnumerator") +] +interface IKeyEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( BSTR* key, IModelObject** value, IKeyStore** metadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(E13613F9-3A3C-40b5-8F48-1E5EBFB9B21B), + helpstring("IRawEnumerator") +] +interface IRawEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( BSTR* name, int *kind, IModelObject** value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(FCB98D1D-1114-4fbf-B24C-EFFCB5DEF0D3), + helpstring("IDataModelConcept") +] +interface IDataModelConcept : IUnknown { + HRESULT InitializeObject( IModelObject* modelObject, IDebugHostTypeSignature* matchingTypeSignature, IDebugHostSymbolEnumerator* wildcardMatches ); + HRESULT GetName( BSTR* modelName ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(D28E8D70-6C00-4205-940D-501016601EA3), + helpstring("IStringDisplayableConcept") +] +interface IStringDisplayableConcept : IUnknown { + HRESULT ToDisplayString( IModelObject* contextObject, IKeyStore* metadata, BSTR* displayString ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(C7371568-5C78-4A00-A4AB-6EF8823184CB), + helpstring("ICodeAddressConcept") +] +interface ICodeAddressConcept : IUnknown { + HRESULT GetContainingSymbol( IModelObject* pContextObject, IDebugHostSymbol **ppSymbol ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(E4622136-927D-4490-874F-581F3E4E3688), + helpstring("IModelIterator") +] +interface IModelIterator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( IModelObject** object, unsigned __int64 dimensions, IModelObject** indexers, IKeyStore** metadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(F5D49D0C-0B02-4301-9C9B-B3A6037628F3), + helpstring("IIterableConcept") +] +interface IIterableConcept : IUnknown { + HRESULT GetDefaultIndexDimensionality( IModelObject* contextObject, ULONG64* dimensionality ); + HRESULT GetIterator( IModelObject* contextObject, IModelIterator** iterator ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(D1FAD99F-3F53-4457-850C-8051DF2D3FB5), + helpstring("IIndexableConcept") +] +interface IIndexableConcept : IUnknown { + HRESULT GetDimensionality( IModelObject* contextObject, ULONG64* dimensionality ); + HRESULT GetAt( IModelObject* contextObject, unsigned __int64 indexerCount, IModelObject** indexers, IModelObject** object, IKeyStore** metadata ); + HRESULT SetAt( IModelObject* contextObject, unsigned __int64 indexerCount, IModelObject** indexers, IModelObject *value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(9D6C1D7B-A76F-4618-8068-5F76BD9A4E8A), + helpstring("IPreferredRuntimeTypeConcept") +] +interface IPreferredRuntimeTypeConcept : IUnknown { + HRESULT CastToPreferredRuntimeType( IModelObject* contextObject, IModelObject** object ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(B8C74943-6B2C-4eeb-B5C5-35D378A6D99D), + helpstring("IDebugHost") +] +interface IDebugHost : IUnknown { + HRESULT GetHostDefinedInterface( IUnknown** hostUnk ); + HRESULT GetCurrentContext( IDebugHostContext** context ); + HRESULT GetDefaultMetadata( IKeyStore** defaultMetadataStore ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(A68C70D8-5EC0-46e5-B775-3134A48EA2E3), + helpstring("IDebugHostContext") +] +interface IDebugHostContext : IUnknown { + HRESULT IsEqualTo( IDebugHostContext *pContext, bool *pIsEqual ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(C8FF0F0B-FCE9-467e-8BB3-5D69EF109C00), + helpstring("IDebugHostErrorSink") +] +interface IDebugHostErrorSink : IUnknown { + HRESULT ReportError( int errClass, HRESULT hrError, const wchar_t* message ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(0F819103-87DE-4e96-8277-E05CD441FB22), + helpstring("IDebugHostSymbol") +] +interface IDebugHostSymbol : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT CompareAgainst( IDebugHostSymbol *pComparisonSymbol, unsigned long comparisonFlags, bool *pMatches ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(28D96C86-10A3-4976-B14E-EAEF4790AA1F), + helpstring("IDebugHostSymbolEnumerator") +] +interface IDebugHostSymbolEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( IDebugHostSymbol** symbol ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(C9BA3E18-D070-4378-BBD0-34613B346E1E), + helpstring("IDebugHostModule") +] +interface IDebugHostModule : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetImageName( bool allowPath, BSTR* imageName ); + HRESULT GetBaseLocation( Location* moduleBaseLocation ); + HRESULT GetVersion( ULONG64* fileVersion, ULONG64* productVersion ); + HRESULT FindTypeByName( const wchar_t* typeName, IDebugHostType** type ); + HRESULT FindSymbolByRVA( unsigned __int64 rva, IDebugHostSymbol** symbol ); + HRESULT FindSymbolByName( const wchar_t* symbolName, IDebugHostSymbol** symbol ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(F219B848-63B2-4A43-A6C9-72ABF25A9711), + helpstring("IDebugHostType") +] +interface IDebugHostType : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetTypeKind( TypeKind *kind ); + HRESULT GetSize( ULONG64* size ); + HRESULT GetBaseType( IDebugHostType** baseType ); + HRESULT GetHashCode( ULONG* hashCode ); + HRESULT GetIntrinsicType( int *intrinsicKind, VARTYPE *carrierType ); + HRESULT GetBitField( ULONG* lsbOfField, ULONG* lengthOfField ); + HRESULT GetPointerKind( int* pointerKind ); + HRESULT GetMemberType( IDebugHostType** memberType ); + HRESULT CreatePointerTo( int kind, IDebugHostType** newType ); + HRESULT GetArrayDimensionality( ULONG64* arrayDimensionality ); + HRESULT GetArrayDimensions( unsigned __int64 dimensions, ArrayDimension *pDimensions ); + HRESULT CreateArrayOf( unsigned __int64 dimensions, ArrayDimension *pDimensions, IDebugHostType** newType ); + HRESULT GetFunctionCallingConvention( int* conventionKind ); + HRESULT GetFunctionReturnType( IDebugHostType** returnType ); + HRESULT GetFunctionParameterTypeCount( ULONG64* count ); + HRESULT GetFunctionParameterTypeAt( unsigned __int64 i, IDebugHostType** parameterType ); + HRESULT IsGeneric( bool* isGeneric ); + HRESULT GetGenericArgumentCount( ULONG64* argCount ); + HRESULT GetGenericArgumentAt( unsigned __int64 i, IDebugHostSymbol** argument ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(62787EDC-FA76-4690-BD71-5E8C3E2937EC), + helpstring("IDebugHostConstant") +] +interface IDebugHostConstant : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetValue( VARIANT* value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(E06F6495-16BC-4cc9-B11D-2A6B23FA72F3), + helpstring("IDebugHostField") +] +interface IDebugHostField : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetLocationKind( int *locationKind ); + HRESULT GetOffset( ULONG64* offset ); + HRESULT GetLocation( Location* location ); + HRESULT GetValue( VARIANT* value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(A3D64993-826C-44fa-897D-926F2FE7AD0B), + helpstring("IDebugHostData") +] +interface IDebugHostData : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetLocationKind( int *locationKind ); + HRESULT GetLocation( Location* location ); + HRESULT GetValue( VARIANT* value ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(6C597AC9-FB4D-4f6d-9F39-22488539F8F4), + helpstring("IDebugHostPublic") +] +interface IDebugHostPublic : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetLocationKind( int *locationKind ); + HRESULT GetLocation( Location* location ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(B94D57D2-390B-40f7-B5B4-B6DB897D974B), + helpstring("IDebugHostBaseClass") +] +interface IDebugHostBaseClass : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetOffset( ULONG64* offset ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(854FD751-C2E1-4eb2-B525-6619CB97A588), + helpstring("IDebugHostSymbols") +] +interface IDebugHostSymbols : IUnknown { + HRESULT CreateModuleSignature( const wchar_t* pwszModuleName, const wchar_t* pwszMinVersion, const wchar_t* pwszMaxVersion, IDebugHostModuleSignature** ppModuleSignature ); + HRESULT CreateTypeSignature( const wchar_t* signatureSpecification, IDebugHostModule* hmodule, IDebugHostTypeSignature** typeSignature ); + HRESULT CreateTypeSignatureForModuleRange( const wchar_t* signatureSpecification, const wchar_t* moduleName, const wchar_t* minVersion, const wchar_t* maxVersion, IDebugHostTypeSignature** typeSignature ); + HRESULT EnumerateModules( IDebugHostContext* context, IDebugHostSymbolEnumerator** moduleEnum ); + HRESULT FindModuleByName( IDebugHostContext* context, const wchar_t* moduleName, IDebugHostModule **hmodule ); + HRESULT FindModuleByLocation( IDebugHostContext* context, Location moduleLocation, IDebugHostModule **hmodule ); + HRESULT GetMostDerivedObject( IDebugHostContext *pContext, Location location, IDebugHostType* objectType, Location* derivedLocation, IDebugHostType** derivedType ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(212149C9-9183-4a3e-B00E-4FD1DC95339B), + helpstring("IDebugHostMemory") +] +interface IDebugHostMemory : IUnknown { + HRESULT ReadBytes( IDebugHostContext* context, Location location, void* buffer, unsigned __int64 bufferSize, ULONG64* bytesRead ); + HRESULT WriteBytes( IDebugHostContext* context, Location location, void* buffer, unsigned __int64 bufferSize, ULONG64* bytesWritten ); + HRESULT ReadPointers( IDebugHostContext* context, Location location, unsigned __int64 count, ULONG64* pointers ); + HRESULT WritePointers( IDebugHostContext* context, Location location, unsigned __int64 count, ULONG64* pointers ); + HRESULT GetDisplayStringForLocation( IDebugHostContext* context, Location location, bool verbose, BSTR* locationName ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(0FEF9A21-577E-4997-AC7B-1C4883241D99), + helpstring("IDebugHostEvaluator") +] +interface IDebugHostEvaluator : IUnknown { + HRESULT EvaluateExpression( IDebugHostContext* context, const wchar_t* expression, IModelObject* bindingContext, IModelObject** result, IKeyStore** metadata ); + HRESULT EvaluateExtendedExpression( IDebugHostContext* context, const wchar_t* expression, IModelObject* bindingContext, IModelObject** result, IKeyStore** metadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(31E53A5A-01EE-4BBB-B899-4B46AE7D595C), + helpstring("IDebugHostModuleSignature") +] +interface IDebugHostModuleSignature : IUnknown { + HRESULT IsMatch( IDebugHostModule* pModule, bool* isMatch ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(3AADC353-2B14-4abb-9893-5E03458E07EE), + helpstring("IDebugHostTypeSignature") +] +interface IDebugHostTypeSignature : IUnknown { + HRESULT GetHashCode( ULONG* hashCode ); + HRESULT IsMatch( IDebugHostType* type, bool* isMatch, IDebugHostSymbolEnumerator** wildcardMatches ); + HRESULT CompareAgainst( IDebugHostTypeSignature* typeSignature, int* result ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(21515B67-6720-4257-8A68-077DC944471C), + helpstring("IDebugHostSymbol2") +] +interface IDebugHostSymbol2 : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT CompareAgainst( IDebugHostSymbol *pComparisonSymbol, unsigned long comparisonFlags, bool *pMatches ); + HRESULT EnumerateChildrenEx( int kind, const wchar_t* name, SymbolSearchInfo* searchInfo, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT GetLanguage( int *pKind ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(B28632B9-8506-4676-87CE-8F7E05E59876), + helpstring("IDebugHostType2") +] +interface IDebugHostType2 : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetTypeKind( TypeKind *kind ); + HRESULT GetSize( ULONG64* size ); + HRESULT GetBaseType( IDebugHostType** baseType ); + HRESULT GetHashCode( ULONG* hashCode ); + HRESULT GetIntrinsicType( int *intrinsicKind, VARTYPE *carrierType ); + HRESULT GetBitField( ULONG* lsbOfField, ULONG* lengthOfField ); + HRESULT GetPointerKind( int* pointerKind ); + HRESULT GetMemberType( IDebugHostType** memberType ); + HRESULT CreatePointerTo( int kind, IDebugHostType** newType ); + HRESULT GetArrayDimensionality( ULONG64* arrayDimensionality ); + HRESULT GetArrayDimensions( unsigned __int64 dimensions, ArrayDimension *pDimensions ); + HRESULT CreateArrayOf( unsigned __int64 dimensions, ArrayDimension *pDimensions, IDebugHostType** newType ); + HRESULT GetFunctionCallingConvention( int* conventionKind ); + HRESULT GetFunctionReturnType( IDebugHostType** returnType ); + HRESULT GetFunctionParameterTypeCount( ULONG64* count ); + HRESULT GetFunctionParameterTypeAt( unsigned __int64 i, IDebugHostType** parameterType ); + HRESULT IsGeneric( bool* isGeneric ); + HRESULT GetGenericArgumentCount( ULONG64* argCount ); + HRESULT GetGenericArgumentAt( unsigned __int64 i, IDebugHostSymbol** argument ); + HRESULT IsTypedef( bool* isTypedef ); + HRESULT GetTypedefBaseType( IDebugHostType2** baseType ); + HRESULT GetTypedefFinalBaseType( IDebugHostType2** finalBaseType ); + HRESULT GetFunctionVarArgsKind( int* varArgsKind ); + HRESULT GetFunctionInstancePointerType( IDebugHostType2** instancePointerType ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(4F3E1CE2-86B2-4C7A-9C65-D0A9D0EECF44), + helpstring("IDebugHostStatus") +] +interface IDebugHostStatus : IUnknown { + HRESULT PollUserInterrupt( bool* interruptRequested ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(3B362B0E-89F0-46c6-A663-DFDC95194AEF), + helpstring("IDataModelScriptClient") +] +interface IDataModelScriptClient : IUnknown { + HRESULT ReportError( int errClass, HRESULT hrFail, const wchar_t* message, unsigned long line, unsigned long position ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(1303DEC4-FA3B-4F1B-9224-B953D16BABB5), + helpstring("IDataModelScriptTemplate") +] +interface IDataModelScriptTemplate : IUnknown { + HRESULT GetName( BSTR *templateName ); + HRESULT GetDescription( BSTR *templateDescription ); + HRESULT GetContent( IStream **contentStream ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(7B4D30FC-B14A-49f8-8D87-D9A1480C97F7), + helpstring("IDataModelScript") +] +interface IDataModelScript : IUnknown { + HRESULT GetName( BSTR *scriptName ); + HRESULT Rename( const wchar_t* scriptName ); + HRESULT Populate( IStream *contentStream ); + HRESULT Execute( IDataModelScriptClient *client ); + HRESULT Unlink( ); + HRESULT IsInvocable( bool *isInvocable ); + HRESULT InvokeMain( IDataModelScriptClient *client ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(69CE6AE2-2268-4e6f-B062-20CE62BFE677), + helpstring("IDataModelScriptTemplateEnumerator") +] +interface IDataModelScriptTemplateEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( IDataModelScriptTemplate **templateContent ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(513461E0-4FCA-48ce-8658-32F3E2056F3B), + helpstring("IDataModelScriptProvider") +] +interface IDataModelScriptProvider : IUnknown { + HRESULT GetName( BSTR *name ); + HRESULT GetExtension( BSTR *extension ); + HRESULT CreateScript( IDataModelScript **script ); + HRESULT GetDefaultTemplateContent( IDataModelScriptTemplate **templateContent ); + HRESULT EnumerateTemplates( IDataModelScriptTemplateEnumerator **enumerator ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(95BA00E2-704A-4fe2-A8F1-A7E7D8FB0941), + helpstring("IDataModelScriptProviderEnumerator") +] +interface IDataModelScriptProviderEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( IDataModelScriptProvider **provider ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(6FD11E33-E5AD-410b-8011-68C6BC4BF80D), + helpstring("IDataModelScriptManager") +] +interface IDataModelScriptManager : IUnknown { + HRESULT GetDefaultNameBinder( IDataModelNameBinder **ppNameBinder ); + HRESULT RegisterScriptProvider( IDataModelScriptProvider *provider ); + HRESULT UnregisterScriptProvider( IDataModelScriptProvider *provider ); + HRESULT FindProviderForScriptType( const wchar_t* scriptType, IDataModelScriptProvider **provider ); + HRESULT FindProviderForScriptExtension( const wchar_t* scriptExtension, IDataModelScriptProvider **provider ); + HRESULT EnumerateScriptProviders( IDataModelScriptProviderEnumerator **enumerator ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(E7983FA1-80A7-498c-988F-518DDC5D4025), + helpstring("IDynamicKeyProviderConcept") +] +interface IDynamicKeyProviderConcept : IUnknown { + HRESULT GetKey( IModelObject *contextObject, const wchar_t* key, IModelObject** keyValue, IKeyStore** metadata, bool *hasKey ); + HRESULT SetKey( IModelObject *contextObject, const wchar_t* key, IModelObject *keyValue, IKeyStore *metadata ); + HRESULT EnumerateKeys( IModelObject *contextObject, IKeyEnumerator **ppEnumerator ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(95A7F7DD-602E-483f-9D06-A15C0EE13174), + helpstring("IDynamicConceptProviderConcept") +] +interface IDynamicConceptProviderConcept : IUnknown { + HRESULT GetConcept( IModelObject *contextObject, REFIID conceptId, IUnknown **conceptInterface, IKeyStore **conceptMetadata, bool *hasConcept ); + HRESULT SetConcept( IModelObject *contextObject, REFIID conceptId, IUnknown *conceptInterface, IKeyStore *conceptMetadata ); + HRESULT NotifyParent( IModelObject *parentModel ); + HRESULT NotifyParentChange( IModelObject *parentModel ); + HRESULT NotifyDestruct( ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(014D366A-1F23-4981-9219-B2DB8B402054), + helpstring("IDataModelScriptHostContext") +] +interface IDataModelScriptHostContext : IUnknown { + HRESULT NotifyScriptChange( IDataModelScript* script, int changeKind ); + HRESULT GetNamespaceObject( IModelObject** namespaceObject ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(B70334A4-B92C-4570-93A1-D3EB686649A0), + helpstring("IDebugHostScriptHost") +] +interface IDebugHostScriptHost : IUnknown { + HRESULT CreateContext( IDataModelScript* script, IDataModelScriptHostContext** scriptContext ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(AF352B7B-8292-4c01-B360-2DC3696C65E7), + helpstring("IDataModelNameBinder") +] +interface IDataModelNameBinder : IUnknown { + HRESULT BindValue( IModelObject* contextObject, const wchar_t* name, IModelObject** value, IKeyStore** metadata ); + HRESULT BindReference( IModelObject* contextObject, const wchar_t* name, IModelObject** reference, IKeyStore** metadata ); + HRESULT EnumerateValues( IModelObject* contextObject, IKeyEnumerator** enumerator ); + HRESULT EnumerateReferences( IModelObject* contextObject, IKeyEnumerator** enumerator ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(80E2F7C5-7159-4e92-887E-7E0347E88406), + helpstring("IModelKeyReference2") +] +interface IModelKeyReference2 : IUnknown { + HRESULT GetKeyName( BSTR* keyName ); + HRESULT GetOriginalObject( IModelObject** originalObject ); + HRESULT GetContextObject( IModelObject** containingObject ); + HRESULT GetKey( IModelObject** object, IKeyStore** metadata ); + HRESULT GetKeyValue( IModelObject** object, IKeyStore** metadata ); + HRESULT SetKey( IModelObject* object, IKeyStore* metadata ); + HRESULT SetKeyValue( IModelObject* object ); + HRESULT OverrideContextObject( IModelObject* newContextObject ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(A117A435-1FB4-4092-A2AB-A929576C1E87), + helpstring("IDebugHostEvaluator2") +] +interface IDebugHostEvaluator2 : IUnknown { + HRESULT EvaluateExpression( IDebugHostContext* context, const wchar_t* expression, IModelObject* bindingContext, IModelObject** result, IKeyStore** metadata ); + HRESULT EvaluateExtendedExpression( IDebugHostContext* context, const wchar_t* expression, IModelObject* bindingContext, IModelObject** result, IKeyStore** metadata ); + HRESULT AssignTo( IModelObject* assignmentReference, IModelObject* assignmentValue, IModelObject** assignmentResult, IKeyStore** assignmentMetadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(F412C5EA-2284-4622-A660-A697160D3312), + helpstring("IDataModelManager2") +] +interface IDataModelManager2 : IUnknown { + HRESULT Close( ); + HRESULT CreateNoValue( IModelObject** object ); + HRESULT CreateErrorObject( HRESULT hrError, const wchar_t* pwszMessage, IModelObject** object ); + HRESULT CreateTypedObject( IDebugHostContext* context, Location objectLocation, IDebugHostType* objectType, IModelObject** object ); + HRESULT CreateTypedObjectReference( IDebugHostContext* context, Location objectLocation, IDebugHostType* objectType, IModelObject** object ); + HRESULT CreateSyntheticObject( IDebugHostContext* context, IModelObject** object ); + HRESULT CreateDataModelObject( IDataModelConcept* dataModel, IModelObject** object ); + HRESULT CreateIntrinsicObject( int objectKind, VARIANT* intrinsicData, IModelObject** object ); + HRESULT CreateTypedIntrinsicObject( VARIANT* intrinsicData, IDebugHostType* type, IModelObject** object ); + HRESULT GetModelForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject** dataModel ); + HRESULT GetModelForType( IDebugHostType* type, IModelObject** dataModel, IDebugHostTypeSignature** typeSignature, IDebugHostSymbolEnumerator** wildcardMatches ); + HRESULT RegisterModelForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject* dataModel ); + HRESULT UnregisterModelForTypeSignature( IModelObject* dataModel, IDebugHostTypeSignature* typeSignature ); + HRESULT RegisterExtensionForTypeSignature( IDebugHostTypeSignature* typeSignature, IModelObject* dataModel ); + HRESULT UnregisterExtensionForTypeSignature( IModelObject* dataModel, IDebugHostTypeSignature* typeSignature ); + HRESULT CreateMetadataStore( IKeyStore* parentStore, IKeyStore** metadataStore ); + HRESULT GetRootNamespace( IModelObject** rootNamespace ); + HRESULT RegisterNamedModel( const wchar_t* modelName, IModelObject *modeObject ); + HRESULT UnregisterNamedModel( const wchar_t* modelName ); + HRESULT AcquireNamedModel( const wchar_t* modelName, IModelObject **modelObject ); + HRESULT AcquireSubNamespace( const wchar_t* modelName, const wchar_t* subNamespaceModelName, const wchar_t* accessName, IKeyStore *metadata, IModelObject **namespaceModelObject ); + HRESULT CreateTypedIntrinsicObjectEx( IDebugHostContext* context, VARIANT* intrinsicData, IDebugHostType* type, IModelObject** object ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(EEA033DE-38F6-416b-A251-1D3771001270), + helpstring("IDebugHostMemory2") +] +interface IDebugHostMemory2 : IUnknown { + HRESULT ReadBytes( IDebugHostContext* context, Location location, void* buffer, unsigned __int64 bufferSize, ULONG64* bytesRead ); + HRESULT WriteBytes( IDebugHostContext* context, Location location, void* buffer, unsigned __int64 bufferSize, ULONG64* bytesWritten ); + HRESULT ReadPointers( IDebugHostContext* context, Location location, unsigned __int64 count, ULONG64* pointers ); + HRESULT WritePointers( IDebugHostContext* context, Location location, unsigned __int64 count, ULONG64* pointers ); + HRESULT GetDisplayStringForLocation( IDebugHostContext* context, Location location, bool verbose, BSTR* locationName ); + HRESULT LinearizeLocation( IDebugHostContext* context, Location location, Location *pLinearizedLocation ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(3C2B24E1-11D0-4f86-8AE5-4DF166F73253), + helpstring("IDebugHostExtensibility") +] +interface IDebugHostExtensibility : IUnknown { + HRESULT CreateFunctionAlias( const wchar_t* aliasName, IModelObject *functionObject ); + HRESULT DestroyFunctionAlias( const wchar_t* aliasName ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(53159B6D-D4C4-471b-A863-5B110CA800CA), + helpstring("IDataModelScriptDebugClient") +] +interface IDataModelScriptDebugClient : IUnknown { + HRESULT NotifyDebugEvent( ScriptDebugEventInformation *pEventInfo, IDataModelScript *pScript, IModelObject *pEventDataObject, int *resumeEventKind ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(0F9FEED7-D045-4ac3-98A8-A98942CF6A35), + helpstring("IDataModelScriptDebugVariableSetEnumerator") +] +interface IDataModelScriptDebugVariableSetEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( BSTR *variableName, IModelObject **variableValue, IKeyStore **variableMetadata ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(DEC6ED5E-6360-4941-AB4C-A26409DE4F82), + helpstring("IDataModelScriptDebugStackFrame") +] +interface IDataModelScriptDebugStackFrame : IUnknown { + HRESULT GetName( BSTR *name ); + HRESULT GetPosition( ScriptDebugPosition *position, ScriptDebugPosition *positionSpanEnd, BSTR *lineText ); + HRESULT IsTransitionPoint( bool *isTransitionPoint ); + HRESULT GetTransition( IDataModelScript **transitionScript, bool *isTransitionContiguous ); + HRESULT Evaluate( const wchar_t* pwszExpression, IModelObject **ppResult ); + HRESULT EnumerateLocals( IDataModelScriptDebugVariableSetEnumerator **variablesEnum ); + HRESULT EnumerateArguments( IDataModelScriptDebugVariableSetEnumerator **variablesEnum ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(051364DD-E449-443e-9762-FE578F4A5473), + helpstring("IDataModelScriptDebugStack") +] +interface IDataModelScriptDebugStack : IUnknown { + HRESULT GetStackFrame( unsigned __int64 frameNumber, IDataModelScriptDebugStackFrame **stackFrame ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(6BB27B35-02E6-47cb-90A0-5371244032DE), + helpstring("IDataModelScriptDebugBreakpoint") +] +interface IDataModelScriptDebugBreakpoint : IUnknown { + HRESULT GetPosition( ScriptDebugPosition *position, ScriptDebugPosition *positionSpanEnd, BSTR *lineText ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(39484A75-B4F3-4799-86DA-691AFA57B299), + helpstring("IDataModelScriptDebugBreakpointEnumerator") +] +interface IDataModelScriptDebugBreakpointEnumerator : IUnknown { + HRESULT Reset( ); + HRESULT GetNext( IDataModelScriptDebugBreakpoint **breakpoint ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(DE8E0945-9750-4471-AB76-A8F79D6EC350), + helpstring("IDataModelScriptDebug") +] +interface IDataModelScriptDebug : IUnknown { + HRESULT GetCurrentPosition( ScriptDebugPosition *currentPosition, ScriptDebugPosition *positionSpanEnd, BSTR *lineText ); + HRESULT GetStack( IDataModelScriptDebugStack **stack ); + HRESULT SetBreakpoint( unsigned long linePosition, unsigned long columnPosition, IDataModelScriptDebugBreakpoint **breakpoint ); + HRESULT FindBreakpointById( unsigned __int64 breakpointId, IDataModelScriptDebugBreakpoint **breakpoint ); + HRESULT EnumerateBreakpoints( IDataModelScriptDebugBreakpointEnumerator **breakpointEnum ); + HRESULT GetEventFilter( int eventFilter, bool *isBreakEnabled ); + HRESULT SetEventFilter( int eventFilter, bool isBreakEnabled ); + HRESULT StartDebugging( IDataModelScriptDebugClient *debugClient ); + HRESULT StopDebugging( IDataModelScriptDebugClient *debugClient ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(CBB10ED3-839E-426c-9243-E23535C1AE1A), + helpstring("IDataModelScriptDebug2") +] +interface IDataModelScriptDebug2 : IUnknown { + HRESULT GetCurrentPosition( ScriptDebugPosition *currentPosition, ScriptDebugPosition *positionSpanEnd, BSTR *lineText ); + HRESULT GetStack( IDataModelScriptDebugStack **stack ); + HRESULT SetBreakpoint( unsigned long linePosition, unsigned long columnPosition, IDataModelScriptDebugBreakpoint **breakpoint ); + HRESULT FindBreakpointById( unsigned __int64 breakpointId, IDataModelScriptDebugBreakpoint **breakpoint ); + HRESULT EnumerateBreakpoints( IDataModelScriptDebugBreakpointEnumerator **breakpointEnum ); + HRESULT GetEventFilter( int eventFilter, bool *isBreakEnabled ); + HRESULT SetEventFilter( int eventFilter, bool isBreakEnabled ); + HRESULT StartDebugging( IDataModelScriptDebugClient *debugClient ); + HRESULT StopDebugging( IDataModelScriptDebugClient *debugClient ); + HRESULT SetBreakpointAtFunction( const wchar_t* functionName, IDataModelScriptDebugBreakpoint **breakpoint ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(B51887E8-BCD0-4e8f-A8C7-434398B78C37), + helpstring("IDebugHostModule2") +] +interface IDebugHostModule2 : IUnknown { + HRESULT GetContext( IDebugHostContext** context ); + HRESULT EnumerateChildren( int kind, const wchar_t* name, IDebugHostSymbolEnumerator **ppEnum ); + HRESULT Getint( int *kind ); + HRESULT GetName( BSTR* symbolName ); + HRESULT GetType( IDebugHostType** type ); + HRESULT GetContainingModule( IDebugHostModule **containingModule ); + HRESULT GetImageName( bool allowPath, BSTR* imageName ); + HRESULT GetBaseLocation( Location* moduleBaseLocation ); + HRESULT GetVersion( ULONG64* fileVersion, ULONG64* productVersion ); + HRESULT FindTypeByName( const wchar_t* typeName, IDebugHostType** type ); + HRESULT FindSymbolByRVA( unsigned __int64 rva, IDebugHostSymbol** symbol ); + HRESULT FindSymbolByName( const wchar_t* symbolName, IDebugHostSymbol** symbol ); + HRESULT FindContainingSymbolByRVA( unsigned __int64 rva, IDebugHostSymbol** symbol, unsigned __int64 *offset ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(A7830646-9F0C-4a31-BA19-503F33E6C8A3), + helpstring("IComparableConcept") +] +interface IComparableConcept : IUnknown { + HRESULT CompareObjects( IModelObject *contextObject, IModelObject *otherObject, int *comparisonResult ); +}; + +/////////////////////////////////////////////////////////// +[ + object, + uuid(C52D5D3D-609D-4d5d-8A82-46B0ACDEC4F4), + helpstring("IEquatableConcept") +] +interface IEquatableConcept : IUnknown { + HRESULT AreObjectsEqual( IModelObject *contextObject, IModelObject *otherObject, bool *isEqual ); +}; + +}; + \ No newline at end of file diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idatamodelmanager.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idatamodelmanager.py new file mode 100644 index 0000000000..d0734a66d2 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idatamodelmanager.py @@ -0,0 +1,96 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +import dbgmodel.imodelobject as mo + +class DataModelManager(object): + def __init__(self, mgr): + self._mgr = mgr + exception.wrap_comclass(self._mgr) + + def Release(self): + cnt = self._mgr.Release() + if cnt == 0: + self._mgr = None + return cnt + + # DataModelManager + + def GetRootNamespace(self): + root = POINTER(DbgMod.IModelObject)() + hr = self._mgr.GetRootNamespace(byref(root)) + exception.check_err(hr) + return mo.ModelObject(root) + + def AcquireNamedModel(self, modelName, modelObject): + raise exception.E_NOTIMPL_Error + + def Close(self): + raise exception.E_NOTIMPL_Error + + def CreateNoValue(self, object): + raise exception.E_NOTIMPL_Error + + def CreateErrorObject(self, error, message, object): + raise exception.E_NOTIMPL_Error + + def CreateTypedObject(self, context, objectLocation, objectType, object): + raise exception.E_NOTIMPL_Error + + def CreateTypedObjectByReference(self, context, objectLocation, objectType, object): + raise exception.E_NOTIMPL_Error + + def CreateSyntheticObject(self, context, object): + raise exception.E_NOTIMPL_Error + + def CreateDataModelObject(self, dataModel, object): + raise exception.E_NOTIMPL_Error + + def CreateTypedIntrinsicObject(self, intrinsicData, type, object): + raise exception.E_NOTIMPL_Error + + def CreateIntrinsicObject(self, objectKind, intrinsicData, object): + raise exception.E_NOTIMPL_Error + + def GetModelForTypeSignature(self, typeSignature, dataModel): + raise exception.E_NOTIMPL_Error + + def GetModelForType(self, type, dataModel, typeSignature, wildcardMatches): + raise exception.E_NOTIMPL_Error + + def RegisterExtensionForTypeSignature(self, typeSignature, dataModel): + raise exception.E_NOTIMPL_Error + + def RegisterModelForTypeSignature(self, typeSignature, dataModel): + raise exception.E_NOTIMPL_Error + + def RegisterNamedModel(self, modelName, modelObject): + raise exception.E_NOTIMPL_Error + + def UnregisterExtensionForTypeSignature(self, dataModel, typeSignature): + raise exception.E_NOTIMPL_Error + + def UnregisterModelForTypeSignature(self, dataModel, typeSignature): + raise exception.E_NOTIMPL_Error + + def UnregisterNamedModel(self, modelName): + raise exception.E_NOTIMPL_Error + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idebughost.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idebughost.py new file mode 100644 index 0000000000..65eac4ec2f --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/idebughost.py @@ -0,0 +1,48 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +from pybag.dbgeng import win32 + +class DebugHost(object): + def __init__(self, host): + self._host = host + exception.wrap_comclass(self._host) + + def Release(self): + cnt = self._host.Release() + if cnt == 0: + self._host = None + return cnt + + # DebugHost + + def GetCurrentContext(self, context): + raise exception.E_NOTIMPL_Error + + def GetDefaultMetadata(self, metadata): + raise exception.E_NOTIMPL_Error + + def GetHostDefinedInterface(self, hostUnk): + raise exception.E_NOTIMPL_Error + + + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ihostdatamodelaccess.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ihostdatamodelaccess.py new file mode 100644 index 0000000000..fde3dc5529 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ihostdatamodelaccess.py @@ -0,0 +1,46 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception + +from .idatamodelmanager import DataModelManager +from .idebughost import DebugHost + +class HostDataModelAccess(object): + def __init__(self, hdma): + self._hdma = hdma + exception.wrap_comclass(self._hdma) + + def Release(self): + cnt = self._hdma.Release() + if cnt == 0: + self._hdma = None + return cnt + + # HostDataModelAccess + + def GetDataModel(self): + manager = POINTER(DbgMod.IDataModelManager)() + host = POINTER(DbgMod.IDebugHost)() + hr = self._hdma.GetDataModel(byref(manager), byref(host)) + exception.check_err(hr) + return (DataModelManager(manager), DebugHost(host)) + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/iiterableconcept.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/iiterableconcept.py new file mode 100644 index 0000000000..9a077a8908 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/iiterableconcept.py @@ -0,0 +1,44 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes import COMError +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +from .imodeliterator import ModelIterator + +class IterableConcept(object): + def __init__(self, concept): + self._concept = concept + concept.AddRef() + + + # IterableConcept + + def GetDefaultIndexDimensionality(self, context, dimensionality): + raise exception.E_NOTIMPL_Error + + def GetIterator(self, context): + iterator = POINTER(DbgMod.IModelIterator)() + try: + self._concept.GetIterator(context._obj, byref(iterator)) + except COMError as ce: + return None + return ModelIterator(iterator) + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ikeyenumerator.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ikeyenumerator.py new file mode 100644 index 0000000000..3f5407abb5 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/ikeyenumerator.py @@ -0,0 +1,51 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes import BSTR +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +import dbgmodel.imodelobject as mo + +class KeyEnumerator(object): + def __init__(self, keys): + self._keys = keys + exception.wrap_comclass(self._keys) + + def Release(self): + cnt = self._keys.Release() + if cnt == 0: + self._keys = None + return cnt + + # KeyEnumerator + + def GetNext(self): + key = BSTR() + value = POINTER(DbgMod.IModelObject)() + store = POINTER(DbgMod.IKeyStore)() + hr = self._keys.GetNext(byref(key), byref(value), byref(store)) + if hr != S_OK: + return (None, None) + return (key, mo.ModelObject(value)) + + def Reset(self): + hr = self._keys.Reset() + exception.check_err(hr) + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodeliterator.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodeliterator.py new file mode 100644 index 0000000000..2e23db69a1 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodeliterator.py @@ -0,0 +1,48 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes import COMError +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +import dbgmodel.imodelobject as mo + +class ModelIterator(object): + def __init__(self, iter): + self._iter = iter + iter.AddRef() + + # ModelIterator + + def GetNext(self, dimensions): + object = POINTER(DbgMod.IModelObject)() + indexer = POINTER(DbgMod.IModelObject)() + metadata = POINTER(DbgMod.IKeyStore)() + try: + self._iter.GetNext(byref(object), dimensions, byref(indexer), byref(metadata)) + except COMError as ce: + return None + index = mo.ModelObject(indexer) + id = index.GetIntrinsicValue().value + return (id, mo.ModelObject(object)) + + def Reset(self): + hr = self._keys.Reset() + exception.check_err(hr) + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodelobject.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodelobject.py new file mode 100644 index 0000000000..f7fbb3be6f --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/imodelobject.py @@ -0,0 +1,273 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes import IUnknown, COMError +from comtypes.automation import IID, VARIANT +from comtypes.hresult import S_OK, S_FALSE +from comtypes.gen.DbgMod import * +from enum import Enum + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception + +from .ikeyenumerator import KeyEnumerator +from .iiterableconcept import IterableConcept + +class ModelObjectKind(Enum): + PROPERTY_ACCESSOR = 0 + CONTEXT = 1 + TARGET_OBJECT = 2 + TARGET_OBJECT_REFERENCE = 3 + SYNTHETIC = 4 + NO_VALUE = 5 + ERROR = 6 + INTRINSIC = 7 + METHOD = 8 + KEY_REFERENCE = 9 + +class ModelObject(object): + def __init__(self, obj): + self._obj = obj + self.concept = None + exception.wrap_comclass(self._obj) + + def Release(self): + print("RELEASE ModelObject") + breakpoint() + cnt = self._obj.Release() + if cnt == 0: + self._obj = None + return cnt + + # ModelObject + + def AddParentModel(self, model, contextObject, override): + raise exception.E_NOTIMPL_Error + + def ClearConcepts(self): + raise exception.E_NOTIMPL_Error + + def ClearKeys(self): + raise exception.E_NOTIMPL_Error + + def Compare(self, other, equal): + raise exception.E_NOTIMPL_Error + + def Dereference(self, object): + raise exception.E_NOTIMPL_Error + + def EnumerateKeyReferences(self): + raise exception.E_NOTIMPL_Error + + def EnumerateKeys(self): + keys = POINTER(DbgMod.IKeyEnumerator)() + hr = self._obj.EnumerateKeys(byref(keys)) + if hr != S_OK: + return None + return KeyEnumerator(keys) + + def EnumerateKeyValues(self): + raise exception.E_NOTIMPL_Error + + def EnumerateRawReferences(self, kind, searchFlags): + raise exception.E_NOTIMPL_Error + + def EnumerateRawValues(self, kind, searchFlag): + keys = POINTER(DbgMod.IRawEnumerator)() + hr = self._obj.EnumerateRawValues(kind, searchFlag, byref(keys)) + if hr != S_OK: + return None + return RawEnumerator(keys, kind) + + def GetConcept(self, ref): + ifc = POINTER(IUnknown)() + metadata = POINTER(DbgMod.IKeyStore)() + hr = self._obj.GetConcept(ref._iid_, byref(ifc), byref(metadata)) + if hr != S_OK: + return None + return cast(ifc, POINTER(ref)) + + def GetContext(self, context): + raise exception.E_NOTIMPL_Error + + def GetContextForDataModel(self, dataModelObject, context): + raise exception.E_NOTIMPL_Error + + def GetIntrinsicValue(self): + var = VARIANT() + hr = self._obj.GetIntrinsicValue(var) + if hr != S_OK: + return None + return var + + def GetIntrinsicValueAs(self, vt): + raise exception.E_NOTIMPL_Error + + def GetKey(self, key, object, metadata): + raise exception.E_NOTIMPL_Error + + def GetKeyReference(self, key, objectReference, metadata): + raise exception.E_NOTIMPL_Error + + def GetKeyValue(self, key): + kbuf = cast(c_wchar_p(key),POINTER(c_ushort)) + value = POINTER(DbgMod.IModelObject)() + store = POINTER(DbgMod.IKeyStore)() + hr = self._obj.GetKeyValue(kbuf, byref(value), byref(store)) + if hr != S_OK: + return None + return ModelObject(value) + + def GetKind(self): + kind = c_long() + hr = self._obj.GetKind(kind) + exception.check_err(hr) + return kind + + def GetLocation(self, location): + raise exception.E_NOTIMPL_Error + + def GetNumberOfParentModels(self, numModels): + raise exception.E_NOTIMPL_Error + + def GetParentModel(self, i, model, context): + raise exception.E_NOTIMPL_Error + + def GetRawReference(self, kind, name, searchFlags, object): + raise exception.E_NOTIMPL_Error + + def GetRawValue(self, kind, name, searchFlags, object): + raise exception.E_NOTIMPL_Error + + def GetTargetInfo(self): + location = POINTER(DbgMod._Location)() + type = POINTER(DbgMod.IDebugHostType)() + hr = self._obj.GetTargetInfo(location, byref(type)) + exception.check_err(hr) + return type + + def GetTypeInfo(self, type): + raise exception.E_NOTIMPL_Error + + def IsEqualTo(self, other, equal): + raise exception.E_NOTIMPL_Error + + def RemoveParentModel(self, model): + raise exception.E_NOTIMPL_Error + + def SetConcept(self, ref, interface, metadata): + raise exception.E_NOTIMPL_Error + + def SetContextForDataModel(self, modelObject, context): + raise exception.E_NOTIMPL_Error + + def SetKey(self, key, object, metadata): + raise exception.E_NOTIMPL_Error + + def SetKeyValue(self, key, object): + raise exception.E_NOTIMPL_Error + + def TryCastToRuntimeType(self, runtimeTypedObject): + raise exception.E_NOTIMPL_Error + + # Auxiliary + + def GetKeyValueMap(self): + map = {} + keys = self.EnumerateKeys() + (k,v) = keys.GetNext() + while k is not None: + map[k.value] = self.GetKeyValue(k.value) + (k,v) = keys.GetNext() + return map + + def GetRawValueMap(self): + map = {} + kind = self.GetKind() + keys = self.EnumerateRawValues(kind, c_long(0)) + (k,v) = keys.GetNext() + while k is not None: + map[k.value] = v + (k,v) = keys.GetNext() + return map + + def GetAttributes(self): + map = {} + kind = self.GetKind() + if kind == ModelObjectKind.ERROR: + return map + if kind == ModelObjectKind.INTRINSIC or \ + kind == ModelObjectKind.TARGET_OBJECT or \ + kind == ModelObjectKind.TARGET_OBJECT_REFERENCE: + return self.GetRawValueMap() + return self.GetKeyValueMap() + + + def GetElements(self): + list = [] + if self.concept is None: + iconcept = self.GetConcept(DbgMod.IIterableConcept) + if iconcept is None: + return list + self.concept = IterableConcept(iconcept) + iter = self.concept.GetIterator(self) + if iter is None: + print("WARNING: iter is None") + return list + next = iter.GetNext(1) + while next is not None: + list.append(next) + next = iter.GetNext(1) + return list + + def GetElement(self, key): + list = self.GetElements() + for k, v in list: + if k == key: + return v + return None + + def GetOffspring(self, path): + next = self + for element in path: + if element.startswith("["): + idx = element[1:len(element)-1] + if "x" not in idx: + idx = int(idx) + else: + idx = int(idx,16) + next = next.GetElement(idx) + else: + next = next.GetKeyValue(element) + if next is None: + print(f"{element} not found") + return next + + def GetValue(self): + value = self.GetIntrinsicValue() + if value is None: + return None + if value.vt == 0xd: + return None + return value.value + + def GetTypeKind(self): + kind = self.GetKind() + if kind == ModelObjectKind.TARGET_OBJECT or \ + kind == ModelObjectKind.INTRINSIC: + return self.GetTargetInfo() + return None + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/irawenumerator.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/irawenumerator.py new file mode 100644 index 0000000000..273bb096b3 --- /dev/null +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/dbgmodel/irawenumerator.py @@ -0,0 +1,51 @@ +## ### +# IP: GHIDRA +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +## +from ctypes import * +from comtypes import BSTR +from comtypes.hresult import S_OK, S_FALSE + +from comtypes.gen import DbgMod +from pybag.dbgeng import exception +import dbgmodel.imodelobject as mo + +class RawEnumerator(object): + def __init__(self, keys, kind): + self._keys = keys + self._kind = kind + exception.wrap_comclass(self._keys) + + def Release(self): + cnt = self._keys.Release() + if cnt == 0: + self._keys = None + return cnt + + # KeyEnumerator + + def GetNext(self): + key = BSTR() + value = POINTER(DbgMod.IModelObject)() + hr = self._keys.GetNext(byref(key), byref(self._kind), byref(value)) + if hr != S_OK: + return (None, None) + return (key, mo.ModelObject(value)) + + def Reset(self): + hr = self._keys.Reset() + exception.check_err(hr) + + + diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/__init__.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/__init__.py index 6d6349f7af..536e1b3473 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/__init__.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/__init__.py @@ -14,7 +14,44 @@ # limitations under the License. ## from . import util, commands, methods, hooks +from dbgmodel.ihostdatamodelaccess import HostDataModelAccess import ctypes +import platform +import os ctypes.windll.kernel32.SetErrorMode(0x0001 | 0x0002 | 0x8000) + +if platform.architecture()[0] == '64bit': + dbgdirs = [os.getenv('OPT_DBGMODEL_PATH'), + r'C:\Program Files\Windows Kits\10\Debuggers\x64', + r'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64'] +else: + dbgdirs = [os.getenv('OPT_DBGMODEL_PATH'), + r'C:\Program Files\Windows Kits\10\Debuggers\x86', + r'C:\Program Files (x86)\Windows Kits\10\Debuggers\x86'] +dbgdir = None +for _dir in dbgdirs: + if os.path.exists(_dir): + dbgdir = _dir + break + +if not dbgdir: + raise RuntimeError("Windbg install directory not found!") + +# preload these to get correct DLLs loaded +try: + ctypes.windll.LoadLibrary(os.path.join(dbgdir, 'dbghelp.dll')) +except Exception as exc: + print(f"LoadLibrary failed: {dbgdir}\dbghelp.dll {exc}") + pass +try: + ctypes.windll.LoadLibrary(os.path.join(dbgdir, 'dbgeng.dll')) +except Exception as exc: + print(f"LoadLibrary failed: {dbgdir}\dbgeng.dll {exc}") + pass +try: + ctypes.windll.LoadLibrary(os.path.join(dbgdir, 'DbgModel.dll')) +except Exception as exc: + print(f"LoadLibrary failed: {dbgdir}\dbgmodel.dll {exc}") + pass diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py index 82f37f592e..e693937a4d 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py @@ -25,6 +25,7 @@ import time from pybag import pydbg, userdbg, kerneldbg from pybag.dbgeng import core as DbgEng from pybag.dbgeng import exception +from dbgmodel.imodelobject import ModelObjectKind from ghidratrace import sch from ghidratrace.client import Client, Address, AddressRange, TraceObject @@ -37,20 +38,21 @@ PAGE_SIZE = 4096 AVAILABLES_PATH = 'Available' AVAILABLE_KEY_PATTERN = '[{pid}]' AVAILABLE_PATTERN = AVAILABLES_PATH + AVAILABLE_KEY_PATTERN -PROCESSES_PATH = 'Processes' +PROCESSES_PATH = 'Sessions[0].Processes' PROCESS_KEY_PATTERN = '[{procnum}]' PROCESS_PATTERN = PROCESSES_PATH + PROCESS_KEY_PATTERN -PROC_BREAKS_PATTERN = PROCESS_PATTERN + '.Breakpoints' +PROC_BREAKS_PATTERN = PROCESS_PATTERN + '.Debug.Breakpoints' PROC_BREAK_KEY_PATTERN = '[{breaknum}]' PROC_BREAK_PATTERN = PROC_BREAKS_PATTERN + PROC_BREAK_KEY_PATTERN ENV_PATTERN = PROCESS_PATTERN + '.Environment' THREADS_PATTERN = PROCESS_PATTERN + '.Threads' THREAD_KEY_PATTERN = '[{tnum}]' THREAD_PATTERN = THREADS_PATTERN + THREAD_KEY_PATTERN -STACK_PATTERN = THREAD_PATTERN + '.Stack' +STACK_PATTERN = THREAD_PATTERN + '.Stack.Frames' FRAME_KEY_PATTERN = '[{level}]' FRAME_PATTERN = STACK_PATTERN + FRAME_KEY_PATTERN REGS_PATTERN = THREAD_PATTERN + '.Registers' +USER_REGS_PATTERN = THREAD_PATTERN + '.Registers.User' MEMORY_PATTERN = PROCESS_PATTERN + '.Memory' REGION_KEY_PATTERN = '[{start:08x}]' REGION_PATTERN = MEMORY_PATTERN + REGION_KEY_PATTERN @@ -60,6 +62,7 @@ MODULE_PATTERN = MODULES_PATTERN + MODULE_KEY_PATTERN SECTIONS_ADD_PATTERN = '.Sections' SECTION_KEY_PATTERN = '[{secname}]' SECTION_ADD_PATTERN = SECTIONS_ADD_PATTERN + SECTION_KEY_PATTERN +GENERIC_KEY_PATTERN = '[{key}]' # TODO: Symbols @@ -209,7 +212,7 @@ def start_trace(name): with open(schema_fn, 'r') as schema_file: schema_xml = schema_file.read() with STATE.trace.open_tx("Create Root Object"): - root = STATE.trace.create_root_object(schema_xml, 'DbgengSession') + root = STATE.trace.create_root_object(schema_xml, 'Root') root.set_value('_display', util.DBG_VERSION.full + ' via pybag') util.set_convenience_variable('_ghidra_tracing', "true") @@ -481,6 +484,18 @@ def ghidra_trace_delmem(address, length): @util.dbg.eng_thread def putreg(): + if util.dbg.use_generics: + nproc = util.selected_process() + if nproc < 0: + return + nthrd = util.selected_thread() + rpath = REGS_PATTERN.format(procnum=nproc, tnum=nthrd) + create_generic(rpath) + STATE.trace.create_overlay_space('register', rpath) + path = USER_REGS_PATTERN.format(procnum=nproc, tnum=nthrd) + (values, keys) = create_generic(path) + return {'missing': STATE.trace.put_registers(rpath, values)} + nproc = util.selected_process() if nproc < 0: return @@ -834,6 +849,17 @@ def compute_proc_state(nproc=None): def put_processes(running=False): # | always displays PID in hex # TODO: I'm not sure about the engine id + + # NB: This speeds things up, but desirable? + if running: + return + + if util.dbg.use_generics and not running: + ppath = PROCESSES_PATH + (values, keys) = create_generic(ppath) + STATE.trace.proxy_object_path(PROCESSES_PATH).retain_values(keys) + return + keys = [] # Set running=True to avoid process changes, even while stopped for i, p in enumerate(util.process_list(running=True)): @@ -979,8 +1005,18 @@ def put_single_breakpoint(bp, ibobj, nproc, ikeys): @util.dbg.eng_thread def put_breakpoints(): - target = util.get_target() nproc = util.selected_process() + + # NB: Am leaving this code here in case we change our minds, but the cost + # of using put_generic here outweighs the advantage of uniformity + # + # if util.dbg.use_generics: + # path = PROC_BREAKS_PATTERN.format(procnum=nproc) + # (values, keys) = create_generic(path) + # STATE.trace.proxy_object_path(path).retain_values(keys) + # return + + target = util.get_target() ibpath = PROC_BREAKS_PATTERN.format(procnum=nproc) ibobj = STATE.trace.create_object(ibpath) keys = [] @@ -1010,7 +1046,8 @@ def ghidra_trace_put_breakpoints(): def put_environment(): - epath = ENV_PATTERN.format(procnum=util.selected_process()) + nproc = util.selected_process() + epath = ENV_PATTERN.format(procnum=nproc) envobj = STATE.trace.create_object(epath) envobj.set_value('_debugger', 'pydbg') envobj.set_value('_arch', arch.get_arch()) @@ -1036,8 +1073,7 @@ def put_regions(): regions = util.dbg._base.memory_list() except Exception: regions = [] - if len(regions) == 0 and util.selected_thread() != None: - regions = [util.REGION_INFO_READER.full_mem()] + mapper = STATE.trace.memory_mapper keys = [] # r : MEMORY_BASIC_INFORMATION64 @@ -1045,9 +1081,7 @@ def put_regions(): rpath = REGION_PATTERN.format(procnum=nproc, start=r.BaseAddress) keys.append(REGION_KEY_PATTERN.format(start=r.BaseAddress)) regobj = STATE.trace.create_object(rpath) - start_base, start_addr = mapper.map(nproc, r.BaseAddress) - if start_base != start_addr.space: - STATE.trace.create_overlay_space(start_base, start_addr.space) + (start_base, start_addr) = map_address(r.BaseAddress) regobj.set_value('_range', start_addr.extend(r.RegionSize)) regobj.set_value('_readable', r.Protect == None or r.Protect & 0x66 != 0) @@ -1078,8 +1112,15 @@ def ghidra_trace_put_regions(): @util.dbg.eng_thread def put_modules(): - target = util.get_target() nproc = util.selected_process() + if util.dbg.use_generics: + mpath = MODULES_PATTERN.format(procnum=nproc) + (values, keys) = create_generic(mpath) + STATE.trace.proxy_object_path( + MODULES_PATTERN.format(procnum=nproc)).retain_values(keys) + return + + target = util.get_target() modules = util.dbg._base.module_list() mapper = STATE.trace.memory_mapper mod_keys = [] @@ -1141,9 +1182,21 @@ def compute_thread_display(i, pid, tid, t): def put_threads(running=False): # ~ always displays PID:TID in hex # TODO: I'm not sure about the engine id + + # NB: This speeds things up, but desirable? + if running: + return + nproc = util.selected_process() if nproc is None: return + if util.dbg.use_generics and not running: + tpath = THREADS_PATTERN.format(procnum=nproc) + (values, keys) = create_generic(tpath) + STATE.trace.proxy_object_path( + THREADS_PATTERN.format(procnum=nproc)).retain_values(keys) + return + pid = util.dbg.pid keys = [] @@ -1192,10 +1245,19 @@ def ghidra_trace_put_threads(): @util.dbg.eng_thread def put_frames(): nproc = util.selected_process() - mapper = STATE.trace.memory_mapper + if nproc < 0: + return nthrd = util.selected_thread() if nthrd is None: return + + if util.dbg.use_generics: + path = STACK_PATTERN.format(procnum=nproc, tnum=nthrd) + (values, keys) = create_generic(path) + STATE.trace.proxy_object_path(path).retain_values(keys) + return + + mapper = STATE.trace.memory_mapper keys = [] # f : _DEBUG_STACK_FRAME for f in util.dbg._base.backtrace_list(): @@ -1228,6 +1290,134 @@ def ghidra_trace_put_frames(): put_frames() +def update_by_container(np, index, obj): + if np.endswith("Processes") or np.endswith("Threads"): + istate = compute_proc_state(index) + obj.set_value('_state', istate) + if np.endswith("Processes"): + create_generic(obj.path) + id = util.get_proc_id(index) + obj.set_value('_pid', index) + obj.set_value('_display', '{:x} {:x}'.format(id, index)) + if np.endswith("Breakpoints"): + create_generic(obj.path) + #id = util.get_thread_id(index) + #obj.set_value('_tid', index) + #obj.set_value('_display','{:x} {:x}'.format(id, index)) + if np.endswith("Threads"): + create_generic(obj.path) + id = util.get_thread_id(index) + obj.set_value('_tid', index) + obj.set_value('_display', '{:x} {:x}'.format(id, index)) + if np.endswith("Frames"): + mo = util.get_object(obj.path) + map = util.get_attributes(mo) + attr = map["Attributes"] + if attr is None: + return + create_generic(obj.path+".Attributes") + map = util.get_attributes(attr) + pc = util.get_value(map["InstructionOffset"]) + (pc_base, pc_addr) = map_address(pc) + obj.set_value('_pc', pc_addr) + obj.set_value('_display', '#{:x} 0x{:x}'.format(index, pc)) + if np.endswith("Modules"): + create_generic(obj.path) + mo = util.get_object(obj.path) + map = util.get_attributes(mo) + base = util.get_value(map["BaseAddress"]) + size = util.get_value(map["Size"]) + name = util.get_value(map["Name"]) + obj.set_value('_module_name', '{}'.format(name)) + (base_base, base_addr) = map_address(base) + obj.set_value('_range', base_addr.extend(size)) + obj.set_value('_display', '{:x} {:x} {}'.format(index, base, name)) + obj.set_value('Base', hex(base)) + + +def create_generic(path): + obj = STATE.trace.create_object(path) + obj.insert() + result = put_generic(obj) + return result + + +def put_generic(node): + #print(f"put_generic: {node}") + nproc = util.selected_process() + if nproc is None: + return + nthrd = util.selected_thread() + + mapper = STATE.trace.memory_mapper + mo = util.get_object(node.path) + kind = util.get_kind(mo) + type = util.get_type(mo) + vstr = util.get_value(mo) + if kind is not None: + node.set_value("_kind", kind) + if type is not None: + node.set_value("_type", type.value) + # print(f"MO={mo}") + attributes = util.get_attributes(mo) + # print(f"ATTR={attributes}") + mapper = STATE.trace.register_mapper + values = [] + for key, value in attributes.items(): + if value is None: + continue + kind = util.get_kind(value) + vstr = util.get_value(value) + #print(f"key={key} kind={kind} value={vstr} type={type}") + if kind == ModelObjectKind.PROPERTY_ACCESSOR.value or \ + kind == ModelObjectKind.SYNTHETIC.value or \ + kind == ModelObjectKind.METHOD.value: + if vstr is not None: + key += " : " + vstr + apath = node.path+'.'+key + aobj = STATE.trace.create_object(apath) + aobj.insert() + else: + try: + if node.path.endswith('.User'): + values.append(mapper.map_value(nproc, key, vstr)) + node.set_value(key, hex(vstr)) + except Exception as e: + pass # Error is printed by another mechanism + elements = util.get_elements(mo) + # print(f"ELEM={elements}") + keys = [] + for el in elements: + index = el[0] + key = GENERIC_KEY_PATTERN.format(key=index) + lpath = node.path+key + lobj = STATE.trace.create_object(lpath) + update_by_container(node.path, index, lobj) + lobj.insert() + keys.append(key) + node.retain_values(keys) + return (values, keys) + + +def map_address(address): + nproc = util.selected_process() + mapper = STATE.trace.memory_mapper + base, addr = mapper.map(nproc, address) + if base != addr.space: + STATE.trace.create_overlay_space(base, addr.space) + return (base, addr) + + +def ghidra_trace_put_generic(node): + """ + Put the current thread's frames into the Ghidra trace + """ + + STATE.require_tx() + with STATE.client.batch() as b: + put_generic(node) + + def ghidra_trace_put_all(): """ Put everything currently selected into the Ghidra trace diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/hooks.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/hooks.py index 2fd17ef6a0..2a241baa05 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/hooks.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/hooks.py @@ -30,7 +30,6 @@ from pybag.dbgeng.idebugbreakpoint import DebugBreakpoint from . import commands, util - ALL_EVENTS = 0xFFFF @@ -103,8 +102,9 @@ class ProcessState(object): commands.STATE.trace.snapshot(description) proc = util.selected_process() ipath = commands.PROCESS_PATTERN.format(procnum=proc) - commands.STATE.trace.proxy_object_path( - ipath).set_value('_exit_code', exit_code) + procobj = commands.STATE.trace.proxy_object_path(ipath) + procobj.set_value('_exit_code', exit_code) + procobj.set_value('_state', 'TERMINATED') class BrkState(object): @@ -178,6 +178,8 @@ def on_state_changed(*args): commands.put_state(proc) if args[1] == DbgEng.DEBUG_STATUS_BREAK: return on_stop(args) + elif args[1] == DbgEng.DEBUG_STATUS_NO_DEBUGGEE: + return on_exited(proc) else: return on_cont(args) return S_OK @@ -376,6 +378,7 @@ def on_stop(*args): def on_exited(proc): + # print("ON EXITED") if proc not in PROC_STATE: # print("not in state") return diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py index babbd5b72f..5765e2b931 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/methods.py @@ -40,13 +40,16 @@ AVAILABLE_PATTERN = re.compile('Available\[(?P\\d*)\]') WATCHPOINT_PATTERN = re.compile('Watchpoints\[(?P\\d*)\]') BREAKPOINT_PATTERN = re.compile('Breakpoints\[(?P\\d*)\]') BREAK_LOC_PATTERN = extre(BREAKPOINT_PATTERN, '\[(?P\\d*)\]') -PROCESS_PATTERN = re.compile('Processes\[(?P\\d*)\]') -PROC_BREAKS_PATTERN = extre(PROCESS_PATTERN, '\.Breakpoints') +SESSIONS_PATTERN = re.compile('Sessions') +SESSION_PATTERN = extre(SESSIONS_PATTERN, '\[(?P\\d*)\]') +PROCESSES_PATTERN = extre(SESSION_PATTERN, '\.Processes') +PROCESS_PATTERN = extre(PROCESSES_PATTERN, '\[(?P\\d*)\]') +PROC_BREAKS_PATTERN = extre(PROCESS_PATTERN, '\.Debug.Breakpoints') PROC_BREAKBPT_PATTERN = extre(PROC_BREAKS_PATTERN, '\[(?P\\d*)\]') ENV_PATTERN = extre(PROCESS_PATTERN, '\.Environment') THREADS_PATTERN = extre(PROCESS_PATTERN, '\.Threads') THREAD_PATTERN = extre(THREADS_PATTERN, '\[(?P\\d*)\]') -STACK_PATTERN = extre(THREAD_PATTERN, '\.Stack') +STACK_PATTERN = extre(THREAD_PATTERN, '\.Stack.Frames') FRAME_PATTERN = extre(STACK_PATTERN, '\[(?P\\d*)\]') REGS_PATTERN0 = extre(THREAD_PATTERN, '.Registers') REGS_PATTERN = extre(FRAME_PATTERN, '.Registers') @@ -204,14 +207,21 @@ def evaluate(expr: str): return str(eval(expr, shared_globals)) -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display="Refresh", condition=util.dbg.use_generics) +def refresh_generic(node: sch.OBJECT): + """List processes on pydbg's host system.""" + with commands.open_tracked_tx('Refresh Generic'): + commands.ghidra_trace_put_generic(node) + + +@REGISTRY.method(action='refresh', display='Refresh Available') def refresh_available(node: sch.Schema('AvailableContainer')): """List processes on pydbg's host system.""" with commands.open_tracked_tx('Refresh Available'): commands.ghidra_trace_put_available() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Breakpoints') def refresh_breakpoints(node: sch.Schema('BreakpointContainer')): """ Refresh the list of breakpoints (including locations for the current @@ -221,14 +231,14 @@ def refresh_breakpoints(node: sch.Schema('BreakpointContainer')): commands.ghidra_trace_put_breakpoints() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Processes') def refresh_processes(node: sch.Schema('ProcessContainer')): """Refresh the list of processes.""" with commands.open_tracked_tx('Refresh Processes'): - commands.ghidra_trace_put_threads() + commands.ghidra_trace_put_processes() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Breakpoint Locations') def refresh_proc_breakpoints(node: sch.Schema('BreakpointLocationContainer')): """ Refresh the breakpoint locations for the process. @@ -240,21 +250,21 @@ def refresh_proc_breakpoints(node: sch.Schema('BreakpointLocationContainer')): commands.ghidra_trace_put_breakpoints() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Environment') def refresh_environment(node: sch.Schema('Environment')): """Refresh the environment descriptors (arch, os, endian).""" with commands.open_tracked_tx('Refresh Environment'): commands.ghidra_trace_put_environment() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Threads') def refresh_threads(node: sch.Schema('ThreadContainer')): """Refresh the list of threads in the process.""" with commands.open_tracked_tx('Refresh Threads'): commands.ghidra_trace_put_threads() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Stack') def refresh_stack(node: sch.Schema('Stack')): """Refresh the backtrace for the thread.""" tnum = find_thread_by_stack_obj(node) @@ -262,7 +272,7 @@ def refresh_stack(node: sch.Schema('Stack')): commands.ghidra_trace_put_frames() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Registers') def refresh_registers(node: sch.Schema('RegisterValueContainer')): """Refresh the register values for the frame.""" tnum = find_thread_by_regs_obj(node) @@ -270,14 +280,14 @@ def refresh_registers(node: sch.Schema('RegisterValueContainer')): commands.ghidra_trace_putreg() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Memory') def refresh_mappings(node: sch.Schema('Memory')): """Refresh the list of memory regions for the process.""" with commands.open_tracked_tx('Refresh Memory Regions'): commands.ghidra_trace_put_regions() -@REGISTRY.method(action='refresh') +@REGISTRY.method(action='refresh', display='Refresh Modules') def refresh_modules(node: sch.Schema('ModuleContainer')): """ Refresh the modules and sections list for the process. diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml index 48b0ea017f..4c1347ca1c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml @@ -1,5 +1,34 @@ - + + + + + + + + + + + + @@ -25,7 +54,7 @@ @@ -38,6 +67,19 @@ + + + + + @@ -50,7 +92,7 @@ @@ -76,7 +118,7 @@ @@ -134,12 +176,14 @@ - + + + @@ -184,7 +228,7 @@ @@ -235,7 +279,7 @@ @@ -251,8 +295,10 @@ - + + + @@ -282,6 +328,7 @@ @@ -315,6 +362,19 @@ + + + + + @@ -325,7 +385,7 @@ @@ -360,7 +420,6 @@ @@ -396,6 +455,9 @@ + + +