GP-4367: Package dbgmodel (ghidradbg) better

This commit is contained in:
Dan 2024-02-28 14:15:33 -05:00
parent 9934159e25
commit 5b16857468
21 changed files with 269 additions and 219 deletions

View File

@ -21,7 +21,6 @@ apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
apply from: "$rootProject.projectDir/gradle/debugger/hasNodepJar.gradle" apply from: "$rootProject.projectDir/gradle/debugger/hasNodepJar.gradle"
apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle" apply from: "$rootProject.projectDir/gradle/debugger/hasPythonPackage.gradle"
apply from: "buildNatives.gradle"
apply plugin: 'eclipse' apply plugin: 'eclipse'
eclipse.project.name = 'Debug Debugger-agent-dbgeng' eclipse.project.name = 'Debug Debugger-agent-dbgeng'
@ -37,12 +36,45 @@ dependencies {
testImplementation project(path: ":Debugger-gadp", configuration: 'testArtifacts') testImplementation project(path: ":Debugger-gadp", configuration: 'testArtifacts')
} }
// Include buildable native source in distribution if ("win_x86_64".equals(getCurrentPlatformName())) {
rootProject.assembleDistribution {
from (this.project.projectDir.toString()) { String makeName = "win_x86_64DbgmodelTlbMake"
include "src/**" task(type: Exec, makeName) {
into { getZipPath(this.project) } ext.tmpBatch = file("build/buildTlb.bat")
} ext.idl = file("src/main/py/src/ghidradbg/dbgmodel/DbgModel.idl")
ext.tlb = file("build/os/win_x86_64/dbgmodel.tlb")
inputs.file(idl)
outputs.file(tlb)
doFirst {
file(tlb).parentFile.mkdirs()
def midlCmd = "midl /tlb ${tlb} ${idl}"
println "Executing: " + midlCmd
tmpBatch.withWriter { out ->
out.println "call " + VISUAL_STUDIO_VCVARS_CMD
out.println midlCmd
}
}
doLast {
assert file(tlb).exists() : "Failed to build dbgmodel.tlb"
}
commandLine "cmd", "/c", tmpBatch
}
tasks.assemblePyPackage {
from(tasks."$makeName") {
into("src/ghidradbg/dbgmodel/tlb")
}
}
}
else {
tasks.assemblePyPackage {
from(rootProject.BIN_REPO + '/' + getGhidraRelativePath(project) + "/os/win_x86_64/dbgmodel.tlb") {
into("src/ghidradbg/dbgmodel/tlb")
}
}
} }
tasks.nodepJar { tasks.nodepJar {

View File

@ -1,49 +0,0 @@
/* ###
* 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)
}
}

View File

@ -5,5 +5,5 @@ data/debugger-launchers/local-dbgeng.bat||GHIDRA||||END|
src/main/py/LICENSE||GHIDRA||||END| src/main/py/LICENSE||GHIDRA||||END|
src/main/py/README.md||GHIDRA||||END| src/main/py/README.md||GHIDRA||||END|
src/main/py/pyproject.toml||GHIDRA||||END| src/main/py/pyproject.toml||GHIDRA||||END|
src/main/py/src/dbgmodel/DbgModel.idl||GHIDRA||||END| src/main/py/src/ghidradbg/dbgmodel/DbgModel.idl||GHIDRA||||END|
src/main/py/src/ghidradbg/schema.xml||GHIDRA||||END| src/main/py/src/ghidradbg/schema.xml||GHIDRA||||END|

View File

@ -18,7 +18,7 @@ classifiers = [
] ]
dependencies = [ dependencies = [
"ghidratrace==10.4", "ghidratrace==10.4",
"pybag>=2.2.8" "pybag>=2.2.9"
] ]
[project.urls] [project.urls]

View File

@ -13,45 +13,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from . import util, commands, methods, hooks
from dbgmodel.ihostdatamodelaccess import HostDataModelAccess
import ctypes
import platform
import os
# NOTE: libraries must precede EVERYTHING, esp pybag and DbgMod
ctypes.windll.kernel32.SetErrorMode(0x0001 | 0x0002 | 0x8000) from . import libraries, util, commands, methods, hooks
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

View File

@ -14,11 +14,11 @@
# limitations under the License. # limitations under the License.
## ##
from ghidratrace.client import Address, RegVal from ghidratrace.client import Address, RegVal
from pybag import pydbg from pybag import pydbg
from . import util from . import util
language_map = { language_map = {
'ARM': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:AppleSilicon', 'AARCH64:LE:64:v8A', 'ARM:BE:64:v8', 'ARM:LE:64:v8'], 'ARM': ['AARCH64:BE:64:v8A', 'AARCH64:LE:64:AppleSilicon', 'AARCH64:LE:64:v8A', 'ARM:BE:64:v8', 'ARM:LE:64:v8'],
'Itanium': [], 'Itanium': [],

View File

@ -22,15 +22,14 @@ import socket
import sys import sys
import time import time
from ghidratrace import sch
from ghidratrace.client import Client, Address, AddressRange, TraceObject
from pybag import pydbg, userdbg, kerneldbg from pybag import pydbg, userdbg, kerneldbg
from pybag.dbgeng import core as DbgEng from pybag.dbgeng import core as DbgEng
from pybag.dbgeng import exception from pybag.dbgeng import exception
from dbgmodel.imodelobject import ModelObjectKind
from ghidratrace import sch
from ghidratrace.client import Client, Address, AddressRange, TraceObject
from . import util, arch, methods, hooks from . import util, arch, methods, hooks
from .dbgmodel.imodelobject import ModelObjectKind
PAGE_SIZE = 4096 PAGE_SIZE = 4096

View File

@ -0,0 +1,20 @@
## ###
# 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.
##
import os
def module_locator():
return os.path.dirname(os.path.realpath(__file__))

View File

@ -13,12 +13,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes.hresult import S_OK, S_FALSE
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
import dbgmodel.imodelobject as mo
from . import imodelobject as mo
class DataModelManager(object): class DataModelManager(object):
def __init__(self, mgr): def __init__(self, mgr):
@ -41,43 +43,43 @@ class DataModelManager(object):
def AcquireNamedModel(self, modelName, modelObject): def AcquireNamedModel(self, modelName, modelObject):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def Close(self): def Close(self):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateNoValue(self, object): def CreateNoValue(self, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateErrorObject(self, error, message, object): def CreateErrorObject(self, error, message, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateTypedObject(self, context, objectLocation, objectType, object): def CreateTypedObject(self, context, objectLocation, objectType, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateTypedObjectByReference(self, context, objectLocation, objectType, object): def CreateTypedObjectByReference(self, context, objectLocation, objectType, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateSyntheticObject(self, context, object): def CreateSyntheticObject(self, context, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateDataModelObject(self, dataModel, object): def CreateDataModelObject(self, dataModel, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateTypedIntrinsicObject(self, intrinsicData, type, object): def CreateTypedIntrinsicObject(self, intrinsicData, type, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def CreateIntrinsicObject(self, objectKind, intrinsicData, object): def CreateIntrinsicObject(self, objectKind, intrinsicData, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetModelForTypeSignature(self, typeSignature, dataModel): def GetModelForTypeSignature(self, typeSignature, dataModel):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetModelForType(self, type, dataModel, typeSignature, wildcardMatches): def GetModelForType(self, type, dataModel, typeSignature, wildcardMatches):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def RegisterExtensionForTypeSignature(self, typeSignature, dataModel): def RegisterExtensionForTypeSignature(self, typeSignature, dataModel):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def RegisterModelForTypeSignature(self, typeSignature, dataModel): def RegisterModelForTypeSignature(self, typeSignature, dataModel):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
@ -92,5 +94,3 @@ class DataModelManager(object):
def UnregisterNamedModel(self, modelName): def UnregisterNamedModel(self, modelName):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error

View File

@ -13,13 +13,14 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes.hresult import S_OK, S_FALSE
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
from pybag.dbgeng import win32 from pybag.dbgeng import win32
class DebugHost(object): class DebugHost(object):
def __init__(self, host): def __init__(self, host):
self._host = host self._host = host
@ -38,11 +39,6 @@ class DebugHost(object):
def GetDefaultMetadata(self, metadata): def GetDefaultMetadata(self, metadata):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetHostDefinedInterface(self, hostUnk): def GetHostDefinedInterface(self, hostUnk):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error

View File

@ -13,14 +13,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes.hresult import S_OK, S_FALSE
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
from .idatamodelmanager import DataModelManager from .idatamodelmanager import DataModelManager
from .idebughost import DebugHost from .idebughost import DebugHost
class HostDataModelAccess(object): class HostDataModelAccess(object):
def __init__(self, hdma): def __init__(self, hdma):
@ -41,6 +42,3 @@ class HostDataModelAccess(object):
hr = self._hdma.GetDataModel(byref(manager), byref(host)) hr = self._hdma.GetDataModel(byref(manager), byref(host))
exception.check_err(hr) exception.check_err(hr)
return (DataModelManager(manager), DebugHost(host)) return (DataModelManager(manager), DebugHost(host))

View File

@ -13,20 +13,21 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes import COMError
from comtypes.hresult import S_OK, S_FALSE
from comtypes import COMError
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
from .imodeliterator import ModelIterator from .imodeliterator import ModelIterator
class IterableConcept(object): class IterableConcept(object):
def __init__(self, concept): def __init__(self, concept):
self._concept = concept self._concept = concept
concept.AddRef() concept.AddRef()
# IterableConcept # IterableConcept
def GetDefaultIndexDimensionality(self, context, dimensionality): def GetDefaultIndexDimensionality(self, context, dimensionality):
@ -39,6 +40,3 @@ class IterableConcept(object):
except COMError as ce: except COMError as ce:
return None return None
return ModelIterator(iterator) return ModelIterator(iterator)

View File

@ -13,13 +13,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes import BSTR
from comtypes.hresult import S_OK, S_FALSE
from comtypes import BSTR
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
import dbgmodel.imodelobject as mo
from . import imodelobject as mo
class KeyEnumerator(object): class KeyEnumerator(object):
def __init__(self, keys): def __init__(self, keys):
@ -46,6 +48,3 @@ class KeyEnumerator(object):
def Reset(self): def Reset(self):
hr = self._keys.Reset() hr = self._keys.Reset()
exception.check_err(hr) exception.check_err(hr)

View File

@ -13,13 +13,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes import COMError
from comtypes.hresult import S_OK, S_FALSE
from comtypes import COMError
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
import dbgmodel.imodelobject as mo
from . import imodelobject as mo
class ModelIterator(object): class ModelIterator(object):
def __init__(self, iter): def __init__(self, iter):
@ -33,7 +35,8 @@ class ModelIterator(object):
indexer = POINTER(DbgMod.IModelObject)() indexer = POINTER(DbgMod.IModelObject)()
metadata = POINTER(DbgMod.IKeyStore)() metadata = POINTER(DbgMod.IKeyStore)()
try: try:
self._iter.GetNext(byref(object), dimensions, byref(indexer), byref(metadata)) self._iter.GetNext(byref(object), dimensions,
byref(indexer), byref(metadata))
except COMError as ce: except COMError as ce:
return None return None
index = mo.ModelObject(indexer) index = mo.ModelObject(indexer)
@ -43,6 +46,3 @@ class ModelIterator(object):
def Reset(self): def Reset(self):
hr = self._keys.Reset() hr = self._keys.Reset()
exception.check_err(hr) exception.check_err(hr)

View File

@ -13,18 +13,20 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes import IUnknown, COMError from enum import Enum
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 import IUnknown, COMError
from comtypes.automation import IID, VARIANT
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
from .ikeyenumerator import KeyEnumerator from comtypes.gen.DbgMod import *
from .iiterableconcept import IterableConcept from .iiterableconcept import IterableConcept
from .ikeyenumerator import KeyEnumerator
class ModelObjectKind(Enum): class ModelObjectKind(Enum):
PROPERTY_ACCESSOR = 0 PROPERTY_ACCESSOR = 0
@ -38,6 +40,7 @@ class ModelObjectKind(Enum):
METHOD = 8 METHOD = 8
KEY_REFERENCE = 9 KEY_REFERENCE = 9
class ModelObject(object): class ModelObject(object):
def __init__(self, obj): def __init__(self, obj):
self._obj = obj self._obj = obj
@ -56,42 +59,42 @@ class ModelObject(object):
def AddParentModel(self, model, contextObject, override): def AddParentModel(self, model, contextObject, override):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def ClearConcepts(self): def ClearConcepts(self):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def ClearKeys(self): def ClearKeys(self):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def Compare(self, other, equal): def Compare(self, other, equal):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def Dereference(self, object): def Dereference(self, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def EnumerateKeyReferences(self): def EnumerateKeyReferences(self):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def EnumerateKeys(self): def EnumerateKeys(self):
keys = POINTER(DbgMod.IKeyEnumerator)() keys = POINTER(DbgMod.IKeyEnumerator)()
hr = self._obj.EnumerateKeys(byref(keys)) hr = self._obj.EnumerateKeys(byref(keys))
if hr != S_OK: if hr != S_OK:
return None return None
return KeyEnumerator(keys) return KeyEnumerator(keys)
def EnumerateKeyValues(self): def EnumerateKeyValues(self):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def EnumerateRawReferences(self, kind, searchFlags): def EnumerateRawReferences(self, kind, searchFlags):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def EnumerateRawValues(self, kind, searchFlag): def EnumerateRawValues(self, kind, searchFlag):
keys = POINTER(DbgMod.IRawEnumerator)() keys = POINTER(DbgMod.IRawEnumerator)()
hr = self._obj.EnumerateRawValues(kind, searchFlag, byref(keys)) hr = self._obj.EnumerateRawValues(kind, searchFlag, byref(keys))
if hr != S_OK: if hr != S_OK:
return None return None
return RawEnumerator(keys, kind) return RawEnumerator(keys, kind)
def GetConcept(self, ref): def GetConcept(self, ref):
ifc = POINTER(IUnknown)() ifc = POINTER(IUnknown)()
metadata = POINTER(DbgMod.IKeyStore)() metadata = POINTER(DbgMod.IKeyStore)()
@ -102,10 +105,10 @@ class ModelObject(object):
def GetContext(self, context): def GetContext(self, context):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetContextForDataModel(self, dataModelObject, context): def GetContextForDataModel(self, dataModelObject, context):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetIntrinsicValue(self): def GetIntrinsicValue(self):
var = VARIANT() var = VARIANT()
hr = self._obj.GetIntrinsicValue(var) hr = self._obj.GetIntrinsicValue(var)
@ -123,7 +126,7 @@ class ModelObject(object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetKeyValue(self, key): def GetKeyValue(self, key):
kbuf = cast(c_wchar_p(key),POINTER(c_ushort)) kbuf = cast(c_wchar_p(key), POINTER(c_ushort))
value = POINTER(DbgMod.IModelObject)() value = POINTER(DbgMod.IModelObject)()
store = POINTER(DbgMod.IKeyStore)() store = POINTER(DbgMod.IKeyStore)()
hr = self._obj.GetKeyValue(kbuf, byref(value), byref(store)) hr = self._obj.GetKeyValue(kbuf, byref(value), byref(store))
@ -142,16 +145,16 @@ class ModelObject(object):
def GetNumberOfParentModels(self, numModels): def GetNumberOfParentModels(self, numModels):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetParentModel(self, i, model, context): def GetParentModel(self, i, model, context):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetRawReference(self, kind, name, searchFlags, object): def GetRawReference(self, kind, name, searchFlags, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetRawValue(self, kind, name, searchFlags, object): def GetRawValue(self, kind, name, searchFlags, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def GetTargetInfo(self): def GetTargetInfo(self):
location = POINTER(DbgMod._Location)() location = POINTER(DbgMod._Location)()
type = POINTER(DbgMod.IDebugHostType)() type = POINTER(DbgMod.IDebugHostType)()
@ -161,47 +164,47 @@ class ModelObject(object):
def GetTypeInfo(self, type): def GetTypeInfo(self, type):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def IsEqualTo(self, other, equal): def IsEqualTo(self, other, equal):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def RemoveParentModel(self, model): def RemoveParentModel(self, model):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def SetConcept(self, ref, interface, metadata): def SetConcept(self, ref, interface, metadata):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def SetContextForDataModel(self, modelObject, context): def SetContextForDataModel(self, modelObject, context):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def SetKey(self, key, object, metadata): def SetKey(self, key, object, metadata):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def SetKeyValue(self, key, object): def SetKeyValue(self, key, object):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
def TryCastToRuntimeType(self, runtimeTypedObject): def TryCastToRuntimeType(self, runtimeTypedObject):
raise exception.E_NOTIMPL_Error raise exception.E_NOTIMPL_Error
# Auxiliary # Auxiliary
def GetKeyValueMap(self): def GetKeyValueMap(self):
map = {} map = {}
keys = self.EnumerateKeys() keys = self.EnumerateKeys()
(k,v) = keys.GetNext() (k, v) = keys.GetNext()
while k is not None: while k is not None:
map[k.value] = self.GetKeyValue(k.value) map[k.value] = self.GetKeyValue(k.value)
(k,v) = keys.GetNext() (k, v) = keys.GetNext()
return map return map
def GetRawValueMap(self): def GetRawValueMap(self):
map = {} map = {}
kind = self.GetKind() kind = self.GetKind()
keys = self.EnumerateRawValues(kind, c_long(0)) keys = self.EnumerateRawValues(kind, c_long(0))
(k,v) = keys.GetNext() (k, v) = keys.GetNext()
while k is not None: while k is not None:
map[k.value] = v map[k.value] = v
(k,v) = keys.GetNext() (k, v) = keys.GetNext()
return map return map
def GetAttributes(self): def GetAttributes(self):
@ -210,12 +213,11 @@ class ModelObject(object):
if kind == ModelObjectKind.ERROR: if kind == ModelObjectKind.ERROR:
return map return map
if kind == ModelObjectKind.INTRINSIC or \ if kind == ModelObjectKind.INTRINSIC or \
kind == ModelObjectKind.TARGET_OBJECT or \ kind == ModelObjectKind.TARGET_OBJECT or \
kind == ModelObjectKind.TARGET_OBJECT_REFERENCE: kind == ModelObjectKind.TARGET_OBJECT_REFERENCE:
return self.GetRawValueMap() return self.GetRawValueMap()
return self.GetKeyValueMap() return self.GetKeyValueMap()
def GetElements(self): def GetElements(self):
list = [] list = []
if self.concept is None: if self.concept is None:
@ -248,7 +250,7 @@ class ModelObject(object):
if "x" not in idx: if "x" not in idx:
idx = int(idx) idx = int(idx)
else: else:
idx = int(idx,16) idx = int(idx, 16)
next = next.GetElement(idx) next = next.GetElement(idx)
else: else:
next = next.GetKeyValue(element) next = next.GetKeyValue(element)
@ -268,6 +270,5 @@ class ModelObject(object):
kind = self.GetKind() kind = self.GetKind()
if kind == ModelObjectKind.TARGET_OBJECT or \ if kind == ModelObjectKind.TARGET_OBJECT or \
kind == ModelObjectKind.INTRINSIC: kind == ModelObjectKind.INTRINSIC:
return self.GetTargetInfo() return self.GetTargetInfo()
return None return None

View File

@ -13,13 +13,15 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
## ##
from ctypes import * from ctypes import *
from comtypes import BSTR
from comtypes.hresult import S_OK, S_FALSE
from comtypes import BSTR
from comtypes.gen import DbgMod from comtypes.gen import DbgMod
from comtypes.hresult import S_OK, S_FALSE
from pybag.dbgeng import exception from pybag.dbgeng import exception
import dbgmodel.imodelobject as mo
from . import imodelobject as mo
class RawEnumerator(object): class RawEnumerator(object):
def __init__(self, keys, kind): def __init__(self, keys, kind):
@ -46,6 +48,3 @@ class RawEnumerator(object):
def Reset(self): def Reset(self):
hr = self._keys.Reset() hr = self._keys.Reset()
exception.check_err(hr) exception.check_err(hr)

View File

@ -0,0 +1,69 @@
## ###
# 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.
##
import ctypes
import os
import platform
import comtypes
import comtypes.client
from ghidradbg import dbgmodel
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 _dir is not None and os.path.exists(_dir):
dbgdir = _dir
break
if not dbgdir:
raise RuntimeError("Windbg install directory not found!")
print(f"Loading dbgeng and friends from {dbgdir}")
# 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
try:
from comtypes.gen import DbgMod
except:
tlb = os.path.join(dbgmodel.module_locator(), 'tlb', 'dbgmodel.tlb')
print(f"Loading TLB: {tlb}")
comtypes.client.GetModule(tlb)
from comtypes.gen import DbgMod

View File

@ -19,11 +19,10 @@ from io import StringIO
import re import re
import sys import sys
from pybag import pydbg
from pybag.dbgeng import core as DbgEng, exception
from ghidratrace import sch from ghidratrace import sch
from ghidratrace.client import MethodRegistry, ParamDesc, Address, AddressRange from ghidratrace.client import MethodRegistry, ParamDesc, Address, AddressRange
from pybag import pydbg
from pybag.dbgeng import core as DbgEng, exception
from . import util, commands from . import util, commands

View File

@ -28,22 +28,16 @@ import traceback
from comtypes import CoClass, GUID from comtypes import CoClass, GUID
import comtypes import comtypes
from comtypes.gen import DbgMod
from comtypes.hresult import S_OK from comtypes.hresult import S_OK
from pybag import pydbg, userdbg, kerneldbg, crashdbg from pybag import pydbg, userdbg, kerneldbg, crashdbg
from pybag.dbgeng import core as DbgEng from pybag.dbgeng import core as DbgEng
from pybag.dbgeng import exception from pybag.dbgeng import exception
from pybag.dbgeng import util as DbgUtil from pybag.dbgeng import util as DbgUtil
from pybag.dbgeng.callbacks import DbgEngCallbacks from pybag.dbgeng.callbacks import DbgEngCallbacks
from dbgmodel.ihostdatamodelaccess import HostDataModelAccess from ghidradbg.dbgmodel.ihostdatamodelaccess import HostDataModelAccess
import comtypes.client
try:
from comtypes.gen import DbgMod
except:
tlb = "..\..\..\..\build\os\win_x86_64\dbgmodel.tlb"
comtypes.client.GetModule(tlb)
from comtypes.gen import DbgMod
DbgVersion = namedtuple('DbgVersion', ['full', 'name', 'dotted', 'arch']) DbgVersion = namedtuple('DbgVersion', ['full', 'name', 'dotted', 'arch'])

View File

@ -14,6 +14,39 @@
* limitations under the License. * limitations under the License.
*/ */
def checkPythonVersion(String pyCmd) {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine pyCmd, "-c", "import sys; print('{0}.{1}'.format(*sys.version_info))"
standardOutput = stdout
}
def version = "$stdout".strip()
println "$pyCmd is version $version"
return version
}
catch (Exception e) {
println "Could not run $pyCmd: $e"
return "ABSENT"
}
}
ext.SUPPORTED_PY_VERSIONS = ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
def findPython3() {
for (pyCmd in ['python3', 'python']) {
if (checkPythonVersion(pyCmd) in SUPPORTED_PY_VERSIONS) {
println "Using $pyCmd"
return pyCmd
}
}
println "Could not find compatible Python 3"
// Don't fail until task execution. Just let "python3" fail.
return 'python3'
}
ext.PYTHON3 = findPython3()
task assemblePyPackage(type: Copy) { task assemblePyPackage(type: Copy) {
from "src/main/py" from "src/main/py"
into "build/pypkg/" into "build/pypkg/"
@ -27,7 +60,7 @@ task buildPyPackage(type: Exec) {
outputs.dir(dist) outputs.dir(dist)
workingDir { "build/pypkg" } workingDir { "build/pypkg" }
commandLine "python3", "-m", "build" commandLine PYTHON3, "-m", "build"
} }
// At the moment, any module with a python package also distributes it. // At the moment, any module with a python package also distributes it.