summaryrefslogtreecommitdiff
path: root/python/examples
diff options
context:
space:
mode:
authorAndrew Lamoureux <lwerdna@users.noreply.github.com>2017-03-15 20:33:55 -0400
committerGitHub <noreply@github.com>2017-03-15 20:33:55 -0400
commit31d34d5d067ed4c5fe071eb8637b10ed50607555 (patch)
tree9347ba4e5e6a2b26baf620f59e56db7965bb47b5 /python/examples
parent164c7a680697be72d7f42af28b89012e5c6dd53b (diff)
parent1f7523ce2b1edac1014d781fc771d5b82568e2f1 (diff)
Merge branch 'dev' into dev
Diffstat (limited to 'python/examples')
-rw-r--r--python/examples/angr_plugin.py51
-rw-r--r--python/examples/bin_info.py91
-rw-r--r--python/examples/breakpoint.py48
-rwxr-xr-xpython/examples/export_svg.py92
-rw-r--r--python/examples/instruction_iterator.py70
-rw-r--r--python/examples/jump_table.py29
-rw-r--r--python/examples/nds.py205
-rw-r--r--python/examples/nes.py447
-rw-r--r--python/examples/nsf.py91
-rw-r--r--python/examples/print_syscalls.py81
-rw-r--r--python/examples/version_switcher.py67
11 files changed, 762 insertions, 510 deletions
diff --git a/python/examples/angr_plugin.py b/python/examples/angr_plugin.py
index c6e6f87d..90217d65 100644
--- a/python/examples/angr_plugin.py
+++ b/python/examples/angr_plugin.py
@@ -1,3 +1,24 @@
+# Copyright (c) 2015-2016 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.
#
@@ -9,14 +30,20 @@
# virtual environment. A later update may allow for a manual override to link to the required version
# of Python.
-__name__ = "__console__" # angr looks for this, it won't load from within a UI without it
-import angr
-from binaryninja import *
import tempfile
-import threading
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
+
# Disable warning logs as they show up as errors in the UI
logging.disable(logging.WARNING)
@@ -24,9 +51,11 @@ logging.disable(logging.WARNING)
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):
@@ -81,37 +110,41 @@ class Solver(BackgroundTaskThread):
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(GreenHighlightColor, alpha = 128))
- block.function.set_auto_instr_highlight(block.arch, addr, GreenHighlightColor)
+ 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(RedHighlightColor, alpha = 128))
- block.function.set_auto_instr_highlight(block.arch, addr, RedHighlightColor)
+ 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.", OKButtonSet, ErrorIcon)
+ "continue.", MessageBoxButtonSet.OKButtonSet, MessageBoxButtonSet.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)
diff --git a/python/examples/bin_info.py b/python/examples/bin_info.py
index 48073894..4c4ab8fd 100644
--- a/python/examples/bin_info.py
+++ b/python/examples/bin_info.py
@@ -1,34 +1,73 @@
#!/usr/bin/env python
-import sys, binaryninja, time
-if sys.platform.lower().startswith("linux"):
- bintype="ELF"
-elif sys.platform.lower() == "darwin":
- bintype="Mach-O"
-else:
- raise Exception, "%s is not supported on this plugin" % sys.platform
+# Copyright (c) 2015-2016 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.
-if len(sys.argv) > 1:
- target = sys.argv[1]
-else:
- target = "/bin/ls"
+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 = binaryninja.BinaryViewType[bintype].open(target)
-bv.update_analysis_and_wait()
+ bv = BinaryViewType.get_view_of_file(filename)
+ log.redirect_output_to_log()
+ log.log_to_stdout(True)
-print "-------- %s --------" % target
-print "START: 0x%x" % bv.start
-print "ENTRY: 0x%x" % bv.entry_point
-print "ARCH: %s" % bv.arch.name
-print "\n-------- Function List --------"
+ 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"
-for func in bv.functions:
- print func.symbol.name
+ 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
-print "\n-------- First 10 strings --------"
-for i in xrange(10):
- start = bv.strings[i].start
- length = bv.strings[i].length
- string = bv.read(start,length)
- print "0x%x (%d):\t%s" % (start, length, string)
+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
index 44df19e2..b1297e26 100644
--- a/python/examples/breakpoint.py
+++ b/python/examples/breakpoint.py
@@ -1,4 +1,27 @@
-from binaryninja import *
+# Copyright (c) 2015-2016 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:
@@ -6,11 +29,22 @@ def write_breakpoint(view, start, length):
register_for_address
register_for_function
"""
- if view.arch.name.startswith("x86"):
- view.write(start, "\xcc" * length)
- elif view.arch.name == "armv7":
- view.write(start, "\x7a\x00\x20\xe1" * (length/4))
- else:
- log_error("No support for breakpoint on %s" % view.arch.name)
+ 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
index a54dc879..95e2d62d 100755
--- a/python/examples/export_svg.py
+++ b/python/examples/export_svg.py
@@ -1,11 +1,14 @@
-from binaryninja import *
+# from binaryninja import *
import os
import webbrowser
try:
- from urllib import pathname2url # Python 2.x
+ from urllib import pathname2url # Python 2.x
except:
- from urllib.request import pathname2url # Python 3.x
+ 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]}
@@ -17,47 +20,58 @@ escape_table = {
' ': "&#160;"
}
-def escape(string):
- string=string.decode('utf-8').encode('ascii','xmlcharrefreplace') #handle extended unicode
- return ''.join(escape_table.get(i,i) for i in string) #still escape the basics
-def save_svg(bv,function):
- address = hex(function.start).replace('L','')
+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))
+ 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)
- output = open(outputfile,'w')
+ output = open(outputfile, 'w')
output.write(content)
output.close()
- if show_message_box("Open SVG", "Would you like to view the exported SVG?", buttons = core.YesNoButtonSet, icon = core.QuestionIcon) == core.YesButton:
+ 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):
+
+def instruction_data_flow(function, address):
''' TODO: Extract data flow information '''
- length = function.view.get_instruction_length(function.arch,address)
+ 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)])
+ padded = ' '.join([hex[i:i + 2] for i in range(0, len(hex), 2)])
return 'Opcode: {bytes}'.format(bytes=padded)
+
def render_svg(function):
graph = function.create_graph()
graph.layout_and_wait()
heightconst = 15
ratio = 0.48
- widthconst = heightconst*ratio
+ 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);
+ }
svg {
background-color: rgb(42, 42, 42);
+ display: block;
+ margin: 0 auto;
}
.basicblock {
stroke: rgb(224, 224, 224);
@@ -66,6 +80,10 @@ def render_svg(function):
fill: none;
stroke-width: 1px;
}
+ .back_edge {
+ fill: none;
+ stroke-width: 2px;
+ }
.UnconditionalBranch, .IndirectBranch {
stroke: rgb(128, 198, 233);
color: rgb(128, 198, 233);
@@ -130,59 +148,67 @@ def render_svg(function):
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
</defs>
- '''.format(width=graph.width*widthconst, height=graph.height*heightconst)
+ '''.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):
+ for i, block in enumerate(graph.blocks):
- #Calculate basic block location and coordinates
+ # Calculate basic block location and coordinates
x = ((block.x) * widthconst)
y = ((block.y) * heightconst)
width = ((block.width) * widthconst)
height = ((block.height) * heightconst)
- #Render block
+ # Render block
output += ' <g id="basicblock{i}">\n'.format(i=i)
output += ' <title>Basic Block {i}</title>\n'.format(i=i)
- rgb=colors['none']
+ 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]
+ 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,height=height,r=rgb[0],g=rgb[1],b=rgb[2])
+ 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
+ # 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,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1])
+ 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=token.type)
+ 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
+ # 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 = ""
- for x,y in edge.points:
- points += str(x*widthconst)+","+str(y*heightconst) + " "
- edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(type=edge.type,points=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></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
index 43bc000e..7ff2d692 100644
--- a/python/examples/instruction_iterator.py
+++ b/python/examples/instruction_iterator.py
@@ -1,49 +1,53 @@
#!/usr/bin/env python
+# Copyright (c) 2015-2016 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
-try:
- import binaryninja
-except ImportError:
- sys.path.append("/Applications/Binary Ninja.app/Contents/Resources/python/")
- import binaryninja
-import time
-
-if sys.platform.lower().startswith("linux"):
- bintype="ELF"
-elif sys.platform.lower() == "darwin":
- bintype="Mach-O"
-else:
- raise Exception, "%s is not supported on this plugin" % sys.platform
+import binaryninja as binja
if len(sys.argv) > 1:
target = sys.argv[1]
-else:
- target = "/bin/ls"
-
-bv = binaryninja.BinaryViewType[bintype].open(target)
-bv.update_analysis_and_wait()
-print "-------- %s --------" % target
-print "START: 0x%x" % bv.start
-print "ENTRY: 0x%x" % bv.entry_point
-print "ARCH: %s" % bv.arch.name
-print "\n-------- Function List --------"
+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:
- print repr(func)
- for block in func.low_level_il:
- print "\t{0}".format(block)
+ binja.log_info(repr(func))
+ for block in func.low_level_il:
+ binja.log_info("\t{0}".format(block))
- for insn in block:
- print "\t\t{0}".format(insn)
+ 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:
- print repr(func)
- for block in func:
- print "\t{0}".format(block)
+ binja.log_info(repr(func))
+ for block in func:
+ binja.log_info("\t{0}".format(block))
- for insn in block:
- print "\t\t{0}".format(insn)
+ 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
index 39fed1a5..439e2ab6 100644
--- a/python/examples/jump_table.py
+++ b/python/examples/jump_table.py
@@ -1,8 +1,30 @@
+# Copyright (c) 2015-2016 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 import *
+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
@@ -28,7 +50,7 @@ def find_jump_table(bv, addr):
# Collect the branch targets for any tables referenced by the clicked instruction
branches = []
for token in tokens:
- if token.type == "PossibleAddressToken": # Table addresses will be a "possible address" token
+ 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
@@ -56,7 +78,8 @@ def find_jump_table(bv, addr):
i += 1
# Set the indirect branch targets on the jump instruction to be the list of targets discovered
- func.set_user_indirect_branches(arch, jump_addr, branches)
+ 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
diff --git a/python/examples/nds.py b/python/examples/nds.py
index 5300018c..ff137b4b 100644
--- a/python/examples/nds.py
+++ b/python/examples/nds.py
@@ -1,88 +1,117 @@
-from binaryninja import *
-import struct
-import traceback
-import os
-
-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,
- SegmentReadable | 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,
- SegmentReadable | 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()
+# Copyright (c) 2015-2016 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
index 23f5f3d8..4122cde0 100644
--- a/python/examples/nes.py
+++ b/python/examples/nes.py
@@ -18,44 +18,52 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-from binaryninja import *
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
+ "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
@@ -81,105 +89,106 @@ 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
+ 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
+ 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(PossibleAddressToken, "$%.4x" % value, value)], # ABS
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value)], # ABS_DEST
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x")], # ABS_X
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x")], # ABS_X_DEST
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "y")], # ABS_Y
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "y")], # ABS_Y_DEST
- lambda value: [InstructionTextToken(RegisterToken, "a")], # ACCUM
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value)], # ADDR
- lambda value: [InstructionTextToken(TextToken, "#"), InstructionTextToken(IntegerToken, "$%.2x" % value, value)], # IMMED
- lambda value: [InstructionTextToken(TextToken, "["), InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value),
- InstructionTextToken(TextToken, "]")], # IND
- lambda value: [InstructionTextToken(TextToken, "["), InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x"),
- InstructionTextToken(TextToken, "]")], # IND_X
- lambda value: [InstructionTextToken(TextToken, "["), InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x"),
- InstructionTextToken(TextToken, "]")], # IND_X_DEST
- lambda value: [InstructionTextToken(TextToken, "["), InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, "], "), InstructionTextToken(RegisterToken, "y")], # IND_Y
- lambda value: [InstructionTextToken(TextToken, "["), InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, "], "), InstructionTextToken(RegisterToken, "y")], # IND_Y_DEST
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.4x" % value, value)], # REL
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value)], # ZERO
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value)], # ZERO_DEST
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x")], # ZERO_X
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "x")], # ZERO_X_DEST
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "y")], # ZERO_Y
- lambda value: [InstructionTextToken(PossibleAddressToken, "$%.2x" % value, value),
- InstructionTextToken(TextToken, ", "), InstructionTextToken(RegisterToken, "y")] # ZERO_Y_DEST
+ 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(2, value)
@@ -189,8 +198,9 @@ def indirect_load(il, value):
return il.or_expr(2, lo, hi)
return il.load(2, il.const(2, value))
+
def load_zero_page_16(il, value):
- if il[value].operation == "LLIL_CONST":
+ if il[value].operation == LowLevelILOperation.LLIL_CONST:
if il[value].value == 0xff:
lo = il.zero_extend(2, il.load(1, il.const(2, 0xff)))
hi = il.shift_left(2, il.zero_extend(2, il.load(1, il.const(2, 0)), il.const(2, 8)))
@@ -204,34 +214,36 @@ def load_zero_page_16(il, value):
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(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(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(2, value), # REL
- lambda il, value: il.load(1, il.const(2, value)), # ZERO
- lambda il, value: il.const(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
+ lambda il, value: None, # NONE
+ lambda il, value: il.load(1, il.const(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(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(2, value), # REL
+ lambda il, value: il.load(1, il.const(2, value)), # ZERO
+ lambda il, value: il.const(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 == LLIL_CONST:
+ if il[dest].operation == LowLevelILOperation.LLIL_CONST:
t = il.get_label_for_address(Architecture['6502'], il[dest].value)
if t is None:
t = LowLevelILLabel()
@@ -246,9 +258,10 @@ def cond_branch(il, cond, dest):
il.mark_label(f)
return None
+
def jump(il, dest):
label = None
- if il[dest].operation == LLIL_CONST:
+ if il[dest].operation == LowLevelILOperation.LLIL_CONST:
label = il.get_label_for_address(Architecture['6502'], il[dest].value)
if label is None:
il.append(il.jump(dest))
@@ -256,6 +269,7 @@ def jump(il, dest):
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)
@@ -267,6 +281,7 @@ def get_p_value(il):
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))))
@@ -278,22 +293,24 @@ def set_p_value(il, value):
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, 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(LLFC_UGE), operand),
- "bcs": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_ULT), operand),
- "beq": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_E), operand),
+ "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(LLFC_NEG), operand),
- "bne": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_NE), operand),
- "bpl": lambda il, operand: cond_branch(il, il.flag_condition(LLFC_POS), operand),
+ "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),
@@ -345,6 +362,7 @@ InstructionIL = {
"tya": lambda il, operand: il.set_reg(1, "a", il.reg(1, "y"), flags = "zs")
}
+
class M6502(Architecture):
name = "6502"
address_size = 2
@@ -360,18 +378,18 @@ class M6502(Architecture):
flags = ["c", "z", "i", "d", "b", "v", "s"]
flag_write_types = ["*", "czs", "zvs", "zs"]
flag_roles = {
- "c": SpecialFlagRole, # Not a normal carry flag, subtract result is inverted
- "z": ZeroFlagRole,
- "v": OverflowFlagRole,
- "s": NegativeSignFlagRole
+ "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 = {
- LLFC_UGE: ["c"],
- LLFC_ULT: ["c"],
- LLFC_E: ["z"],
- LLFC_NE: ["z"],
- LLFC_NEG: ["s"],
- LLFC_POS: ["s"]
+ 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"],
@@ -413,17 +431,17 @@ class M6502(Architecture):
result.length = length
if instr == "jmp":
if operand == ADDR:
- result.add_branch(UnconditionalBranch, struct.unpack("<H", data[1:3])[0])
+ result.add_branch(BranchType.UnconditionalBranch, struct.unpack("<H", data[1:3])[0])
else:
- result.add_branch(UnresolvedBranch)
+ result.add_branch(BranchType.UnresolvedBranch)
elif instr == "jsr":
- result.add_branch(CallDestination, struct.unpack("<H", data[1:3])[0])
+ result.add_branch(BranchType.CallDestination, struct.unpack("<H", data[1:3])[0])
elif instr in ["rti", "rts"]:
- result.add_branch(FunctionReturn)
+ 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(TrueBranch, dest)
- result.add_branch(FalseBranch, addr + 2)
+ result.add_branch(BranchType.TrueBranch, dest)
+ result.add_branch(BranchType.FalseBranch, addr + 2)
return result
def perform_get_instruction_text(self, data, addr):
@@ -432,7 +450,7 @@ class M6502(Architecture):
return None
tokens = []
- tokens.append(InstructionTextToken(TextToken, "%-7s " % instr.replace("@", "")))
+ tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "%-7s " % instr.replace("@", "")))
tokens += OperandTokens[operand](value)
return tokens, length
@@ -488,12 +506,14 @@ class M6502(Architecture):
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):
@@ -521,55 +541,55 @@ class NESView(BinaryView):
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, SegmentReadable | SegmentWritable | SegmentExecutable)
+ 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,
- SegmentReadable | SegmentExecutable)
+ SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
self.add_auto_segment(0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000,
- SegmentReadable | SegmentExecutable)
+ 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(FunctionSymbol, nmi, "_nmi"))
- self.define_auto_symbol(Symbol(FunctionSymbol, start, "_start"))
- self.define_auto_symbol(Symbol(FunctionSymbol, irq, "_irq"))
- self.add_function(Architecture['6502'].standalone_platform, nmi)
- self.add_function(Architecture['6502'].standalone_platform, irq)
- self.add_entry_point(Architecture['6502'].standalone_platform, start)
+ 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(DataSymbol, 0x2000, "PPUCTRL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2001, "PPUMASK"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2002, "PPUSTATUS"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2003, "OAMADDR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2004, "OAMDATA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2005, "PPUSCROLL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2006, "PPUADDR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2007, "PPUDATA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4000, "SQ1_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4001, "SQ1_SWEEP"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4002, "SQ1_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4003, "SQ1_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4004, "SQ2_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4005, "SQ2_SWEEP"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4006, "SQ2_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4007, "SQ2_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4008, "TRI_LINEAR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400a, "TRI_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400b, "TRI_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400c, "NOISE_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400e, "NOISE_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400f, "NOISE_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4010, "DMC_FREQ"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4011, "DMC_RAW"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4012, "DMC_START"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4013, "DMC_LEN"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4014, "OAMDMA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4015, "SND_CHN"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4016, "JOY1"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4017, "JOY2"))
+ 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",
@@ -584,9 +604,9 @@ class NESView(BinaryView):
break
addr = int(sym[0][1:], 16)
name = sym[1]
- self.define_auto_symbol(Symbol(FunctionSymbol, addr, name))
+ self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, addr, name))
if addr >= 0x8000:
- self.add_function(Architecture['6502'].standalone_platform, addr)
+ self.add_function(addr)
return True
except:
@@ -599,6 +619,7 @@ class NESView(BinaryView):
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):
diff --git a/python/examples/nsf.py b/python/examples/nsf.py
index 9d4ebd5c..b1bac3a8 100644
--- a/python/examples/nsf.py
+++ b/python/examples/nsf.py
@@ -23,17 +23,23 @@
# https://scarybeastsecurity.blogspot.com/2016/11/0day-exploit-compromising-linux-desktop.html
#
-from binaryninja import *
+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
-import os
+
class NSFView(BinaryView):
name = "NSF"
long_name = "Nintendo Sound Format"
def __init__(self, data):
- BinaryView.__init__(self, parent_view = data, file_metadata = data.file)
+ BinaryView.__init__(self, parent_view=data, file_metadata=data.file)
+ self.platform = Architecture["6502"].standalone_platform
@classmethod
def is_valid_for_data(self, data):
@@ -71,58 +77,58 @@ class NSFView(BinaryView):
self.ntsc = True
self.extra_sound_bits = struct.unpack("B", hdr[123])[0]
- if self.bank_switching == "\0"*8:
- #no bank switching
+ if self.bank_switching == "\0" * 8:
+ # no bank switching
self.load_address & 0xFFF
self.rom_offset = 128
else:
- #bank switching not implemented
+ # 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, SegmentReadable | SegmentWritable | SegmentExecutable)
+ 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,
- SegmentReadable | SegmentExecutable)
+ SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
- self.define_auto_symbol(Symbol(FunctionSymbol, self.play_address, "_play"))
- self.define_auto_symbol(Symbol(FunctionSymbol, self.init_address, "_init"))
- self.add_entry_point(Architecture['6502'].standalone_platform, self.init_address)
- self.add_function(Architecture['6502'].standalone_platform, self.play_address)
+ 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(DataSymbol, 0x2000, "PPUCTRL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2001, "PPUMASK"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2002, "PPUSTATUS"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2003, "OAMADDR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2004, "OAMDATA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2005, "PPUSCROLL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2006, "PPUADDR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x2007, "PPUDATA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4000, "SQ1_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4001, "SQ1_SWEEP"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4002, "SQ1_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4003, "SQ1_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4004, "SQ2_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4005, "SQ2_SWEEP"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4006, "SQ2_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4007, "SQ2_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4008, "TRI_LINEAR"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400a, "TRI_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400b, "TRI_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400c, "NOISE_VOL"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400e, "NOISE_LO"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x400f, "NOISE_HI"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4010, "DMC_FREQ"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4011, "DMC_RAW"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4012, "DMC_START"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4013, "DMC_LEN"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4014, "OAMDMA"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4015, "SND_CHN"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4016, "JOY1"))
- self.define_auto_symbol(Symbol(DataSymbol, 0x4017, "JOY2"))
+ 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:
@@ -135,4 +141,5 @@ class NSFView(BinaryView):
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
index 7e93356c..2af4d38d 100644
--- a/python/examples/print_syscalls.py
+++ b/python/examples/print_syscalls.py
@@ -1,50 +1,55 @@
#!/usr/bin/env python
-"""
- 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 import BinaryView, core
-
+# Copyright (c) 2015-2016 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.
-def print_syscalls(bv):
- """ Print Syscall numbers for a provided binaryview """
- calling_convention = bv.platform.system_call_convention
- if not calling_convention:
- 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 == core.LLIL_SYSCALL)
- for il in syscalls:
- value = func.get_reg_value_at(bv.arch, il.address, register).value
- print("System call address: {:#x} - {:d}".format(il.address, value))
+# 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
-def main():
- if len(sys.argv) != 2:
- print('Usage: {} <file>'.format(sys.argv[0]))
- return -1
+from binaryninja.binaryview import BinaryViewType
+from binaryninja.enums import LowLevelILOperation
- target = sys.argv[1]
- bv = BinaryView.open(target)
- view_type = next(bvt for bvt in bv.available_view_types if bvt.name != 'Raw')
- if not view_type:
- print('Error: Unable to get any other view type besides Raw')
- return -1
+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
- bv = bv.file.get_view_of_type(view_type.name)
- bv.update_analysis_and_wait()
+ register = calling_convention.int_arg_regs[0]
- print_syscalls(bv)
+ 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__":
- sys.exit(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
index 6199c578..9d5bbf05 100644
--- a/python/examples/version_switcher.py
+++ b/python/examples/version_switcher.py
@@ -1,26 +1,50 @@
#!/usr/bin/env python
+# Copyright (c) 2015-2016 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
+
+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 = binaryninja.UpdateChannel.list[0].name
+chandefault = UpdateChannel.list[0].name
channel = None
versions = []
+
def load_channel(newchannel):
global channel
global versions
- if (channel != None and newchannel == channel.name):
+ if (channel is not None and newchannel == channel.name):
print "Same channel, not updating."
else:
try:
print "Loading channel %s" % newchannel
- channel = binaryninja.UpdateChannel[newchannel]
+ channel = UpdateChannel[newchannel]
print "Loading versions..."
versions = channel.versions
except Exception:
print "%s is not a valid channel name. Defaulting to " % chandefault
- channel = binaryninja.UpdateChannel[chandefault]
+ channel = UpdateChannel[chandefault]
+
def select(version):
done = False
@@ -44,43 +68,50 @@ def select(version):
print "Requesting update to latest version."
else:
print "Requesting update to prior version."
- if binaryninja.are_auto_updates_enabled():
+ if are_auto_updates_enabled():
print "Disabling automatic updates."
- binaryninja.set_auto_updates_enabled(False)
- if (version.version == binaryninja.core_version):
+ set_auto_updates_enabled(False)
+ if (version.version == core_version):
print "Already running %s" % version.version
else:
print "version.version %s" % version.version
- print "binaryninja.core_version %s" % binaryninja.core_version
- print "Updating..."
+ print "core_version %s" % core_version
+ print "Downloading..."
print version.update()
- #forward updating won't work without reloading
+ 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 = binaryninja.UpdateChannel.list
+ 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")
+ 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):
+ 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():
- binaryninja.set_auto_updates_enabled(not binaryninja.are_auto_updates_enabled())
+ set_auto_updates_enabled(not are_auto_updates_enabled())
+
def main():
global channel
@@ -89,8 +120,8 @@ def main():
while not done:
print "\n\tBinary Ninja Version Switcher"
print "\t\tCurrent Channel:\t%s" % channel.name
- print "\t\tCurrent Version:\t%s" % binaryninja.core_version
- print "\t\tAuto-Updates On:\t%s\n" % binaryninja.are_auto_updates_enabled()
+ 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)