From bd104cc1d88cc1cd56dc71e54032fe34168b4cf0 Mon Sep 17 00:00:00 2001 From: plafosse Date: Mon, 5 Sep 2016 17:15:15 +0100 Subject: Adding a bunch of fixes found with linter --- python/__init__.py | 501 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 286 insertions(+), 215 deletions(-) (limited to 'python') diff --git a/python/__init__.py b/python/__init__.py index cd559fe5..f32fa612 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -19,7 +19,14 @@ # IN THE SOFTWARE. import _binaryninjacore as core -import ctypes, traceback, json, struct, threading, code, sys +import abc +import ctypes +import traceback +import json +import struct +import threading +import code +import sys _plugin_init = False def _init_plugins(): @@ -31,11 +38,11 @@ def _init_plugins(): if not core.BNIsLicenseValidated(): raise RuntimeError, "License is not valid. Please supply a valid license." -class DataBuffer: - def __init__(self, contents = "", handle = None): +class DataBuffer(object): + def __init__(self, contents="", handle=None): if handle is not None: self.handle = core.handle_of_type(handle, core.BNDataBuffer) - elif (type(contents) is int) or (type(contents) is long): + elif isinstance(contents, int) or isinstance(contents, long): self.handle = core.BNCreateDataBuffer(None, contents) elif isinstance(contents, DataBuffer): self.handle = core.BNDuplicateDataBuffer(contents.handle) @@ -123,7 +130,7 @@ class DataBuffer: return core.BNDataBufferToEscapedString(self.handle) def unescape(self): - return DataBuffer(handle = core.BNDecodeEscapedString(str(self))) + return DataBuffer(handle=core.BNDecodeEscapedString(str(self))) def base64_encode(self): return core.BNDataBufferToBase64(self.handle) @@ -193,7 +200,7 @@ class FileMetadata(object): self.handle = core.BNCreateFileMetadata() if filename is not None: core.BNSetFilename(self.handle, str(filename)) - self.__dict__['navigation'] = None + self.nav = None def __del__(self): if self.navigation is not None: @@ -268,6 +275,15 @@ class FileMetadata(object): else: core.BNMarkFileModified(self.handle) + @property + def navigation(self): + return self.nav + + @navigation.setter + def navigation(self, value): + value._register(self.handle) + self.nav = value + def close(self): """ Closes the underlying file handle. It is recommended that this is done in a @@ -411,14 +427,10 @@ class FileMetadata(object): return BinaryView(self, handle = view) def __setattr__(self, name, value): - if name == "navigation": - value._register(self.handle) - self.__dict__["navigation"] = value - else: - try: - object.__setattr__(self,name,value) - except AttributeError: - raise AttributeError, "attribute '%s' is read only" % name + try: + object.__setattr__(self,name,value) + except AttributeError: + raise AttributeError, "attribute '%s' is read only" % name class FileAccessor: def __init__(self): @@ -526,7 +538,7 @@ class UndoAction: raise TypeError, "undo action type not registered" action_type = self.__class__.action_type if isinstance(action_type, str): - self._cb.type = BNActionType_by_name[action_type] + self._cb.type = core.BNActionType_by_name[action_type] else: self._cb.type = action_type self._cb.context = 0 @@ -583,7 +595,7 @@ class UndoAction: log_error(traceback.format_exc()) return "null" -class StringReference: +class StringReference(object): def __init__(self, string_type, start, length): self.type = string_type self.start = start @@ -592,7 +604,7 @@ class StringReference: def __repr__(self): return "<%s: %#x, len %#x>" % (self.type, self.start, self.length) -class BinaryDataNotificationCallbacks: +class BinaryDataNotificationCallbacks(object): def __init__(self, view, notify): self.view = view self.notify = notify @@ -619,7 +631,7 @@ class BinaryDataNotificationCallbacks: def _data_written(self, ctxt, view, offset, length): try: self.notify.data_written(self.view, offset, length) - except: + except OSError: log_error(traceback.format_exc()) def _data_inserted(self, ctxt, view, offset, length): @@ -723,7 +735,7 @@ class _BinaryViewTypeMetaclass(type): def __setattr__(self, name, value): try: - type.__setattr__(self,name,value) + type.__setattr__(self, name, value) except AttributeError: raise AttributeError, "attribute '%s' is read only" % name @@ -784,7 +796,7 @@ class BinaryViewType(object): def __setattr__(self, name, value): try: - object.__setattr__(self,name,value) + object.__setattr__(self, name, value) except AttributeError: raise AttributeError, "attribute '%s' is read only" % name @@ -831,8 +843,8 @@ class LinearDisassemblyPosition(object): """ ``class LinearDisassemblyPosition`` is a helper object containing the position of the current Linear Disassembly. - .. note:: This object should not be instantiated directly. Rather call :py:method:`get_linear_disassembly_position_at` \ - which instantiates this object. + .. note:: This object should not be instantiated directly. Rather call \ + :py:method:`get_linear_disassembly_position_at` which instantiates this object. """ def __init__(self, func, block, addr): self.function = func @@ -945,7 +957,6 @@ class BinaryView(object): self._cb.isOffsetReadable = self._cb.isOffsetReadable.__class__(self._is_offset_readable) self._cb.isOffsetWritable = self._cb.isOffsetWritable.__class__(self._is_offset_writable) self._cb.isOffsetExecutable = self._cb.isOffsetExecutable.__class__(self._is_offset_executable) - self._cb.isOffsetBackedByFile = self._cb.isOffsetExecutable.__class__(self._is_offset_backed_by_file) self._cb.getNextValidOffset = self._cb.getNextValidOffset.__class__(self._get_next_valid_offset) self._cb.getStart = self._cb.getStart.__class__(self._get_start) self._cb.getLength = self._cb.getLength.__class__(self._get_length) @@ -1390,13 +1401,6 @@ class BinaryView(object): log_error(traceback.format_exc()) return False - def _is_offset_backed_by_file(self, ctxt, offset): - try: - return self.perform_is_offset_backed_by_file(offset) - except: - log_error(traceback.format_exc()) - return False - def _get_next_valid_offset(self, ctxt, offset): try: return self.perform_get_next_valid_offset(offset) @@ -1506,6 +1510,19 @@ class BinaryView(object): return None return ''.join(str(a) for a in txt).strip() + @abc.abstractmethod + def perform_save(self, accessor): + raise NotImplementedError + + @abc.abstractmethod + def perform_get_address_size(self): + raise NotImplementedError + + @abc.abstractmethod + def perform_get_length(self): + raise NotImplementedError + + @abc.abstractmethod def perform_read(self, addr, length): """ ``perform_read`` implements a mapping between a virtual address and an absolute file offset, reading @@ -1520,8 +1537,9 @@ class BinaryView(object): :return: length bytes read from addr, should return empty string on error :rtype: int """ - return "" + raise NotImplementedError + @abc.abstractmethod def perform_write(self, addr, data): """ ``perform_write`` implements a mapping between a virtual address and an absolute file offset, writing @@ -1536,8 +1554,9 @@ class BinaryView(object): :return: length of data written, should return 0 on error :rtype: int """ - return 0 + raise NotImplementedError + @abc.abstractmethod def perform_insert(self, addr, data): """ ``perform_insert`` implements a mapping between a virtual address and an absolute file offset, inserting @@ -1552,8 +1571,9 @@ class BinaryView(object): :return: length of data inserted, should return 0 on error :rtype: int """ - return 0 + raise NotImplementedError + @abc.abstractmethod def perform_remove(self, addr, length): """ ``perform_remove`` implements a mapping between a virtual address and an absolute file offset, removing @@ -1568,8 +1588,9 @@ class BinaryView(object): :return: length of data removed, should return 0 on error :rtype: int """ - return 0 + raise NotImplementedError + @abc.abstractmethod def perform_get_modification(self, addr): """ ``perform_get_modification`` implements query to the whether the virtual address ``addr`` is modified. @@ -1583,6 +1604,7 @@ class BinaryView(object): """ return core.Original + @abc.abstractmethod def perform_is_valid_offset(self, addr): """ ``perform_is_valid_offset`` implements a check if an virtual address ``addr`` is valid. @@ -1598,6 +1620,7 @@ class BinaryView(object): data = self.read(addr, 1) return (data is not None) and (len(data) == 1) + @abc.abstractmethod def perform_is_offset_readable(self, offset): """ ``perform_is_offset_readable`` implements a check if an virtual address is readable. @@ -1612,6 +1635,7 @@ class BinaryView(object): """ return self.is_valid_offset(offset) + @abc.abstractmethod def perform_is_offset_writable(self, addr): """ ``perform_is_offset_writable`` implements a check if a virtual address ``addr`` is writable. @@ -1626,6 +1650,7 @@ class BinaryView(object): """ return self.is_valid_offset(addr) + @abc.abstractmethod def perform_is_offset_executable(self, addr): """ ``perform_is_offset_writable`` implements a check if a virtual address ``addr`` is executable. @@ -1640,20 +1665,7 @@ class BinaryView(object): """ return self.is_valid_offset(addr) - def perform_is_offset_backed_by_file(self, addr): - """ - ``perform_is_offset_backed_by_file`` implements a check if a virtual address ``addr`` is backed by the file - contents. - - .. warning:: This method **must not** be called directly. - - :param int addr: a virtual address to be checked - :return: true if the virtual address is backed by the file, false if the virtual address is initialized by \ - the loader - :rtype: int - """ - return self.is_valid_offset(addr) - + @abc.abstractmethod def perform_get_next_valid_offset(self, addr): """ ``perform_get_next_valid_offset`` implements a query for the next valid readable, writable, or executable virtual @@ -1670,6 +1682,7 @@ class BinaryView(object): return self.perform_get_start() return addr + @abc.abstractmethod def perform_get_start(self): """ ``perform_get_start`` implements a query for the first readable, writable, or executable virtual address in @@ -1683,6 +1696,7 @@ class BinaryView(object): """ return 0 + @abc.abstractmethod def perform_get_entry_point(self): """ ``perform_get_entry_point`` implements a query for the initial entry point for code execution. @@ -1695,6 +1709,7 @@ class BinaryView(object): """ return 0 + @abc.abstractmethod def perform_is_executable(self): """ ``perform_is_executable`` implements a check which returns true if the BinaryView is executable. @@ -1705,13 +1720,14 @@ class BinaryView(object): :return: true if the current BinaryView is executable, false if it is not executable or on error :rtype: bool """ - return False + raise NotImplementedError + @abc.abstractmethod def perform_get_default_endianness(self): """ ``perform_get_default_endianness`` implements a check which returns true if the BinaryView is executable. - .. note:: This method **must** be implemented for custom BinaryViews that are not LittleEndian. + .. note:: This method **may** be implemented for custom BinaryViews that are not LittleEndian. .. warning:: This method **must not** be called directly. :return: either ``core.LittleEndian`` or ``core.BigEndian`` @@ -1728,7 +1744,7 @@ class BinaryView(object): :return: true on success, false on failure :rtype: bool """ - return self.file.create_database(filename) + return self.file.create_database(filename, progress_func) def save_auto_snapshot(self, progress_func = None): """ @@ -1940,7 +1956,7 @@ class BinaryView(object): if length is None: return core.BNGetModification(self.handle, addr) data = (core.BNModificationStatus * length)() - length = core.BNGetModificationArray(self.handle, addr, data, length); + length = core.BNGetModificationArray(self.handle, addr, data, length) return data[0:length] def is_valid_offset(self, addr): @@ -1983,17 +1999,6 @@ class BinaryView(object): """ return core.BNIsOffsetExecutable(self.handle, addr) - def is_offset_backed_by_file(self, addr): - """ - ``is_offset_backed_by_file`` checks if an virtual address ``addr`` is backed by the file contents. - - :param int addr: a virtual address to be checked - :return: true if the virtual address is backed by the file, false if the virtual address is initialized by \ - the loader - :rtype: bool - """ - return core.BNIsOffsetBackedByFile(self.handle, addr) - def save(self, dest): """ ``save`` saves the original binary file to the provided destination ``dest`` along with any modifications. @@ -3898,7 +3903,7 @@ class Type(object): @property def type_class(self): """Type class (read-only)""" - return BNTypeClass_names[core.BNGetTypeClass(self.handle)] + return core.BNTypeClass_names[core.BNGetTypeClass(self.handle)] @property def width(self): @@ -4028,8 +4033,12 @@ class Type(object): return Type(core.BNCreateFloatType(width)) @classmethod - def structure_type(self, s): - return Type(core.BNCreateStructureType(s.handle)) + def structure_type(self, structure_type): + return Type(core.BNCreateStructureType(structure_type.handle)) + + @classmethod + def unknown_type(self, unknown_type): + return Type(core.BNCreateUnknownType(unknown_type.handle)) @classmethod def enumeration_type(self, arch, e, width = None): @@ -4050,7 +4059,7 @@ class Type(object): param_buf = (core.BNNameAndType * len(params))() for i in xrange(0, len(params)): if isinstance(params[i], Type): - param_buf[i].name = ""; + param_buf[i].name = "" param_buf[i].type = params[i].handle else: param_buf[i].name = params[i][1] @@ -4066,7 +4075,32 @@ class Type(object): except AttributeError: raise AttributeError, "attribute '%s' is read only" % name -class StructureMember: + +class UnknownType(object): + def __init__(self, handle = None): + if handle is None: + self.handle = core.BNCreateUnknownType() + else: + self.handle = handle + + def __del__(self): + core.BNFreeUnknownType(self.handle) + + @property + def name(self): + count = ctypes.c_ulonglong() + nameList = core.BNGetUnknownTypeName(self.handle, count) + result = [] + for i in xrange(count.value): + result.append(nameList[i]) + return get_qualified_name(result) + + @name.setter + def name(self, value): + core.BNSetUnknownTypeName(self.handle, value) + + +class StructureMember(object): def __init__(self, t, name, offset): self.type = t self.name = name @@ -4090,7 +4124,12 @@ class Structure(object): @property def name(self): - return core.BNGetStructureName(self.handle) + count = ctypes.c_ulonglong() + nameList = core.BNGetStructureName(self.handle, count) + result = [] + for i in xrange(count.value): + result.append(nameList[i]) + return get_qualified_name(result) @name.setter def name(self, value): @@ -4154,7 +4193,7 @@ class Structure(object): def remove(self, i): core.BNRemoveStructureMember(self.handle, i) -class EnumerationMember: +class EnumerationMember(object): def __init__(self, name, value, default): self.name = name self.value = value @@ -4209,7 +4248,7 @@ class Enumeration(object): else: core.BNAddEnumerationMemberWithValue(self.handle, name, value) -class LookupTableEntry: +class LookupTableEntry(object): def __init__(self, from_values, to_value): self.from_values = from_values self.to_value = to_value @@ -4217,19 +4256,19 @@ class LookupTableEntry: def __repr__(self): return "[%s] -> %#x" % (', '.join(["%#x" % i for i in self.from_values]), self.to_value) -class RegisterValue: +class RegisterValue(object): def __init__(self, arch, value): self.type = value.state - if value.state == EntryValue: + if value.state == core.EntryValue: self.reg = arch.get_reg_name(value.reg) - elif value.state == OffsetFromEntryValue: + elif value.state == core.OffsetFromEntryValue: self.reg = arch.get_reg_name(value.reg) self.offset = value.value - elif value.state == ConstantValue: + elif value.state == core.ConstantValue: self.value = value.value - elif value.state == StackFrameOffset: + elif value.state == core.StackFrameOffset: self.offset = value.value - elif value.state == SignedRangeValue: + elif value.state == core.SignedRangeValue: self.offset = value.value self.start = value.rangeStart self.end = value.rangeEnd @@ -4238,12 +4277,12 @@ class RegisterValue: self.start |= ~((1 << 63) - 1) if self.end & (1 << 63): self.end |= ~((1 << 63) - 1) - elif value.state == UnsignedRangeValue: + elif value.state == core.UnsignedRangeValue: self.offset = value.value self.start = value.rangeStart self.end = value.rangeEnd self.step = value.rangeStep - elif value.state == LookupTableValue: + elif value.state == core.LookupTableValue: self.table = [] self.mapping = {} for i in xrange(0, value.rangeEnd): @@ -4252,29 +4291,29 @@ class RegisterValue: from_list.append(value.table[i].fromValues[j]) self.mapping[value.table[i].fromValues[j]] = value.table[i].toValue self.table.append(LookupTableEntry(from_list, value.table[i].toValue)) - elif value.state == OffsetFromUndeterminedValue: + elif value.state == core.OffsetFromUndeterminedValue: self.offset = value.value def __repr__(self): - if self.type == EntryValue: + if self.type == core.EntryValue: return "" % self.reg - if self.type == OffsetFromEntryValue: + if self.type == core.OffsetFromEntryValue: return "" % (self.reg, self.offset) - if self.type == ConstantValue: + if self.type == core.ConstantValue: return "" % self.value - if self.type == StackFrameOffset: + if self.type == core.StackFrameOffset: return "" % self.offset - if (self.type == SignedRangeValue) or (self.type == UnsignedRangeValue): + if (self.type == core.SignedRangeValue) or (self.type == core.UnsignedRangeValue): if self.step == 1: return "" % (self.start, self.end) return "" % (self.start, self.end, self.step) - if self.type == LookupTableValue: + if self.type == core.LookupTableValue: return "" % ', '.join([repr(i) for i in self.table]) - if self.type == OffsetFromUndeterminedValue: + if self.type == core.OffsetFromUndeterminedValue: return "" % self.offset return "" -class StackVariable: +class StackVariable(object): def __init__(self, ofs, name, t): self.offset = ofs self.name = name @@ -4348,7 +4387,7 @@ class Function(object): if self.symbol is not None: self.view.undefine_user_symbol(self.symbol) else: - symbol = Symbol(FunctionSymbol,self.start,value) + symbol = Symbol(core.FunctionSymbol,self.start,value) self.view.define_user_symbol(symbol) @property @@ -4764,7 +4803,7 @@ class AdvancedFunctionAnalysisDataRequestor(object): self._function.release_advanced_analysis_data() self._function = None -class BasicBlockEdge: +class BasicBlockEdge(object): def __init__(self, branch_type, target, arch): self.type = core.BNBranchType_names[branch_type] if self.type != "UnresolvedBranch": @@ -4912,7 +4951,7 @@ class LowLevelILBasicBlock(BasicBlock): for idx in xrange(self.start, self.end): yield self.il_function[idx] -class DisassemblyTextLine: +class DisassemblyTextLine(object): def __init__(self, addr, tokens): self.address = addr self.tokens = tokens @@ -5081,12 +5120,12 @@ class DisassemblySettings(object): def is_option_set(self, option): if isinstance(option, str): - option = core.BNDisassemblyOption_by_name(option) + option = core.BNDisassemblyOption_by_name[option] return core.BNIsDisassemblySettingsOptionSet(self.handle, option) def set_option(self, option, state = True): if isinstance(option, str): - option = core.BNDisassemblyOption_by_name(option) + option = core.BNDisassemblyOption_by_name[option] core.BNSetDisassemblySettingsOption(self.handle, option, state) class FunctionGraph(object): @@ -5230,7 +5269,7 @@ class FunctionGraph(object): option = core.BNDisassemblyOption_by_name(option) core.BNSetFunctionGraphOption(self.handle, option, state) -class RegisterInfo: +class RegisterInfo(object): def __init__(self, full_width_reg, size, offset = 0, extend = core.NoExtend, index = None): self.full_width_reg = full_width_reg self.offset = offset @@ -5247,7 +5286,7 @@ class RegisterInfo: extend = "" return "" % (self.size, self.offset, self.full_width_reg, extend) -class InstructionBranch: +class InstructionBranch(object): def __init__(self, branch_type, target = 0, arch = None): self.type = branch_type self.target = target @@ -5261,7 +5300,7 @@ class InstructionBranch: return "<%s: %s@%#x>" % (branch_type, self.arch.name, self.target) return "<%s: %#x>" % (branch_type, self.target) -class InstructionInfo: +class InstructionInfo(object): def __init__(self): self.length = 0 self.branch_delay = False @@ -5276,7 +5315,7 @@ class InstructionInfo: branch_delay = ", delay slot" return "" % (self.length, branch_delay, repr(self.branches)) -class InstructionTextToken: +class InstructionTextToken(object): """ ``class InstructionTextToken`` is used to tell the core about the various components in the disassembly views. @@ -5473,7 +5512,7 @@ class Architecture(object): self._flags_required_for_flag_condition = {} self.__dict__["flags_required_for_flag_condition"] = {} - for cond in core.BNLowLevelILFlagCondition_names.keys(): + for cond in core.BNLowLevelILFlagCondition_names: count = ctypes.c_ulonglong() flags = core.BNGetArchitectureFlagsRequiredForFlagCondition(self.handle, cond, count) flag_indexes = [] @@ -5560,7 +5599,7 @@ class Architecture(object): self._regs_by_index = {} self.__dict__["regs"] = self.__class__.regs reg_index = 0 - for reg in self.regs.keys(): + for reg in self.regs: info = self.regs[reg] if reg not in self._all_regs: self._all_regs[reg] = reg_index @@ -5597,7 +5636,7 @@ class Architecture(object): self._flag_roles = {} self.__dict__["flag_roles"] = self.__class__.flag_roles - for flag in self.__class__.flag_roles.keys(): + for flag in self.__class__.flag_roles: role = self.__class__.flag_roles[flag] if isinstance(role, str): role = core.BNFlagRole_by_name[role] @@ -5605,7 +5644,7 @@ class Architecture(object): self._flags_required_for_flag_condition = {} self.__dict__["flags_required_for_flag_condition"] = self.__class__.flags_required_for_flag_condition - for cond in self.__class__.flags_required_for_flag_condition.keys(): + for cond in self.__class__.flags_required_for_flag_condition: flags = [] for flag in self.__class__.flags_required_for_flag_condition[cond]: flags.append(self._flags[flag]) @@ -5613,7 +5652,7 @@ class Architecture(object): self._flags_written_by_flag_write_type = {} self.__dict__["flags_written_by_flag_write_type"] = self.__class__.flags_written_by_flag_write_type - for write_type in self.__class__.flags_written_by_flag_write_type.keys(): + for write_type in self.__class__.flags_written_by_flag_write_type: flags = [] for flag in self.__class__.flags_written_by_flag_write_type[write_type]: flags.append(self._flags[flag]) @@ -5723,7 +5762,7 @@ class Architecture(object): else: result[0].branchArch[i] = info.branches[i].arch.handle return True - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return False @@ -5740,7 +5779,7 @@ class Architecture(object): token_buf = (core.BNInstructionTextToken * len(tokens))() for i in xrange(0, len(tokens)): if isinstance(tokens[i].type, str): - token_buf[i].type = BNInstructionTextTokenType_by_name[tokens[i].type] + token_buf[i].type = core.BNInstructionTextTokenType_by_name[tokens[i].type] else: token_buf[i].type = tokens[i].type token_buf[i].text = tokens[i].text @@ -5751,7 +5790,7 @@ class Architecture(object): ptr = ctypes.cast(token_buf, ctypes.c_void_p) self._pending_token_lists[ptr.value] = (ptr.value, token_buf) return True - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return False @@ -5761,7 +5800,7 @@ class Architecture(object): if buf.value not in self._pending_token_lists: raise ValueError, "freeing token list that wasn't allocated" del self._pending_token_lists[buf.value] - except: + except KeyError: log_error(traceback.format_exc()) def _get_instruction_low_level_il(self, ctxt, data, addr, length, il): @@ -5774,7 +5813,7 @@ class Architecture(object): return False length[0] = result return True - except: + except OSError: log_error(traceback.format_exc()) return False @@ -5783,7 +5822,7 @@ class Architecture(object): if reg in self._regs_by_index: return core.BNAllocString(self._regs_by_index[reg]) return core.BNAllocString("") - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return core.BNAllocString("") @@ -5792,7 +5831,7 @@ class Architecture(object): if flag in self._flags_by_index: return core.BNAllocString(self._flags_by_index[flag]) return core.BNAllocString("") - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return core.BNAllocString("") @@ -5801,7 +5840,7 @@ class Architecture(object): if write_type in self._flag_write_types_by_index: return core.BNAllocString(self._flag_write_types_by_index[write_type]) return core.BNAllocString("") - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return core.BNAllocString("") @@ -5815,7 +5854,7 @@ class Architecture(object): result = ctypes.cast(reg_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, reg_buf) return result.value - except: + except KeyError: log_error(traceback.format_exc()) count[0] = 0 return None @@ -5830,7 +5869,7 @@ class Architecture(object): result = ctypes.cast(reg_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, reg_buf) return result.value - except: + except KeyError: log_error(traceback.format_exc()) count[0] = 0 return None @@ -5845,7 +5884,7 @@ class Architecture(object): result = ctypes.cast(flag_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, flag_buf) return result.value - except: + except KeyError: log_error(traceback.format_exc()) count[0] = 0 return None @@ -5860,7 +5899,7 @@ class Architecture(object): result = ctypes.cast(type_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, type_buf) return result.value - except: + except KeyError: log_error(traceback.format_exc()) count[0] = 0 return None @@ -5870,7 +5909,7 @@ class Architecture(object): if flag in self._flag_roles: return self._flag_roles[flag] return core.SpecialFlagRole - except: + except KeyError: log_error(traceback.format_exc()) return None @@ -5887,7 +5926,7 @@ class Architecture(object): result = ctypes.cast(flag_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, flag_buf) return result.value - except: + except KeyError: log_error(traceback.format_exc()) count[0] = 0 return None @@ -5905,7 +5944,7 @@ class Architecture(object): result = ctypes.cast(flag_buf, ctypes.c_void_p) self._pending_reg_lists[result.value] = (result, flag_buf) return result.value - except: + except (KeyError, OSError): log_error(traceback.format_exc()) count[0] = 0 return None @@ -5926,7 +5965,7 @@ class Architecture(object): operand_list.append(("reg", self._regs_by_index[operands[i].reg])) return self.perform_get_flag_write_low_level_il(op, size, write_type_name, flag_name, operand_list, LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index - except: + except (KeyError, OSError): log_error(traceback.format_exc()) return False @@ -5934,7 +5973,7 @@ class Architecture(object): try: return self.perform_get_flag_condition_low_level_il(cond, LowLevelILFunction(self, core.BNNewLowLevelILFunctionReference(il))).index - except: + except OSError: log_error(traceback.format_exc()) return 0 @@ -5944,7 +5983,7 @@ class Architecture(object): if buf.value not in self._pending_reg_lists: raise ValueError, "freeing register list that wasn't allocated" del self._pending_reg_lists[buf.value] - except: + except (ValueError, KeyError): log_error(traceback.format_exc()) def _get_register_info(self, ctxt, reg, result): @@ -5963,7 +6002,7 @@ class Architecture(object): result[0].extend = core.BNImplicitRegisterExtend_by_name[info.extend] else: result[0].extend = info.extend - except: + except KeyError: log_error(traceback.format_exc()) result[0].fullWidthRegister = 0 result[0].offset = 0 @@ -5973,7 +6012,7 @@ class Architecture(object): def _get_stack_pointer_register(self, ctxt): try: return self._all_regs[self.__class__.stack_pointer] - except: + except KeyError: log_error(traceback.format_exc()) return 0 @@ -5982,7 +6021,7 @@ class Architecture(object): if self.__class__.link_reg is None: return 0xffffffff return self._all_regs[self.__class__.link_reg] - except: + except KeyError: log_error(traceback.format_exc()) return 0 @@ -6111,6 +6150,7 @@ class Architecture(object): log_error(traceback.format_exc()) return False + @abc.abstractmethod def perform_get_instruction_info(self, data, addr): """ ``perform_get_instruction_info`` implements a method which interpretes the bytes passed in ``data`` as an @@ -6120,7 +6160,7 @@ class Architecture(object): ===================== =================================================== BranchType Description ===================== =================================================== - UnconditionalBranch Branch will alwasy be taken + UnconditionalBranch Branch will always be taken FalseBranch False branch condition TrueBranch True branch condition CallDestination Branch is a call instruction (Branch with Link) @@ -6135,8 +6175,9 @@ class Architecture(object): :return: a :py:class:`InstructionInfo` object containing the length and branche types for the given instruction :rtype: InstructionInfo """ - return None + raise NotImplementedError + @abc.abstractmethod def perform_get_instruction_text(self, data, addr): """ ``perform_get_instruction_text`` implements a method which interpretes the bytes passed in ``data`` as a @@ -6147,8 +6188,9 @@ class Architecture(object): :return: a tuple of list(InstructionTextToken) and length of instruction decoded :rtype: tuple(list(InstructionTextToken), int) """ - return None, None + raise NotImplementedError + @abc.abstractmethod def perform_get_instruction_low_level_il(self, data, addr, il): """ ``perform_get_instruction_low_level_il`` implements a method to interpret the bytes passed in ``data`` to @@ -6161,8 +6203,9 @@ class Architecture(object): :param LowLevelILFunction il: LowLevelILFunction object to append LowLevelILExpr objects to :rtype: None """ - return None + raise NotImplementedError + @abc.abstractmethod def perform_get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il): """ .. note:: Architecture subclasses should implement this method. @@ -6178,6 +6221,7 @@ class Architecture(object): """ return il.unimplemented() + @abc.abstractmethod def perform_get_flag_condition_low_level_il(self, cond, il): """ .. note:: Architecture subclasses should implement this method. @@ -6189,6 +6233,7 @@ class Architecture(object): """ return il.unimplemented() + @abc.abstractmethod def perform_assemble(self, code, addr): """ ``perform_assemble`` implements a method to convert the string of assembly instructions ``code`` loaded at @@ -6207,6 +6252,7 @@ class Architecture(object): """ return None, "Architecture does not implement an assembler.\n" + @abc.abstractmethod def perform_is_never_branch_patch_available(self, data, addr): """ ``perform_is_never_branch_patch_available`` implements a check to determine if the instruction represented by @@ -6222,6 +6268,7 @@ class Architecture(object): """ return False + @abc.abstractmethod def perform_is_always_branch_patch_available(self, data, addr): """ ``perform_is_always_branch_patch_available`` implements a check to determine if the instruction represented by @@ -6237,6 +6284,7 @@ class Architecture(object): """ return False + @abc.abstractmethod def perform_is_invert_branch_patch_available(self, data, addr): """ ``perform_is_invert_branch_patch_available`` implements a check to determine if the instruction represented by @@ -6251,6 +6299,7 @@ class Architecture(object): """ return False + @abc.abstractmethod def perform_is_skip_and_return_zero_patch_available(self, data, addr): """ ``perform_is_skip_and_return_zero_patch_available`` implements a check to determine if the instruction represented by @@ -6268,6 +6317,7 @@ class Architecture(object): """ return False + @abc.abstractmethod def perform_is_skip_and_return_value_patch_available(self, data, addr): """ ``perform_is_skip_and_return_value_patch_available`` implements a check to determine if the instruction represented by @@ -6285,6 +6335,7 @@ class Architecture(object): """ return False + @abc.abstractmethod def perform_convert_to_nop(self, data, addr): """ ``perform_convert_to_nop`` implements a method which returns a nop sequence of len(data) bytes long. @@ -6299,6 +6350,7 @@ class Architecture(object): """ return None + @abc.abstractmethod def perform_always_branch(self, data, addr): """ ``perform_always_branch`` implements a method which converts the branch represented by the bytes in ``data`` to @@ -6314,6 +6366,7 @@ class Architecture(object): """ return None + @abc.abstractmethod def perform_invert_branch(self, data, addr): """ ``perform_invert_branch`` implements a method which inverts the branch represented by the bytes in ``data`` to @@ -6329,6 +6382,7 @@ class Architecture(object): """ return None + @abc.abstractmethod def perform_skip_and_return_value(self, data, addr, value): """ ``perform_skip_and_return_value`` implements a method which converts a *call-like* instruction represented by @@ -6921,7 +6975,7 @@ class Architecture(object): """ core.BNRegisterCallingConvention(self.handle, cc.handle) -class ReferenceSource: +class ReferenceSource(object): def __init__(self, func, arch, addr): self.function = func self.arch = arch @@ -6933,7 +6987,7 @@ class ReferenceSource: else: return "" % self.address -class LowLevelILLabel: +class LowLevelILLabel(object): def __init__(self, handle = None): if handle is None: self.handle = (core.BNLowLevelILLabel * 1)() @@ -6949,73 +7003,73 @@ class LowLevelILInstruction(object): """ ILOperations = { - core.LLIL_NOP: [], - core.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")], + core.LLIL_NOP: [], + core.LLIL_SET_REG: [("dest", "reg"), ("src", "expr")], core.LLIL_SET_REG_SPLIT: [("hi", "reg"), ("lo", "reg"), ("src", "expr")], - core.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")], - core.LLIL_LOAD: [("src", "expr")], - core.LLIL_STORE: [("dest", "expr"), ("src", "expr")], - core.LLIL_PUSH: [("src", "expr")], - core.LLIL_POP: [], - core.LLIL_REG: [("src", "reg")], - core.LLIL_CONST: [("value", "int")], - core.LLIL_FLAG: [("src", "flag")], - core.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")], - core.LLIL_ADD: [("left", "expr"), ("right", "expr")], - core.LLIL_ADC: [("left", "expr"), ("right", "expr")], - core.LLIL_SUB: [("left", "expr"), ("right", "expr")], - core.LLIL_SBB: [("left", "expr"), ("right", "expr")], - core.LLIL_AND: [("left", "expr"), ("right", "expr")], - core.LLIL_OR: [("left", "expr"), ("right", "expr")], - core.LLIL_XOR: [("left", "expr"), ("right", "expr")], - core.LLIL_LSL: [("left", "expr"), ("right", "expr")], - core.LLIL_LSR: [("left", "expr"), ("right", "expr")], - core.LLIL_ASR: [("left", "expr"), ("right", "expr")], - core.LLIL_ROL: [("left", "expr"), ("right", "expr")], - core.LLIL_RLC: [("left", "expr"), ("right", "expr")], - core.LLIL_ROR: [("left", "expr"), ("right", "expr")], - core.LLIL_RRC: [("left", "expr"), ("right", "expr")], - core.LLIL_MUL: [("left", "expr"), ("right", "expr")], - core.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")], - core.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")], - core.LLIL_DIVU: [("left", "expr"), ("right", "expr")], - core.LLIL_DIVU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], - core.LLIL_DIVS: [("left", "expr"), ("right", "expr")], - core.LLIL_DIVS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], - core.LLIL_MODU: [("left", "expr"), ("right", "expr")], - core.LLIL_MODU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], - core.LLIL_MODS: [("left", "expr"), ("right", "expr")], - core.LLIL_MODS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], - core.LLIL_NEG: [("src", "expr")], - core.LLIL_NOT: [("src", "expr")], - core.LLIL_SX: [("src", "expr")], - core.LLIL_ZX: [("src", "expr")], - core.LLIL_JUMP: [("dest", "expr")], - core.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], - core.LLIL_CALL: [("dest", "expr")], - core.LLIL_RET: [("dest", "expr")], - core.LLIL_NORET: [], - core.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], - core.LLIL_GOTO: [("dest", "int")], - core.LLIL_FLAG_COND: [("condition", "cond")], - core.LLIL_CMP_E: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], - core.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], - core.LLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], - core.LLIL_BOOL_TO_INT: [("src", "expr")], - core.LLIL_SYSCALL: [], - core.LLIL_BP: [], - core.LLIL_TRAP: [("value", "int")], - core.LLIL_UNDEF: [], - core.LLIL_UNIMPL: [], - core.LLIL_UNIMPL_MEM: [("src", "expr")] + core.LLIL_SET_FLAG: [("dest", "flag"), ("src", "expr")], + core.LLIL_LOAD: [("src", "expr")], + core.LLIL_STORE: [("dest", "expr"), ("src", "expr")], + core.LLIL_PUSH: [("src", "expr")], + core.LLIL_POP: [], + core.LLIL_REG: [("src", "reg")], + core.LLIL_CONST: [("value", "int")], + core.LLIL_FLAG: [("src", "flag")], + core.LLIL_FLAG_BIT: [("src", "flag"), ("bit", "int")], + core.LLIL_ADD: [("left", "expr"), ("right", "expr")], + core.LLIL_ADC: [("left", "expr"), ("right", "expr")], + core.LLIL_SUB: [("left", "expr"), ("right", "expr")], + core.LLIL_SBB: [("left", "expr"), ("right", "expr")], + core.LLIL_AND: [("left", "expr"), ("right", "expr")], + core.LLIL_OR: [("left", "expr"), ("right", "expr")], + core.LLIL_XOR: [("left", "expr"), ("right", "expr")], + core.LLIL_LSL: [("left", "expr"), ("right", "expr")], + core.LLIL_LSR: [("left", "expr"), ("right", "expr")], + core.LLIL_ASR: [("left", "expr"), ("right", "expr")], + core.LLIL_ROL: [("left", "expr"), ("right", "expr")], + core.LLIL_RLC: [("left", "expr"), ("right", "expr")], + core.LLIL_ROR: [("left", "expr"), ("right", "expr")], + core.LLIL_RRC: [("left", "expr"), ("right", "expr")], + core.LLIL_MUL: [("left", "expr"), ("right", "expr")], + core.LLIL_MULU_DP: [("left", "expr"), ("right", "expr")], + core.LLIL_MULS_DP: [("left", "expr"), ("right", "expr")], + core.LLIL_DIVU: [("left", "expr"), ("right", "expr")], + core.LLIL_DIVU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + core.LLIL_DIVS: [("left", "expr"), ("right", "expr")], + core.LLIL_DIVS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + core.LLIL_MODU: [("left", "expr"), ("right", "expr")], + core.LLIL_MODU_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + core.LLIL_MODS: [("left", "expr"), ("right", "expr")], + core.LLIL_MODS_DP: [("hi", "expr"), ("lo", "expr"), ("right", "expr")], + core.LLIL_NEG: [("src", "expr")], + core.LLIL_NOT: [("src", "expr")], + core.LLIL_SX: [("src", "expr")], + core.LLIL_ZX: [("src", "expr")], + core.LLIL_JUMP: [("dest", "expr")], + core.LLIL_JUMP_TO: [("dest", "expr"), ("targets", "int_list")], + core.LLIL_CALL: [("dest", "expr")], + core.LLIL_RET: [("dest", "expr")], + core.LLIL_NORET: [], + core.LLIL_IF: [("condition", "expr"), ("true", "int"), ("false", "int")], + core.LLIL_GOTO: [("dest", "int")], + core.LLIL_FLAG_COND: [("condition", "cond")], + core.LLIL_CMP_E: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_NE: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_SLT: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_ULT: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_SLE: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_ULE: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_SGE: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_UGE: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_SGT: [("left", "expr"), ("right", "expr")], + core.LLIL_CMP_UGT: [("left", "expr"), ("right", "expr")], + core.LLIL_TEST_BIT: [("left", "expr"), ("right", "expr")], + core.LLIL_BOOL_TO_INT: [("src", "expr")], + core.LLIL_SYSCALL: [], + core.LLIL_BP: [], + core.LLIL_TRAP: [("value", "int")], + core.LLIL_UNDEF: [], + core.LLIL_UNIMPL: [], + core.LLIL_UNIMPL_MEM: [("src", "expr")] } def __init__(self, func, expr_index, instr_index = None): @@ -7103,7 +7157,7 @@ class LowLevelILInstruction(object): except AttributeError: raise AttributeError, "attribute '%s' is read only" % name -class LowLevelILExpr: +class LowLevelILExpr(object): """ ``class LowLevelILExpr`` hold the index of IL Expressions. @@ -7203,13 +7257,12 @@ class LowLevelILFunction(object): raise IndexError, "index out of range" return LowLevelILInstruction(self, core.BNGetLowLevelILIndexForInstruction(self.handle, i), i) - def __setitem__(self, i): + def __setitem__(self, i, j): raise IndexError, "instruction modification not implemented" def __iter__(self): count = ctypes.c_ulonglong() blocks = core.BNGetLowLevelILBasicBlockList(self.handle, count) - result = [] view = None if self.source_function is not None: view = self.source_function.view @@ -7231,7 +7284,7 @@ class LowLevelILFunction(object): def expr(self, operation, a = 0, b = 0, c = 0, d = 0, size = 0, flags = None): if isinstance(operation, str): - operation = BNLowLevelILOperation_by_name[operation] + operation = core.BNLowLevelILOperation_by_name[operation] if isinstance(flags, str): flags = self.arch.get_flag_write_type_by_name(flags) elif flags is None: @@ -7846,7 +7899,7 @@ class LowLevelILFunction(object): :rtype: LowLevelILExpr """ if isinstance(cond, str): - cond = BNLowLevelILFlagCondition_by_name[cond] + cond = core.BNLowLevelILFlagCondition_by_name[cond] return self.expr(core.LLIL_FLAG_COND, cond) def compare_equal(self, size, a, b): @@ -8081,7 +8134,7 @@ class LowLevelILFunction(object): :return: the label list expression :rtype: LowLevelILExpr """ - label_list = (ctypes.POINTER(BNLowLevelILLabel) * len(labels))() + label_list = (ctypes.POINTER(core.BNLowLevelILLabel) * len(labels))() for i in xrange(len(labels)): label_list[i] = labels[i].handle return LowLevelILExpr(core.BNLowLevelILAddLabelList(self.handle, label_list, len(labels))) @@ -8151,7 +8204,7 @@ class LowLevelILFunction(object): return None return LowLevelILLabel(label) -class TypeParserResult: +class TypeParserResult(object): def __init__(self, types, variables, functions): self.types = types self.variables = variables @@ -8209,7 +8262,7 @@ class _TransformMetaClass(type): cls._registered_cb = xform._cb xform.handle = core.BNRegisterTransformType(cls.transform_type, cls.name, cls.long_name, cls.group, xform._cb) -class TransformParameter: +class TransformParameter(object): def __init__(self, name, long_name = None, fixed_length = 0): self.name = name if long_name is None: @@ -8318,11 +8371,13 @@ class Transform: log_error(traceback.format_exc()) return False + @abc.abstractmethod def perform_decode(self, data, params): if self.type == "InvertingTransform": return self.perform_encode(data, params) return None + @abc.abstractmethod def perform_encode(self, data, params): return None @@ -8354,7 +8409,7 @@ class Transform: return None return str(output_buf) -class FunctionRecognizer: +class FunctionRecognizer(object): _instance = None def __init__(self): @@ -8453,7 +8508,7 @@ class _UpdateChannelMetaClass(type): raise KeyError, "'%s' is not a valid channel" % str(name) return result -class UpdateProgressCallback: +class UpdateProgressCallback(object): def __init__(self, func): self.cb = ctypes.CFUNCTYPE(ctypes.c_bool, ctypes.c_void_p, ctypes.c_ulonglong, ctypes.c_ulonglong)(self.callback) self.func = func @@ -8541,7 +8596,7 @@ class UpdateChannel(object): raise IOError, error_str return core.BNUpdateResult_names[result] -class UpdateVersion: +class UpdateVersion(object): def __init__(self, channel, ver, notes, t): self.channel = channel self.version = ver @@ -8564,7 +8619,7 @@ class UpdateVersion: raise IOError, error_str return core.BNUpdateResult_names[result] -class PluginCommandContext: +class PluginCommandContext(object): def __init__(self, view): self.view = view self.address = 0 @@ -8777,7 +8832,7 @@ class PluginCommand: def __repr__(self): return "" % self.name -class CallingConvention: +class CallingConvention(object): name = None caller_saved_regs = [] int_arg_regs = [] @@ -9297,26 +9352,33 @@ class ScriptingInstance(object): except: log_error(traceback.format_exc()) + @abc.abstractmethod def perform_destroy_instance(self): - pass + raise NotImplementedError + @abc.abstractmethod def perform_execute_script_input(self, text): return core.InvalidScriptInput + @abc.abstractmethod def perform_set_current_binary_view(self, view): - pass + raise NotImplementedError + @abc.abstractmethod def perform_set_current_function(self, func): - pass + raise NotImplementedError + @abc.abstractmethod def perform_set_current_basic_block(self, block): - pass + raise NotImplementedError + @abc.abstractmethod def perform_set_current_address(self, addr): - pass + raise NotImplementedError + @abc.abstractmethod def perform_set_current_selection(self, begin, end): - pass + raise NotImplementedError @property def input_ready_state(self): @@ -9640,9 +9702,11 @@ class PythonScriptingInstance(ScriptingInstance): self.queued_input = "" self.input_ready_state = core.ReadyForScriptExecution + @abc.abstractmethod def perform_destroy_instance(self): self.interpreter.end() + @abc.abstractmethod def perform_execute_script_input(self, text): if self.input_ready_state == core.NotReadyForInput: return core.InvalidScriptInput @@ -9667,18 +9731,23 @@ class PythonScriptingInstance(ScriptingInstance): self.interpreter.execute(text) return core.SuccessfulScriptExecution + @abc.abstractmethod def perform_set_current_binary_view(self, view): self.interpreter.current_view = view + @abc.abstractmethod def perform_set_current_function(self, func): self.interpreter.current_func = func + @abc.abstractmethod def perform_set_current_basic_block(self, block): self.interpreter.current_block = block + @abc.abstractmethod def perform_set_current_address(self, addr): self.interpreter.current_addr = addr + @abc.abstractmethod def perform_set_current_selection(self, begin, end): self.interpreter.current_selection_begin = begin self.interpreter.current_selection_end = end @@ -9979,15 +10048,17 @@ def demangle_ms(arch, mangled_name): if core.BNDemangleMS(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize)): for i in xrange(outSize.value): names.append(outName[i]) + #core.BNFreeDemangledName(outName.value, outSize.value) return (Type(handle), names) return (None, mangled_name) + _output_to_log = False def redirect_output_to_log(): global _output_to_log _output_to_log = True -class _ThreadActionContext: +class _ThreadActionContext(object): _actions = [] def __init__(self, func): -- cgit v1.3.1