mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-16 07:30:16 +00:00
GP-4367: Package dbgmodel (ghidradbg) better
This commit is contained in:
parent
9934159e25
commit
5b16857468
@ -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 {
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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|
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
|
||||||
|
@ -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': [],
|
||||||
|
@ -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
|
||||||
|
@ -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__))
|
@ -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
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
@ -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
|
||||||
|
|
||||||
|
@ -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'])
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user