diff options
| author | Peter LaFosse <peter@vector35.com> | 2017-01-05 09:14:31 -0500 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2017-01-05 09:14:31 -0500 |
| commit | 4761ea9c83104b872d8d49fcde45f17d17e7872d (patch) | |
| tree | 0acca0d74701a834c36f85aebd7dd9955ecbfb8f /python/examples | |
| parent | 96acbed85902d8dfd43ef624afac72145ae6e577 (diff) | |
Modifying how enumerations are exposed and used, and a bunch of cleanup of existing plugins
Diffstat (limited to 'python/examples')
| -rw-r--r-- | python/examples/angr_plugin.py | 25 | ||||
| -rw-r--r-- | python/examples/bin_info.py | 15 | ||||
| -rw-r--r-- | python/examples/breakpoint.py | 28 | ||||
| -rwxr-xr-x | python/examples/export_svg.py | 84 | ||||
| -rw-r--r-- | python/examples/jump_table.py | 8 | ||||
| -rw-r--r-- | python/examples/nds.py | 225 | ||||
| -rw-r--r-- | python/examples/nes.py | 430 | ||||
| -rw-r--r-- | python/examples/nsf.py | 86 | ||||
| -rw-r--r-- | python/examples/print_syscalls.py | 55 | ||||
| -rw-r--r-- | python/examples/version_switcher.py | 15 |
10 files changed, 510 insertions, 461 deletions
diff --git a/python/examples/angr_plugin.py b/python/examples/angr_plugin.py index 852eff65..9c91d970 100644 --- a/python/examples/angr_plugin.py +++ b/python/examples/angr_plugin.py @@ -30,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 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) @@ -109,8 +115,8 @@ 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(core.BNHighlightStandardColor.GreenHighlightColor, alpha = 128)) - block.function.set_auto_instr_highlight(block.arch, addr, core.BNHighlightStandardColor.GreenHighlightColor) + block.set_auto_highlight(HighlightColor(HighlightStandardColor.GreenHighlightColor, alpha = 128)) + block.function.set_auto_instr_highlight(block.arch, addr, HighlightStandardColor.GreenHighlightColor) # Add the instruction to the list associated with the current view bv.session_data.angr_find.add(addr) @@ -120,8 +126,8 @@ 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(core.BNHighlightStandardColor.RedHighlightColor, alpha = 128)) - block.function.set_auto_instr_highlight(block.arch, addr, core.BNHighlightStandardColor.RedHighlightColor) + block.set_auto_highlight(HighlightColor(HighlightStandardColor.RedHighlightColor, alpha = 128)) + block.function.set_auto_instr_highlight(block.arch, addr, HighlightStandardColor.RedHighlightColor) # Add the instruction to the list associated with the current view bv.session_data.angr_avoid.add(addr) @@ -131,13 +137,14 @@ 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.", core.BNMessageBoxButtonSet.OKButtonSet, core.BNMessageBoxButtonSet.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 c574a530..4c4ab8fd 100644 --- a/python/examples/bin_info.py +++ b/python/examples/bin_info.py @@ -21,12 +21,12 @@ import sys import binaryninja.log as log -import binaryninja.binaryview as view +from binaryninja.binaryview import BinaryViewType import binaryninja.interaction as interaction from binaryninja.plugin import PluginCommand -def bininfo(bv): +def get_bininfo(bv): if bv is None: filename = "" if len(sys.argv) > 1: @@ -37,7 +37,7 @@ def bininfo(bv): log.log_warn("No file specified") sys.exit(1) - bv = view.BinaryViewType.get_view_of_file(filename) + bv = BinaryViewType.get_view_of_file(filename) log.redirect_output_to_log() log.log_to_stdout(True) @@ -60,11 +60,14 @@ def bininfo(bv): length = bv.strings[i].length string = bv.read(start, length) contents += "| 0x%x |%d | %s |\n" % (start, length, string) + return contents - interaction.show_markdown_report("Binary Info Report", contents) + +def display_bininfo(bv): + interaction.show_markdown_report("Binary Info Report", get_bininfo(bv)) if __name__ == "__main__": - bininfo(None) + print get_bininfo(None) else: - PluginCommand.register("Binary Info", "Display basic info about the binary", bininfo) + 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 2426e6a1..e694329b 100644 --- a/python/examples/breakpoint.py +++ b/python/examples/breakpoint.py @@ -18,7 +18,11 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -from binaryninja import * + +from binaryninja.plugin import PluginCommand +from binaryninja.log import log_error +from binaryninja.architecture import Architecture + def write_breakpoint(view, start, length): """Sample function to show registering a plugin menu item for a range of bytes. Also possible: @@ -26,11 +30,21 @@ 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 = Architecture[view.arch.name].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 5a4d2982..bab00f5d 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 +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,40 +20,46 @@ escape_table = { ' ': " " } -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 = MessageBoxButtonSet.QuestionIcon) + if result == MessageBoxButtonSet.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(function.arch, 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> @@ -135,63 +144,64 @@ def render_svg(function): <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) + '''.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 + 16,height=height + 12,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 + 6,y=y + 6 + (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=token.type) 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 = "" - 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) + " " - 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) + " " + edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(type=edge.type, 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/jump_table.py b/python/examples/jump_table.py index 0fd0dbab..f24eea12 100644 --- a/python/examples/jump_table.py +++ b/python/examples/jump_table.py @@ -20,7 +20,8 @@ # 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. -import binaryninja +from binaryninja.plugin import PluginCommand +from binaryninja.enum import InstructionTextTokenType import struct @@ -49,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 == core.BNInstructionTextTokenType.PossibleAddressToken: # Table addresses will be a "possible address" token + if 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 @@ -79,6 +80,7 @@ def find_jump_table(bv, addr): # 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 -binaryninja.PluginCommand.register_for_address("Process jump table", "Look for jump table destinations", find_jump_table) +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 index 302bbc0d..ff137b4b 100644 --- a/python/examples/nds.py +++ b/python/examples/nds.py @@ -1,108 +1,117 @@ -# 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 *
-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,
- core.BNSegmentFlag.SegmentReadable | core.BNSegmentFlag.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,
- core.BNSegmentFlag.SegmentReadable | core.BNSegmentFlag.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 6a05539c..a1410398 100644 --- a/python/examples/nes.py +++ b/python/examples/nes.py @@ -22,43 +22,48 @@ import struct import traceback import os - -from binaryninja import * - +from binaryninja.architecture import Architecture +from binaryninja.lowlevelil import LowLevelILLabel, LLIL_TEMP +from binaryninja.function import RegisterInfo, InstructionInfo +from binaryninja.binaryview import BinaryView +from binaryninja.types import Symbol +from binaryninja.log import log_error +from enums import (BranchType, InstructionTextToken, 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 @@ -84,103 +89,103 @@ 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(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ABS - lambda value: [InstructionTextToken(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ABS_DEST - lambda value: [InstructionTextToken(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value), - InstructionTextToken(core.core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.core.BNInstructionTextTokenType.RegisterToken, "x")], # ABS_X - lambda value: [InstructionTextToken(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value), - InstructionTextToken(core.core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.core.BNInstructionTextTokenType.RegisterToken, "x")], # ABS_X_DEST - lambda value: [InstructionTextToken(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value), - InstructionTextToken(core.core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.core.BNInstructionTextTokenType.RegisterToken, "y")], # ABS_Y - lambda value: [InstructionTextToken(core.core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "y")], # ABS_Y_DEST - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "a")], # ACCUM - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # ADDR - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "#"), InstructionTextToken(core.BNInstructionTextTokenType.IntegerToken, "$%.2x" % value, value)], # IMMED - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "["), InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "]")], # IND - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "["), InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "x"), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "]")], # IND_X - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "["), InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "x"), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "]")], # IND_X_DEST - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "["), InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "], "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "y")], # IND_Y - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "["), InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "], "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "y")], # IND_Y_DEST - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.4x" % value, value)], # REL - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value)], # ZERO - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value)], # ZERO_DEST - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "x")], # ZERO_X - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "x")], # ZERO_X_DEST - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.RegisterToken, "y")], # ZERO_Y - lambda value: [InstructionTextToken(core.BNInstructionTextTokenType.PossibleAddressToken, "$%.2x" % value, value), - InstructionTextToken(core.BNInstructionTextTokenType.TextToken, ", "), InstructionTextToken(core.BNInstructionTextTokenType.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 ] @@ -195,7 +200,7 @@ def indirect_load(il, value): def load_zero_page_16(il, value): - if il[value].operation == core.BNLowLevelILOperation.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))) @@ -209,35 +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 == core.BNLowLevelILOperation.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() @@ -255,7 +261,7 @@ def cond_branch(il, cond, dest): def jump(il, dest): label = None - if il[dest].operation == core.BNLowLevelILOperation.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)) @@ -292,18 +298,19 @@ 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(core.BNLowLevelILFlagCondition.LLFC_UGE), operand), - "bcs": lambda il, operand: cond_branch(il, il.flag_condition(core.BNLowLevelILFlagCondition.LLFC_ULT), operand), - "beq": lambda il, operand: cond_branch(il, il.flag_condition(core.BNLowLevelILFlagCondition.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(core.BNLowLevelILFlagCondition.LLFC_NEG), operand), - "bne": lambda il, operand: cond_branch(il, il.flag_condition(core.BNLowLevelILFlagCondition.LLFC_NE), operand), - "bpl": lambda il, operand: cond_branch(il, il.flag_condition(core.BNLowLevelILFlagCondition.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), @@ -371,18 +378,18 @@ class M6502(Architecture): flags = ["c", "z", "i", "d", "b", "v", "s"] flag_write_types = ["*", "czs", "zvs", "zs"] flag_roles = { - "c": core.BNFlagRole.SpecialFlagRole, # Not a normal carry flag, subtract result is inverted - "z": core.BNFlagRole.ZeroFlagRole, - "v": core.BNFlagRole.OverflowFlagRole, - "s": core.BNFlagRole.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 = { - core.BNLowLevelILFlagCondition.LLFC_UGE: ["c"], - core.BNLowLevelILFlagCondition.LLFC_ULT: ["c"], - core.BNLowLevelILFlagCondition.LLFC_E: ["z"], - core.BNLowLevelILFlagCondition.LLFC_NE: ["z"], - core.BNLowLevelILFlagCondition.LLFC_NEG: ["s"], - core.BNLowLevelILFlagCondition.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"], @@ -424,17 +431,17 @@ class M6502(Architecture): result.length = length if instr == "jmp": if operand == ADDR: - result.add_branch(core.BNBranchType.UnconditionalBranch, struct.unpack("<H", data[1:3])[0]) + result.add_branch(BranchType.UnconditionalBranch, struct.unpack("<H", data[1:3])[0]) else: - result.add_branch(core.BNBranchType.UnresolvedBranch) + result.add_branch(BranchType.UnresolvedBranch) elif instr == "jsr": - result.add_branch(core.BNBranchType.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(core.BNBranchType.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(core.BNBranchType.TrueBranch, dest) - result.add_branch(core.BNBranchType.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): @@ -443,7 +450,7 @@ class M6502(Architecture): return None tokens = [] - tokens.append(InstructionTextToken(core.BNInstructionTextTokenType.TextToken, "%-7s " % instr.replace("@", ""))) + tokens.append(InstructionTextToken(InstructionTextTokenType.TextToken, "%-7s " % instr.replace("@", ""))) tokens += OperandTokens[operand](value) return tokens, length @@ -533,55 +540,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, core.BNSegmentFlag.SegmentReadable | core.BNSegmentFlag.SegmentWritable | core.BNSegmentFlag.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, - core.BNSegmentFlag.SegmentReadable | core.BNSegmentFlag.SegmentExecutable) + SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable) self.add_auto_segment(0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000, - core.BNSegmentFlag.SegmentReadable | core.BNSegmentFlag.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(core.BNSymbolType.FunctionSymbol, nmi, "_nmi")) - self.define_auto_symbol(Symbol(core.BNSymbolType.FunctionSymbol, start, "_start")) - self.define_auto_symbol(Symbol(core.BNSymbolType.FunctionSymbol, irq, "_irq")) + 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(Architecture['6502'].standalone_platform, nmi) self.add_function(Architecture['6502'].standalone_platform, irq) self.add_entry_point(Architecture['6502'].standalone_platform, start) # Hardware registers - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2000, "PPUCTRL")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2001, "PPUMASK")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2002, "PPUSTATUS")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2003, "OAMADDR")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2004, "OAMDATA")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2005, "PPUSCROLL")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2006, "PPUADDR")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x2007, "PPUDATA")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4000, "SQ1_VOL")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4001, "SQ1_SWEEP")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4002, "SQ1_LO")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4003, "SQ1_HI")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4004, "SQ2_VOL")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4005, "SQ2_SWEEP")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4006, "SQ2_LO")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4007, "SQ2_HI")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4008, "TRI_LINEAR")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x400a, "TRI_LO")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x400b, "TRI_HI")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x400c, "NOISE_VOL")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x400e, "NOISE_LO")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x400f, "NOISE_HI")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4010, "DMC_FREQ")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4011, "DMC_RAW")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4012, "DMC_START")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4013, "DMC_LEN")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4014, "OAMDMA")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4015, "SND_CHN")) - self.define_auto_symbol(Symbol(core.BNSymbolType.DataSymbol, 0x4016, "JOY1")) - self.define_auto_symbol(Symbol(core.BNSymbolType.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", @@ -596,7 +603,7 @@ class NESView(BinaryView): break addr = int(sym[0][1:], 16) name = sym[1] - self.define_auto_symbol(Symbol(core.BNSymbolType.FunctionSymbol, addr, name)) + self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, addr, name)) if addr >= 0x8000: self.add_function(Architecture['6502'].standalone_platform, addr) @@ -611,6 +618,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..de775d34 100644 --- a/python/examples/nsf.py +++ b/python/examples/nsf.py @@ -23,17 +23,22 @@ # 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) @classmethod def is_valid_for_data(self, data): @@ -71,58 +76,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.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(Architecture['6502'].standalone_platform, self.init_address) self.add_function(Architecture['6502'].standalone_platform, 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 +140,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 003b388e..2af4d38d 100644 --- a/python/examples/print_syscalls.py +++ b/python/examples/print_syscalls.py @@ -26,45 +26,30 @@ import sys from itertools import chain -from binaryninja import BinaryView, core +from binaryninja.binaryview import BinaryViewType +from binaryninja.enums import LowLevelILOperation -def print_syscalls(bv): - """ Print Syscall numbers for a provided binaryview """ +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 - 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] - 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.BNLowLevelILOperation.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)) - - -def main(): - if len(sys.argv) != 2: - print('Usage: {} <file>'.format(sys.argv[0])) - return -1 - - 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 - - bv = bv.file.get_view_of_type(view_type.name) - bv.update_analysis_and_wait() - - 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 e8f8814d..bc4f576c 100644 --- a/python/examples/version_switcher.py +++ b/python/examples/version_switcher.py @@ -27,10 +27,11 @@ chandefault = binaryninja.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 None and newchannel == channel.name): print "Same channel, not updating." else: try: @@ -42,6 +43,7 @@ def load_channel(newchannel): print "%s is not a valid channel name. Defaulting to " % chandefault channel = binaryninja.UpdateChannel[chandefault] + def select(version): done = False date = datetime.datetime.fromtimestamp(version.time).strftime('%c') @@ -74,34 +76,37 @@ def select(version): print "binaryninja.core_version %s" % binaryninja.core_version print "Updating..." print version.update() - #forward updating won't work without reloading + # 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 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()) + def main(): global channel done = False |
