From 105fb2549bd8fc0e19907fefff1168322dee3bb3 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 26 Feb 2018 22:37:19 -0500 Subject: Architecture plugins no longer need to override the perform_* methods (you can now override get_instruction_info, not perform_get_instruction_info). The perform_* methods are now deprecated but will still function as expected. Added architecture hooks to Python API using this new style. --- python/platform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'python/platform.py') diff --git a/python/platform.py b/python/platform.py index 5e63d836..09670bac 100644 --- a/python/platform.py +++ b/python/platform.py @@ -105,7 +105,7 @@ class Platform(object): else: self.handle = handle self.__dict__["name"] = core.BNGetPlatformName(self.handle) - self.arch = architecture.Architecture(core.BNGetPlatformArchitecture(self.handle)) + self.arch = architecture.CoreArchitecture(core.BNGetPlatformArchitecture(self.handle)) def __del__(self): core.BNFreePlatform(self.handle) -- cgit v1.3.1 From 5f07bf18df013860c9d9870a4ad0fba78379b0f1 Mon Sep 17 00:00:00 2001 From: Ryan Snyder Date: Tue, 20 Mar 2018 09:53:59 -0400 Subject: Cache all created CoreArchitecture objects --- python/architecture.py | 18 +++++++++++++----- python/basicblock.py | 2 +- python/binaryview.py | 6 +++--- python/callingconvention.py | 2 +- python/function.py | 8 ++++---- python/platform.py | 2 +- 6 files changed, 23 insertions(+), 15 deletions(-) (limited to 'python/platform.py') diff --git a/python/architecture.py b/python/architecture.py index 781edcfd..c5f87ec6 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -44,7 +44,7 @@ class _ArchitectureMetaClass(type): archs = core.BNGetArchitectureList(count) result = [] for i in xrange(0, count.value): - result.append(CoreArchitecture(archs[i])) + result.append(CoreArchitecture._from_cache(archs[i])) core.BNFreeArchitectureList(archs) return result @@ -54,7 +54,7 @@ class _ArchitectureMetaClass(type): archs = core.BNGetArchitectureList(count) try: for i in xrange(0, count.value): - yield CoreArchitecture(archs[i]) + yield CoreArchitecture._from_cache(archs[i]) finally: core.BNFreeArchitectureList(archs) @@ -63,7 +63,7 @@ class _ArchitectureMetaClass(type): arch = core.BNGetArchitectureByName(name) if arch is None: raise KeyError("'%s' is not a valid architecture" % str(name)) - return CoreArchitecture(arch) + return CoreArchitecture._from_cache(arch) def register(cls): startup._init_plugins() @@ -2037,6 +2037,7 @@ class Architecture(object): core.BNRegisterCallingConvention(self.handle, cc.handle) +_architecture_cache = {} class CoreArchitecture(Architecture): def __init__(self, handle): super(CoreArchitecture, self).__init__() @@ -2256,12 +2257,19 @@ class CoreArchitecture(Architecture): self._intrinsics[name] = intrinsics[i] self._intrinsics_by_index[intrinsics[i]] = (name, self.intrinsics[name]) core.BNFreeRegisterList(intrinsics) + global _architecture_cache + _architecture_cache[ctypes.addressof(handle.contents)] = self + + @classmethod + def _from_cache(cls, handle): + global _architecture_cache + return _architecture_cache.get(ctypes.addressof(handle.contents)) or cls(handle) def get_associated_arch_by_address(self, addr): new_addr = ctypes.c_ulonglong() new_addr.value = addr result = core.BNGetAssociatedArchitectureByAddress(self.handle, new_addr) - return CoreArchitecture(handle = result), new_addr.value + return CoreArchitecture._from_cache(handle = result), new_addr.value def get_instruction_info(self, data, addr): """ @@ -2289,7 +2297,7 @@ class CoreArchitecture(Architecture): for i in xrange(0, info.branchCount): target = info.branchTarget[i] if info.branchArch[i]: - arch = CoreArchitecture(info.branchArch[i]) + arch = CoreArchitecture._from_cache(info.branchArch[i]) else: arch = None result.add_branch(BranchType(info.branchType[i]), target, arch) diff --git a/python/basicblock.py b/python/basicblock.py index c93d0b2c..1d932c5e 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -100,7 +100,7 @@ class BasicBlock(object): arch = core.BNGetBasicBlockArchitecture(self.handle) if arch is None: return None - self._arch = architecture.CoreArchitecture(arch) + self._arch = architecture.CoreArchitecture._from_cache(arch) return self._arch @property diff --git a/python/binaryview.py b/python/binaryview.py index 3af0ee50..0cf25e70 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -411,7 +411,7 @@ class BinaryViewType(object): arch = core.BNGetArchitectureForViewType(self.handle, ident, endian) if arch is None: return None - return architecture.CoreArchitecture(arch) + return architecture.CoreArchitecture._from_cache(arch) def register_platform(self, ident, arch, plat): core.BNRegisterPlatformForViewType(self.handle, ident, arch.handle, plat.handle) @@ -823,7 +823,7 @@ class BinaryView(object): arch = core.BNGetDefaultArchitecture(self.handle) if arch is None: return None - return architecture.CoreArchitecture(handle=arch) + return architecture.CoreArchitecture._from_cache(handle=arch) @arch.setter def arch(self, value): @@ -2211,7 +2211,7 @@ class BinaryView(object): else: func = None if refs[i].arch: - arch = architecture.CoreArchitecture(refs[i].arch) + arch = architecture.CoreArchitecture._from_cache(refs[i].arch) else: arch = None addr = refs[i].addr diff --git a/python/callingconvention.py b/python/callingconvention.py index 49ef7666..e3ec7261 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -75,7 +75,7 @@ class CallingConvention(object): self.__class__._registered_calling_conventions.append(self) else: self.handle = handle - self.arch = architecture.CoreArchitecture(core.BNGetCallingConventionArchitecture(self.handle)) + self.arch = architecture.CoreArchitecture._from_cache(core.BNGetCallingConventionArchitecture(self.handle)) self.__dict__["name"] = core.BNGetCallingConventionName(self.handle) self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(self.handle) self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(self.handle) diff --git a/python/function.py b/python/function.py index 0d796d98..8c4b7765 100644 --- a/python/function.py +++ b/python/function.py @@ -420,7 +420,7 @@ class Function(object): arch = core.BNGetFunctionArchitecture(self.handle) if arch is None: return None - self._arch = architecture.CoreArchitecture(arch) + self._arch = architecture.CoreArchitecture._from_cache(arch) return self._arch @property @@ -558,7 +558,7 @@ class Function(object): branches = core.BNGetIndirectBranches(self.handle, count) result = [] for i in xrange(0, count.value): - result.append(IndirectBranchInfo(architecture.CoreArchitecture(branches[i].sourceArch), branches[i].sourceAddr, architecture.Architecture(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined)) + result.append(IndirectBranchInfo(architecture.CoreArchitecture._from_cache(branches[i].sourceArch), branches[i].sourceAddr, architecture.Architecture(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined)) core.BNFreeIndirectBranchList(branches) return result @@ -1142,7 +1142,7 @@ class Function(object): branches = core.BNGetIndirectBranchesAt(self.handle, arch.handle, addr, count) result = [] for i in xrange(0, count.value): - result.append(IndirectBranchInfo(architecture.CoreArchitecture(branches[i].sourceArch), branches[i].sourceAddr, architecture.Architecture(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined)) + result.append(IndirectBranchInfo(architecture.CoreArchitecture._from_cache(branches[i].sourceArch), branches[i].sourceAddr, architecture.Architecture(branches[i].destArch), branches[i].destAddr, branches[i].autoDefined)) core.BNFreeIndirectBranchList(branches) return result @@ -1660,7 +1660,7 @@ class FunctionGraphBlock(object): arch = core.BNGetFunctionGraphBlockArchitecture(self.handle) if arch is None: return None - return architecture.CoreArchitecture(arch) + return architecture.CoreArchitecture._from_cache(arch) @property def start(self): diff --git a/python/platform.py b/python/platform.py index 09670bac..a79e3b9a 100644 --- a/python/platform.py +++ b/python/platform.py @@ -105,7 +105,7 @@ class Platform(object): else: self.handle = handle self.__dict__["name"] = core.BNGetPlatformName(self.handle) - self.arch = architecture.CoreArchitecture(core.BNGetPlatformArchitecture(self.handle)) + self.arch = architecture.CoreArchitecture._from_cache(core.BNGetPlatformArchitecture(self.handle)) def __del__(self): core.BNFreePlatform(self.handle) -- cgit v1.3.1 From 3b433195716732f63f352730d481a0a9415639a1 Mon Sep 17 00:00:00 2001 From: negasora Date: Mon, 11 Jun 2018 19:03:18 -0400 Subject: Add empty list properties to some classes to allow for visibility --- python/architecture.py | 5 +++++ python/binaryview.py | 4 ++++ python/platform.py | 5 +++++ python/plugin.py | 10 ++++++++++ python/scriptingprovider.py | 5 +++++ python/transform.py | 5 +++++ python/update.py | 4 ++++ 7 files changed, 38 insertions(+) (limited to 'python/platform.py') diff --git a/python/architecture.py b/python/architecture.py index c5f87ec6..df22da7f 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -391,6 +391,11 @@ class Architecture(object): return True return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + @property def full_width_regs(self): """List of full width register strings (read-only)""" diff --git a/python/binaryview.py b/python/binaryview.py index 0cf25e70..80298304 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -341,6 +341,10 @@ class BinaryViewType(object): if not isinstance(value, BinaryViewType): return True return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass @property def name(self): diff --git a/python/platform.py b/python/platform.py index a79e3b9a..dd756178 100644 --- a/python/platform.py +++ b/python/platform.py @@ -120,6 +120,11 @@ class Platform(object): return True return ctypes.addressof(self.handle.contents) != ctypes.addressof(value.handle.contents) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + @property def default_calling_convention(self): """ diff --git a/python/plugin.py b/python/plugin.py index 30a46412..13ca51af 100644 --- a/python/plugin.py +++ b/python/plugin.py @@ -83,6 +83,11 @@ class PluginCommand(object): self.description = str(cmd.description) self.type = PluginCommandType(cmd.type) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + @classmethod def _default_action(cls, view, action): try: @@ -587,6 +592,11 @@ class BackgroundTask(object): def __del__(self): core.BNFreeBackgroundTask(self.handle) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + @property def progress(self): """Text description of the progress of the background task (displayed in status bar of the UI)""" diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 988f856d..1e2338d9 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -303,6 +303,11 @@ class ScriptingProvider(object): if handle is not None: self.handle = core.handle_of_type(handle, core.BNScriptingProvider) self.__dict__["name"] = core.BNGetScriptingProviderName(handle) + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + def register(self): self._cb = core.BNScriptingProviderCallbacks() diff --git a/python/transform.py b/python/transform.py index 59d719e7..3284ed74 100644 --- a/python/transform.py +++ b/python/transform.py @@ -200,6 +200,11 @@ class Transform(object): log.log_error(traceback.format_exc()) return False + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass + @abc.abstractmethod def perform_decode(self, data, params): if self.type == TransformType.InvertingTransform: diff --git a/python/update.py b/python/update.py index 1eb8ea61..2f817595 100644 --- a/python/update.py +++ b/python/update.py @@ -115,6 +115,10 @@ class UpdateChannel(object): self.name = name self.description = desc self.latest_version_num = ver + @property + def list(self): + """Allow tab completion to discover metaclass list property""" + pass @property def versions(self): -- cgit v1.3.1