diff options
Diffstat (limited to 'python')
| -rw-r--r-- | python/__init__.py | 26 | ||||
| -rw-r--r-- | python/architecture.py | 35 | ||||
| -rw-r--r-- | python/basicblock.py | 5 | ||||
| -rw-r--r-- | python/binaryview.py | 34 | ||||
| -rw-r--r-- | python/callingconvention.py | 7 | ||||
| -rw-r--r-- | python/databuffer.py | 4 | ||||
| -rw-r--r-- | python/demangle.py | 4 | ||||
| -rw-r--r-- | python/downloadprovider.py | 4 | ||||
| -rw-r--r-- | python/fileaccessor.py | 3 | ||||
| -rw-r--r-- | python/filemetadata.py | 2 | ||||
| -rw-r--r-- | python/function.py | 25 | ||||
| -rw-r--r-- | python/functionrecognizer.py | 14 | ||||
| -rw-r--r-- | python/highlight.py | 2 | ||||
| -rw-r--r-- | python/interaction.py | 17 | ||||
| -rw-r--r-- | python/log.py | 14 | ||||
| -rw-r--r-- | python/lowlevelil.py | 4 | ||||
| -rw-r--r-- | python/mainthread.py | 2 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 2 | ||||
| -rw-r--r-- | python/metadata.py | 6 | ||||
| -rw-r--r-- | python/platform.py | 76 | ||||
| -rw-r--r-- | python/plugin.py | 19 | ||||
| -rw-r--r-- | python/pluginmanager.py | 6 | ||||
| -rw-r--r-- | python/scriptingprovider.py | 46 | ||||
| -rw-r--r-- | python/setting.py | 8 | ||||
| -rw-r--r-- | python/transform.py | 15 | ||||
| -rw-r--r-- | python/types.py | 15 | ||||
| -rw-r--r-- | python/undoaction.py | 4 | ||||
| -rw-r--r-- | python/update.py | 12 |
28 files changed, 231 insertions, 180 deletions
diff --git a/python/__init__.py b/python/__init__.py index 2f7cc5a0..e1288b0a 100644 --- a/python/__init__.py +++ b/python/__init__.py @@ -25,6 +25,32 @@ import sys import ctypes from time import gmtime + +# 2-3 compatibility +try: + import builtins # __builtins__ for python2 +except ImportError: + pass +def range(*args): + """ A Python2 and Python3 Compatible Range Generator """ + try: + return xrange(*args) + except NameError: + return builtins.range(*args) + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + class metaclass(type): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + # Binary Ninja components import binaryninja._binaryninjacore as core # __all__ = [ diff --git a/python/architecture.py b/python/architecture.py index 521c750a..aee7c301 100644 --- a/python/architecture.py +++ b/python/architecture.py @@ -23,13 +23,12 @@ import traceback import ctypes import abc -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import (Endianness, ImplicitRegisterExtend, BranchType, InstructionTextTokenType, LowLevelILFlagCondition, FlagRole) import binaryninja from binaryninja import log - from binaryninja import lowlevelil from binaryninja import types from binaryninja import databuffer @@ -37,8 +36,9 @@ from binaryninja import platform from binaryninja import callingconvention # 2-3 compatibility -from six import with_metaclass -from six.moves import range +from binaryninja import range +from binaryninja import with_metaclass + class _ArchitectureMetaClass(type): @@ -624,7 +624,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_full_width_registers(self, ctxt, count): try: - regs = self._full_width_regs.values() + regs = list(self._full_width_regs.values()) count[0] = len(regs) reg_buf = (ctypes.c_uint * len(regs))() for i in range(0, len(regs)): @@ -639,7 +639,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_registers(self, ctxt, count): try: - regs = self._regs_by_index.keys() + regs = list(self._regs_by_index.keys()) count[0] = len(regs) reg_buf = (ctypes.c_uint * len(regs))() for i in range(0, len(regs)): @@ -654,7 +654,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_flags(self, ctxt, count): try: - flags = self._flags_by_index.keys() + flags = list(self._flags_by_index.keys()) count[0] = len(flags) flag_buf = (ctypes.c_uint * len(flags))() for i in range(0, len(flags)): @@ -669,7 +669,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_flag_write_types(self, ctxt, count): try: - write_types = self._flag_write_types_by_index.keys() + write_types = list(self._flag_write_types_by_index.keys()) count[0] = len(write_types) type_buf = (ctypes.c_uint * len(write_types))() for i in range(0, len(write_types)): @@ -684,7 +684,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_semantic_flag_classes(self, ctxt, count): try: - sem_classes = self._semantic_flag_classes_by_index.keys() + sem_classes = list(self._semantic_flag_classes_by_index.keys()) count[0] = len(sem_classes) class_buf = (ctypes.c_uint * len(sem_classes))() for i in range(0, len(sem_classes)): @@ -699,7 +699,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_semantic_flag_groups(self, ctxt, count): try: - sem_groups = self._semantic_flag_groups_by_index.keys() + sem_groups = list(self._semantic_flag_groups_by_index.keys()) count[0] = len(sem_groups) group_buf = (ctypes.c_uint * len(sem_groups))() for i in range(0, len(sem_groups)): @@ -938,7 +938,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_register_stacks(self, ctxt, count): try: - regs = self._reg_stacks_by_index.keys() + regs = list(self._reg_stacks_by_index.keys()) count[0] = len(regs) reg_buf = (ctypes.c_uint * len(regs))() for i in range(0, len(regs)): @@ -989,7 +989,7 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)): def _get_all_intrinsics(self, ctxt, count): try: - regs = self._intrinsics_by_index.keys() + regs = list(self._intrinsics_by_index.keys()) count[0] = len(regs) reg_buf = (ctypes.c_uint * len(regs))() for i in range(0, len(regs)): @@ -2415,8 +2415,8 @@ class CoreArchitecture(Architecture): :param str code: string representation of the instructions to be assembled :param int addr: virtual address that the instructions will be loaded at - :return: the bytes for the assembled instructions or error string - :rtype: (a tuple of instructions and empty string) or (or None and error string) + :return: the bytes for the assembled instructions + :rtype: Python3 - a 'bytes' object; Python2 - a 'str' :Example: >>> arch.assemble("je 10") @@ -2426,8 +2426,11 @@ class CoreArchitecture(Architecture): result = databuffer.DataBuffer() errors = ctypes.c_char_p() if not core.BNAssemble(self.handle, code, addr, result.handle, errors): - return None, errors.value - return str(result), errors.value + raise ValueError("Could not assemble") + if isinstance(str(result), bytes): + return str(result) + else: + return bytes(result) def is_never_branch_patch_available(self, data, addr): """ diff --git a/python/basicblock.py b/python/basicblock.py index b1f95ba3..11d5a7f4 100644 --- a/python/basicblock.py +++ b/python/basicblock.py @@ -20,14 +20,15 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import highlight from binaryninja import _binaryninjacore as core from binaryninja.enums import BranchType, HighlightColorStyle, HighlightStandardColor, InstructionTextTokenType # 2-3 compatibility -from six.moves import range +from binaryninja import range + class BasicBlockEdge(object): def __init__(self, branch_type, source, target, back_edge): diff --git a/python/binaryview.py b/python/binaryview.py index b1bc4822..d439f563 100644 --- a/python/binaryview.py +++ b/python/binaryview.py @@ -23,7 +23,7 @@ import traceback import ctypes import abc -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import (AnalysisState, SymbolType, InstructionTextTokenType, Endianness, ModificationStatus, StringType, SegmentFlag, SectionSemantics) @@ -38,8 +38,8 @@ from binaryninja import lineardisassembly from binaryninja import metadata # 2-3 compatibility -from six import with_metaclass -from six.moves import range +from binaryninja import range +from binaryninja import with_metaclass class BinaryDataNotification(object): @@ -98,17 +98,19 @@ class StringReference(object): @property def value(self): - return self.view.read(self.start, self.length) + return self.view.read(self.start, self.length).decode("charmap") def __repr__(self): return "<%s: %#x, len %#x>" % (self.type, self.start, self.length) +_pending_analysis_completion_events = {} class AnalysisCompletionEvent(object): """ The ``AnalysisCompletionEvent`` object provides an asynchronous mechanism for receiving callbacks when analysis is complete. The callback runs once. A completion event must be added - for each new analysis in order to be notified of each analysis completion. + for each new analysis in order to be notified of each analysis completion. The + AnalysisCompletionEvent class takes responcibility for keeping track of the object's lifetime. :Example: >>> def on_complete(self): @@ -122,11 +124,19 @@ class AnalysisCompletionEvent(object): self.callback = callback self._cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(self._notify) self.handle = core.BNAddAnalysisCompletionEvent(self.view.handle, None, self._cb) + global _pending_analysis_completion_events + _pending_analysis_completion_events[id(self)] = self def __del__(self): + global _pending_analysis_completion_events + if id(self) in _pending_analysis_completion_events: + del _pending_analysis_completion_events[id(self)] core.BNFreeAnalysisCompletionEvent(self.handle) def _notify(self, ctxt): + global _pending_analysis_completion_events + if id(self) in _pending_analysis_completion_events: + del _pending_analysis_completion_events[id(self)] try: self.callback(self) except: @@ -142,6 +152,9 @@ class AnalysisCompletionEvent(object): """ self.callback = self._empty_callback core.BNCancelAnalysisCompletionEvent(self.handle) + global _pending_analysis_completion_events + if id(self) in _pending_analysis_completion_events: + del _pending_analysis_completion_events[id(self)] class ActiveAnalysisInfo(object): @@ -1731,10 +1744,13 @@ class BinaryView(object): """ ``read`` returns the data reads at most ``length`` bytes from virtual address ``addr``. + Note: Python2 returns a str, but Python3 returns a bytes object. str(DataBufferObject) will + still get you a str in either case. + :param int addr: virtual address to read from. :param int length: number of bytes to read. :return: at most ``length`` bytes from the virtual address ``addr``, empty string on error or no data. - :rtype: str + :rtype: python2 - str; python3 - bytes :Example: >>> #Opening a x86_64 Mach-O binary @@ -2784,7 +2800,9 @@ class BinaryView(object): def add_analysis_completion_event(self, callback): """ ``add_analysis_completion_event`` sets up a call back function to be called when analysis has been completed. - This is helpful when using asynchronously analysis. + This is helpful when using ``update_analysis`` which does not wait for analysis completion before returning. + + The callee of this function is not resposible for maintaining the lifetime of the returned AnalysisCompletionEvent object. :param callable() callback: A function to be called with no parameters when analysis has completed. :return: An initialized AnalysisCompletionEvent object. @@ -3481,7 +3499,7 @@ class BinaryView(object): def get_unique_section_names(self, name_list): incoming_names = (ctypes.c_char_p * len(name_list))() for i in range(0, len(name_list)): - incoming_names[i] = name_list[i] + incoming_names[i] = name_list[i].encode('charmap') outgoing_names = core.BNGetUniqueSectionNames(self.handle, incoming_names, len(name_list)) result = [] for i in range(0, len(name_list)): diff --git a/python/callingconvention.py b/python/callingconvention.py index 1b0d068e..6b906184 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -21,18 +21,17 @@ import traceback import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import _binaryninjacore as core from binaryninja import log from binaryninja.enums import VariableSourceType # 2-3 compatibility -from six.moves import range +from binaryninja import range class CallingConvention(object): - from binaryninja import types name = None caller_saved_regs = [] int_arg_regs = [] @@ -48,7 +47,7 @@ class CallingConvention(object): _registered_calling_conventions = [] - def __init__(self, arch=None, name=None, handle=None, confidence=types.max_confidence): + def __init__(self, arch=None, name=None, handle=None, confidence=binaryninja.types.max_confidence): if handle is None: if arch is None or name is None: raise ValueError("Must specify either handle or architecture and name") diff --git a/python/databuffer.py b/python/databuffer.py index 1b29a7eb..298d0002 100644 --- a/python/databuffer.py +++ b/python/databuffer.py @@ -20,7 +20,7 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core @@ -114,7 +114,7 @@ class DataBuffer(object): def __str__(self): buf = ctypes.create_string_buffer(len(self)) ctypes.memmove(buf, core.BNGetDataBufferContents(self.handle), len(self)) - if type(buf.raw) is str: + if isinstance(buf.raw, str): return buf.raw else: return buf.raw.decode("charmap") diff --git a/python/demangle.py b/python/demangle.py index 90a19761..466324bc 100644 --- a/python/demangle.py +++ b/python/demangle.py @@ -20,11 +20,11 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core # 2-3 compatibility -from six.moves import range +from binaryninja import range def get_qualified_name(names): diff --git a/python/downloadprovider.py b/python/downloadprovider.py index d34ca358..c714cb98 100644 --- a/python/downloadprovider.py +++ b/python/downloadprovider.py @@ -28,6 +28,7 @@ import traceback # Binary Ninja Components import binaryninja._binaryninjacore as core from binaryninja.setting import Setting +from binaryninja import with_metaclass from binaryninja import startup from binaryninja import log @@ -109,8 +110,7 @@ class _DownloadProviderMetaclass(type): raise AttributeError("attribute '%s' is read only" % name) -class DownloadProvider(object): - __metaclass__ = _DownloadProviderMetaclass +class DownloadProvider(with_metaclass(_DownloadProviderMetaclass, object)): name = None instance_class = None _registered_providers = [] diff --git a/python/fileaccessor.py b/python/fileaccessor.py index 3c7c5e45..c2539b39 100644 --- a/python/fileaccessor.py +++ b/python/fileaccessor.py @@ -21,11 +21,10 @@ import traceback import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core class FileAccessor(object): - def __init__(self): self._cb = core.BNFileAccessor() self._cb.context = 0 diff --git a/python/filemetadata.py b/python/filemetadata.py index ee69dce8..cafe1d67 100644 --- a/python/filemetadata.py +++ b/python/filemetadata.py @@ -22,7 +22,7 @@ from __future__ import absolute_import import traceback import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja Components import binaryninja from binaryninja import _binaryninjacore as core from binaryninja import associateddatastore #required for _FileMetadataAssociatedDataStore diff --git a/python/function.py b/python/function.py index 6392d7f2..8407eece 100644 --- a/python/function.py +++ b/python/function.py @@ -23,20 +23,20 @@ import threading import traceback import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import _binaryninjacore as core +from binaryninja import associateddatastore #required in the main scope due to being an argument for _FunctionAssociatedDataStore +from binaryninja import highlight +from binaryninja import log +from binaryninja import types from binaryninja.enums import (AnalysisSkipReason, FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType, HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend, DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType, FunctionAnalysisSkipOverride) -from binaryninja import associateddatastore #required in the main scope due to being an argument for _FunctionAssociatedDataStore -from binaryninja import types -from binaryninja import highlight -from binaryninja import log # 2-3 compatibility -from six.moves import range +from binaryninja import range class LookupTableEntry(object): @@ -49,7 +49,7 @@ class LookupTableEntry(object): class RegisterValue(object): - def __init__(self, arch = None, value = None, confidence = binaryninja.types.max_confidence): + def __init__(self, arch = None, value = None, confidence = types.max_confidence): self.is_constant = False if value is None: self.type = RegisterValueType.UndeterminedValue @@ -1160,6 +1160,8 @@ class Function(object): for j in range(0, lines[i].count): token_type = InstructionTextTokenType(lines[i].tokens[j].type) text = lines[i].tokens[j].text + if not isinstance(text, str): + text = text.encode("charmap") value = lines[i].tokens[j].value size = lines[i].tokens[j].size operand = lines[i].tokens[j].operand @@ -1836,6 +1838,7 @@ class DisassemblySettings(object): core.BNSetDisassemblySettingsOption(self.handle, option, state) +_pending_function_graph_completion_events = {} class FunctionGraph(object): def __init__(self, view, handle): self.view = view @@ -1969,6 +1972,9 @@ class FunctionGraph(object): try: if self._on_complete is not None: self._on_complete() + global _pending_function_graph_completion_events + if id(self) in _pending_function_graph_completion_events: + del _pending_function_graph_completion_events[id(self)] except: log.log_error(traceback.format_exc()) @@ -1993,11 +1999,16 @@ class FunctionGraph(object): self._wait_cond.release() def on_complete(self, callback): + global _pending_function_graph_completion_events + _pending_function_graph_completion_events[id(self)] = self self._on_complete = callback core.BNSetFunctionGraphCompleteCallback(self.handle, None, self._cb) def abort(self): core.BNAbortFunctionGraph(self.handle) + global _pending_function_graph_completion_events + if id(self) in _pending_function_graph_completion_events: + del _pending_function_graph_completion_events[id(self)] def get_blocks_in_region(self, left, top, right, bottom): count = ctypes.c_ulonglong() diff --git a/python/functionrecognizer.py b/python/functionrecognizer.py index e390a3c8..319bff0e 100644 --- a/python/functionrecognizer.py +++ b/python/functionrecognizer.py @@ -20,15 +20,15 @@ import traceback -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core +from binaryninja import function +from binaryninja import filemetadata +from binaryninja import binaryview +from binaryninja import lowlevelil class FunctionRecognizer(object): - from binaryninja import function - from binaryninja import filemetadata - from binaryninja import binaryview - from binaryninja import lowlevelil _instance = None @@ -54,7 +54,7 @@ class FunctionRecognizer(object): try: file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(data)) view = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(data)) - func = binaryninja.function.Function(view, handle = core.BNNewFunctionReference(func)) + func = function.Function(view, handle = core.BNNewFunctionReference(func)) il = lowlevelil.LowLevelILFunction(func.arch, handle = core.BNNewLowLevelILFunctionReference(il)) return self.recognize_low_level_il(view, func, il) except: @@ -68,7 +68,7 @@ class FunctionRecognizer(object): try: file_metadata = filemetadata.FileMetadata(handle = core.BNGetFileForView(data)) view = binaryview.BinaryView(file_metadata = file_metadata, handle = core.BNNewViewReference(data)) - func = binaryninja.function.Function(view, handle = core.BNNewFunctionReference(func)) + func = function.Function(view, handle = core.BNNewFunctionReference(func)) il = mediumlevelil.MediumLevelILFunction(func.arch, handle = core.BNNewMediumLevelILFunctionReference(il)) return self.recognize_medium_level_il(view, func, il) except: diff --git a/python/highlight.py b/python/highlight.py index b04561bd..55246a9a 100644 --- a/python/highlight.py +++ b/python/highlight.py @@ -19,7 +19,7 @@ # IN THE SOFTWARE. -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import HighlightColorStyle, HighlightStandardColor diff --git a/python/interaction.py b/python/interaction.py index 5b78b278..49b4e024 100644 --- a/python/interaction.py +++ b/python/interaction.py @@ -21,12 +21,13 @@ import ctypes import traceback -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import FormInputFieldType, MessageBoxIcon, MessageBoxButtonSet, MessageBoxButtonResult +from binaryninja import binaryview # 2-3 compatibility -from six.moves import range +from binaryninja import range class LabelField(object): @@ -152,7 +153,11 @@ class AddressField(object): class ChoiceField(object): """ ``ChoiceField`` prompts the user to choose from the list of strings provided in ``choices``. Result is stored - in self.result as an index in to the coices array. + in self.result as an index in to the choices array. + + :attr str prompt: prompt to be presented to the user + :attr list(str) choices: list of choices to choose from + """ def __init__(self, prompt, choices): self.prompt = prompt @@ -164,7 +169,7 @@ class ChoiceField(object): value.prompt = self.prompt choice_buf = (ctypes.c_char_p * len(self.choices))() for i in range(0, len(self.choices)): - choice_buf[i] = str(self.choices[i]) + choice_buf[i] = self.choices[i].encode('charmap') value.choices = choice_buf value.count = len(self.choices) @@ -242,8 +247,6 @@ class DirectoryNameField(object): class InteractionHandler(object): - - from binaryninja import binaryview _interaction_handler = None def __init__(self): @@ -617,7 +620,7 @@ def get_choice_input(prompt, title, choices): """ choice_buf = (ctypes.c_char_p * len(choices))() for i in range(0, len(choices)): - choice_buf[i] = str(choices[i]) + choice_buf[i] = str(choices[i]).encode('charmap') value = ctypes.c_ulonglong() if not core.BNGetChoiceInput(value, prompt, title, choice_buf, len(choices)): return None diff --git a/python/log.py b/python/log.py index d4d87019..9a5e1358 100644 --- a/python/log.py +++ b/python/log.py @@ -19,7 +19,7 @@ # IN THE SOFTWARE. -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import LogLevel @@ -55,7 +55,7 @@ def log(level, text): :param str text: message to print :rtype: None """ - core.BNLog(level, "%s", str(text)) + core.BNLog(level,text) def log_debug(text): @@ -70,7 +70,7 @@ def log_debug(text): >>> log_debug("Hotdogs!") Hotdogs! """ - core.BNLogDebug("%s", str(text)) + core.BNLogDebug(text) def log_info(text): @@ -85,7 +85,7 @@ def log_info(text): Saucisson! >>> """ - core.BNLogInfo("%s", str(text)) + core.BNLogInfo(text) def log_warn(text): @@ -101,7 +101,7 @@ def log_warn(text): Chilidogs! >>> """ - core.BNLogWarn("%s", str(text)) + core.BNLogWarn(text) def log_error(text): @@ -117,7 +117,7 @@ def log_error(text): Spanferkel! >>> """ - core.BNLogError("%s", str(text)) + core.BNLogError(text) def log_alert(text): @@ -133,7 +133,7 @@ def log_alert(text): Kielbasa! >>> """ - core.BNLogAlert("%s", str(text)) + core.BNLogAlert(text) def log_to_stdout(min_level=LogLevel.InfoLog): diff --git a/python/lowlevelil.py b/python/lowlevelil.py index 272b2474..e714eb48 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -21,14 +21,14 @@ import ctypes import struct -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import _binaryninjacore as core from binaryninja.enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType from binaryninja import basicblock #required for LowLevelILBasicBlock # 2-3 compatibility -from six.moves import range +from binaryninja import range class LowLevelILLabel(object): diff --git a/python/mainthread.py b/python/mainthread.py index 16938f1a..5b0cd53c 100644 --- a/python/mainthread.py +++ b/python/mainthread.py @@ -18,7 +18,7 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja import scriptingprovider diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index f7e9951a..cfa8f900 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -30,7 +30,7 @@ from binaryninja import types from binaryninja import lowlevelil # 2-3 compatibility -from six.moves import range +from binaryninja import range class SSAVariable(object): diff --git a/python/metadata.py b/python/metadata.py index fed8bdaa..b17bbf4f 100644 --- a/python/metadata.py +++ b/python/metadata.py @@ -22,12 +22,12 @@ from __future__ import absolute_import import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import MetadataType # 2-3 compatibility -from six.moves import range +from binaryninja import range class Metadata(object): @@ -147,7 +147,7 @@ class Metadata(object): result = core.BNMetadataGetValueStore(self.handle) try: for i in range(result.contents.size): - if type(result.contents.keys[i]) is bytes: + if isinstance(result.contents.keys[i], bytes): yield str(result.contents.keys[i].decode('charmap')) else: yield result.contents.keys[i] diff --git a/python/platform.py b/python/platform.py index c57315ce..9a5f70df 100644 --- a/python/platform.py +++ b/python/platform.py @@ -20,18 +20,18 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import _binaryninjacore as core +from binaryninja import types -#2-3 compatibility -from six import with_metaclass -from six.moves import range +# 2-3 compatibility +from binaryninja import range +from binaryninja import with_metaclass class _PlatformMetaClass(type): - from binaryninja import types @property def list(self): binaryninja._init_plugins() @@ -240,8 +240,8 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): type_list = core.BNGetPlatformTypes(self.handle, count) result = {} for i in range(0, count.value): - name = binaryninja.types.QualifiedName._from_core_struct(type_list[i].name) - result[name] = binaryninja.types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) + name = types.QualifiedName._from_core_struct(type_list[i].name) + result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) core.BNFreeTypeList(type_list, count.value) return result @@ -252,8 +252,8 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): type_list = core.BNGetPlatformVariables(self.handle, count) result = {} for i in range(0, count.value): - name = binaryninja.types.QualifiedName._from_core_struct(type_list[i].name) - result[name] = binaryninja.types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) + name = types.QualifiedName._from_core_struct(type_list[i].name) + result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) core.BNFreeTypeList(type_list, count.value) return result @@ -264,8 +264,8 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): type_list = core.BNGetPlatformFunctions(self.handle, count) result = {} for i in range(0, count.value): - name = binaryninja.types.QualifiedName._from_core_struct(type_list[i].name) - result[name] = binaryninja.types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) + name = types.QualifiedName._from_core_struct(type_list[i].name) + result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self) core.BNFreeTypeList(type_list, count.value) return result @@ -276,8 +276,8 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): call_list = core.BNGetPlatformSystemCalls(self.handle, count) result = {} for i in range(0, count.value): - name = binaryninja.types.QualifiedName._from_core_struct(call_list[i].name) - t = binaryninja.types.Type(core.BNNewTypeReference(call_list[i].type), platform = self) + name = types.QualifiedName._from_core_struct(call_list[i].name) + t = types.Type(core.BNNewTypeReference(call_list[i].type), platform = self) result[call_list[i].number] = (name, t) core.BNFreeSystemCallList(call_list, count.value) return result @@ -328,25 +328,25 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): return Platform(None, handle = result), new_addr.value def get_type_by_name(self, name): - name = binaryninja.types.QualifiedName(name)._get_core_struct() + name = types.QualifiedName(name)._get_core_struct() obj = core.BNGetPlatformTypeByName(self.handle, name) if not obj: return None - return binaryninja.types.Type(obj, platform = self) + return types.Type(obj, platform = self) def get_variable_by_name(self, name): - name = binaryninja.types.QualifiedName(name)._get_core_struct() + name = types.QualifiedName(name)._get_core_struct() obj = core.BNGetPlatformVariableByName(self.handle, name) if not obj: return None - return binaryninja.types.Type(obj, platform = self) + return types.Type(obj, platform = self) def get_function_by_name(self, name): - name = binaryninja.types.QualifiedName(name)._get_core_struct() + name = types.QualifiedName(name)._get_core_struct() obj = core.BNGetPlatformFunctionByName(self.handle, name) if not obj: return None - return binaryninja.types.Type(obj, platform = self) + return types.Type(obj, platform = self) def get_system_call_name(self, number): return core.BNGetPlatformSystemCallName(self.handle, number) @@ -355,15 +355,15 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): obj = core.BNGetPlatformSystemCallType(self.handle, number) if not obj: return None - return binaryninja.types.Type(obj, platform = self) + return types.Type(obj, platform = self) def generate_auto_platform_type_id(self, name): - name = binaryninja.types.QualifiedName(name)._get_core_struct() + name = types.QualifiedName(name)._get_core_struct() return core.BNGenerateAutoPlatformTypeId(self.handle, name) def generate_auto_platform_type_ref(self, type_class, name): type_id = self.generate_auto_platform_type_id(name) - return binaryninja.types.NamedTypeReference(type_class, type_id, name) + return types.NamedTypeReference(type_class, type_id, name) def get_auto_platform_type_id_source(self): return core.BNGetAutoPlatformTypeIdSource(self.handle) @@ -391,7 +391,7 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): filename = "input" dir_buf = (ctypes.c_char_p * len(include_dirs))() for i in range(0, len(include_dirs)): - dir_buf[i] = str(include_dirs[i]) + dir_buf[i] = include_dirs[i].encode('charmap') parse = core.BNTypeParserResult() errors = ctypes.c_char_p() result = core.BNParseTypesFromSource(self.handle, source, filename, parse, errors, dir_buf, @@ -404,16 +404,16 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): variables = {} functions = {} for i in range(0, parse.typeCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.types[i].name) - type_dict[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.types[i].name) + type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) for i in range(0, parse.variableCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.variables[i].name) - variables[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.variables[i].name) + variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self) for i in range(0, parse.functionCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.functions[i].name) - functions[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.functions[i].name) + functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self) core.BNFreeTypeParserResult(parse) - return binaryninja.types.TypeParserResult(type_dict, variables, functions) + return types.TypeParserResult(type_dict, variables, functions) def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None): """ @@ -437,7 +437,7 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): """ dir_buf = (ctypes.c_char_p * len(include_dirs))() for i in range(0, len(include_dirs)): - dir_buf[i] = str(include_dirs[i]) + dir_buf[i] = include_dirs[i].encode('charmap') parse = core.BNTypeParserResult() errors = ctypes.c_char_p() result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf, @@ -450,13 +450,13 @@ class Platform(with_metaclass(_PlatformMetaClass, object)): variables = {} functions = {} for i in range(0, parse.typeCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.types[i].name) - type_dict[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.types[i].name) + type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self) for i in range(0, parse.variableCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.variables[i].name) - variables[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.variables[i].name) + variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self) for i in range(0, parse.functionCount): - name = binaryninja.types.QualifiedName._from_core_struct(parse.functions[i].name) - functions[name] = binaryninja.types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self) + name = types.QualifiedName._from_core_struct(parse.functions[i].name) + functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self) core.BNFreeTypeParserResult(parse) - return binaryninja.types.TypeParserResult(type_dict, variables, functions) + return types.TypeParserResult(type_dict, variables, functions) diff --git a/python/plugin.py b/python/plugin.py index 52feced4..b8217f0b 100644 --- a/python/plugin.py +++ b/python/plugin.py @@ -22,15 +22,18 @@ import traceback import ctypes import threading -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import log from binaryninja import _binaryninjacore as core from binaryninja.enums import PluginCommandType +from binaryninja import filemetadata +from binaryninja import binaryview +from binaryninja import function -#2-3 compatibility -from six import with_metaclass -from six.moves import range +# 2-3 compatibility +from binaryninja import range +from binaryninja import with_metaclass class PluginCommandContext(object): @@ -43,7 +46,6 @@ class PluginCommandContext(object): class _PluginCommandMetaClass(type): - @property def list(self): binaryninja._init_plugins() @@ -73,11 +75,6 @@ class _PluginCommandMetaClass(type): class PluginCommand(with_metaclass(_PluginCommandMetaClass, object)): - - from binaryninja import filemetadata - from binaryninja import binaryview - from binaryninja import function - _registered_commands = [] def __init__(self, cmd): @@ -540,7 +537,6 @@ class MainThreadAction(object): class MainThreadActionHandler(object): - _main_thread = None def __init__(self): @@ -586,7 +582,6 @@ class _BackgroundTaskMetaclass(type): class BackgroundTask(with_metaclass(_BackgroundTaskMetaclass, object)): - def __init__(self, initial_progress_text = "", can_cancel = False, handle = None): if handle is None: self.handle = core.BNBeginBackgroundTask(initial_progress_text, can_cancel) diff --git a/python/pluginmanager.py b/python/pluginmanager.py index ad314629..c7a0c83a 100644 --- a/python/pluginmanager.py +++ b/python/pluginmanager.py @@ -20,11 +20,12 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core # 2-3 compatibility -from six.moves import range +from binaryninja import range + class RepoPlugin(object): """ @@ -201,7 +202,6 @@ class RepositoryManager(object): ``RepositoryManager`` Keeps track of all the repositories and keeps the enabled_plugins.json file coherent with the plugins that are installed/unstalled enabled/disabled """ - def __init__(self, handle=None): raise Exception("RepositoryManager temporarily disabled!") self.handle = core.BNGetRepositoryManager() diff --git a/python/scriptingprovider.py b/python/scriptingprovider.py index 374b2f41..37642ed4 100644 --- a/python/scriptingprovider.py +++ b/python/scriptingprovider.py @@ -26,14 +26,15 @@ import threading import abc import sys -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components +import binaryninja from binaryninja import _binaryninjacore as core from binaryninja.enums import ScriptingProviderExecuteResult, ScriptingProviderInputReadyState -import binaryninja.log +from binaryninja import log -#2-3 compatibility -from six import with_metaclass -from six.moves import range +# 2-3 compatibility +from binaryninja import range +from binaryninja import with_metaclass class _ThreadActionContext(object): @@ -75,19 +76,19 @@ class ScriptingOutputListener(object): try: self.notify_output(text) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _error(self, ctxt, text): try: self.notify_error(text) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _input_ready_state_changed(self, ctxt, state): try: self.notify_input_ready_state_changed(state) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def notify_output(self, text): pass @@ -123,13 +124,13 @@ class ScriptingInstance(object): try: self.perform_destroy_instance() except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _execute_script_input(self, ctxt, text): try: return self.perform_execute_script_input(text) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) return ScriptingProviderExecuteResult.InvalidScriptInput def _set_current_binary_view(self, ctxt, view): @@ -140,7 +141,7 @@ class ScriptingInstance(object): view = None self.perform_set_current_binary_view(view) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _set_current_function(self, ctxt, func): try: @@ -150,7 +151,7 @@ class ScriptingInstance(object): func = None self.perform_set_current_function(func) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _set_current_basic_block(self, ctxt, block): try: @@ -165,19 +166,19 @@ class ScriptingInstance(object): block = None self.perform_set_current_basic_block(block) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _set_current_address(self, ctxt, addr): try: self.perform_set_current_address(addr) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) def _set_current_selection(self, ctxt, begin, end): try: self.perform_set_current_selection(begin, end) except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) @abc.abstractmethod def perform_destroy_instance(self): @@ -324,7 +325,7 @@ class ScriptingProvider(with_metaclass(_ScriptingProviderMetaclass, object)): return None return ctypes.cast(core.BNNewScriptingInstanceReference(result.handle), ctypes.c_void_p).value except: - binaryninja.log.log_error(traceback.format_exc()) + log.log_error(traceback.format_exc()) return None def create_instance(self): @@ -390,7 +391,7 @@ class _PythonScriptingInstanceOutput(object): interpreter = PythonScriptingInstance._interpreter.value if interpreter is None: - if binaryninja.log.is_output_redirected_to_log(): + if log.is_output_redirected_to_log(): self.buffer += data while True: i = self.buffer.find('\n') @@ -400,9 +401,9 @@ class _PythonScriptingInstanceOutput(object): self.buffer = self.buffer[i + 1:] if self.is_error: - binaryninja.log.log_error(line) + log.log_error(line) else: - binaryninja.log.log_info(line) + log.log_info(line) else: self.orig.write(data) else: @@ -490,7 +491,7 @@ class PythonScriptingInstance(ScriptingInstance): self.code = None self.input = "" - self.interpreter.push("from binaryninja import *\n") + self.interpreter.push("from binaryninja import *") def execute(self, code): self.code = code @@ -553,8 +554,8 @@ class PythonScriptingInstance(ScriptingInstance): self.locals["current_llil"] = self.active_func.low_level_il self.locals["current_mlil"] = self.active_func.medium_level_il - for line in code.split("\n"): - self.interpreter.push(line) + for line in code.split(b'\n'): + self.interpreter.push(line.decode('charmap')) if self.locals["here"] != self.active_addr: if not self.active_view.file.navigate(self.active_view.file.view, self.locals["here"]): @@ -660,3 +661,4 @@ def redirect_stdio(): sys.stdin = _PythonScriptingInstanceInput(sys.stdin) sys.stdout = _PythonScriptingInstanceOutput(sys.stdout, False) sys.stderr = _PythonScriptingInstanceOutput(sys.stderr, True) + sys.excepthook = sys.__excepthook__
\ No newline at end of file diff --git a/python/setting.py b/python/setting.py index fea06140..355492aa 100644 --- a/python/setting.py +++ b/python/setting.py @@ -20,11 +20,11 @@ import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core # 2-3 compatibility -from six.moves import range +from binaryninja import range class Setting(object): @@ -113,7 +113,7 @@ class Setting(object): length.value = len(value) default_list = (ctypes.c_char_p * len(value))() for i in range(len(value)): - default_list[i] = value[i].encode('utf-8') + default_list[i] = value[i].encode('charmap') return core.BNSettingSetStringList(self.plugin_name, name, default_list, length, auto_flush) @@ -141,4 +141,4 @@ class Setting(object): core.BNSettingRemoveSettingGroup(self.plugin_name, auto_flush) def remove_setting(self, setting, auto_flush=True): - core.BNSettingRemoveSetting(self.plugin_name, setting, auto_flush)
\ No newline at end of file + core.BNSettingRemoveSetting(self.plugin_name, setting, auto_flush) diff --git a/python/transform.py b/python/transform.py index e16c6bfc..1734d248 100644 --- a/python/transform.py +++ b/python/transform.py @@ -22,20 +22,19 @@ import traceback import ctypes import abc -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import log from binaryninja import databuffer from binaryninja import _binaryninjacore as core from binaryninja.enums import TransformType -#2-3 compatibility -from six import with_metaclass -from six.moves import range +# 2-3 compatibility +from binaryninja import range +from binaryninja import with_metaclass class _TransformMetaClass(type): - @property def list(self): binaryninja._init_plugins() @@ -96,8 +95,6 @@ class TransformParameter(object): class Transform(with_metaclass(_TransformMetaClass, object)): - - from binaryninja import databuffer transform_type = None name = None long_name = None @@ -224,7 +221,7 @@ class Transform(with_metaclass(_TransformMetaClass, object)): def decode(self, input_buf, params = {}): input_buf = databuffer.DataBuffer(input_buf) output_buf = databuffer.DataBuffer() - keys = params.keys() + keys = list(params.keys()) param_buf = (core.BNTransformParameter * len(keys))() for i in range(0, len(keys)): data = databuffer.DataBuffer(params[keys[i]]) @@ -237,7 +234,7 @@ class Transform(with_metaclass(_TransformMetaClass, object)): def encode(self, input_buf, params = {}): input_buf = databuffer.DataBuffer(input_buf) output_buf = databuffer.DataBuffer() - keys = params.keys() + keys = list(params.keys()) param_buf = (core.BNTransformParameter * len(keys))() for i in range(0, len(keys)): data = databuffer.DataBuffer(params[keys[i]]) diff --git a/python/types.py b/python/types.py index 2ad8d2c2..e8ce7464 100644 --- a/python/types.py +++ b/python/types.py @@ -23,23 +23,26 @@ max_confidence = 255 import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components import binaryninja from binaryninja import _binaryninjacore as core from binaryninja.enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType, VariableSourceType -#2-3 compatibility -from six.moves import range +# 2-3 compatibility +from binaryninja import range class QualifiedName(object): def __init__(self, name = []): if isinstance(name, str): self.name = [name] + self.byte_name = [name.encode('charmap')] elif isinstance(name, QualifiedName): self.name = name.name + self.byte_name = [n.encode('charmap') for n in name.name] else: - self.name = [i.decode('utf-8') for i in name] + self.name = [i.decode('charmap') for i in name] + self.byte_name = name def __str__(self): return "::".join(self.name) @@ -102,7 +105,7 @@ class QualifiedName(object): result = core.BNQualifiedName() name_list = (ctypes.c_char_p * len(self.name))() for i in range(0, len(self.name)): - name_list[i] = self.name[i] + name_list[i] = self.name[i].encode('charmap') result.name = name_list result.nameCount = len(self.name) return result @@ -1022,7 +1025,7 @@ def preprocess_source(source, filename=None, include_dirs=[]): filename = "input" dir_buf = (ctypes.c_char_p * len(include_dirs))() for i in range(0, len(include_dirs)): - dir_buf[i] = str(include_dirs[i]) + dir_buf[i] = include_dirs[i].encode('charmap') output = ctypes.c_char_p() errors = ctypes.c_char_p() result = core.BNPreprocessSource(source, filename, output, errors, dir_buf, len(include_dirs)) diff --git a/python/undoaction.py b/python/undoaction.py index 732d559a..7891bf54 100644 --- a/python/undoaction.py +++ b/python/undoaction.py @@ -22,14 +22,12 @@ import traceback import json import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import ActionType class UndoAction(object): - - name = None action_type = None _registered = False diff --git a/python/update.py b/python/update.py index 4c77b202..7f5d6f9c 100644 --- a/python/update.py +++ b/python/update.py @@ -21,18 +21,16 @@ import traceback import ctypes -# Binary Ninja components -- additional imports belong in the appropriate class +# Binary Ninja components from binaryninja import _binaryninjacore as core from binaryninja.enums import UpdateResult - -#2-3 compatibility -from six import with_metaclass -from six.moves import range +# 2-3 compatibility +from binaryninja import range +from binaryninja import with_metaclass class _UpdateChannelMetaClass(type): - @property def list(self): binaryninja._init_plugins() @@ -99,7 +97,6 @@ class _UpdateChannelMetaClass(type): 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 @@ -114,7 +111,6 @@ class UpdateProgressCallback(object): class UpdateChannel(with_metaclass(_UpdateChannelMetaClass, object)): - def __init__(self, name, desc, ver): self.name = name self.description = desc |
