summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorJordan Wiens <jordan@psifertex.com>2018-03-04 18:08:04 -0500
committerRyan Snyder <ryan@vector35.com>2018-07-10 18:11:08 -0400
commit8849fb2b2b8dc824bd3f17ce1026a04856477a94 (patch)
treee85f3db97d6d6b5fa2a21162c684fd08d47e4ab0 /python
parent8028bd325bc94a385f99122d87ac906ba717ecbf (diff)
working division, prints, and metaclasses, but imports broken, still needs work
Diffstat (limited to 'python')
-rw-r--r--python/__init__.py60
-rw-r--r--python/architecture.py36
-rw-r--r--python/basicblock.py12
-rw-r--r--python/binaryview.py66
-rw-r--r--python/callingconvention.py17
-rw-r--r--python/databuffer.py4
-rw-r--r--python/demangle.py7
-rw-r--r--python/examples/README.md56
-rw-r--r--python/examples/angr_plugin.py153
-rw-r--r--python/examples/arch_hook.py16
-rw-r--r--python/examples/bin_info.py72
-rw-r--r--python/examples/breakpoint.py50
-rwxr-xr-xpython/examples/export_svg.py224
-rw-r--r--python/examples/instruction_iterator.py53
-rw-r--r--python/examples/jump_table.py86
-rw-r--r--python/examples/nds.py117
-rw-r--r--python/examples/nes.py646
-rw-r--r--python/examples/notification_callbacks.py51
-rw-r--r--python/examples/nsf.py145
-rw-r--r--python/examples/print_syscalls.py55
-rw-r--r--python/examples/version_switcher.py150
-rw-r--r--python/fileaccessor.py7
-rw-r--r--python/filemetadata.py17
-rw-r--r--python/function.py35
-rw-r--r--python/functionrecognizer.py14
-rw-r--r--python/generator.cpp4
-rw-r--r--python/highlight.py6
-rw-r--r--python/interaction.py12
-rw-r--r--python/log.py5
-rw-r--r--python/lowlevelil.py25
-rw-r--r--python/mainthread.py6
-rw-r--r--python/mediumlevelil.py18
-rw-r--r--python/metadata.py7
-rw-r--r--python/platform.py19
-rw-r--r--python/plugin.py29
-rw-r--r--python/pluginmanager.py8
-rw-r--r--python/scriptingprovider.py25
-rw-r--r--python/setting.py4
-rw-r--r--python/startup.py2
-rw-r--r--python/transform.py18
-rw-r--r--python/types.py15
-rw-r--r--python/undoaction.py10
-rw-r--r--python/update.py17
43 files changed, 278 insertions, 2101 deletions
diff --git a/python/__init__.py b/python/__init__.py
index fda5f297..66f4bfe8 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -19,41 +19,41 @@
# IN THE SOFTWARE.
+from __future__ import absolute_import
import atexit
import sys
from time import gmtime
# Binary Ninja components
-import _binaryninjacore as core
-from .enums import *
-from .databuffer import *
-from .filemetadata import *
-from .fileaccessor import *
-from .binaryview import *
-from .transform import *
-from .architecture import *
-from .basicblock import *
-from .function import *
-from .log import *
-from .lowlevelil import *
-from .mediumlevelil import *
-from .types import *
-from .functionrecognizer import *
-from .update import *
-from .plugin import *
-from .callingconvention import *
-from .platform import *
-from .demangle import *
-from .mainthread import *
-from .interaction import *
-from .lineardisassembly import *
-from .undoaction import *
-from .highlight import *
-from .scriptingprovider import *
-from .downloadprovider import *
-from .pluginmanager import *
-from .setting import *
-from .metadata import *
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import *
+from binaryninja.databuffer import *
+from binaryninja.filemetadata import *
+from binaryninja.fileaccessor import *
+from binaryninja.binaryview import *
+from binaryninja.transform import *
+from binaryninja.architecture import *
+from binaryninja.basicblock import *
+from binaryninja.function import *
+from binaryninja.log import *
+from binaryninja.lowlevelil import *
+from binaryninja.mediumlevelil import *
+from binaryninja.types import *
+from binaryninja.functionrecognizer import *
+from binaryninja.update import *
+from binaryninja.plugin import *
+from binaryninja.callingconvention import *
+from binaryninja.platform import *
+from binaryninja.demangle import *
+from binaryninja.mainthread import *
+from binaryninja.interaction import *
+from binaryninja.lineardisassembly import *
+from binaryninja.undoaction import *
+from binaryninja.highlight import *
+from binaryninja.scriptingprovider import *
+from binaryninja.pluginmanager import *
+from binaryninja.setting import *
+from binaryninja.metadata import *
def shutdown():
diff --git a/python/architecture.py b/python/architecture.py
index df22da7f..360ce6bf 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -18,25 +18,22 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+from __future__ import absolute_import
import traceback
import ctypes
import abc
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import (Endianness, ImplicitRegisterExtend, BranchType,
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import (Endianness, ImplicitRegisterExtend, BranchType,
InstructionTextTokenType, LowLevelILFlagCondition, FlagRole)
-import startup
-import function
-import lowlevelil
-import callingconvention
-import platform
-import log
-import databuffer
-import types
+
+#2-3 compatibility
+from six import with_metaclass
class _ArchitectureMetaClass(type):
+ from binaryninja import startup
@property
def list(self):
startup._init_plugins()
@@ -80,12 +77,12 @@ class _ArchitectureMetaClass(type):
raise AttributeError("attribute '%s' is read only" % name)
-class Architecture(object):
+class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
"""
``class Architecture`` is the parent class for all CPU architectures. Subclasses of Architecture implement assembly,
disassembly, IL lifting, and patching.
- ``class Architecture`` has a ``__metaclass__`` with the additional methods ``register``, and supports
+ ``class Architecture`` has a metaclass with the additional methods ``register``, and supports
iteration::
>>> #List the architectures
@@ -130,10 +127,17 @@ class Architecture(object):
semantic_class_for_flag_write_type = {}
reg_stacks = {}
intrinsics = {}
- __metaclass__ = _ArchitectureMetaClass
next_address = 0
def __init__(self):
+ from binaryninja import function
+ from binaryninja import startup
+ from binaryninja import lowlevelil
+ from binaryninja import types
+ from binaryninja import databuffer
+ from binaryninja import log
+ from binaryninja import platform
+ from binaryninja import callingconvention
startup._init_plugins()
if self.__class__.opcode_display_length > self.__class__.max_instr_length:
@@ -2045,6 +2049,10 @@ class Architecture(object):
_architecture_cache = {}
class CoreArchitecture(Architecture):
def __init__(self, handle):
+ from binaryninja import function
+ from binaryninja import types
+ from binaryninja import databuffer
+ from binaryninja import lowlevelil
super(CoreArchitecture, self).__init__()
self.handle = core.handle_of_type(handle, core.BNArchitecture)
diff --git a/python/basicblock.py b/python/basicblock.py
index a79b53ad..907b4065 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -20,12 +20,9 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import BranchType, HighlightColorStyle, HighlightStandardColor, InstructionTextTokenType
-import architecture
-import highlight
-import function
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import BranchType, HighlightColorStyle, HighlightStandardColor, InstructionTextTokenType
class BasicBlockEdge(object):
@@ -54,6 +51,9 @@ class BasicBlockEdge(object):
class BasicBlock(object):
def __init__(self, view, handle):
+ from binaryninja import architecture
+ from binaryninja import function
+ from binaryninja import highlight
self.view = view
self.handle = core.handle_of_type(handle, core.BNBasicBlock)
self._arch = None
diff --git a/python/binaryview.py b/python/binaryview.py
index 1e078523..f6a1bc83 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -24,23 +24,14 @@ import ctypes
import abc
import threading
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import (AnalysisState, SymbolType, InstructionTextTokenType,
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import (AnalysisState, SymbolType, InstructionTextTokenType,
Endianness, ModificationStatus, StringType, SegmentFlag, SectionSemantics)
-import function
-import startup
-import architecture
-import platform
-import associateddatastore
-import fileaccessor
-import filemetadata
-import log
-import databuffer
-import basicblock
-import types
-import lineardisassembly
-import metadata
+from binaryninja import associateddatastore # required for _BinaryViewAssociatedDataStore
+
+#2-3 compatibility
+from six import with_metaclass
class BinaryDataNotification(object):
@@ -113,12 +104,13 @@ class AnalysisCompletionEvent(object):
:Example:
>>> def on_complete(self):
- ... print "Analysis Complete", self.view
+ ... print("Analysis Complete", self.view)
...
>>> evt = AnalysisCompletionEvent(bv, on_complete)
>>>
"""
def __init__(self, view, callback):
+ from binaryninja import log
self.view = view
self.callback = callback
self._cb = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(self._notify)
@@ -197,6 +189,9 @@ class DataVariable(object):
class BinaryDataNotificationCallbacks(object):
def __init__(self, view, notify):
+ from binaryninja import function
+ from binaryninja import types
+ from binaryninja import log
self.view = view
self.notify = notify
self._cb = core.BNBinaryDataNotification()
@@ -319,6 +314,7 @@ class BinaryDataNotificationCallbacks(object):
class _BinaryViewTypeMetaclass(type):
+ from binaryninja import startup
@property
def list(self):
"""List all BinaryView types (read-only)"""
@@ -349,10 +345,12 @@ class _BinaryViewTypeMetaclass(type):
return BinaryViewType(view_type)
-class BinaryViewType(object):
- __metaclass__ = _BinaryViewTypeMetaclass
+class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
def __init__(self, handle):
+ from binaryninja import architecture
+ from binaryninja import filemetadata
+ from binaryninja import platform
self.handle = core.handle_of_type(handle, core.BNBinaryViewType)
def __eq__(self, value):
@@ -581,6 +579,18 @@ class BinaryView(object):
database (e.g. ``remove_user_function()`` rather than ``remove_function()``). Thus use ``_user_`` methods if saving \
to the database is desired.
"""
+ import binaryninja.function
+ import binaryninja.architecture
+ import binaryninja.platform
+ import binaryninja.fileaccessor
+ import binaryninja.filemetadata
+ import binaryninja.databuffer
+ import binaryninja.basicblock
+ import binaryninja.types
+ import binaryninja.log
+ import binaryninja.startup
+ import binaryninja.lineardisassembly
+ import binaryninja.metadata
name = None
long_name = None
_registered = False
@@ -590,6 +600,18 @@ class BinaryView(object):
_associated_data = {}
def __init__(self, file_metadata=None, parent_view=None, handle=None):
+ function = binaryninja.function
+ architecture = binaryninja.architecture
+ platform = binaryninja.platform
+ fileaccessor = binaryninja.fileaccessor
+ filemetadata = binaryninja.filemetadata
+ databuffer = binaryninja.databuffer
+ basicblock = binaryninja.basicblock
+ types = binaryninja.types
+ log = binaryninja.log
+ startup = binaryninja.startup
+ lineardisassembly = binaryninja.lineardisassembly
+ metadata = binaryninja.metadata
if handle is not None:
self.handle = core.handle_of_type(handle, core.BNBinaryView)
if file_metadata is None:
@@ -680,7 +702,7 @@ class BinaryView(object):
@classmethod
def open(cls, src, file_metadata=None):
- startup._init_plugins()
+ binaryninja.startup._init_plugins()
if isinstance(src, fileaccessor.FileAccessor):
if file_metadata is None:
file_metadata = filemetadata.FileMetadata()
@@ -2790,7 +2812,7 @@ class BinaryView(object):
:Example:
>>> def completionEvent():
- ... print "done"
+ ... print("done")
...
>>> bv.add_analysis_completion_event(completionEvent)
<binaryninja.AnalysisCompletionEvent object at 0x10a2c9f10>
@@ -3098,7 +3120,7 @@ class BinaryView(object):
>>> settings = DisassemblySettings()
>>> lines = bv.get_linear_disassembly(settings)
>>> for line in lines:
- ... print line
+ ... print(line)
... break
...
cf fa ed fe 07 00 00 01 ........
diff --git a/python/callingconvention.py b/python/callingconvention.py
index e3ec7261..ab8058fc 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -21,17 +21,11 @@
import traceback
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-import architecture
-import log
-import types
-import function
-import binaryview
-from enums import VariableSourceType
-
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class CallingConvention(object):
+ from binaryninja import types
name = None
caller_saved_regs = []
int_arg_regs = []
@@ -48,6 +42,11 @@ class CallingConvention(object):
_registered_calling_conventions = []
def __init__(self, arch=None, name=None, handle=None, confidence=types.max_confidence):
+ from binaryninja import architecture
+ from binaryninja import log
+ from binaryninja import function
+ from binaryninja import binaryview
+ from binaryninja.enums import VariableSourceType
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 3f9e4ce5..bf366750 100644
--- a/python/databuffer.py
+++ b/python/databuffer.py
@@ -20,8 +20,8 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class DataBuffer(object):
diff --git a/python/demangle.py b/python/demangle.py
index 11673263..50322694 100644
--- a/python/demangle.py
+++ b/python/demangle.py
@@ -20,9 +20,8 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-import types
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
def get_qualified_name(names):
@@ -56,6 +55,7 @@ def demangle_ms(arch, mangled_name):
(<type: public: static enum Foobar::foo __cdecl (enum Foobar::foo)>, ['Foobar', 'testf'])
>>>
"""
+ from binaryninja import types
handle = ctypes.POINTER(core.BNType)()
outName = ctypes.POINTER(ctypes.c_char_p)()
outSize = ctypes.c_ulonglong()
@@ -69,6 +69,7 @@ def demangle_ms(arch, mangled_name):
def demangle_gnu3(arch, mangled_name):
+ from binaryninja import types
handle = ctypes.POINTER(core.BNType)()
outName = ctypes.POINTER(ctypes.c_char_p)()
outSize = ctypes.c_ulonglong()
diff --git a/python/examples/README.md b/python/examples/README.md
deleted file mode 100644
index 43af34be..00000000
--- a/python/examples/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Binary Ninja Python API Examples
-
-The following examples demonstrate some of the Binary Ninja API. They include both stand-alone examples that directly call into the core without a GUI, as well as examples meant to be loaded as plugins available from the UI.
-
-## Stand-alone
-
-These plugins only operate when run directly outside of the UI
-
-* bin_info.py - general binary information
-* print_syscalls.py - extract syscall numbers from IL on specified file. Can be run both headless and in Binary Ninja
-* version_switcher.py - uses the update API to see raw version notes and manually downgrade or upgrade
-* instruction_iterator.py - very simple plugin that iterates through functions, blocks, and instructions
-
-To use the stand-alone Python examples, make sure your `PYTHON_PATH` includes the API, as shown below. Please note, this is a feature that requires the "GUI-less processing" capability not available in the personal edition. In the personal edition, all scripts must by run from the integrated python console (follow the directions below under "Loading Plugins" section)
-
-```
-PYTHONPATH=$PYTHONPATH:/Applications/Binary\ Ninja.app/Contents/Resources/python
-```
-
-## GUI Plugins
-
-These plugins require the UI to be running
-
-* breakpoint.py - small example showing how to modify a file and register a GUI menu item
-* jump_table.py - heuristic based jump table detection for when the data-flow based computation fails, triggered by right-clicking on the location where the jump value is computed
-* angr_plugin.py - a plugin to demonstrate both background threads, the simplified plugin UI elements, and highlighting
-* export_svg.py - exports the graph view of a function to an SVG file for including in reports
-
-## Both
-
-These plugins are able to operate in either the GUI or as stand-alone plugins
-
-* nes.py - 6502 CPU architecture including LLIL lifting and `.NES` file format parser
-
-
-## Loading Plugins
-
-Plugins are meant to be loaded into a running Binary Ninja GUI and should either be copied or symlinked into the appropriate plugin folder. You'll need to then re-start Binary Ninja.
-
-### OSX
-
-```
-~/Library/Application Support/Binary Ninja/plugins
-```
-
-### Windows
-
-```
-%APPDATA%\Binary Ninja\plugins
-```
-
-### Linux
-
-```
-~/.binaryninja/plugins
-```
diff --git a/python/examples/angr_plugin.py b/python/examples/angr_plugin.py
deleted file mode 100644
index 26f8040c..00000000
--- a/python/examples/angr_plugin.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-
-# This plugin assumes angr is already installed and available on the system. See the angr documentation
-# for information about installing angr. It should be installed using the virtualenv method.
-#
-# This plugin is currently only known to work on Linux using virtualenv. Switch to the virtual environment
-# (using a command such as "workon angr"), then run the Binary Ninja UI from the command line.
-#
-# This method is known to fail on Mac OS X as the virtualenv used by angr does not appear to provide a
-# way to automatically link to the correct version of Python, even when running the UI from within the
-# virtual environment. A later update may allow for a manual override to link to the required version
-# of Python.
-
-import tempfile
-import logging
-import os
-
-__name__ = "__console__" # angr looks for this, it won't load from within a UI without it
-
-import angr
-# For the lazy instead you can just import everything 'from binaryninja import *''
-from binaryninja.binaryview import BinaryView
-from binaryninja.plugin import BackgroundTaskThread, PluginCommand
-from binaryninja.interaction import show_plain_text_report, show_message_box
-from binaryninja.highlight import HighlightColor
-from binaryninja.enums import HighlightStandardColor, MessageBoxButtonSet, MessageBoxIcon
-
-# Disable warning logs as they show up as errors in the UI
-logging.disable(logging.WARNING)
-
-# Create sets in the BinaryView's data field to store the desired path for each view
-BinaryView.set_default_session_data("angr_find", set())
-BinaryView.set_default_session_data("angr_avoid", set())
-
-
-def escaped_output(str):
- return '\n'.join([s.encode("string_escape") for s in str.split('\n')])
-
-
-# Define a background thread object for solving in the background
-class Solver(BackgroundTaskThread):
- def __init__(self, find, avoid, view):
- BackgroundTaskThread.__init__(self, "Solving with angr...", True)
- self.find = tuple(find)
- self.avoid = tuple(avoid)
- self.view = view
-
- # Write the binary to disk so that the angr API can read it
- self.binary = tempfile.NamedTemporaryFile()
- self.binary.write(view.file.raw.read(0, len(view.file.raw)))
- self.binary.flush()
-
- def run(self):
- # Create an angr project and an explorer with the user's settings
- p = angr.Project(self.binary.name)
- e = p.surveyors.Explorer(find = self.find, avoid = self.avoid)
-
- # Solve loop
- while not e.done:
- if self.cancelled:
- # Solve cancelled, show results if there were any
- if len(e.found) > 0:
- break
- return
-
- # Perform the next step in the solve
- e.step()
-
- # Update status
- active_count = len(e.active)
- found_count = len(e.found)
-
- progress = "Solving with angr (%d active path%s" % (active_count, "s" if active_count != 1 else "")
- if found_count > 0:
- progress += ", %d path%s found" % (found_count, "s" if found_count != 1 else "")
- self.progress = progress + ")..."
-
- # Solve complete, show report
- text_report = "Found %d path%s.\n\n" % (len(e.found), "s" if len(e.found) != 1 else "")
- i = 1
- for f in e.found:
- text_report += "Path %d\n" % i + "=" * 10 + "\n"
- text_report += "stdin:\n" + escaped_output(f.state.posix.dumps(0)) + "\n\n"
- text_report += "stdout:\n" + escaped_output(f.state.posix.dumps(1)) + "\n\n"
- text_report += "stderr:\n" + escaped_output(f.state.posix.dumps(2)) + "\n\n"
- i += 1
-
- name = self.view.file.filename
- if len(name) > 0:
- show_plain_text_report("Results from angr - " + os.path.basename(self.view.file.filename), text_report)
- else:
- show_plain_text_report("Results from angr", text_report)
-
-
-def find_instr(bv, addr):
- # Highlight the instruction in green
- blocks = bv.get_basic_blocks_at(addr)
- for block in blocks:
- block.set_auto_highlight(HighlightColor(HighlightStandardColor.GreenHighlightColor, alpha = 128))
- block.function.set_auto_instr_highlight(addr, HighlightStandardColor.GreenHighlightColor)
-
- # Add the instruction to the list associated with the current view
- bv.session_data.angr_find.add(addr)
-
-
-def avoid_instr(bv, addr):
- # Highlight the instruction in red
- blocks = bv.get_basic_blocks_at(addr)
- for block in blocks:
- block.set_auto_highlight(HighlightColor(HighlightStandardColor.RedHighlightColor, alpha = 128))
- block.function.set_auto_instr_highlight(addr, HighlightStandardColor.RedHighlightColor)
-
- # Add the instruction to the list associated with the current view
- bv.session_data.angr_avoid.add(addr)
-
-
-def solve(bv):
- if len(bv.session_data.angr_find) == 0:
- show_message_box("Angr Solve", "You have not specified a goal instruction.\n\n" +
- "Please right click on the goal instruction and select \"Find Path to This Instruction\" to " +
- "continue.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon)
- return
-
- # Start a solver thread for the path associated with the view
- s = Solver(bv.session_data.angr_find, bv.session_data.angr_avoid, bv)
- s.start()
-
-
-# Register commands for the user to interact with the plugin
-PluginCommand.register_for_address("Find Path to This Instruction",
- "When solving, find a path that gets to this instruction", find_instr)
-PluginCommand.register_for_address("Avoid This Instruction",
- "When solving, avoid paths that reach this instruction", avoid_instr)
-PluginCommand.register("Solve With Angr", "Attempt to solve for a path that satisfies the constraints given", solve)
diff --git a/python/examples/arch_hook.py b/python/examples/arch_hook.py
deleted file mode 100644
index 452bd2b6..00000000
--- a/python/examples/arch_hook.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from binaryninja.architecture import Architecture, ArchitectureHook
-
-class X86ReturnHook(ArchitectureHook):
- def get_instruction_text(self, data, addr):
- # Call the original implementation's method by calling the superclass
- result, length = super(X86ReturnHook, self).get_instruction_text(data, addr)
-
- # Patch the name of the 'retn' instruction to 'ret'
- if len(result) > 0 and result[0].text == 'retn':
- result[0].text = 'ret'
-
- return result, length
-
-# Install the hook by constructing it with the desired architecture to hook, then registering it
-X86ReturnHook(Architecture['x86']).register()
-
diff --git a/python/examples/bin_info.py b/python/examples/bin_info.py
deleted file mode 100644
index 17a96685..00000000
--- a/python/examples/bin_info.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import sys
-import binaryninja.log as log
-from binaryninja.binaryview import BinaryViewType
-import binaryninja.interaction as interaction
-from binaryninja.plugin import PluginCommand
-
-
-def get_bininfo(bv):
- if bv is None:
- filename = ""
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = interaction.get_open_filename_input("Filename:")
- if filename is None:
- log.log_warn("No file specified")
- sys.exit(1)
-
- bv = BinaryViewType.get_view_of_file(filename)
- log.log_to_stdout(True)
-
- contents = "## %s ##\n" % bv.file.filename
- contents += "- START: 0x%x\n\n" % bv.start
- contents += "- ENTRY: 0x%x\n\n" % bv.entry_point
- contents += "- ARCH: %s\n\n" % bv.arch.name
- contents += "### First 10 Functions ###\n"
-
- contents += "| Start | Name |\n"
- contents += "|------:|:-------|\n"
- for i in xrange(min(10, len(bv.functions))):
- contents += "| 0x%x | %s |\n" % (bv.functions[i].start, bv.functions[i].symbol.full_name)
-
- contents += "### First 10 Strings ###\n"
- contents += "| Start | Length | String |\n"
- contents += "|------:|-------:|:-------|\n"
- for i in xrange(min(10, len(bv.strings))):
- start = bv.strings[i].start
- length = bv.strings[i].length
- string = bv.read(start, length)
- contents += "| 0x%x |%d | %s |\n" % (start, length, string)
- return contents
-
-
-def display_bininfo(bv):
- interaction.show_markdown_report("Binary Info Report", get_bininfo(bv))
-
-
-if __name__ == "__main__":
- print get_bininfo(None)
-else:
- PluginCommand.register("Binary Info", "Display basic info about the binary", display_bininfo)
diff --git a/python/examples/breakpoint.py b/python/examples/breakpoint.py
deleted file mode 100644
index a2801511..00000000
--- a/python/examples/breakpoint.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-
-from binaryninja.plugin import PluginCommand
-from binaryninja.log import log_error
-
-
-def write_breakpoint(view, start, length):
- """Sample function to show registering a plugin menu item for a range of bytes. Also possible:
- register
- register_for_address
- register_for_function
- """
- bkpt_str = {
- "x86": "int3",
- "x86_64": "int3",
- "armv7": "bkpt",
- "aarch64": "brk #0",
- "mips32": "break"}
-
- if view.arch.name not in bkpt_str:
- log_error("Architecture %s not supported" % view.arch.name)
- return
-
- bkpt, err = view.arch.assemble(bkpt_str[view.arch.name])
- if bkpt is None:
- log_error(err)
- return
- view.write(start, bkpt * length / len(bkpt))
-
-
-PluginCommand.register_for_range("Convert to breakpoint", "Fill region with breakpoint instructions.", write_breakpoint)
diff --git a/python/examples/export_svg.py b/python/examples/export_svg.py
deleted file mode 100755
index 7814c9fd..00000000
--- a/python/examples/export_svg.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# from binaryninja import *
-import os
-import webbrowser
-import time
-try:
- from urllib import pathname2url # Python 2.x
-except:
- from urllib.request import pathname2url # Python 3.x
-
-from binaryninja.interaction import get_save_filename_input, show_message_box
-from binaryninja.enums import MessageBoxButtonSet, MessageBoxIcon, MessageBoxButtonResult, InstructionTextTokenType, BranchType
-from binaryninja.plugin import PluginCommand
-
-colors = {'green': [162, 217, 175], 'red': [222, 143, 151], 'blue': [128, 198, 233], 'cyan': [142, 230, 237], 'lightCyan': [176, 221, 228], 'orange': [237, 189, 129], 'yellow': [237, 223, 179], 'magenta': [218, 196, 209], 'none': [74, 74, 74]}
-
-escape_table = {
- "'": "&#39;",
- ">": "&#62;",
- "<": "&#60;",
- '"': "&#34;",
- ' ': "&#160;"
-}
-
-
-def escape(toescape):
- toescape = toescape.decode('utf-8').encode('ascii', 'xmlcharrefreplace') # handle extended unicode
- return ''.join(escape_table.get(i, i) for i in toescape) # still escape the basics
-
-
-def save_svg(bv, function):
- address = hex(function.start).replace('L', '')
- path = os.path.dirname(bv.file.filename)
- origname = os.path.basename(bv.file.filename)
- filename = os.path.join(path, 'binaryninja-{filename}-{function}.html'.format(filename=origname, function=address))
- outputfile = get_save_filename_input('File name for export_svg', 'HTML files (*.html)', filename)
- if outputfile is None:
- return
- content = render_svg(function, origname)
- output = open(outputfile, 'w')
- output.write(content)
- output.close()
- result = show_message_box("Open SVG", "Would you like to view the exported SVG?",
- buttons = MessageBoxButtonSet.YesNoButtonSet, icon = MessageBoxIcon.QuestionIcon)
- if result == MessageBoxButtonResult.YesButton:
- url = 'file:{}'.format(pathname2url(outputfile))
- webbrowser.open(url)
-
-
-def instruction_data_flow(function, address):
- ''' TODO: Extract data flow information '''
- length = function.view.get_instruction_length(address)
- bytes = function.view.read(address, length)
- hex = bytes.encode('hex')
- padded = ' '.join([hex[i:i + 2] for i in range(0, len(hex), 2)])
- return 'Opcode: {bytes}'.format(bytes=padded)
-
-
-def render_svg(function, origname):
- graph = function.create_graph()
- graph.layout_and_wait()
- heightconst = 15
- ratio = 0.48
- widthconst = heightconst * ratio
-
- output = '''<html>
- <head>
- <style type="text/css">
- @import url(https://fonts.googleapis.com/css?family=Source+Code+Pro);
- body {
- background-color: rgb(42, 42, 42);
- color: rgb(220, 220, 220);
- font-family: "Source Code Pro", "Lucida Console", "Consolas", monospace;
- }
- a, a:visited {
- color: rgb(200, 200, 200);
- font-weight: bold;
- }
- svg {
- background-color: rgb(42, 42, 42);
- display: block;
- margin: 0 auto;
- }
- .basicblock {
- stroke: rgb(224, 224, 224);
- }
- .edge {
- fill: none;
- stroke-width: 1px;
- }
- .back_edge {
- fill: none;
- stroke-width: 2px;
- }
- .UnconditionalBranch, .IndirectBranch {
- stroke: rgb(128, 198, 233);
- color: rgb(128, 198, 233);
- }
- .FalseBranch {
- stroke: rgb(222, 143, 151);
- color: rgb(222, 143, 151);
- }
- .TrueBranch {
- stroke: rgb(162, 217, 175);
- color: rgb(162, 217, 175);
- }
- .arrow {
- stroke-width: 1;
- fill: currentColor;
- }
- text {
- font-family: "Source Code Pro", "Lucida Console", "Consolas", monospace;
- font-size: 9pt;
- fill: rgb(224, 224, 224);
- }
- .CodeSymbolToken {
- fill: rgb(128, 198, 223);
- }
- .DataSymbolToken {
- fill: rgb(142, 230, 237);
- }
- .TextToken, .InstructionToken, .BeginMemoryOperandToken, .EndMemoryOperandToken {
- fill: rgb(224, 224, 224);
- }
- .PossibleAddressToken, .IntegerToken {
- fill: rgb(162, 217, 175);
- }
- .RegisterToken {
- fill: rgb(237, 223, 179);
- }
- .AnnotationToken {
- fill: rgb(218, 196, 209);
- }
- .ImportToken {
- fill: rgb(237, 189, 129);
- }
- .StackVariableToken {
- fill: rgb(193, 220, 199);
- }
- </style>
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
- </head>
-'''
- output += '''<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}">
- <defs>
- <marker id="arrow-TrueBranch" class="arrow TrueBranch" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
- <path d="M 0 0 L 10 5 L 0 10 z" />
- </marker>
- <marker id="arrow-FalseBranch" class="arrow FalseBranch" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
- <path d="M 0 0 L 10 5 L 0 10 z" />
- </marker>
- <marker id="arrow-UnconditionalBranch" class="arrow UnconditionalBranch" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
- <path d="M 0 0 L 10 5 L 0 10 z" />
- </marker>
- <marker id="arrow-IndirectBranch" class="arrow IndirectBranch" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
- <path d="M 0 0 L 10 5 L 0 10 z" />
- </marker>
- </defs>
- '''.format(width=graph.width * widthconst + 20, height=graph.height * heightconst + 20)
- output += ''' <g id="functiongraph0" class="functiongraph">
- <title>Function Graph 0</title>
- '''
- edges = ''
- for i, block in enumerate(graph.blocks):
-
- # Calculate basic block location and coordinates
- x = ((block.x) * widthconst)
- y = ((block.y) * heightconst)
- width = ((block.width) * widthconst)
- height = ((block.height) * heightconst)
-
- # Render block
- output += ' <g id="basicblock{i}">\n'.format(i=i)
- output += ' <title>Basic Block {i}</title>\n'.format(i=i)
- rgb = colors['none']
- try:
- bb = block.basic_block
- color_code = bb.highlight.color
- color_str = bb.highlight._standard_color_to_str(color_code)
- if color_str in colors:
- rgb = colors[color_str]
- except:
- pass
- output += ' <rect class="basicblock" x="{x}" y="{y}" fill-opacity="0.4" height="{height}" width="{width}" fill="rgb({r},{g},{b})"/>\n'.format(x=x, y=y, width=width + 16, height=height + 12, r=rgb[0], g=rgb[1], b=rgb[2])
-
- # Render instructions, unfortunately tspans don't allow copying/pasting more
- # than one line at a time, need SVG 1.2 textarea tags for that it looks like
-
- output += ' <text x="{x}" y="{y}">\n'.format(x=x, y=y + (i + 1) * heightconst)
- for i, line in enumerate(block.lines):
- output += ' <tspan id="instr-{address}" x="{x}" y="{y}">'.format(x=x + 6, y=y + 6 + (i + 0.7) * heightconst, address=hex(line.address)[:-1])
- hover = instruction_data_flow(function, line.address)
- output += '<title>{hover}</title>'.format(hover=hover)
- for token in line.tokens:
- # TODO: add hover for hex, function, and reg tokens
- output += '<tspan class="{tokentype}">{text}</tspan>'.format(text=escape(token.text), tokentype=InstructionTextTokenType(token.type).name)
- output += '</tspan>\n'
- output += ' </text>\n'
- output += ' </g>\n'
-
- # Edges are rendered in a seperate chunk so they have priority over the
- # basic blocks or else they'd render below them
-
- for edge in block.outgoing_edges:
- points = ""
- x, y = edge.points[0]
- points += str(x * widthconst) + "," + str(y * heightconst + 12) + " "
- for x, y in edge.points[1:-1]:
- points += str(x * widthconst) + "," + str(y * heightconst) + " "
- x, y = edge.points[-1]
- points += str(x * widthconst) + "," + str(y * heightconst + 0) + " "
- if edge.back_edge:
- edges += ' <polyline class="back_edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(type=BranchType(edge.type).name, points=points)
- else:
- edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(type=BranchType(edge.type).name, points=points)
- output += ' ' + edges + '\n'
- output += ' </g>\n'
- output += '</svg>'
-
- output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring}.</p>'.format(filename = origname, timestring = time.strftime("%c"))
- output += '</html>'
- return output
-
-
-PluginCommand.register_for_function("Export to SVG", "Exports an SVG of the current function", save_svg)
diff --git a/python/examples/instruction_iterator.py b/python/examples/instruction_iterator.py
deleted file mode 100644
index f55e1c1b..00000000
--- a/python/examples/instruction_iterator.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import sys
-import binaryninja as binja
-
-if len(sys.argv) > 1:
- target = sys.argv[1]
-
-bv = binja.BinaryViewType.get_view_of_file(target)
-binja.log_to_stdout(True)
-binja.log_info("-------- %s --------" % target)
-binja.log_info("START: 0x%x" % bv.start)
-binja.log_info("ENTRY: 0x%x" % bv.entry_point)
-binja.log_info("ARCH: %s" % bv.arch.name)
-binja.log_info("\n-------- Function List --------")
-
-""" print all the functions, their basic blocks, and their il instructions """
-for func in bv.functions:
- binja.log_info(repr(func))
- for block in func.low_level_il:
- binja.log_info("\t{0}".format(block))
-
- for insn in block:
- binja.log_info("\t\t{0}".format(insn))
-
-
-""" print all the functions, their basic blocks, and their mc instructions """
-for func in bv.functions:
- binja.log_info(repr(func))
- for block in func:
- binja.log_info("\t{0}".format(block))
-
- for insn in block:
- binja.log_info("\t\t{0}".format(insn))
diff --git a/python/examples/jump_table.py b/python/examples/jump_table.py
deleted file mode 100644
index 419cc188..00000000
--- a/python/examples/jump_table.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-# This plugin will attempt to resolve simple jump tables (an array of code pointers) and add the destinations
-# as indirect branch targets so that the flow graph reflects the jump table's control flow.
-from binaryninja.plugin import PluginCommand
-from binaryninja.enums import InstructionTextTokenType
-import struct
-
-
-def find_jump_table(bv, addr):
- for block in bv.get_basic_blocks_at(addr):
- func = block.function
- arch = func.arch
- addrsize = arch.address_size
-
- # Grab the instruction tokens so that we can look for the table's starting address
- tokens, length = arch.get_instruction_text(bv.read(addr, 16), addr)
-
- # Look for the next jump instruction, which may be the current instruction. Some jump tables will
- # compute the address first then jump to the computed address as a separate instruction.
- jump_addr = addr
- while jump_addr < block.end:
- info = arch.get_instruction_info(bv.read(jump_addr, 16), jump_addr)
- if len(info.branches) != 0:
- break
- jump_addr += info.length
- if jump_addr >= block.end:
- print "Unable to find jump after instruction 0x%x" % addr
- continue
- print "Jump at 0x%x" % jump_addr
-
- # Collect the branch targets for any tables referenced by the clicked instruction
- branches = []
- for token in tokens:
- if InstructionTextTokenType(token.type) == InstructionTextTokenType.PossibleAddressToken: # Table addresses will be a "possible address" token
- tbl = token.value
- print "Found possible table at 0x%x" % tbl
- i = 0
- while True:
- # Read the next pointer from the table
- data = bv.read(tbl + (i * addrsize), addrsize)
- if len(data) == addrsize:
- if addrsize == 4:
- ptr = struct.unpack("<I", data)[0]
- else:
- ptr = struct.unpack("<Q", data)[0]
-
- # If the pointer is within the binary, add it as a destination and continue
- # to the next entry
- if (ptr >= bv.start) and (ptr < bv.end):
- print "Found destination 0x%x" % ptr
- branches.append((arch, ptr))
- else:
- # Once a value that is not a pointer is encountered, the jump table is ended
- break
- else:
- # Reading invalid memory
- break
-
- i += 1
-
- # Set the indirect branch targets on the jump instruction to be the list of targets discovered
- func.set_user_indirect_branches(jump_addr, branches)
-
-
-# Create a plugin command so that the user can right click on an instruction referencing a jump table and
-# invoke the command
-PluginCommand.register_for_address("Process jump table", "Look for jump table destinations", find_jump_table)
diff --git a/python/examples/nds.py b/python/examples/nds.py
deleted file mode 100644
index 34d8a292..00000000
--- a/python/examples/nds.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-# from binaryninja import *
-from binaryninja.binaryview import BinaryView
-from binaryninja.architecture import Architecture
-from binaryninja.enums import SegmentFlag
-from binaryninja.log import log_error
-
-import struct
-import traceback
-
-
-def crc16(data):
- crc = 0xffff
- for ch in data:
- crc ^= ord(ch)
- for bit in xrange(0, 8):
- if (crc & 1) == 1:
- crc = (crc >> 1) ^ 0xa001
- else:
- crc >>= 1
- return crc
-
-
-class DSView(BinaryView):
- def __init__(self, data):
- BinaryView.__init__(self, file_metadata = data.file, parent_view = data)
- self.raw = data
-
- @classmethod
- def is_valid_for_data(self, data):
- hdr = data.read(0, 0x160)
- if len(hdr) < 0x160:
- return False
- if struct.unpack("<H", hdr[0x15e:0x160])[0] != crc16(hdr[0:0x15e]):
- return False
- if struct.unpack("<H", hdr[0x15c:0x15e])[0] != crc16(hdr[0xc0:0x15c]):
- return False
- return True
-
- def init_common(self):
- self.platform = Architecture["armv7"].standalone_platform
- self.hdr = self.raw.read(0, 0x160)
-
- def init_arm9(self):
- try:
- self.init_common()
- self.arm9_offset = struct.unpack("<L", self.hdr[0x20:0x24])[0]
- self.arm_entry_addr = struct.unpack("<L", self.hdr[0x24:0x28])[0]
- self.arm9_load_addr = struct.unpack("<L", self.hdr[0x28:0x2C])[0]
- self.arm9_size = struct.unpack("<L", self.hdr[0x2C:0x30])[0]
- self.add_auto_segment(self.arm9_load_addr, self.arm9_size, self.arm9_offset, self.arm9_size,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
- self.add_entry_point(Architecture['armv7'].standalone_platform, self.arm_entry_addr)
- return True
- except:
- log_error(traceback.format_exc())
- return False
-
- def init_arm7(self):
- try:
- self.init_common()
- self.arm7_offset = struct.unpack("<L", self.hdr[0x30:0x34])[0]
- self.arm_entry_addr = struct.unpack("<L", self.hdr[0x34:0x38])[0]
- self.arm7_load_addr = struct.unpack("<L", self.hdr[0x38:0x3C])[0]
- self.arm7_size = struct.unpack("<L", self.hdr[0x3C:0x40])[0]
- self.add_auto_segment(self.arm7_load_addr, self.arm7_size, self.arm7_offset, self.arm7_size,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
- self.add_entry_point(Architecture['armv7'].standalone_platform, self.arm_entry_addr)
- return True
- except:
- log_error(traceback.format_exc())
- return False
-
- def perform_is_executable(self):
- return True
-
- def perform_get_entry_point(self):
- return self.arm_entry_addr
-
-
-class DSARM9View(DSView):
- name = "DSARM9"
- long_name = "DS ARM9 ROM"
-
- def init(self):
- return self.init_arm9()
-
-
-class DSARM7View(DSView):
- name = "DSARM7"
- long_name = "DS ARM7 ROM"
-
- def init(self):
- return self.init_arm7()
-
-
-DSARM9View.register()
-DSARM7View.register()
diff --git a/python/examples/nes.py b/python/examples/nes.py
deleted file mode 100644
index 00451abd..00000000
--- a/python/examples/nes.py
+++ /dev/null
@@ -1,646 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import struct
-import traceback
-import os
-
-from binaryninja.architecture import Architecture
-from binaryninja.lowlevelil import LowLevelILLabel, LLIL_TEMP
-from binaryninja.function import RegisterInfo, InstructionInfo, InstructionTextToken
-from binaryninja.binaryview import BinaryView
-from binaryninja.types import Symbol
-from binaryninja.log import log_error
-from binaryninja.enums import (BranchType, InstructionTextTokenType,
- LowLevelILOperation, LowLevelILFlagCondition, FlagRole, SegmentFlag, SymbolType)
-
-InstructionNames = [
- "brk", "ora", None, None, None, "ora", "asl", None, # 0x00
- "php", "ora", "asl@", None, None, "ora", "asl", None, # 0x08
- "bpl", "ora", None, None, None, "ora", "asl", None, # 0x10
- "clc", "ora", None, None, None, "ora", "asl", None, # 0x18
- "jsr", "and", None, None, "bit", "and", "rol", None, # 0x20
- "plp", "and", "rol@", None, "bit", "and", "rol", None, # 0x28
- "bmi", "and", None, None, None, "and", "rol", None, # 0x30
- "sec", "and", None, None, None, "and", "rol", None, # 0x38
- "rti", "eor", None, None, None, "eor", "lsr", None, # 0x40
- "pha", "eor", "lsr@", None, "jmp", "eor", "lsr", None, # 0x48
- "bvc", "eor", None, None, None, "eor", "lsr", None, # 0x50
- "cli", "eor", None, None, None, "eor", "lsr", None, # 0x58
- "rts", "adc", None, None, None, "adc", "ror", None, # 0x60
- "pla", "adc", "ror@", None, "jmp", "adc", "ror", None, # 0x68
- "bvs", "adc", None, None, None, "adc", "ror", None, # 0x70
- "sei", "adc", None, None, None, "adc", "ror", None, # 0x78
- None, "sta", None, None, "sty", "sta", "stx", None, # 0x80
- "dey", None, "txa", None, "sty", "sta", "stx", None, # 0x88
- "bcc", "sta", None, None, "sty", "sta", "stx", None, # 0x90
- "tya", "sta", "txs", None, None, "sta", None, None, # 0x98
- "ldy", "lda", "ldx", None, "ldy", "lda", "ldx", None, # 0xa0
- "tay", "lda", "tax", None, "ldy", "lda", "ldx", None, # 0xa8
- "bcs", "lda", None, None, "ldy", "lda", "ldx", None, # 0xb0
- "clv", "lda", "tsx", None, "ldy", "lda", "ldx", None, # 0xb8
- "cpy", "cmp", None, None, "cpy", "cmp", "dec", None, # 0xc0
- "iny", "cmp", "dex", None, "cpy", "cmp", "dec", None, # 0xc8
- "bne", "cmp", None, None, None, "cmp", "dec", None, # 0xd0
- "cld", "cmp", None, None, None, "cmp", "dec", None, # 0xd8
- "cpx", "sbc", None, None, "cpx", "sbc", "inc", None, # 0xe0
- "inx", "sbc", "nop", None, "cpx", "sbc", "inc", None, # 0xe8
- "beq", "sbc", None, None, None, "sbc", "inc", None, # 0xf0
- "sed", "sbc", None, None, None, "sbc", "inc", None # 0xf8
-]
-
-NONE = 0
-ABS = 1
-ABS_DEST = 2
-ABS_X = 3
-ABS_X_DEST = 4
-ABS_Y = 5
-ABS_Y_DEST = 6
-ACCUM = 7
-ADDR = 8
-IMMED = 9
-IND = 10
-IND_X = 11
-IND_X_DEST = 12
-IND_Y = 13
-IND_Y_DEST = 14
-REL = 15
-ZERO = 16
-ZERO_DEST = 17
-ZERO_X = 18
-ZERO_X_DEST = 19
-ZERO_Y = 20
-ZERO_Y_DEST = 21
-InstructionOperandTypes = [
- NONE, IND_X, NONE, NONE, NONE, ZERO, ZERO_DEST, NONE, # 0x00
- NONE, IMMED, ACCUM, NONE, NONE, ABS, ABS_DEST, NONE, # 0x08
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0x10
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE, # 0x18
- ADDR, IND_X, NONE, NONE, ZERO, ZERO, ZERO_DEST, NONE, # 0x20
- NONE, IMMED, ACCUM, NONE, ABS, ABS, ABS_DEST, NONE, # 0x28
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0x30
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE, # 0x38
- NONE, IND_X, NONE, NONE, NONE, ZERO, ZERO_DEST, NONE, # 0x40
- NONE, IMMED, ACCUM, NONE, ADDR, ABS, ABS_DEST, NONE, # 0x48
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0x50
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE, # 0x58
- NONE, IND_X, NONE, NONE, NONE, ZERO, ZERO_DEST, NONE, # 0x60
- NONE, IMMED, ACCUM, NONE, IND, ABS, ABS_DEST, NONE, # 0x68
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0x70
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE, # 0x78
- NONE, IND_X_DEST, NONE, NONE, ZERO_DEST, ZERO_DEST, ZERO_DEST, NONE, # 0x80
- NONE, NONE, NONE, NONE, ABS_DEST, ABS_DEST, ABS_DEST, NONE, # 0x88
- REL, IND_Y_DEST, NONE, NONE, ZERO_X_DEST, ZERO_X_DEST, ZERO_Y_DEST, NONE, # 0x90
- NONE, ABS_Y_DEST, NONE, NONE, NONE, ABS_X_DEST, NONE, NONE, # 0x98
- IMMED, IND_X, IMMED, NONE, ZERO, ZERO, ZERO, NONE, # 0xa0
- NONE, IMMED, NONE, NONE, ABS, ABS, ABS, NONE, # 0xa8
- REL, IND_Y, NONE, NONE, ZERO_X, ZERO_X, ZERO_Y, NONE, # 0xb0
- NONE, ABS_Y, NONE, NONE, ABS_X, ABS_X, ABS_Y, NONE, # 0xb8
- IMMED, IND_X, NONE, NONE, ZERO, ZERO, ZERO_DEST, NONE, # 0xc0
- NONE, IMMED, NONE, NONE, ABS, ABS, ABS_DEST, NONE, # 0xc8
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0xd0
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE, # 0xd8
- IMMED, IND_X, NONE, NONE, ZERO, ZERO, ZERO_DEST, NONE, # 0xe0
- NONE, IMMED, NONE, NONE, ABS, ABS, ABS_DEST, NONE, # 0xe8
- REL, IND_Y, NONE, NONE, NONE, ZERO_X, ZERO_X_DEST, NONE, # 0xf0
- NONE, ABS_Y, NONE, NONE, NONE, ABS_X, ABS_X_DEST, NONE # 0xf8
-]
-
-OperandLengths = [
- 0, # NONE
- 2, # ABS
- 2, # ABS_DEST
- 2, # ABS_X
- 2, # ABS_X_DEST
- 2, # ABS_Y
- 2, # ABS_Y_DEST
- 0, # ACCUM
- 2, # ADDR
- 1, # IMMED
- 2, # IND
- 1, # IND_X
- 1, # IND_X_DEST
- 1, # IND_Y
- 1, # IND_Y_DEST
- 1, # REL
- 1, # ZERO
- 1, # ZREO_DEST
- 1, # ZERO_X
- 1, # ZERO_X_DEST
- 1, # ZERO_Y
- 1 # ZERO_Y_DEST
-]
-
-OperandTokens = [
- lambda value: [], # NONE
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ABS
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ABS_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x")], # ABS_X
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x")], # ABS_X_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")], # ABS_Y
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")], # ABS_Y_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.RegisterToken, "a")], # ACCUM
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ADDR
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "#"), InstructionTextToken(InstructionTextTokenType.IntegerToken, "$%.2x" % value, value)], # IMMED
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "["), InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, "]")], # IND
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "["), InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x"),
- InstructionTextToken(InstructionTextTokenType.TextToken, "]")], # IND_X
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "["), InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x"),
- InstructionTextToken(InstructionTextTokenType.TextToken, "]")], # IND_X_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "["), InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, "], "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")], # IND_Y
- lambda value: [InstructionTextToken(InstructionTextTokenType.TextToken, "["), InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, "], "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")], # IND_Y_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # REL
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value)], # ZERO
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value)], # ZERO_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x")], # ZERO_X
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "x")], # ZERO_X_DEST
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")], # ZERO_Y
- lambda value: [InstructionTextToken(InstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(InstructionTextTokenType.TextToken, ", "), InstructionTextToken(InstructionTextTokenType.RegisterToken, "y")] # ZERO_Y_DEST
-]
-
-
-def indirect_load(il, value):
- if (value & 0xff) == 0xff:
- lo_addr = il.const_pointer(2, value)
- hi_addr = il.const_pointer(2, (value & 0xff00) | ((value + 1) & 0xff))
- lo = il.zero_extend(2, il.load(1, lo_addr))
- hi = il.shift_left(2, il.zero_extend(2, il.load(1, hi_addr)), il.const(2, 8))
- return il.or_expr(2, lo, hi)
- return il.load(2, il.const_pointer(2, value))
-
-
-def load_zero_page_16(il, value):
- if il[value].operation == LowLevelILOperation.LLIL_CONST:
- if il[value].constant == 0xff:
- lo = il.zero_extend(2, il.load(1, il.const_pointer(2, 0xff)))
- hi = il.shift_left(2, il.zero_extend(2, il.load(1, il.const_pointer(2, 0)), il.const(2, 8)))
- return il.or_expr(2, lo, hi)
- return il.load(2, il.const_pointer(2, il[value].constant))
- il.append(il.set_reg(1, LLIL_TEMP(0), value))
- value = il.reg(1, LLIL_TEMP(0))
- lo_addr = value
- hi_addr = il.add(1, value, il.const(1, 1))
- lo = il.zero_extend(2, il.load(1, lo_addr))
- hi = il.shift_left(2, il.zero_extend(2, il.load(1, hi_addr)), il.const(2, 8))
- return il.or_expr(2, lo, hi)
-
-
-OperandIL = [
- lambda il, value: None, # NONE
- lambda il, value: il.load(1, il.const_pointer(2, value)), # ABS
- lambda il, value: il.const(2, value), # ABS_DEST
- lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x")))), # ABS_X
- lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x"))), # ABS_X_DEST
- lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y")))), # ABS_Y
- lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y"))), # ABS_Y_DEST
- lambda il, value: il.reg(1, "a"), # ACCUM
- lambda il, value: il.const_pointer(2, value), # ADDR
- lambda il, value: il.const(1, value), # IMMED
- lambda il, value: indirect_load(il, value), # IND
- lambda il, value: il.load(1, load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x")))), # IND_X
- lambda il, value: load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x"))), # IND_X_DEST
- lambda il, value: il.load(1, il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y"))), # IND_Y
- lambda il, value: il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y")), # IND_Y_DEST
- lambda il, value: il.const_pointer(2, value), # REL
- lambda il, value: il.load(1, il.const_pointer(2, value)), # ZERO
- lambda il, value: il.const_pointer(2, value), # ZERO_DEST
- lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x")))), # ZERO_X
- lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x"))), # ZERO_X_DEST
- lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y")))), # ZERO_Y
- lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y"))) # ZERO_Y_DEST
-]
-
-
-def cond_branch(il, cond, dest):
- t = None
- if il[dest].operation == LowLevelILOperation.LLIL_CONST:
- t = il.get_label_for_address(Architecture['6502'], il[dest].constant)
- if t is None:
- t = LowLevelILLabel()
- indirect = True
- else:
- indirect = False
- f = LowLevelILLabel()
- il.append(il.if_expr(cond, t, f))
- if indirect:
- il.mark_label(t)
- il.append(il.jump(dest))
- il.mark_label(f)
- return None
-
-
-def jump(il, dest):
- label = None
- if il[dest].operation == LowLevelILOperation.LLIL_CONST:
- label = il.get_label_for_address(Architecture['6502'], il[dest].constant)
- if label is None:
- il.append(il.jump(dest))
- else:
- il.append(il.goto(label))
- return None
-
-
-def get_p_value(il):
- c = il.flag_bit(1, "c", 0)
- z = il.flag_bit(1, "z", 1)
- i = il.flag_bit(1, "i", 2)
- d = il.flag_bit(1, "d", 3)
- b = il.flag_bit(1, "b", 4)
- v = il.flag_bit(1, "v", 6)
- s = il.flag_bit(1, "s", 7)
- return il.or_expr(1, il.or_expr(1, il.or_expr(1, il.or_expr(1, il.or_expr(1,
- il.or_expr(1, c, z), i), d), b), v), s)
-
-
-def set_p_value(il, value):
- il.append(il.set_reg(1, LLIL_TEMP(0), value))
- il.append(il.set_flag("c", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x01))))
- il.append(il.set_flag("z", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x02))))
- il.append(il.set_flag("i", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x04))))
- il.append(il.set_flag("d", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x08))))
- il.append(il.set_flag("b", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x10))))
- il.append(il.set_flag("v", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x40))))
- il.append(il.set_flag("s", il.test_bit(1, il.reg(1, LLIL_TEMP(0)), il.const(1, 0x80))))
- return None
-
-
-def rti(il):
- set_p_value(il, il.pop(1))
- return il.ret(il.pop(2))
-
-
-InstructionIL = {
- "adc": lambda il, operand: il.set_reg(1, "a", il.add_carry(1, il.reg(1, "a"), operand, il.flag("c"), flags = "*")),
- "asl": lambda il, operand: il.store(1, operand, il.shift_left(1, il.load(1, operand), il.const(1, 1), flags = "czs")),
- "asl@": lambda il, operand: il.set_reg(1, "a", il.shift_left(1, operand, il.const(1, 1), flags = "czs")),
- "and": lambda il, operand: il.set_reg(1, "a", il.and_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "bcc": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_UGE), operand),
- "bcs": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_ULT), operand),
- "beq": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_E), operand),
- "bit": lambda il, operand: il.and_expr(1, il.reg(1, "a"), operand, flags = "czs"),
- "bmi": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NEG), operand),
- "bne": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NE), operand),
- "bpl": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_POS), operand),
- "brk": lambda il, operand: il.system_call(),
- "bvc": lambda il, operand: cond_branch(il, il.not_expr(0, il.flag("v")), operand),
- "bvs": lambda il, operand: cond_branch(il, il.flag("v"), operand),
- "clc": lambda il, operand: il.set_flag("c", il.const(0, 0)),
- "cld": lambda il, operand: il.set_flag("d", il.const(0, 0)),
- "cli": lambda il, operand: il.set_flag("i", il.const(0, 0)),
- "clv": lambda il, operand: il.set_flag("v", il.const(0, 0)),
- "cmp": lambda il, operand: il.sub(1, il.reg(1, "a"), operand, flags = "czs"),
- "cpx": lambda il, operand: il.sub(1, il.reg(1, "x"), operand, flags = "czs"),
- "cpy": lambda il, operand: il.sub(1, il.reg(1, "y"), operand, flags = "czs"),
- "dec": lambda il, operand: il.store(1, operand, il.sub(1, il.load(1, operand), il.const(1, 1), flags = "zs")),
- "dex": lambda il, operand: il.set_reg(1, "x", il.sub(1, il.reg(1, "x"), il.const(1, 1), flags = "zs")),
- "dey": lambda il, operand: il.set_reg(1, "y", il.sub(1, il.reg(1, "y"), il.const(1, 1), flags = "zs")),
- "eor": lambda il, operand: il.set_reg(1, "a", il.xor_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "inc": lambda il, operand: il.store(1, operand, il.add(1, il.load(1, operand), il.const(1, 1), flags = "zs")),
- "inx": lambda il, operand: il.set_reg(1, "x", il.add(1, il.reg(1, "x"), il.const(1, 1), flags = "zs")),
- "iny": lambda il, operand: il.set_reg(1, "y", il.add(1, il.reg(1, "y"), il.const(1, 1), flags = "zs")),
- "jmp": lambda il, operand: jump(il, operand),
- "jsr": lambda il, operand: il.call(operand),
- "lda": lambda il, operand: il.set_reg(1, "a", operand, flags = "zs"),
- "ldx": lambda il, operand: il.set_reg(1, "x", operand, flags = "zs"),
- "ldy": lambda il, operand: il.set_reg(1, "y", operand, flags = "zs"),
- "lsr": lambda il, operand: il.store(1, operand, il.logical_shift_right(1, il.load(1, operand), il.const(1, 1), flags = "czs")),
- "lsr@": lambda il, operand: il.set_reg(1, "a", il.logical_shift_right(1, il.reg(1, "a"), il.const(1, 1), flags = "czs")),
- "nop": lambda il, operand: il.nop(),
- "ora": lambda il, operand: il.set_reg(1, "a", il.or_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "pha": lambda il, operand: il.push(1, il.reg(1, "a")),
- "php": lambda il, operand: il.push(1, get_p_value(il)),
- "pla": lambda il, operand: il.set_reg(1, "a", il.pop(1), flags = "zs"),
- "plp": lambda il, operand: set_p_value(il, il.pop(1)),
- "rol": lambda il, operand: il.store(1, operand, il.rotate_left_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags = "czs")),
- "rol@": lambda il, operand: il.set_reg(1, "a", il.rotate_left_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags = "czs")),
- "ror": lambda il, operand: il.store(1, operand, il.rotate_right_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags = "czs")),
- "ror@": lambda il, operand: il.set_reg(1, "a", il.rotate_right_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags = "czs")),
- "rti": lambda il, operand: rti(il),
- "rts": lambda il, operand: il.ret(il.add(2, il.pop(2), il.const(2, 1))),
- "sbc": lambda il, operand: il.set_reg(1, "a", il.sub_borrow(1, il.reg(1, "a"), operand, il.flag("c"), flags = "*")),
- "sec": lambda il, operand: il.set_flag("c", il.const(0, 1)),
- "sed": lambda il, operand: il.set_flag("d", il.const(0, 1)),
- "sei": lambda il, operand: il.set_flag("i", il.const(0, 1)),
- "sta": lambda il, operand: il.store(1, operand, il.reg(1, "a")),
- "stx": lambda il, operand: il.store(1, operand, il.reg(1, "x")),
- "sty": lambda il, operand: il.store(1, operand, il.reg(1, "y")),
- "tax": lambda il, operand: il.set_reg(1, "x", il.reg(1, "a"), flags = "zs"),
- "tay": lambda il, operand: il.set_reg(1, "y", il.reg(1, "a"), flags = "zs"),
- "tsx": lambda il, operand: il.set_reg(1, "x", il.reg(1, "s"), flags = "zs"),
- "txa": lambda il, operand: il.set_reg(1, "a", il.reg(1, "x"), flags = "zs"),
- "txs": lambda il, operand: il.set_reg(1, "s", il.reg(1, "x")),
- "tya": lambda il, operand: il.set_reg(1, "a", il.reg(1, "y"), flags = "zs")
-}
-
-
-class M6502(Architecture):
- name = "6502"
- address_size = 2
- default_int_size = 1
- instr_alignment = 1
- max_instr_length = 3
- regs = {
- "a": RegisterInfo("a", 1),
- "x": RegisterInfo("x", 1),
- "y": RegisterInfo("y", 1),
- "s": RegisterInfo("s", 1)
- }
- stack_pointer = "s"
- flags = ["c", "z", "i", "d", "b", "v", "s"]
- flag_write_types = ["*", "czs", "zvs", "zs"]
- flag_roles = {
- "c": FlagRole.SpecialFlagRole, # Not a normal carry flag, subtract result is inverted
- "z": FlagRole.ZeroFlagRole,
- "v": FlagRole.OverflowFlagRole,
- "s": FlagRole.NegativeSignFlagRole
- }
- flags_required_for_flag_condition = {
- LowLevelILFlagCondition.LLFC_UGE: ["c"],
- LowLevelILFlagCondition.LLFC_ULT: ["c"],
- LowLevelILFlagCondition.LLFC_E: ["z"],
- LowLevelILFlagCondition.LLFC_NE: ["z"],
- LowLevelILFlagCondition.LLFC_NEG: ["s"],
- LowLevelILFlagCondition.LLFC_POS: ["s"]
- }
- flags_written_by_flag_write_type = {
- "*": ["c", "z", "v", "s"],
- "czs": ["c", "z", "s"],
- "zvs": ["z", "v", "s"],
- "zs": ["z", "s"]
- }
-
- def decode_instruction(self, data, addr):
- if len(data) < 1:
- return None, None, None, None
- opcode = ord(data[0])
- instr = InstructionNames[opcode]
- if instr is None:
- return None, None, None, None
-
- operand = InstructionOperandTypes[opcode]
- length = 1 + OperandLengths[operand]
- if len(data) < length:
- return None, None, None, None
-
- if OperandLengths[operand] == 0:
- value = None
- elif operand == REL:
- value = (addr + 2 + struct.unpack("b", data[1])[0]) & 0xffff
- elif OperandLengths[operand] == 1:
- value = ord(data[1])
- else:
- value = struct.unpack("<H", data[1:3])[0]
-
- return instr, operand, length, value
-
- def get_instruction_info(self, data, addr):
- instr, operand, length, value = self.decode_instruction(data, addr)
- if instr is None:
- return None
-
- result = InstructionInfo()
- result.length = length
- if instr == "jmp":
- if operand == ADDR:
- result.add_branch(BranchType.UnconditionalBranch, struct.unpack("<H", data[1:3])[0])
- else:
- result.add_branch(BranchType.UnresolvedBranch)
- elif instr == "jsr":
- result.add_branch(BranchType.CallDestination, struct.unpack("<H", data[1:3])[0])
- elif instr in ["rti", "rts"]:
- result.add_branch(BranchType.FunctionReturn)
- if instr in ["bcc", "bcs", "beq", "bmi", "bne", "bpl", "bvc", "bvs"]:
- dest = (addr + 2 + struct.unpack("b", data[1])[0]) & 0xffff
- result.add_branch(BranchType.TrueBranch, dest)
- result.add_branch(BranchType.FalseBranch, addr + 2)
- return result
-
- def get_instruction_text(self, data, addr):
- instr, operand, length, value = self.decode_instruction(data, addr)
- if instr is None:
- return None
-
- tokens = []
- tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "%-7s " % instr.replace("@", "")))
- tokens += OperandTokens[operand](value)
- return tokens, length
-
- def get_instruction_low_level_il(self, data, addr, il):
- instr, operand, length, value = self.decode_instruction(data, addr)
- if instr is None:
- return None
-
- operand = OperandIL[operand](il, value)
- instr = InstructionIL[instr](il, operand)
- if isinstance(instr, list):
- for i in instr:
- il.append(i)
- elif instr is not None:
- il.append(instr)
-
- return length
-
- def get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il):
- if flag == 'c':
- if (op == LowLevelILOperation.LLIL_SUB) or (op == LowLevelILOperation.LLIL_SBB):
- # Subtraction carry flag is inverted from the commom implementation
- return il.not_expr(0, self.get_default_flag_write_low_level_il(op, size, FlagRole.CarryFlagRole, operands, il))
- # Other operations use a normal carry flag
- return self.get_default_flag_write_low_level_il(op, size, FlagRole.CarryFlagRole, operands, il)
- return Architecture.get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il)
-
- def is_never_branch_patch_available(self, data, addr):
- if (data[0] == "\x10") or (data[0] == "\x30") or (data[0] == "\x50") or (data[0] == "\x70") or (data[0] == "\x90") or (data[0] == "\xb0") or (data[0] == "\xd0") or (data[0] == "\xf0"):
- return True
- return False
-
- def is_invert_branch_patch_available(self, data, addr):
- if (data[0] == "\x10") or (data[0] == "\x30") or (data[0] == "\x50") or (data[0] == "\x70") or (data[0] == "\x90") or (data[0] == "\xb0") or (data[0] == "\xd0") or (data[0] == "\xf0"):
- return True
- return False
-
- def is_always_branch_patch_available(self, data, addr):
- return False
-
- def is_skip_and_return_zero_patch_available(self, data, addr):
- return (data[0] == "\x20") and (len(data) == 3)
-
- def is_skip_and_return_value_patch_available(self, data, addr):
- return (data[0] == "\x20") and (len(data) == 3)
-
- def convert_to_nop(self, data, addr):
- return "\xea" * len(data)
-
- def never_branch(self, data, addr):
- if (data[0] == "\x10") or (data[0] == "\x30") or (data[0] == "\x50") or (data[0] == "\x70") or (data[0] == "\x90") or (data[0] == "\xb0") or (data[0] == "\xd0") or (data[0] == "\xf0"):
- return "\xea" * len(data)
- return None
-
- def invert_branch(self, data, addr):
- if (data[0] == "\x10") or (data[0] == "\x30") or (data[0] == "\x50") or (data[0] == "\x70") or (data[0] == "\x90") or (data[0] == "\xb0") or (data[0] == "\xd0") or (data[0] == "\xf0"):
- return chr(ord(data[0]) ^ 0x20) + data[1:]
- return None
-
- def skip_and_return_value(self, data, addr, value):
- if (data[0] != "\x20") or (len(data) != 3):
- return None
- return "\xa9" + chr(value & 0xff) + "\xea"
-
-
-class NESView(BinaryView):
- name = "NES"
- long_name = "NES ROM"
-
- def __init__(self, data):
- BinaryView.__init__(self, parent_view = data, file_metadata = data.file)
- self.platform = Architecture['6502'].standalone_platform
-
- @classmethod
- def is_valid_for_data(self, data):
- hdr = data.read(0, 16)
- if len(hdr) < 16:
- return False
- if hdr[0:4] != "NES\x1a":
- return False
- rom_banks = struct.unpack("B", hdr[4])[0]
- if rom_banks < (self.bank + 1):
- return False
- return True
-
- def init(self):
- try:
- hdr = self.parent_view.read(0, 16)
- self.rom_banks = struct.unpack("B", hdr[4])[0]
- self.vrom_banks = struct.unpack("B", hdr[5])[0]
- self.rom_flags = struct.unpack("B", hdr[6])[0]
- self.mapper_index = struct.unpack("B", hdr[7])[0] | (self.rom_flags >> 4)
- self.ram_banks = struct.unpack("B", hdr[8])[0]
- self.rom_offset = 16
- if self.rom_flags & 4:
- self.rom_offset += 512
- self.rom_length = self.rom_banks * 0x4000
-
- # Add mapping for RAM and hardware registers, not backed by file contents
- self.add_auto_segment(0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
-
- # Add ROM mappings
- self.add_auto_segment(0x8000, 0x4000, self.rom_offset + (self.__class__.bank * 0x4000), 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
- self.add_auto_segment(0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
-
- nmi = struct.unpack("<H", self.read(0xfffa, 2))[0]
- start = struct.unpack("<H", self.read(0xfffc, 2))[0]
- irq = struct.unpack("<H", self.read(0xfffe, 2))[0]
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, nmi, "_nmi"))
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, start, "_start"))
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, irq, "_irq"))
- self.add_function(nmi)
- self.add_function(irq)
- self.add_entry_point(start)
-
- # Hardware registers
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2000, "PPUCTRL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2001, "PPUMASK"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2002, "PPUSTATUS"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2003, "OAMADDR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2004, "OAMDATA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2005, "PPUSCROLL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2006, "PPUADDR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2007, "PPUDATA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4000, "SQ1_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4001, "SQ1_SWEEP"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4002, "SQ1_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4003, "SQ1_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4004, "SQ2_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4005, "SQ2_SWEEP"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4006, "SQ2_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4007, "SQ2_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4008, "TRI_LINEAR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400a, "TRI_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400b, "TRI_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400c, "NOISE_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400e, "NOISE_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400f, "NOISE_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4010, "DMC_FREQ"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4011, "DMC_RAW"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4012, "DMC_START"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4013, "DMC_LEN"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4014, "OAMDMA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4015, "SND_CHN"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))
-
- sym_files = [self.file.filename + ".%x.nl" % self.__class__.bank,
- self.file.filename + ".ram.nl",
- self.file.filename + ".%x.nl" % (self.rom_banks - 1)]
- for f in sym_files:
- if os.path.exists(f):
- sym_contents = open(f, "r").read()
- lines = sym_contents.split('\n')
- for line in lines:
- sym = line.split('#')
- if len(sym) < 3:
- break
- addr = int(sym[0][1:], 16)
- name = sym[1]
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, addr, name))
- if addr >= 0x8000:
- self.add_function(addr)
-
- return True
- except:
- log_error(traceback.format_exc())
- return False
-
- def perform_is_executable(self):
- return True
-
- def perform_get_entry_point(self):
- return struct.unpack("<H", str(self.perform_read(0xfffc, 2)))[0]
-
-
-banks = []
-for i in xrange(0, 32):
- class NESViewBank(NESView):
- bank = i
- name = "NES Bank %X" % i
- long_name = "NES ROM (bank %X)" % i
-
- def __init__(self, data):
- NESView.__init__(self, data)
-
- banks.append(NESViewBank)
- NESViewBank.register()
-
-M6502.register()
diff --git a/python/examples/notification_callbacks.py b/python/examples/notification_callbacks.py
deleted file mode 100644
index b7c9cde9..00000000
--- a/python/examples/notification_callbacks.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from binaryninja import BinaryDataNotification, PluginCommand, log_info
-import inspect
-
-def reg_notif(view):
- demo_notification = DemoNotification(view)
- view.register_notification(demo_notification)
-
-class DemoNotification(BinaryDataNotification):
- def __init__(self, view):
- self.view = view
-
- def data_written(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def data_inserted(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def data_removed(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def function_added(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def function_removed(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def function_updated(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def data_var_added(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def data_var_updated(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def data_var_removed(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def string_found(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def string_removed(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def type_defined(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
- def type_undefined(self, *args):
- log_info(inspect.stack()[0][3] + str(args))
-
-PluginCommand.register("Register Notification", "", reg_notif)
diff --git a/python/examples/nsf.py b/python/examples/nsf.py
deleted file mode 100644
index b0164065..00000000
--- a/python/examples/nsf.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-#
-#
-# Simple NSF file loader, primarily for analyzing:
-# https://scarybeastsecurity.blogspot.com/2016/11/0day-exploit-compromising-linux-desktop.html
-#
-
-from binaryninja.binaryview import BinaryView
-from binaryninja.architecture import Architecture
-from binaryninja.log import log_error, log_info
-from binaryninja.types import Symbol
-from binaryninja.enums import SymbolType, SegmentFlag
-
-import struct
-import traceback
-
-
-class NSFView(BinaryView):
- name = "NSF"
- long_name = "Nintendo Sound Format"
-
- def __init__(self, data):
- BinaryView.__init__(self, parent_view=data, file_metadata=data.file)
- self.platform = Architecture["6502"].standalone_platform
-
- @classmethod
- def is_valid_for_data(self, data):
- hdr = data.read(0, 128)
- if len(hdr) < 128:
- return False
- if hdr[0:5] != "NESM\x1a":
- return False
- song_count = struct.unpack("B", hdr[6])[0]
- if song_count < 1:
- log_info("Appears to be an NSF, but no songs.")
- return False
- return True
-
- def init(self):
- try:
- hdr = self.parent_view.read(0, 128)
- self.version = struct.unpack("B", hdr[5])[0]
- self.song_count = struct.unpack("B", hdr[6])[0]
- self.starting_song = struct.unpack("B", hdr[7])[0]
- self.load_address = struct.unpack("<H", hdr[8:10])[0]
- self.init_address = struct.unpack("<H", hdr[10:12])[0]
- self.play_address = struct.unpack("<H", hdr[12:14])[0]
- self.song_name = hdr[15].split('\0')[0]
- self.artist_name = hdr[46].split('\0')[0]
- self.copyright_name = hdr[78].split('\0')[0]
- self.play_speed_ntsc = struct.unpack("<H", hdr[110:112])[0]
- self.bank_switching = hdr[112:120]
- self.play_speed_pal = struct.unpack("<H", hdr[120:122])[0]
- self.pal_ntsc_bits = struct.unpack("B", hdr[122])[0]
- self.pal = True if (self.pal_ntsc_bits & 1) == 1 else False
- self.ntsc = not self.pal
- if self.pal_ntsc_bits & 2 == 2:
- self.pal = True
- self.ntsc = True
- self.extra_sound_bits = struct.unpack("B", hdr[123])[0]
-
- if self.bank_switching == "\0" * 8:
- # no bank switching
- self.load_address & 0xFFF
- self.rom_offset = 128
-
- else:
- # bank switching not implemented
- log_info("Bank switching not implemented in this loader.")
-
- # Add mapping for RAM and hardware registers, not backed by file contents
- self.add_auto_segment(0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
-
- # Add ROM mappings
- self.add_auto_segment(0x8000, 0x4000, self.rom_offset, 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
-
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.play_address, "_play"))
- self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.init_address, "_init"))
- self.add_entry_point(self.init_address)
- self.add_function(self.play_address)
-
- # Hardware registers
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2000, "PPUCTRL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2001, "PPUMASK"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2002, "PPUSTATUS"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2003, "OAMADDR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2004, "OAMDATA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2005, "PPUSCROLL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2006, "PPUADDR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x2007, "PPUDATA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4000, "SQ1_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4001, "SQ1_SWEEP"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4002, "SQ1_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4003, "SQ1_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4004, "SQ2_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4005, "SQ2_SWEEP"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4006, "SQ2_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4007, "SQ2_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4008, "TRI_LINEAR"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400a, "TRI_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400b, "TRI_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400c, "NOISE_VOL"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400e, "NOISE_LO"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x400f, "NOISE_HI"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4010, "DMC_FREQ"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4011, "DMC_RAW"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4012, "DMC_START"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4013, "DMC_LEN"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4014, "OAMDMA"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4015, "SND_CHN"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
- self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))
-
- return True
- except:
- log_error(traceback.format_exc())
- return False
-
- def perform_is_executable(self):
- return True
-
- def perform_get_entry_point(self):
- return struct.unpack("<H", str(self.perform_read(0x0a, 2)))[0]
-
-
-NSFView.register()
diff --git a/python/examples/print_syscalls.py b/python/examples/print_syscalls.py
deleted file mode 100644
index d995ad1e..00000000
--- a/python/examples/print_syscalls.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-
-# Thanks to @theqlabs from arm.ninja for the nice writeup and idea for this plugin:
-# http://arm.ninja/2016/03/08/intro-to-binary-ninja-api/
-
-import sys
-from itertools import chain
-
-from binaryninja.binaryview import BinaryViewType
-from binaryninja.enums import LowLevelILOperation
-
-
-def print_syscalls(fileName):
- """ Print Syscall numbers for a provided file """
- bv = BinaryViewType.get_view_of_file(fileName)
- calling_convention = bv.platform.system_call_convention
- if calling_convention is None:
- print('Error: No syscall convention available for {:s}'.format(bv.platform))
- return
-
- register = calling_convention.int_arg_regs[0]
-
- for func in bv.functions:
- syscalls = (il for il in chain.from_iterable(func.low_level_il)
- if il.operation == LowLevelILOperation.LLIL_SYSCALL)
- for il in syscalls:
- value = func.get_reg_value_at(il.address, register).value
- print("System call address: {:#x} - {:d}".format(il.address, value))
-
-
-if __name__ == "__main__":
- if len(sys.argv) != 2:
- print('Usage: {} <file>'.format(sys.argv[0]))
- else:
- print_syscalls(sys.argv[1])
diff --git a/python/examples/version_switcher.py b/python/examples/version_switcher.py
deleted file mode 100644
index 3e1cab40..00000000
--- a/python/examples/version_switcher.py
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2015-2017 Vector 35 LLC
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-# IN THE SOFTWARE.
-
-import sys
-
-from binaryninja.update import UpdateChannel, are_auto_updates_enabled, set_auto_updates_enabled, is_update_installation_pending, install_pending_update
-from binaryninja import core_version
-import datetime
-
-chandefault = UpdateChannel.list[0].name
-channel = None
-versions = []
-
-
-def load_channel(newchannel):
- global channel
- global versions
- if (channel is not None and newchannel == channel.name):
- print "Same channel, not updating."
- else:
- try:
- print "Loading channel %s" % newchannel
- channel = UpdateChannel[newchannel]
- print "Loading versions..."
- versions = channel.versions
- except Exception:
- print "%s is not a valid channel name. Defaulting to " % chandefault
- channel = UpdateChannel[chandefault]
-
-
-def select(version):
- done = False
- date = datetime.datetime.fromtimestamp(version.time).strftime('%c')
- while not done:
- print "Version:\t%s" % version.version
- print "Updated:\t%s" % date
- print "Notes:\n\n-----\n%s" % version.notes
- print "-----"
- print "\t1)\tSwitch to version"
- print "\t2)\tMain Menu"
- selection = raw_input('Choice: ')
- if selection.isdigit():
- selection = int(selection)
- else:
- selection = 0
- if (selection == 2):
- done = True
- elif (selection == 1):
- if (version.version == channel.latest_version.version):
- print "Requesting update to latest version."
- else:
- print "Requesting update to prior version."
- if are_auto_updates_enabled():
- print "Disabling automatic updates."
- set_auto_updates_enabled(False)
- if (version.version == core_version):
- print "Already running %s" % version.version
- else:
- print "version.version %s" % version.version
- print "core_version %s" % core_version
- print "Downloading..."
- print version.update()
- print "Installing..."
- if is_update_installation_pending:
- #note that the GUI will be launched after update but should still do the upgrade headless
- install_pending_update()
- # forward updating won't work without reloading
- sys.exit()
- else:
- print "Invalid selection"
-
-
-def list_channels():
- done = False
- print "\tSelect channel:\n"
- while not done:
- channel_list = UpdateChannel.list
- for index, item in enumerate(channel_list):
- print "\t%d)\t%s" % (index + 1, item.name)
- print "\t%d)\t%s" % (len(channel_list) + 1, "Main Menu")
- selection = raw_input('Choice: ')
- if selection.isdigit():
- selection = int(selection)
- else:
- selection = 0
- if (selection <= 0 or selection > len(channel_list) + 1):
- print "%s is an invalid choice." % selection
- else:
- done = True
- if (selection != len(channel_list) + 1):
- load_channel(channel_list[selection - 1].name)
-
-
-def toggle_updates():
- set_auto_updates_enabled(not are_auto_updates_enabled())
-
-
-def main():
- global channel
- done = False
- load_channel(chandefault)
- while not done:
- print "\n\tBinary Ninja Version Switcher"
- print "\t\tCurrent Channel:\t%s" % channel.name
- print "\t\tCurrent Version:\t%s" % core_version
- print "\t\tAuto-Updates On:\t%s\n" % are_auto_updates_enabled()
- for index, version in enumerate(versions):
- date = datetime.datetime.fromtimestamp(version.time).strftime('%c')
- print "\t%d)\t%s (%s)" % (index + 1, version.version, date)
- print "\t%d)\t%s" % (len(versions) + 1, "Switch Channel")
- print "\t%d)\t%s" % (len(versions) + 2, "Toggle Auto Updates")
- print "\t%d)\t%s" % (len(versions) + 3, "Exit")
- selection = raw_input('Choice: ')
- if selection.isdigit():
- selection = int(selection)
- else:
- selection = 0
- if (selection <= 0 or selection > len(versions) + 3):
- print "%d is an invalid choice.\n\n" % selection
- else:
- if (selection == len(versions) + 3):
- done = True
- elif (selection == len(versions) + 2):
- toggle_updates()
- elif (selection == len(versions) + 1):
- list_channels()
- else:
- select(versions[selection - 1])
-
-
-if __name__ == "__main__":
- main()
diff --git a/python/fileaccessor.py b/python/fileaccessor.py
index 2c1f1d19..5a602b89 100644
--- a/python/fileaccessor.py
+++ b/python/fileaccessor.py
@@ -21,12 +21,11 @@
import traceback
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-import log
-
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class FileAccessor(object):
+ from binaryninja import log
def __init__(self):
self._cb = core.BNFileAccessor()
self._cb.context = 0
diff --git a/python/filemetadata.py b/python/filemetadata.py
index 4bfc0214..695b95f3 100644
--- a/python/filemetadata.py
+++ b/python/filemetadata.py
@@ -18,18 +18,17 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+from __future__ import absolute_import
import traceback
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-import startup
-import associateddatastore
-import log
-import binaryview
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja import associateddatastore #required for _FileMetadataAssociatedDataStore
class NavigationHandler(object):
+ from binaryninja import log
def _register(self, handle):
self._cb = core.BNNavigationHandler()
self._cb.context = 0
@@ -66,12 +65,14 @@ class _FileMetadataAssociatedDataStore(associateddatastore._AssociatedDataStore)
class FileMetadata(object):
- _associated_data = {}
-
"""
``class FileMetadata`` represents the file being analyzed by Binary Ninja. It is responsible for opening,
closing, creating the database (.bndb) files, and is used to keep track of undoable actions.
"""
+ from binaryninja import startup
+ from binaryninja import binaryview
+ _associated_data = {}
+
def __init__(self, filename = None, handle = None):
"""
Instantiates a new FileMetadata class.
diff --git a/python/function.py b/python/function.py
index 2f794f47..2ee9b20d 100644
--- a/python/function.py
+++ b/python/function.py
@@ -18,27 +18,18 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+from __future__ import absolute_import
import threading
import traceback
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import (AnalysisSkipReason, FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType,
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import (AnalysisSkipReason, FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType,
HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend,
DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType,
FunctionAnalysisSkipOverride)
-import architecture
-import platform
-import highlight
-import associateddatastore
-import types
-import basicblock
-import lowlevelil
-import mediumlevelil
-import binaryview
-import log
-import callingconvention
+from binaryninja import associateddatastore #required in the main scope due to being an argument for _FunctionAssociatedDataStore
class LookupTableEntry(object):
@@ -51,6 +42,7 @@ class LookupTableEntry(object):
class RegisterValue(object):
+ from binaryninja import types
def __init__(self, arch = None, value = None, confidence = types.max_confidence):
self.is_constant = False
if value is None:
@@ -329,6 +321,7 @@ class IndirectBranchInfo(object):
class ParameterVariables(object):
+ from binaryninja import types
def __init__(self, var_list, confidence = types.max_confidence):
self.vars = var_list
self.confidence = confidence
@@ -355,6 +348,14 @@ class _FunctionAssociatedDataStore(associateddatastore._AssociatedDataStore):
class Function(object):
+ from binaryninja import callingconvention
+ from binaryninja import mediumlevelil
+ from binaryninja import lowlevelil
+ from binaryninja import basicblock
+ from binaryninja import types
+ from binaryninja import highlight
+ from binaryninja import platform
+ from binaryninja import architecture
_associated_data = {}
def __init__(self, view, handle):
@@ -1631,7 +1632,8 @@ class FunctionGraphEdge(object):
class FunctionGraphBlock(object):
- def __init__(self, handle, graph):
+ def __init__(self, handle):
+ from binaryninja import binaryview
self.handle = handle
self.graph = graph
@@ -1839,6 +1841,8 @@ class DisassemblySettings(object):
class FunctionGraph(object):
+ from binaryninja import log
+ from binaryninja import types
def __init__(self, view, handle):
self.view = view
self.handle = handle
@@ -2140,6 +2144,7 @@ class InstructionTextToken(object):
========================== ============================================
"""
+ from binaryninja import types
def __init__(self, token_type, text, value = 0, size = 0, operand = 0xffffffff,
context = InstructionTextTokenContext.NoTokenContext, address = 0, confidence = types.max_confidence):
self.type = InstructionTextTokenType(token_type)
diff --git a/python/functionrecognizer.py b/python/functionrecognizer.py
index 4ac304ca..158a0700 100644
--- a/python/functionrecognizer.py
+++ b/python/functionrecognizer.py
@@ -20,16 +20,16 @@
import traceback
-# Binary Ninja components
-import _binaryninjacore as core
-import function
-import filemetadata
-import binaryview
-import lowlevelil
-import log
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class FunctionRecognizer(object):
+ from binaryninja import function
+ from binaryninja import filemetadata
+ from binaryninja import binaryview
+ from binaryninja import lowlevelil
+ from binaryninja import log
_instance = None
def __init__(self):
diff --git a/python/generator.cpp b/python/generator.cpp
index f838b36d..bb32ab69 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -374,10 +374,10 @@ int main(int argc, char* argv[])
fprintf(out, "def handle_of_type(value, handle_type):\n");
fprintf(out, "\tif isinstance(value, ctypes.POINTER(handle_type)) or isinstance(value, ctypes.c_void_p):\n");
fprintf(out, "\t\treturn ctypes.cast(value, ctypes.POINTER(handle_type))\n");
- fprintf(out, "\traise ValueError, 'expected pointer to %%s' %% str(handle_type)\n");
+ fprintf(out, "\traise ValueError('expected pointer to %%s' %% str(handle_type))\n");
fprintf(out, "\n# Set path for core plugins\n");
- fprintf(out, "BNSetBundledPluginDirectory(os.path.join(_base_path, \"plugins\"))\n");
+ fprintf(out, "BNSetBundledPluginDirectory(os.path.join(_base_path, \"plugins\").encode('utf-8'))\n");
fclose(out);
fclose(enums);
diff --git a/python/highlight.py b/python/highlight.py
index 96bc543d..b04561bd 100644
--- a/python/highlight.py
+++ b/python/highlight.py
@@ -19,9 +19,9 @@
# IN THE SOFTWARE.
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import HighlightColorStyle, HighlightStandardColor
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import HighlightColorStyle, HighlightStandardColor
class HighlightColor(object):
diff --git a/python/interaction.py b/python/interaction.py
index 5b7ec497..8507682c 100644
--- a/python/interaction.py
+++ b/python/interaction.py
@@ -21,11 +21,9 @@
import ctypes
import traceback
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import FormInputFieldType, MessageBoxIcon, MessageBoxButtonSet, MessageBoxButtonResult
-import binaryview
-import log
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import FormInputFieldType, MessageBoxIcon, MessageBoxButtonSet, MessageBoxButtonResult
class LabelField(object):
@@ -241,6 +239,8 @@ class DirectoryNameField(object):
class InteractionHandler(object):
+ from binaryninja import log
+ from binaryninja import binaryview
_interaction_handler = None
def __init__(self):
@@ -724,7 +724,7 @@ def get_form_input(fields, title):
3) Maybe
Options 1
>>> True
- >>> print tex_f.result, int_f.result, choice_f.result
+ >>> print(tex_f.result, int_f.result, choice_f.result)
Peter 1337 0
"""
value = (core.BNFormInputField * len(fields))()
diff --git a/python/log.py b/python/log.py
index b1fd7095..e7cd956d 100644
--- a/python/log.py
+++ b/python/log.py
@@ -19,9 +19,8 @@
# IN THE SOFTWARE.
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import LogLevel
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
_output_to_log = False
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index bd1e9349..3b12c118 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -19,15 +19,13 @@
# IN THE SOFTWARE.
import ctypes
-
-# Binary Ninja components
-import _binaryninjacore as core
-from .enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType
-import function
-import basicblock
-import mediumlevelil
import struct
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType
+from binaryninja import basicblock #required for LowLevelILBasicBlock
+
class LowLevelILLabel(object):
def __init__(self, handle = None):
@@ -342,6 +340,8 @@ class LowLevelILInstruction(object):
}
def __init__(self, func, expr_index, instr_index=None):
+ from binaryninja import function
+ from binaryninja import mediumlevelil
instr = core.BNGetLowLevelILByIndex(func.handle, expr_index)
self.function = func
self.expr_index = expr_index
@@ -441,7 +441,7 @@ class LowLevelILInstruction(object):
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = []
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
reg = operand_list[j * 2]
reg_version = operand_list[(j * 2) + 1]
value.append(SSARegister(ILRegister(func.arch, reg), reg_version))
@@ -451,7 +451,7 @@ class LowLevelILInstruction(object):
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = []
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
reg_stack = operand_list[j * 2]
reg_version = operand_list[(j * 2) + 1]
value.append(SSARegisterStack(ILRegisterStack(func.arch, reg_stack), reg_version))
@@ -461,7 +461,7 @@ class LowLevelILInstruction(object):
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = []
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
flag = operand_list[j * 2]
flag_version = operand_list[(j * 2) + 1]
value.append(SSAFlag(ILFlag(func.arch, flag), flag_version))
@@ -471,7 +471,7 @@ class LowLevelILInstruction(object):
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = []
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
if (operand_list[j * 2] & (1 << 32)) != 0:
reg_or_flag = ILFlag(func.arch, operand_list[j * 2] & 0xffffffff)
else:
@@ -484,7 +484,7 @@ class LowLevelILInstruction(object):
operand_list = core.BNLowLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = {}
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
reg_stack = operand_list[j * 2]
adjust = operand_list[(j * 2) + 1]
if adjust & 0x80000000:
@@ -720,6 +720,7 @@ class LowLevelILFunction(object):
LLFC_NO !overflow No overflow
======================= ========== ===============================
"""
+ from binaryninja import mediumlevelil
def __init__(self, arch, handle = None, source_func = None):
self.arch = arch
self.source_function = source_func
diff --git a/python/mainthread.py b/python/mainthread.py
index 3e12bd65..16938f1a 100644
--- a/python/mainthread.py
+++ b/python/mainthread.py
@@ -18,9 +18,9 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-# Binary Ninja components
-import _binaryninjacore as core
-import scriptingprovider
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja import scriptingprovider
def execute_on_main_thread(func):
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 100795fe..9a21bb23 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -19,16 +19,13 @@
# IN THE SOFTWARE.
import ctypes
-
-# Binary Ninja components
-import _binaryninjacore as core
-from .enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDependence
-import function
-import basicblock
-import lowlevelil
-import types
import struct
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDependence
+from binaryninja import basicblock #required for MediumLevelILBasicBlock argument
+
class SSAVariable(object):
def __init__(self, var, version):
@@ -208,6 +205,9 @@ class MediumLevelILInstruction(object):
}
def __init__(self, func, expr_index, instr_index=None):
+ from binaryninja import function
+ from binaryninja import types
+ from binaryninja import lowlevelil
instr = core.BNGetMediumLevelILByIndex(func.handle, expr_index)
self.function = func
self.expr_index = expr_index
@@ -272,7 +272,7 @@ class MediumLevelILInstruction(object):
operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count)
i += 1
value = []
- for j in xrange(count.value / 2):
+ for j in xrange(count.value // 2):
var_id = operand_list[j * 2]
var_version = operand_list[(j * 2) + 1]
value.append(SSAVariable(function.Variable.from_identifier(self.function.source_function,
diff --git a/python/metadata.py b/python/metadata.py
index 554bbcf4..21e74533 100644
--- a/python/metadata.py
+++ b/python/metadata.py
@@ -19,11 +19,12 @@
# IN THE SOFTWARE.
+from __future__ import absolute_import
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import MetadataType
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import MetadataType
class Metadata(object):
diff --git a/python/platform.py b/python/platform.py
index dd756178..ff59be50 100644
--- a/python/platform.py
+++ b/python/platform.py
@@ -20,15 +20,16 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-import startup
-import architecture
-import callingconvention
-import types
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+
+#2-3 compatibility
+from six import with_metaclass
class _PlatformMetaClass(type):
+ from binaryninja import startup
+ from binaryninja import types
@property
def list(self):
startup._init_plugins()
@@ -90,12 +91,14 @@ class _PlatformMetaClass(type):
return result
-class Platform(object):
+class Platform(with_metaclass(_PlatformMetaClass, object)):
"""
``class Platform`` contains all information releated to the execution environment of the binary, mainly the
calling conventions used.
"""
- __metaclass__ = _PlatformMetaClass
+ from binaryninja import architecture
+ from binaryninja import callingconvention
+ from binaryninja import types
name = None
def __init__(self, arch, handle = None):
diff --git a/python/plugin.py b/python/plugin.py
index 13ca51af..5dad9fb6 100644
--- a/python/plugin.py
+++ b/python/plugin.py
@@ -22,16 +22,12 @@ import traceback
import ctypes
import threading
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import PluginCommandType
-import startup
-import filemetadata
-import binaryview
-import function
-import log
-import lowlevelil
-import mediumlevelil
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import PluginCommandType
+
+#2-3 compatibility
+from six import with_metaclass
class PluginCommandContext(object):
@@ -44,6 +40,7 @@ class PluginCommandContext(object):
class _PluginCommandMetaClass(type):
+ from binaryninja import startup
@property
def list(self):
startup._init_plugins()
@@ -72,9 +69,13 @@ class _PluginCommandMetaClass(type):
raise AttributeError("attribute '%s' is read only" % name)
-class PluginCommand(object):
+class PluginCommand(with_metaclass(_PluginCommandMetaClass, object)):
+ from binaryninja import startup
+ from binaryninja import filemetadata
+ from binaryninja import binaryview
+ from binaryninja import function
+ from binaryninja import log
_registered_commands = []
- __metaclass__ = _PluginCommandMetaClass
def __init__(self, cmd):
self.command = core.BNPluginCommand()
@@ -536,6 +537,7 @@ class MainThreadAction(object):
class MainThreadActionHandler(object):
+ from binaryninja import log
_main_thread = None
def __init__(self):
@@ -580,8 +582,7 @@ class _BackgroundTaskMetaclass(type):
core.BNFreeBackgroundTaskList(tasks, count.value)
-class BackgroundTask(object):
- __metaclass__ = _BackgroundTaskMetaclass
+class BackgroundTask(with_metaclass(_BackgroundTaskMetaclass, object)):
def __init__(self, initial_progress_text = "", can_cancel = False, handle = None):
if handle is None:
diff --git a/python/pluginmanager.py b/python/pluginmanager.py
index 0cc43aca..66f642c3 100644
--- a/python/pluginmanager.py
+++ b/python/pluginmanager.py
@@ -20,10 +20,8 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from .enums import PluginType, PluginUpdateStatus
-import startup
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class RepoPlugin(object):
@@ -31,6 +29,7 @@ class RepoPlugin(object):
``RepoPlugin` is mostly read-only, however you can install/uninstall enable/disable plugins. RepoPlugins are
created by parsing the plugins.json in a plugin repository.
"""
+ from binaryninja.enums import PluginType, PluginUpdateStatus
def __init__(self, handle):
raise Exception("RepoPlugin temporarily disabled!")
self.handle = core.handle_of_type(handle, core.BNRepoPlugin)
@@ -200,6 +199,7 @@ 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
"""
+ from binaryninja import startup
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 9cacc6ad..ac0ffd4c 100644
--- a/python/scriptingprovider.py
+++ b/python/scriptingprovider.py
@@ -26,14 +26,12 @@ import threading
import abc
import sys
-# Binary Ninja Components
-import _binaryninjacore as core
-from enums import ScriptingProviderExecuteResult, ScriptingProviderInputReadyState
-import binaryview
-import function
-import basicblock
-import startup
-import log
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import ScriptingProviderExecuteResult, ScriptingProviderInputReadyState
+
+#2-3 compatibility
+from six import with_metaclass
class _ThreadActionContext(object):
@@ -60,6 +58,7 @@ class _ThreadActionContext(object):
class ScriptingOutputListener(object):
+ from binaryninja import log
def _register(self, handle):
self._cb = core.BNScriptingOutputListener()
self._cb.context = 0
@@ -100,6 +99,10 @@ class ScriptingOutputListener(object):
class ScriptingInstance(object):
+ from binaryninja import binaryview
+ from binaryninja import basicblock
+ from binaryninja import log
+ from binaryninja import function
def __init__(self, provider, handle = None):
if handle is None:
self._cb = core.BNScriptingInstanceCallbacks()
@@ -256,6 +259,7 @@ class ScriptingInstance(object):
class _ScriptingProviderMetaclass(type):
+ from binaryninja import startup
@property
def list(self):
"""List all ScriptingProvider types (read-only)"""
@@ -292,8 +296,8 @@ class _ScriptingProviderMetaclass(type):
raise AttributeError("attribute '%s' is read only" % name)
-class ScriptingProvider(object):
- __metaclass__ = _ScriptingProviderMetaclass
+class ScriptingProvider(with_metaclass(_ScriptingProviderMetaclass, object)):
+ from binaryninja import log
name = None
instance_class = None
@@ -335,6 +339,7 @@ class ScriptingProvider(object):
class _PythonScriptingInstanceOutput(object):
+ from binaryninja import log
def __init__(self, orig, is_error):
self.orig = orig
self.is_error = is_error
diff --git a/python/setting.py b/python/setting.py
index d58c8955..7cde3865 100644
--- a/python/setting.py
+++ b/python/setting.py
@@ -20,8 +20,8 @@
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
class Setting(object):
diff --git a/python/startup.py b/python/startup.py
index 0abc47cb..919a8fbe 100644
--- a/python/startup.py
+++ b/python/startup.py
@@ -18,7 +18,7 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-import _binaryninjacore as core
+from binaryninja import _binaryninjacore as core
_plugin_init = False
diff --git a/python/transform.py b/python/transform.py
index 3284ed74..f04bfdca 100644
--- a/python/transform.py
+++ b/python/transform.py
@@ -22,15 +22,16 @@ import traceback
import ctypes
import abc
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import TransformType
-import startup
-import log
-import databuffer
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import TransformType
+
+#2-3 compatibility
+from six import with_metaclass
class _TransformMetaClass(type):
+ from binaryninja import startup
@property
def list(self):
startup._init_plugins()
@@ -90,14 +91,15 @@ class TransformParameter(object):
self.fixed_length = fixed_length
-class Transform(object):
+class Transform(with_metaclass(_TransformMetaClass, object)):
+ from binaryninja import log
+ from binaryninja import databuffer
transform_type = None
name = None
long_name = None
group = None
parameters = []
_registered_cb = None
- __metaclass__ = _TransformMetaClass
def __init__(self, handle):
if handle is None:
diff --git a/python/types.py b/python/types.py
index 42ed7ddd..cbe5a7bc 100644
--- a/python/types.py
+++ b/python/types.py
@@ -18,15 +18,14 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
+from __future__ import absolute_import
max_confidence = 255
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType, VariableSourceType
-import callingconvention
-import function
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import SymbolType, TypeClass, NamedTypeReferenceClass, InstructionTextTokenType, StructureType, ReferenceType, VariableSourceType
class QualifiedName(object):
@@ -213,6 +212,8 @@ class FunctionParameter(object):
class Type(object):
def __init__(self, handle, platform = None, confidence = max_confidence):
+ from binaryninja import callingconvention
+ from binaryninja import function
self.handle = handle
self.confidence = confidence
self.platform = platform
@@ -344,7 +345,7 @@ class Type(object):
return None
return Enumeration(result)
- @property
+ @property
def named_type_reference(self):
"""Reference to a named type (read-only)"""
result = core.BNGetTypeNamedTypeReference(self.handle)
@@ -376,7 +377,7 @@ class Type(object):
def __repr__(self):
if self.confidence < max_confidence:
- return "<type: %s, %d%% confidence>" % (str(self), (self.confidence * 100) / max_confidence)
+ return "<type: %s, %d%% confidence>" % (str(self), (self.confidence * 100) // max_confidence)
return "<type: %s>" % str(self)
def get_string_before_name(self):
diff --git a/python/undoaction.py b/python/undoaction.py
index 7e3c76a0..9771df38 100644
--- a/python/undoaction.py
+++ b/python/undoaction.py
@@ -22,14 +22,14 @@ import traceback
import json
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import ActionType
-import startup
-import log
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import ActionType
class UndoAction(object):
+ from binaryninja import startup
+ from binaryninja import log
name = None
action_type = None
_registered = False
diff --git a/python/update.py b/python/update.py
index 1eb8ea61..1fda149b 100644
--- a/python/update.py
+++ b/python/update.py
@@ -21,14 +21,17 @@
import traceback
import ctypes
-# Binary Ninja components
-import _binaryninjacore as core
-from enums import UpdateResult
-import startup
-import log
+# Binary Ninja components -- additional imports belong in the appropriate class
+from binaryninja import _binaryninjacore as core
+from binaryninja.enums import UpdateResult
+
+
+#2-3 compatibility
+from six import with_metaclass
class _UpdateChannelMetaClass(type):
+ from binaryninja import startup
@property
def list(self):
startup._init_plugins()
@@ -95,6 +98,7 @@ class _UpdateChannelMetaClass(type):
class UpdateProgressCallback(object):
+ from binaryninja import log
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
@@ -108,8 +112,7 @@ class UpdateProgressCallback(object):
log.log_error(traceback.format_exc())
-class UpdateChannel(object):
- __metaclass__ = _UpdateChannelMetaClass
+class UpdateChannel(with_metaclass(_UpdateChannelMetaClass, object)):
def __init__(self, name, desc, ver):
self.name = name