mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 13:11:47 +00:00
Merge remote-tracking branch
'origin/GP-4290_d-millar_traceRMI_dbgmodel--SQUASHED' Conflicts: Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/commands.py Ghidra/Debug/Debugger-agent-dbgeng/src/main/py/src/ghidradbg/schema.xml
This commit is contained in:
commit
9934159e25
@ -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'
|
||||
|
49
Ghidra/Debug/Debugger-agent-dbgeng/buildNatives.gradle
Normal file
49
Ghidra/Debug/Debugger-agent-dbgeng/buildNatives.gradle
Normal file
@ -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)
|
||||
}
|
||||
}
|
@ -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|
|
||||
|
@ -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
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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))
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -40,13 +40,16 @@ AVAILABLE_PATTERN = re.compile('Available\[(?P<pid>\\d*)\]')
|
||||
WATCHPOINT_PATTERN = re.compile('Watchpoints\[(?P<watchnum>\\d*)\]')
|
||||
BREAKPOINT_PATTERN = re.compile('Breakpoints\[(?P<breaknum>\\d*)\]')
|
||||
BREAK_LOC_PATTERN = extre(BREAKPOINT_PATTERN, '\[(?P<locnum>\\d*)\]')
|
||||
PROCESS_PATTERN = re.compile('Processes\[(?P<procnum>\\d*)\]')
|
||||
PROC_BREAKS_PATTERN = extre(PROCESS_PATTERN, '\.Breakpoints')
|
||||
SESSIONS_PATTERN = re.compile('Sessions')
|
||||
SESSION_PATTERN = extre(SESSIONS_PATTERN, '\[(?P<snum>\\d*)\]')
|
||||
PROCESSES_PATTERN = extre(SESSION_PATTERN, '\.Processes')
|
||||
PROCESS_PATTERN = extre(PROCESSES_PATTERN, '\[(?P<procnum>\\d*)\]')
|
||||
PROC_BREAKS_PATTERN = extre(PROCESS_PATTERN, '\.Debug.Breakpoints')
|
||||
PROC_BREAKBPT_PATTERN = extre(PROC_BREAKS_PATTERN, '\[(?P<breaknum>\\d*)\]')
|
||||
ENV_PATTERN = extre(PROCESS_PATTERN, '\.Environment')
|
||||
THREADS_PATTERN = extre(PROCESS_PATTERN, '\.Threads')
|
||||
THREAD_PATTERN = extre(THREADS_PATTERN, '\[(?P<tnum>\\d*)\]')
|
||||
STACK_PATTERN = extre(THREAD_PATTERN, '\.Stack')
|
||||
STACK_PATTERN = extre(THREAD_PATTERN, '\.Stack.Frames')
|
||||
FRAME_PATTERN = extre(STACK_PATTERN, '\[(?P<level>\\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.
|
||||
|
@ -1,5 +1,34 @@
|
||||
<context>
|
||||
<schema name="DbgengSession" elementResync="NEVER" attributeResync="NEVER">
|
||||
<schema name="Root" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Configurable" />
|
||||
<attribute name="Sessions" schema="SessionContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Settings" schema="ANY" />
|
||||
<attribute name="State" schema="ANY" />
|
||||
<attribute name="Utility" schema="ANY" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_short_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_base" schema="INT" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="SessionContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Configurable" />
|
||||
<element schema="Session" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_short_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_base" schema="INT" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Session" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Access" />
|
||||
<interface name="Attacher" />
|
||||
<interface name="Interpreter" />
|
||||
@ -25,7 +54,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Selectable" elementResync="NEVER" attributeResync="NEVER">
|
||||
<element schema="OBJECT" />
|
||||
@ -38,6 +67,19 @@
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="DebugBreakpointContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Aggregate" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_short_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="BreakpointContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="BreakpointLocationContainer" />
|
||||
<interface name="BreakpointSpecContainer" />
|
||||
@ -50,7 +92,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="AvailableContainer" canonical="yes" elementResync="ALWAYS" attributeResync="NEVER">
|
||||
<interface name="Configurable" />
|
||||
@ -76,7 +118,7 @@
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_base" schema="INT" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="BreakpointSpec" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="BreakpointSpec" />
|
||||
@ -134,12 +176,14 @@
|
||||
<interface name="Interruptible" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="Threads" schema="ThreadContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Breakpoints" schema="BreakpointContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Debug" schema="DebugBreakpointContainer" required="yes" fixed="yes" />
|
||||
<!-- attribute name="Breakpoints" schema="BreakpointLocationContainer" required="yes" fixed="yes" /-->
|
||||
<attribute name="_exit_code" schema="LONG" />
|
||||
<attribute name="Environment" schema="Environment" required="yes" fixed="yes" />
|
||||
<attribute name="Memory" schema="Memory" required="yes" fixed="yes" />
|
||||
<attribute name="Modules" schema="ModuleContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Handle" schema="STRING" fixed="yes" />
|
||||
<attribute name="Id" schema="STRING" fixed="yes" />
|
||||
<attribute name="_pid" schema="LONG" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_supported_attach_kinds" schema="SET_ATTACH_KIND" required="yes" hidden="yes" />
|
||||
@ -152,7 +196,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Environment" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Environment" />
|
||||
@ -184,7 +228,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Memory" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Memory" />
|
||||
@ -235,7 +279,7 @@
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="_base" schema="INT" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Method" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Method" />
|
||||
@ -251,8 +295,10 @@
|
||||
<interface name="Steppable" />
|
||||
<interface name="Aggregate" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="Stack" schema="Stack" required="yes" fixed="yes" />
|
||||
<attribute name="Stack" schema="StackFramesContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Registers" schema="RegisterValueContainer" required="yes" fixed="yes" />
|
||||
<attribute name="Environment" schema="ANY" fixed="yes" />
|
||||
<attribute name="Id" schema="STRING" fixed="yes" />
|
||||
<attribute name="_tid" schema="LONG" hidden="yes" />
|
||||
<attribute name="_state" schema="EXECUTION_STATE" required="yes" hidden="yes" />
|
||||
<attribute name="_supported_step_kinds" schema="SET_STEP_KIND" required="yes" fixed="yes" hidden="yes" />
|
||||
@ -264,7 +310,7 @@
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="Advance" schema="Method" required="yes" fixed="yes" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Module" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Module" />
|
||||
@ -282,6 +328,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute name="ToDisplayString" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="MemoryRegion" elementResync="NEVER" attributeResync="NEVER">
|
||||
@ -315,6 +362,19 @@
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="StackFramesContainer" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Aggregate" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="Frames" schema="Stack" required="yes" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
<attribute name="_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_short_display" schema="STRING" hidden="yes" />
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
</schema>
|
||||
<schema name="Stack" canonical="yes" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Stack" />
|
||||
<element schema="StackFrame" />
|
||||
@ -325,7 +385,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="SymbolContainer" canonical="yes" elementResync="ONCE" attributeResync="NEVER">
|
||||
<interface name="SymbolNamespace" />
|
||||
@ -360,7 +420,6 @@
|
||||
<interface name="Aggregate" />
|
||||
<element schema="VOID" />
|
||||
<attribute name="_function" schema="STRING" hidden="yes" />
|
||||
<attribute name="Registers" schema="RegisterValueContainer" required="yes" fixed="yes" />
|
||||
<attribute name="_pc" schema="ADDRESS" required="yes" hidden="yes" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
@ -369,7 +428,7 @@
|
||||
<attribute name="_kind" schema="STRING" fixed="yes" hidden="yes" />
|
||||
<attribute name="_order" schema="INT" hidden="yes" />
|
||||
<attribute name="_modified" schema="BOOL" hidden="yes" />
|
||||
<attribute schema="VOID" />
|
||||
<attribute schema="ANY" hidden="yes" />
|
||||
</schema>
|
||||
<schema name="Section" elementResync="NEVER" attributeResync="NEVER">
|
||||
<interface name="Section" />
|
||||
@ -396,6 +455,9 @@
|
||||
<attribute name="Floating Point Registers" schema="RegisterBank" />
|
||||
<attribute name="Advanced Vector Extensions" schema="RegisterBank" />
|
||||
<attribute name="Memory Protection Extensions" schema="RegisterBank" />
|
||||
<attribute name="FloatingPoint" schema="RegisterBank" />
|
||||
<attribute name="SIMD" schema="RegisterBank" />
|
||||
<attribute name="User" schema="RegisterBank" />
|
||||
<attribute name="_descriptions" schema="RegisterValueContainer" />
|
||||
<attribute name="_value" schema="ANY" hidden="yes" />
|
||||
<attribute name="_type" schema="STRING" hidden="yes" />
|
||||
|
@ -29,12 +29,21 @@ import traceback
|
||||
from comtypes import CoClass, GUID
|
||||
import comtypes
|
||||
from comtypes.hresult import S_OK
|
||||
|
||||
from pybag import pydbg, userdbg, kerneldbg, crashdbg
|
||||
from pybag.dbgeng import core as DbgEng
|
||||
from pybag.dbgeng import exception
|
||||
from pybag.dbgeng import util as DbgUtil
|
||||
from pybag.dbgeng.callbacks import DbgEngCallbacks
|
||||
|
||||
from 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'])
|
||||
|
||||
@ -134,12 +143,12 @@ class DbgExecutor(object):
|
||||
self._thread.start()
|
||||
self._executing = False
|
||||
|
||||
def submit(self, fn, / , *args, **kwargs):
|
||||
def submit(self, fn, /, *args, **kwargs):
|
||||
f = self._submit_no_exit(fn, *args, **kwargs)
|
||||
self._ghidra_dbg.exit_dispatch()
|
||||
return f
|
||||
|
||||
def _submit_no_exit(self, fn, / , *args, **kwargs):
|
||||
def _submit_no_exit(self, fn, /, *args, **kwargs):
|
||||
f = Future()
|
||||
if self._executing:
|
||||
f.set_exception(DebuggeeRunningException("Debuggee is Running"))
|
||||
@ -199,6 +208,7 @@ class GhidraDbg(object):
|
||||
# Wait for the executor to be operational before getting base
|
||||
self._queue._submit_no_exit(lambda: None).result()
|
||||
self._install_stdin()
|
||||
self.use_generics = os.getenv('OPT_USE_DBGMODEL') == "true"
|
||||
|
||||
base = self._protected_base
|
||||
for name in ['set_output_mask', 'get_output_mask',
|
||||
@ -447,6 +457,8 @@ def get_breakpoints():
|
||||
@dbg.eng_thread
|
||||
def selected_process():
|
||||
try:
|
||||
if dbg.use_generics:
|
||||
return dbg._base._systems.GetCurrentProcessSystemId()
|
||||
return dbg._base._systems.GetCurrentProcessId()
|
||||
except exception.E_UNEXPECTED_Error:
|
||||
return None
|
||||
@ -455,6 +467,8 @@ def selected_process():
|
||||
@dbg.eng_thread
|
||||
def selected_thread():
|
||||
try:
|
||||
if dbg.use_generics:
|
||||
return dbg._base._systems.GetCurrentThreadSystemId()
|
||||
return dbg._base._systems.GetCurrentThreadId()
|
||||
except exception.E_UNEXPECTED_Error:
|
||||
return None
|
||||
@ -476,11 +490,15 @@ def selected_frame():
|
||||
|
||||
@dbg.eng_thread
|
||||
def select_process(id: int):
|
||||
if dbg.use_generics:
|
||||
id = get_proc_id(id)
|
||||
return dbg._base._systems.SetCurrentProcessId(id)
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def select_thread(id: int):
|
||||
if dbg.use_generics:
|
||||
id = get_thread_id(id)
|
||||
return dbg._base._systems.SetCurrentThreadId(id)
|
||||
|
||||
|
||||
@ -640,6 +658,101 @@ def thread_list(running=False):
|
||||
_dbg._systems.SetCurrentThreadId(curid)
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_proc_id(pid):
|
||||
"""Get the list of all processes"""
|
||||
# TODO: Implement GetProcessIdBySystemId and replace this logic
|
||||
_dbg = dbg._base
|
||||
map = {}
|
||||
try:
|
||||
x = _dbg._systems.GetProcessIdsByIndex()
|
||||
for i in range(0, len(x[0])):
|
||||
map[x[1][i]] = x[0][i]
|
||||
return map[pid]
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_thread_id(tid):
|
||||
"""Get the list of all threads"""
|
||||
# TODO: Implement GetThreadIdBySystemId and replace this logic
|
||||
_dbg = dbg._base
|
||||
map = {}
|
||||
try:
|
||||
x = _dbg._systems.GetThreadIdsByIndex()
|
||||
for i in range(0, len(x[0])):
|
||||
map[x[1][i]] = x[0][i]
|
||||
return map[tid]
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def split_path(pathString):
|
||||
list = []
|
||||
segs = pathString.split(".")
|
||||
for s in segs:
|
||||
if s.endswith("]"):
|
||||
index = s.index("[")
|
||||
list.append(s[:index])
|
||||
list.append(s[index:])
|
||||
else:
|
||||
list.append(s)
|
||||
return list
|
||||
|
||||
|
||||
def IHostDataModelAccess():
|
||||
return HostDataModelAccess(
|
||||
dbg._base._client._cli.QueryInterface(interface=DbgMod.IHostDataModelAccess))
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_object(relpath):
|
||||
"""Get the list of all threads"""
|
||||
_cli = dbg._base._client._cli
|
||||
access = HostDataModelAccess(_cli.QueryInterface(
|
||||
interface=DbgMod.IHostDataModelAccess))
|
||||
(mgr, host) = access.GetDataModel()
|
||||
root = mgr.GetRootNamespace()
|
||||
pathstr = "Debugger"
|
||||
if relpath != '':
|
||||
pathstr += "."+relpath
|
||||
path = split_path(pathstr)
|
||||
return root.GetOffspring(path)
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_attributes(obj):
|
||||
"""Get the list of attributes"""
|
||||
return obj.GetAttributes()
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_elements(obj):
|
||||
"""Get the list of all threads"""
|
||||
return obj.GetElements()
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_kind(obj):
|
||||
"""Get the list of all threads"""
|
||||
return obj.GetKind().value
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_type(obj):
|
||||
"""Get the list of all threads"""
|
||||
return obj.GetTypeKind()
|
||||
|
||||
|
||||
@dbg.eng_thread
|
||||
def get_value(obj):
|
||||
"""Get the list of all threads"""
|
||||
return obj.GetValue()
|
||||
|
||||
|
||||
conv_map = {}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user