summaryrefslogtreecommitdiff
path: root/python/examples
diff options
context:
space:
mode:
Diffstat (limited to 'python/examples')
-rw-r--r--python/examples/angr_plugin.py27
-rw-r--r--python/examples/arch_hook.py17
-rw-r--r--python/examples/asm_to_llil_view.py15
-rw-r--r--python/examples/breakpoint.py8
-rwxr-xr-xpython/examples/cli_dis.py5
-rwxr-xr-xpython/examples/cli_lift.py21
-rwxr-xr-xpython/examples/debug_info.py151
-rwxr-xr-xpython/examples/export_svg.py343
-rw-r--r--python/examples/helloglobalarea.py2
-rw-r--r--python/examples/hellopane.py7
-rw-r--r--python/examples/hellosidebar.py3
-rw-r--r--python/examples/instruction_iterator.py3
-rw-r--r--python/examples/jump_table.py6
-rw-r--r--python/examples/linear_mlil.py47
-rw-r--r--python/examples/mappedview.py27
-rw-r--r--python/examples/nds.py134
-rw-r--r--python/examples/nes.py552
-rw-r--r--python/examples/notification_callbacks.py2
-rw-r--r--python/examples/nsf.py9
-rwxr-xr-xpython/examples/pe_stat.py7
-rw-r--r--python/examples/print_syscalls.py4
-rwxr-xr-xpython/examples/typelib_create.py29
-rwxr-xr-xpython/examples/typelib_dump.py173
-rw-r--r--python/examples/ui_notifications.py102
24 files changed, 923 insertions, 771 deletions
diff --git a/python/examples/angr_plugin.py b/python/examples/angr_plugin.py
index 940aff8b..5f2eeba0 100644
--- a/python/examples/angr_plugin.py
+++ b/python/examples/angr_plugin.py
@@ -18,7 +18,6 @@
# 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.
#
@@ -72,7 +71,7 @@ class Solver(BackgroundTaskThread):
def run(self):
# Create an angr project and an explorer with the user's settings
p = angr.Project(self.binary.name)
- e = p.surveyors.Explorer(find = self.find, avoid = self.avoid)
+ e = p.surveyors.Explorer(find=self.find, avoid=self.avoid)
# Solve loop
while not e.done:
@@ -98,7 +97,7 @@ class Solver(BackgroundTaskThread):
text_report = "Found %d path%s.\n\n" % (len(e.found), "s" if len(e.found) != 1 else "")
i = 1
for f in e.found:
- text_report += "Path %d\n" % i + "=" * 10 + "\n"
+ text_report += "Path %d\n"%i + "="*10 + "\n"
text_report += "stdin:\n" + escaped_output(f.state.posix.dumps(0)) + "\n\n"
text_report += "stdout:\n" + escaped_output(f.state.posix.dumps(1)) + "\n\n"
text_report += "stderr:\n" + escaped_output(f.state.posix.dumps(2)) + "\n\n"
@@ -115,7 +114,7 @@ def find_instr(bv, addr):
# Highlight the instruction in green
blocks = bv.get_basic_blocks_at(addr)
for block in blocks:
- block.set_auto_highlight(HighlightColor(HighlightStandardColor.GreenHighlightColor, alpha = 128))
+ block.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
@@ -126,7 +125,7 @@ def avoid_instr(bv, addr):
# Highlight the instruction in red
blocks = bv.get_basic_blocks_at(addr)
for block in blocks:
- block.set_auto_highlight(HighlightColor(HighlightStandardColor.RedHighlightColor, alpha = 128))
+ block.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
@@ -135,9 +134,11 @@ def avoid_instr(bv, addr):
def solve(bv):
if len(bv.session_data.angr_find) == 0:
- show_message_box("Angr Solve", "You have not specified a goal instruction.\n\n" +
- "Please right click on the goal instruction and select \"Find Path to This Instruction\" to " +
- "continue.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon)
+ show_message_box(
+ "Angr Solve", "You have not specified a goal instruction.\n\n"
+ + "Please right click on the goal instruction and select \"Find Path to This Instruction\" to " + "continue.",
+ MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon
+ )
return
# Start a solver thread for the path associated with the view
@@ -146,8 +147,10 @@ def solve(bv):
# Register commands for the user to interact with the plugin
-PluginCommand.register_for_address("Find Path to This Instruction",
- "When solving, find a path that gets to this instruction", find_instr)
-PluginCommand.register_for_address("Avoid This Instruction",
- "When solving, avoid paths that reach this instruction", avoid_instr)
+PluginCommand.register_for_address(
+ "Find Path to This Instruction", "When solving, find a path that gets to this instruction", find_instr
+)
+PluginCommand.register_for_address(
+ "Avoid This Instruction", "When solving, avoid paths that reach this instruction", avoid_instr
+)
PluginCommand.register("Solve With Angr", "Attempt to solve for a path that satisfies the constraints given", solve)
diff --git a/python/examples/arch_hook.py b/python/examples/arch_hook.py
index 452bd2b6..a6e280cc 100644
--- a/python/examples/arch_hook.py
+++ b/python/examples/arch_hook.py
@@ -1,16 +1,17 @@
from binaryninja.architecture import Architecture, ArchitectureHook
+
class X86ReturnHook(ArchitectureHook):
- def get_instruction_text(self, data, addr):
- # Call the original implementation's method by calling the superclass
- result, length = super(X86ReturnHook, self).get_instruction_text(data, addr)
+ def get_instruction_text(self, data, addr):
+ # Call the original implementation's method by calling the superclass
+ result, length = super(X86ReturnHook, self).get_instruction_text(data, addr)
+
+ # Patch the name of the 'retn' instruction to 'ret'
+ if len(result) > 0 and result[0].text == 'retn':
+ result[0].text = 'ret'
- # Patch the name of the 'retn' instruction to 'ret'
- if len(result) > 0 and result[0].text == 'retn':
- result[0].text = 'ret'
+ return result, length
- return result, length
# Install the hook by constructing it with the desired architecture to hook, then registering it
X86ReturnHook(Architecture['x86']).register()
-
diff --git a/python/examples/asm_to_llil_view.py b/python/examples/asm_to_llil_view.py
index 18c77547..3b7fb374 100644
--- a/python/examples/asm_to_llil_view.py
+++ b/python/examples/asm_to_llil_view.py
@@ -1,5 +1,5 @@
# Copyright (c) 2019-2022 Vector 35 Inc
-#
+#
# 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
@@ -103,13 +103,18 @@ class DisassemblyAndLowLevelILGraph(FlowGraph):
for line in lines:
if line.il_instruction is None:
# For assembly lines, show address
- line.tokens.insert(0, InstructionTextToken(InstructionTextTokenType.AddressDisplayToken,
- "%.8x" % line.address, line.address))
+ line.tokens.insert(
+ 0, InstructionTextToken(InstructionTextTokenType.AddressDisplayToken, "%.8x" % line.address, line.address)
+ )
line.tokens.insert(1, InstructionTextToken(InstructionTextTokenType.TextToken, " "))
else:
# For IL lines, show IL instruction index
- line.tokens.insert(0, InstructionTextToken(InstructionTextTokenType.AnnotationToken,
- "%8s" % ("[%d]" % line.il_instruction.instr_index)))
+ line.tokens.insert(
+ 0,
+ InstructionTextToken(
+ InstructionTextTokenType.AnnotationToken, "%8s" % ("[%d]" % line.il_instruction.instr_index)
+ )
+ )
line.tokens.insert(1, InstructionTextToken(InstructionTextTokenType.AnnotationToken, " => "))
nodes[block.start].lines = lines
diff --git a/python/examples/breakpoint.py b/python/examples/breakpoint.py
index ab2ccfa5..20ff2b6b 100644
--- a/python/examples/breakpoint.py
+++ b/python/examples/breakpoint.py
@@ -18,7 +18,6 @@
# 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
@@ -29,12 +28,7 @@ def write_breakpoint(view, start, length):
register_for_address
register_for_function
"""
- bkpt_str = {
- "x86": "int3",
- "x86_64": "int3",
- "armv7": "bkpt",
- "aarch64": "brk #0",
- "mips32": "break"}
+ 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)
diff --git a/python/examples/cli_dis.py b/python/examples/cli_dis.py
index 8f863db3..cbd4b8f1 100755
--- a/python/examples/cli_dis.py
+++ b/python/examples/cli_dis.py
@@ -55,12 +55,12 @@ archName = sys.argv[1]
bytesList = sys.argv[2:]
# parse byte arguments
-data = b''.join(list(map(lambda x: int(x,16).to_bytes(1,'big'), bytesList)))
+data = b''.join(list(map(lambda x: int(x, 16).to_bytes(1, 'big'), bytesList)))
# disassemble
arch = binaryninja.Architecture[archName]
toksAndLen = arch.get_instruction_text(data, 0)
-if not toksAndLen or toksAndLen[1]==0:
+if not toksAndLen or toksAndLen[1] == 0:
print('disassembly failed')
sys.exit(-1)
@@ -68,4 +68,3 @@ if not toksAndLen or toksAndLen[1]==0:
toks = toksAndLen[0]
strs = map(lambda x: x.text, toks)
print(GREEN, ''.join(strs), NORMAL)
-
diff --git a/python/examples/cli_lift.py b/python/examples/cli_lift.py
index b335a5e4..946f8c3a 100755
--- a/python/examples/cli_lift.py
+++ b/python/examples/cli_lift.py
@@ -34,16 +34,18 @@ from binaryninja import lowlevelil
RED = '\x1B[31m'
NORMAL = '\x1B[0m'
+
def traverse_IL(il, indent):
if isinstance(il, lowlevelil.LowLevelILInstruction):
print('\t'*indent + il.operation.name)
for o in il.operands:
- traverse_IL(o, indent+1)
+ traverse_IL(o, indent + 1)
else:
print('\t'*indent + str(il))
+
if __name__ == '__main__':
if not sys.argv[2:]:
@@ -63,7 +65,7 @@ if __name__ == '__main__':
bytesList = sys.argv[2:]
# parse byte arguments
- data = b''.join(list(map(lambda x: int(x,16).to_bytes(1,'big'), bytesList)))
+ data = b''.join(list(map(lambda x: int(x, 16).to_bytes(1, 'big'), bytesList)))
plat = binaryninja.Platform[platName]
bv = binaryview.BinaryView.new(data)
@@ -71,13 +73,13 @@ if __name__ == '__main__':
bv.add_function(0, plat=plat)
-# print('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))
-# for insn in block:
-# print("\t\t{0}".format(insn))
+ # print('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))
+ # for insn in block:
+ # print("\t\t{0}".format(insn))
print(RED)
for func in bv.functions:
@@ -87,4 +89,3 @@ if __name__ == '__main__':
for insn in block:
traverse_IL(insn, 0)
print(NORMAL)
-
diff --git a/python/examples/debug_info.py b/python/examples/debug_info.py
index 8f379544..28175ba1 100755
--- a/python/examples/debug_info.py
+++ b/python/examples/debug_info.py
@@ -29,7 +29,6 @@
# bv.apply_debug_info(debug_info)
# ```
-
# The rest of this file serves as a test and example of implementing debug info parsers, and the resultant debug info.
#
# All that is required is to provide functions similar to "is_valid" and "parse_info" below, and call
@@ -98,50 +97,56 @@
# }
# ```
-
import binaryninja as bn
import os
-
filename = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_debug_info")
-
# Some setup code not just for informative printing
-
print = print
if __name__ != "__main__":
- print = bn.log_error
+ print = bn.log_error
-def pretty_print_add_data_variable(debug_info: bn.debuginfo.DebugInfo, address: int, t: bn.types.Type, name: str = None) -> None:
- print(f" Adding data variable of type `{t}` at {hex(address)} : {debug_info.add_data_variable(address, t, name)}")
+def pretty_print_add_data_variable(
+ debug_info: bn.debuginfo.DebugInfo, address: int, t: bn.types.Type, name: str = None
+) -> None:
+ print(f" Adding data variable of type `{t}` at {hex(address)} : {debug_info.add_data_variable(address, t, name)}")
-def pretty_print_add_function(debug_info: bn.debuginfo.DebugInfo, address: int, short_name: str = None, full_name: str = None, raw_name: str = None, return_type = None, parameters = None) -> None:
- function_info = bn.debuginfo.DebugFunctionInfo(address, short_name, full_name, raw_name, return_type, parameters)
- if parameters is not None:
- print(f" Adding function `{return_type} {short_name}({', '.join(f'{t} {name}' for name, t in parameters)})` at {hex(address)} : {debug_info.add_function(function_info)}")
- else:
- print(f" Adding function `{return_type} {short_name}()` at {hex(address)} : {debug_info.add_function(function_info)}")
+def pretty_print_add_function(
+ debug_info: bn.debuginfo.DebugInfo, address: int, short_name: str = None, full_name: str = None, raw_name: str = None,
+ return_type=None, parameters=None
+) -> None:
+ function_info = bn.debuginfo.DebugFunctionInfo(address, short_name, full_name, raw_name, return_type, parameters)
+ if parameters is not None:
+ print(
+ f" Adding function `{return_type} {short_name}({', '.join(f'{t} {name}' for name, t in parameters)})` at {hex(address)} : {debug_info.add_function(function_info)}"
+ )
+ else:
+ print(
+ f" Adding function `{return_type} {short_name}()` at {hex(address)} : {debug_info.add_function(function_info)}"
+ )
# The beginning of the actual debug info plugin
def is_valid(bv: bn.binaryview.BinaryView):
- sym = bv.get_symbol_by_raw_name("__elf_interp")
- if sym is None:
- return False
- else:
- var = bv.get_data_var_at(sym.address)
- return b"test_debug_info_parsing" == bv.read(sym.address, var.type.width-1)
+ sym = bv.get_symbol_by_raw_name("__elf_interp")
+ if sym is None:
+ return False
+ else:
+ var = bv.get_data_var_at(sym.address)
+ return b"test_debug_info_parsing" == bv.read(sym.address, var.type.width - 1)
def parse_info(debug_info: bn.debuginfo.DebugInfo, bv: bn.binaryview.BinaryView):
- print("Adding types")
- types = []
- for name, t in bv.parse_types_from_string("""
+ print("Adding types")
+ types = []
+ for name, t in bv.parse_types_from_string(
+ """
struct test_type_1 {
int a;
char b[4];
@@ -153,62 +158,81 @@ def parse_info(debug_info: bn.debuginfo.DebugInfo, bv: bn.binaryview.BinaryView)
struct test_type_1 a;
struct test_type_1* b;
struct test_type_2* c;
- };""").types.items():
- print(f" Adding type \"{name}\" `{t}` : {debug_info.add_type(str(name), t)}")
- types.append(t)
+ };"""
+ ).types.items():
+ print(f" Adding type \"{name}\" `{t}` : {debug_info.add_type(str(name), t)}")
+ types.append(t)
- print("Adding data variables")
- pretty_print_add_data_variable(debug_info, 0x4030, types[0], "test_var_1")
- pretty_print_add_data_variable(debug_info, 0x4010, bn.types.Type.int(4, True), "test_var_2")
- # Names are optional
- pretty_print_add_data_variable(debug_info, 0x4014, bn.types.Type.int(4, True))
+ print("Adding data variables")
+ pretty_print_add_data_variable(debug_info, 0x4030, types[0], "test_var_1")
+ pretty_print_add_data_variable(debug_info, 0x4010, bn.types.Type.int(4, True), "test_var_2")
+ # Names are optional
+ pretty_print_add_data_variable(debug_info, 0x4014, bn.types.Type.int(4, True))
- t = bn.types.Type.int(4, True)
- t.const = True
- pretty_print_add_data_variable(debug_info, 0x2004, t, "test_var_3")
+ t = bn.types.Type.int(4, True)
+ t.const = True
+ pretty_print_add_data_variable(debug_info, 0x2004, t, "test_var_3")
- print("Adding functions")
- char_star = bv.parse_type_string("char*")[0]
- pretty_print_add_function(debug_info, 0x1129, "no_return_type_no_parameters", None, None, bn.types.Type.void(), None)
- pretty_print_add_function(debug_info, 0x1134, "used_parameter", None, None, bn.types.Type.bool(), [("value", bn.types.Type.bool())])
- pretty_print_add_function(debug_info, 0x1155, "unused_parameters", None, None, bn.types.Type.int(4, True), [("value_1", bn.types.Type.bool()), ("value_2", bn.types.Type.int(4, True)), ("value_3", char_star)])
- pretty_print_add_function(debug_info, 0x1170, "used_and_unused_parameters_1", None, None, bn.types.Type.int(4, True), [("value_1", bn.types.Type.int(4, True)), ("value_2", bn.types.Type.int(4, True)), ("value_3", char_star), ("value_4", bn.types.Type.bool())])
- pretty_print_add_function(debug_info, 0x1191, "used_and_unused_parameters_2", None, None, bn.types.Type.int(1, False), [("value_1", bn.types.Type.bool()), ("value_2", bn.types.Type.int(1, False)), ("value_3", char_star), ("value_4", bn.types.Type.int(1, False)), ("value_5", bn.types.Type.char())])
- pretty_print_add_function(debug_info, 0x11c0, "local_parameters", None, None, bn.types.Type.void(), [("value_1", bn.types.Type.bool()), ("value_2", bn.types.Type.int(1, False)), ("value_3", char_star), ("value_4", bn.types.Type.int(1, False)), ("value_5", bn.types.Type.char())])
+ print("Adding functions")
+ char_star = bv.parse_type_string("char*")[0]
+ pretty_print_add_function(debug_info, 0x1129, "no_return_type_no_parameters", None, None, bn.types.Type.void(), None)
+ pretty_print_add_function(
+ debug_info, 0x1134, "used_parameter", None, None, bn.types.Type.bool(), [("value", bn.types.Type.bool())]
+ )
+ pretty_print_add_function(
+ debug_info, 0x1155, "unused_parameters", None, None, bn.types.Type.int(4, True),
+ [("value_1", bn.types.Type.bool()), ("value_2", bn.types.Type.int(4, True)), ("value_3", char_star)]
+ )
+ pretty_print_add_function(
+ debug_info, 0x1170, "used_and_unused_parameters_1", None, None, bn.types.Type.int(4, True),
+ [("value_1", bn.types.Type.int(4, True)), ("value_2", bn.types.Type.int(4, True)), ("value_3", char_star),
+ ("value_4", bn.types.Type.bool())]
+ )
+ pretty_print_add_function(
+ debug_info, 0x1191, "used_and_unused_parameters_2", None, None, bn.types.Type.int(1, False),
+ [("value_1", bn.types.Type.bool()), ("value_2", bn.types.Type.int(1, False)), ("value_3", char_star),
+ ("value_4", bn.types.Type.int(1, False)), ("value_5", bn.types.Type.char())]
+ )
+ pretty_print_add_function(
+ debug_info, 0x11c0, "local_parameters", None, None, bn.types.Type.void(), [("value_1", bn.types.Type.bool()),
+ ("value_2", bn.types.Type.int(1, False)),
+ ("value_3", char_star),
+ ("value_4", bn.types.Type.int(1, False)),
+ ("value_5", bn.types.Type.char())]
+ )
parser = bn.debuginfo.DebugInfoParser.register("test debug info parser", is_valid, parse_info)
print(f"Registered parser: {parser.name}")
-
# The above is all that is needed for a DebugInfo plugin
# The below serves to test the correctness of (the Python bindings' implementation of) debug info parsers' functionality.
-
bn.debuginfo.DebugInfoParser.register("dummy extra debug parser 1", lambda bv: False, lambda di, bv: None)
-bn.debuginfo.DebugInfoParser.register("dummy extra debug parser 2", lambda bv: bv.view_type != "Raw", lambda di, bv: None)
+bn.debuginfo.DebugInfoParser.register(
+ "dummy extra debug parser 2", lambda bv: bv.view_type != "Raw", lambda di, bv: None
+)
# Test fetching parser list and fetching by name
print(f"Availible parsers: {len(list(bn.debuginfo.DebugInfoParser))}")
for p in bn.debuginfo.DebugInfoParser:
- if p == parser:
- print(f" {bn.debuginfo.DebugInfoParser[p.name].name} (the one we just registered)")
- else:
- print(f" {bn.debuginfo.DebugInfoParser[p.name].name}")
+ if p == parser:
+ print(f" {bn.debuginfo.DebugInfoParser[p.name].name} (the one we just registered)")
+ else:
+ print(f" {bn.debuginfo.DebugInfoParser[p.name].name}")
# Test calling our `is_valid` callback
bv = bn.open_view(filename, options={"analysis.experimental.parseDebugInfo": False})
if parser.is_valid_for_view(bv):
- print("Parser is valid")
+ print("Parser is valid")
else:
- print("Parser is NOT valid!")
- quit()
-
+ print("Parser is NOT valid!")
+ quit()
# Test getting list of valid parsers, and DebugInfoParser's repr
print("")
for p in bn.debuginfo.DebugInfoParser.get_parsers_for_view(bv):
- print(f"`{p.name}` is valid for `{bv}`")
+ print(f"`{p.name}` is valid for `{bv}`")
print("")
# Test calling our `parse_info` callback
@@ -219,32 +243,31 @@ print("\nEach of the following pairs of prints should be the same\n")
print("All types:")
for name, t in debug_info.types:
- print(f" \"{name}\": `{t}`")
+ print(f" \"{name}\": `{t}`")
print("Types from parser:")
for name, t in debug_info.types_from_parser(parser.name):
- print(f" \"{name}\": `{t}`")
+ print(f" \"{name}\": `{t}`")
print("")
print("All functions:")
for func in debug_info.functions:
- print(f" {func}")
+ print(f" {func}")
print("Functions from parser:")
for func in debug_info.functions_from_parser(parser.name):
- print(f" {func}")
+ print(f" {func}")
print("")
print("All data variables:")
for data_var in debug_info.data_variables:
- print(f" {data_var}")
+ print(f" {data_var}")
print("Data variables from parser:")
for data_var in debug_info.data_variables_from_parser(parser.name):
- print(f" {data_var}")
-
+ print(f" {data_var}")
print("Appling debug info!")
bv.apply_debug_info(debug_info)
@@ -254,16 +277,16 @@ bv.update_analysis_and_wait()
print("")
print("Types:")
for name, t in debug_info.types:
- print(f" {bv.get_type_by_name(name)}")
+ print(f" {bv.get_type_by_name(name)}")
print("")
print("Functions:")
for func in debug_info.functions:
- print(f" {bv.get_function_at(func.address)}")
+ print(f" {bv.get_function_at(func.address)}")
print("")
print("Data variables:")
for data_var in debug_info.data_variables:
- print(f" {bv.get_data_var_at(data_var.address)}")
+ print(f" {bv.get_data_var_at(data_var.address)}")
diff --git a/python/examples/export_svg.py b/python/examples/export_svg.py
index c96873e1..8166b27a 100755
--- a/python/examples/export_svg.py
+++ b/python/examples/export_svg.py
@@ -12,119 +12,126 @@ from binaryninja.enums import MessageBoxButtonSet, MessageBoxIcon, MessageBoxBut
from binaryninja.function import DisassemblySettings
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],
- 'disabled': [144, 144, 144]}
-
-escape_table = {
- "'": "'",
- ">": ">",
- "<": "&#60;",
- '"': "&#34;",
- ' ': "&#160;"
+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], 'disabled': [144, 144, 144]
}
+escape_table = {"'": "&#39;", ">": "&#62;", "<": "&#60;", '"': "&#34;", ' ': "&#160;"}
+
def escape(toescape):
- # handle extended unicode
- toescape = toescape.encode('ascii', 'xmlcharrefreplace')
- # still escape the basics
- if sys.version_info[0] == 3:
- return ''.join(escape_table.get(chr(i), chr(i)) for i in toescape)
- else:
- return ''.join(escape_table.get(i, i) for i in toescape)
+ # handle extended unicode
+ toescape = toescape.encode('ascii', 'xmlcharrefreplace')
+ # still escape the basics
+ if sys.version_info[0] == 3:
+ return ''.join(escape_table.get(chr(i), chr(i)) for i in toescape)
+ else:
+ return ''.join(escape_table.get(i, i) for i in toescape)
def save_svg(bv, function):
- sym = bv.get_symbol_at(function.start)
- if sym:
- offset = sym.name
- else:
- offset = "%x" % function.start
- path = Path(os.path.dirname(bv.file.filename))
- origname = os.path.basename(bv.file.filename)
- filename = path / f'binaryninja-{origname}-{offset}.html'
+ sym = bv.get_symbol_at(function.start)
+ if sym:
+ offset = sym.name
+ else:
+ offset = "%x" % function.start
+ path = Path(os.path.dirname(bv.file.filename))
+ origname = os.path.basename(bv.file.filename)
+ filename = path / f'binaryninja-{origname}-{offset}.html'
- functionChoice = TextLineField("Blank to accept default")
- # TODO: implement linear disassembly settings and output
- modeChoices = ["Graph"]
- modeChoiceField = ChoiceField("Mode", modeChoices)
- if Settings().get_bool('ui.debugMode'):
- formChoices = ["Assembly", "Lifted IL", "LLIL", "LLIL SSA", "Mapped Medium", "Mapped Medium SSA", "MLIL", "MLIL SSA", "HLIL", "HLIL SSA"]
- formChoiceField = ChoiceField("Form", formChoices)
- else:
- formChoices = ["Assembly", "LLIL", "MLIL", "HLIL"]
- formChoiceField = ChoiceField("Form", formChoices)
+ functionChoice = TextLineField("Blank to accept default")
+ # TODO: implement linear disassembly settings and output
+ modeChoices = ["Graph"]
+ modeChoiceField = ChoiceField("Mode", modeChoices)
+ if Settings().get_bool('ui.debugMode'):
+ formChoices = [
+ "Assembly", "Lifted IL", "LLIL", "LLIL SSA", "Mapped Medium", "Mapped Medium SSA", "MLIL", "MLIL SSA", "HLIL",
+ "HLIL SSA"
+ ]
+ formChoiceField = ChoiceField("Form", formChoices)
+ else:
+ formChoices = ["Assembly", "LLIL", "MLIL", "HLIL"]
+ formChoiceField = ChoiceField("Form", formChoices)
- showOpcodes = ChoiceField("Show Opcodes", ["Yes", "No"])
- showAddresses = ChoiceField("Show Addresses", ["Yes", "No"])
+ showOpcodes = ChoiceField("Show Opcodes", ["Yes", "No"])
+ showAddresses = ChoiceField("Show Addresses", ["Yes", "No"])
- saveFileChoices = SaveFileNameField("Output file", 'HTML files (*.html)', str(filename))
- if not get_form_input([f'Current Function: {offset}', functionChoice, formChoiceField, modeChoiceField, showOpcodes, showAddresses, saveFileChoices], "SVG Export") or saveFileChoices.result is None:
- return
- if saveFileChoices.result == '':
- outputfile = filename
- else:
- outputfile = saveFileChoices.result
- content = render_svg(function, offset, modeChoices[modeChoiceField.result], formChoices[formChoiceField.result], showOpcodes.result == 0, showAddresses.result == 0, origname)
- output = open(outputfile, 'w')
- output.write(content)
- output.close()
- result = show_message_box("Open SVG", "Would you like to view the exported SVG?",
- buttons=MessageBoxButtonSet.YesNoButtonSet, icon=MessageBoxIcon.QuestionIcon)
- if result == MessageBoxButtonResult.YesButton:
- # might need more testing, latest py3 on windows seems.... broken with these APIs relative to other platforms
- if sys.platform == 'win32':
- webbrowser.open(outputfile)
- else:
- webbrowser.open('file://' + str(outputfile))
+ saveFileChoices = SaveFileNameField("Output file", 'HTML files (*.html)', str(filename))
+ if not get_form_input([
+ f'Current Function: {offset}', functionChoice, formChoiceField, modeChoiceField, showOpcodes, showAddresses,
+ saveFileChoices
+ ], "SVG Export") or saveFileChoices.result is None:
+ return
+ if saveFileChoices.result == '':
+ outputfile = filename
+ else:
+ outputfile = saveFileChoices.result
+ content = render_svg(
+ function, offset, modeChoices[modeChoiceField.result], formChoices[formChoiceField.result], showOpcodes.result == 0,
+ showAddresses.result == 0, origname
+ )
+ output = open(outputfile, 'w')
+ output.write(content)
+ output.close()
+ result = show_message_box(
+ "Open SVG", "Would you like to view the exported SVG?", buttons=MessageBoxButtonSet.YesNoButtonSet,
+ icon=MessageBoxIcon.QuestionIcon
+ )
+ if result == MessageBoxButtonResult.YesButton:
+ # might need more testing, latest py3 on windows seems.... broken with these APIs relative to other platforms
+ if sys.platform == 'win32':
+ webbrowser.open(outputfile)
+ else:
+ webbrowser.open('file://' + str(outputfile))
def instruction_data_flow(function, address):
- # TODO: Extract data flow information
- length = function.view.get_instruction_length(address)
- func_bytes = function.view.read(address, length)
- if sys.version_info[0] == 3:
- hex = func_bytes.hex()
- else:
- hex = func_bytes.encode('hex')
- padded = ' '.join([hex[i:i + 2] for i in range(0, len(hex), 2)])
- return 'Opcode: {bytes}'.format(bytes=padded)
+ # TODO: Extract data flow information
+ length = function.view.get_instruction_length(address)
+ func_bytes = function.view.read(address, length)
+ if sys.version_info[0] == 3:
+ hex = func_bytes.hex()
+ else:
+ hex = func_bytes.encode('hex')
+ padded = ' '.join([hex[i:i + 2] for i in range(0, len(hex), 2)])
+ return 'Opcode: {bytes}'.format(bytes=padded)
def render_svg(function, offset, mode, form, showOpcodes, showAddresses, origname):
- settings = DisassemblySettings()
- if showOpcodes:
- settings.set_option(DisassemblyOption.ShowOpcode, True)
- if showAddresses:
- settings.set_option(DisassemblyOption.ShowAddress, True)
- if form == "LLIL":
- graph_type = FunctionGraphType.LowLevelILFunctionGraph
- elif form == "LLIL SSA":
- graph_type = FunctionGraphType.LowLevelILSSAFormFunctionGraph
- elif form == "Lifted IL":
- graph_type = FunctionGraphType.LiftedILFunctionGraph
- elif form == "Mapped Medium":
- graph_type = FunctionGraphType.MappedMediumLevelILFunctionGraph
- elif form == "Mapped Medium SSA":
- graph_type = FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph
- elif form == "MLIL":
- graph_type = FunctionGraphType.MediumLevelILFunctionGraph
- elif form == "MLIL SSA":
- graph_type = FunctionGraphType.MediumLevelILSSAFormFunctionGraph
- elif form == "HLIL":
- graph_type = FunctionGraphType.HighLevelILFunctionGraph
- elif form == "HLIL SSA":
- graph_type = FunctionGraphType.HighLevelILSSAFormFunctionGraph
- else:
- graph_type = FunctionGraphType.NormalFunctionGraph
- graph = function.create_graph(graph_type=graph_type, settings=settings)
- graph.layout_and_wait()
- heightconst = 15
- ratio = 0.48
- widthconst = heightconst * ratio
+ settings = DisassemblySettings()
+ if showOpcodes:
+ settings.set_option(DisassemblyOption.ShowOpcode, True)
+ if showAddresses:
+ settings.set_option(DisassemblyOption.ShowAddress, True)
+ if form == "LLIL":
+ graph_type = FunctionGraphType.LowLevelILFunctionGraph
+ elif form == "LLIL SSA":
+ graph_type = FunctionGraphType.LowLevelILSSAFormFunctionGraph
+ elif form == "Lifted IL":
+ graph_type = FunctionGraphType.LiftedILFunctionGraph
+ elif form == "Mapped Medium":
+ graph_type = FunctionGraphType.MappedMediumLevelILFunctionGraph
+ elif form == "Mapped Medium SSA":
+ graph_type = FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph
+ elif form == "MLIL":
+ graph_type = FunctionGraphType.MediumLevelILFunctionGraph
+ elif form == "MLIL SSA":
+ graph_type = FunctionGraphType.MediumLevelILSSAFormFunctionGraph
+ elif form == "HLIL":
+ graph_type = FunctionGraphType.HighLevelILFunctionGraph
+ elif form == "HLIL SSA":
+ graph_type = FunctionGraphType.HighLevelILSSAFormFunctionGraph
+ else:
+ graph_type = FunctionGraphType.NormalFunctionGraph
+ graph = function.create_graph(graph_type=graph_type, settings=settings)
+ graph.layout_and_wait()
+ heightconst = 15
+ ratio = 0.48
+ widthconst = heightconst * ratio
- output = '''<html>
+ output = '''<html>
<head>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Source+Code+Pro);
@@ -205,7 +212,7 @@ def render_svg(function, offset, mode, form, showOpcodes, showAddresses, orignam
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</head>
'''
- output += '''<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}">
+ output += '''<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="{width}" height="{height}">
<defs>
<marker id="arrow-TrueBranch" class="arrow TrueBranch" viewBox="0 0 10 10" refX="10" refY="5" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
<path d="M 0 0 L 10 5 L 0 10 z" />
@@ -221,83 +228,87 @@ def render_svg(function, offset, mode, form, showOpcodes, showAddresses, orignam
</marker>
</defs>
'''.format(width=graph.width * widthconst + 20, height=graph.height * heightconst + 20)
- output += ''' <g id="functiongraph0" class="functiongraph">
+ output += ''' <g id="functiongraph0" class="functiongraph">
<title>Function Graph 0</title>
'''
- edges = ''
- for i, block in enumerate(graph):
+ edges = ''
+ for i, block in enumerate(graph):
- # Calculate basic block location and coordinates
- x = ((block.x) * widthconst)
- y = ((block.y) * heightconst)
- width = ((block.width) * widthconst)
- height = ((block.height) * heightconst)
+ # Calculate basic block location and coordinates
+ x = ((block.x) * widthconst)
+ y = ((block.y) * heightconst)
+ width = ((block.width) * widthconst)
+ height = ((block.height) * heightconst)
- # Render block
- output += ' <g id="basicblock{i}">\n'.format(i=i)
- output += ' <title>Basic Block {i}</title>\n'.format(i=i)
- rgb = colors['none']
- try:
- bb = block.basic_block
- if hasattr(bb.highlight, 'color'):
- color_code = bb.highlight.color
- color_str = bb.highlight._standard_color_to_str(color_code)
- if color_str in colors:
- rgb = colors[color_str]
- else:
- rgb = [bb.highlight.red, bb.highlight.green, bb.highlight.blue]
- except:
- pass
- output += ' <rect class="basicblock" x="{x}" y="{y}" fill-opacity="0.4" height="{height}" width="{width}" fill="rgb({r},{g},{b})"/>\n'.format(
- x=x, y=y, width=width + 16, height=height + 12, r=rgb[0], g=rgb[1], b=rgb[2])
+ # Render block
+ output += ' <g id="basicblock{i}">\n'.format(i=i)
+ output += ' <title>Basic Block {i}</title>\n'.format(i=i)
+ rgb = colors['none']
+ try:
+ bb = block.basic_block
+ if hasattr(bb.highlight, 'color'):
+ color_code = bb.highlight.color
+ color_str = bb.highlight._standard_color_to_str(color_code)
+ if color_str in colors:
+ rgb = colors[color_str]
+ else:
+ rgb = [bb.highlight.red, bb.highlight.green, bb.highlight.blue]
+ except:
+ pass
+ output += ' <rect class="basicblock" x="{x}" y="{y}" fill-opacity="0.4" height="{height}" width="{width}" fill="rgb({r},{g},{b})"/>\n'.format(
+ x=x, y=y, width=width + 16, height=height + 12, r=rgb[0], g=rgb[1], b=rgb[2]
+ )
- # Render instructions, unfortunately tspans don't allow copying/pasting more
- # than one line at a time, need SVG 1.2 textarea tags for that it looks like
+ # Render instructions, unfortunately tspans don't allow copying/pasting more
+ # than one line at a time, need SVG 1.2 textarea tags for that it looks like
- output += ' <text x="{x}" y="{y}">\n'.format(
- x=x, y=y + (i + 1) * heightconst)
- for i, line in enumerate(block.lines):
- output += ' <tspan id="instr-{address}" x="{x}" y="{y}">'.format(
- x=x + 6, y=y + 6 + (i + 0.7) * heightconst, address=hex(line.address)[:-1])
- hover = instruction_data_flow(function, line.address)
- output += '<title>{hover}</title>'.format(hover=hover)
- for token in line.tokens:
- # TODO: add hover for hex, function, and reg tokens
- output += '<tspan class="{tokentype}">{text}</tspan>'.format(
- text=escape(token.text), tokentype=InstructionTextTokenType(token.type).name)
- output += '</tspan>\n'
- output += ' </text>\n'
- output += ' </g>\n'
+ output += ' <text x="{x}" y="{y}">\n'.format(x=x, y=y + (i+1) * heightconst)
+ for i, line in enumerate(block.lines):
+ output += ' <tspan id="instr-{address}" x="{x}" y="{y}">'.format(
+ x=x + 6, y=y + 6 + (i+0.7) * heightconst, address=hex(line.address)[:-1]
+ )
+ hover = instruction_data_flow(function, line.address)
+ output += '<title>{hover}</title>'.format(hover=hover)
+ for token in line.tokens:
+ # TODO: add hover for hex, function, and reg tokens
+ output += '<tspan class="{tokentype}">{text}</tspan>'.format(
+ text=escape(token.text), tokentype=InstructionTextTokenType(token.type).name
+ )
+ output += '</tspan>\n'
+ output += ' </text>\n'
+ output += ' </g>\n'
- # Edges are rendered in a seperate chunk so they have priority over the
- # basic blocks or else they'd render below them
+ # Edges are rendered in a seperate chunk so they have priority over the
+ # basic blocks or else they'd render below them
- for edge in block.outgoing_edges:
- points = ""
- x, y = edge.points[0]
- points += str(x * widthconst) + "," + \
- str(y * heightconst + 12) + " "
- for x, y in edge.points[1:-1]:
- points += str(x * widthconst) + "," + \
- str(y * heightconst) + " "
- x, y = edge.points[-1]
- points += str(x * widthconst) + "," + \
- str(y * heightconst + 0) + " "
- if edge.back_edge:
- edges += ' <polyline class="back_edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(
- type=BranchType(edge.type).name, points=points)
- else:
- edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(
- type=BranchType(edge.type).name, points=points)
- output += ' ' + edges + '\n'
- output += ' </g>\n'
- output += '</svg>'
+ for edge in block.outgoing_edges:
+ points = ""
+ x, y = edge.points[0]
+ points += str(x * widthconst) + "," + \
+ str(y * heightconst + 12) + " "
+ for x, y in edge.points[1:-1]:
+ points += str(x * widthconst) + "," + \
+ str(y * heightconst) + " "
+ x, y = edge.points[-1]
+ points += str(x * widthconst) + "," + \
+ str(y * heightconst + 0) + " "
+ if edge.back_edge:
+ edges += ' <polyline class="back_edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(
+ type=BranchType(edge.type).name, points=points
+ )
+ else:
+ edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(
+ type=BranchType(edge.type).name, points=points
+ )
+ output += ' ' + edges + '\n'
+ output += ' </g>\n'
+ output += '</svg>'
- output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring} showing {function} as {form}.</p>'.format(
- filename=origname, timestring=time.strftime("%c"), function=offset, form=form)
- output += '</html>'
- return output
+ output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring} showing {function} as {form}.</p>'.format(
+ filename=origname, timestring=time.strftime("%c"), function=offset, form=form
+ )
+ output += '</html>'
+ return output
-PluginCommand.register_for_function(
- "Export to SVG", "Exports an SVG of the current function", save_svg)
+PluginCommand.register_for_function("Export to SVG", "Exports an SVG of the current function", save_svg)
diff --git a/python/examples/helloglobalarea.py b/python/examples/helloglobalarea.py
index d4b1b5ed..b0ac8ede 100644
--- a/python/examples/helloglobalarea.py
+++ b/python/examples/helloglobalarea.py
@@ -29,6 +29,7 @@ from PySide6.QtGui import QImage, QPixmap, QPainter, QFont, QColor
instance_id = 0
+
# Global area widgets must derive from GlobalAreaWidget, not QWidget. GlobalAreaWidget is a QWidget but
# provides callbacks for global area events, and must be created with a title.
class HelloGlobalAreaWidget(GlobalAreaWidget):
@@ -77,6 +78,7 @@ class HelloGlobalAreaWidget(GlobalAreaWidget):
def contextMenuEvent(self, event):
self.m_contextMenuManager.show(self.m_menu, self.actionHandler)
+
# Register the global area widget constructor with Binary Ninja. This will create a new
# global area widget for each window. The callback function receives a `UIContext` object
# for identifying the window.
diff --git a/python/examples/hellopane.py b/python/examples/hellopane.py
index 2b9fbe29..06651a6f 100644
--- a/python/examples/hellopane.py
+++ b/python/examples/hellopane.py
@@ -29,6 +29,7 @@ from PySide6.QtGui import QImage, QPixmap, QPainter, QFont, QColor
instance_id = 0
+
# Class to handle UI context notifications. This will be used to listen for view and address
# changes and update the pane accordingly.
class HelloNotifications(UIContextNotification):
@@ -51,6 +52,7 @@ class HelloNotifications(UIContextNotification):
def OnAddressChange(self, context, frame, view, location):
self.widget.updateState()
+
# Pane widget itself. This can be any QWidget.
class HelloPaneWidget(QWidget, UIContextNotification):
def __init__(self, data):
@@ -120,6 +122,9 @@ class HelloPaneWidget(QWidget, UIContextNotification):
def canCreatePane(context):
return context.context and context.binaryView
+
UIAction.registerAction("Hello Pane")
-UIActionHandler.globalActions().bindAction("Hello Pane", UIAction(HelloPaneWidget.createPane, HelloPaneWidget.canCreatePane))
+UIActionHandler.globalActions().bindAction(
+ "Hello Pane", UIAction(HelloPaneWidget.createPane, HelloPaneWidget.canCreatePane)
+)
Menu.mainMenu("Tools").addAction("Hello Pane", "Hello")
diff --git a/python/examples/hellosidebar.py b/python/examples/hellosidebar.py
index fe7cbae2..69721d4c 100644
--- a/python/examples/hellosidebar.py
+++ b/python/examples/hellosidebar.py
@@ -29,6 +29,7 @@ from PySide6.QtGui import QImage, QPixmap, QPainter, QFont, QColor
instance_id = 0
+
# Sidebar widgets must derive from SidebarWidget, not QWidget. SidebarWidget is a QWidget but
# provides callbacks for sidebar events, and must be created with a title.
class HelloSidebarWidget(SidebarWidget):
@@ -77,6 +78,7 @@ class HelloSidebarWidget(SidebarWidget):
def contextMenuEvent(self, event):
self.m_contextMenuManager.show(self.m_menu, self.actionHandler)
+
class HelloSidebarWidgetType(SidebarWidgetType):
def __init__(self):
# Sidebar icons are 28x28 points. Should be at least 56x56 pixels for
@@ -102,6 +104,7 @@ class HelloSidebarWidgetType(SidebarWidgetType):
# widget is visible and the BinaryView becomes active.
return HelloSidebarWidget("Hello", frame, data)
+
# Register the sidebar widget type with Binary Ninja. This will make it appear as an icon in the
# sidebar and the `createWidget` method will be called when a widget is required.
Sidebar.addSidebarWidgetType(HelloSidebarWidgetType())
diff --git a/python/examples/instruction_iterator.py b/python/examples/instruction_iterator.py
index 9a5d864a..b5cf426f 100644
--- a/python/examples/instruction_iterator.py
+++ b/python/examples/instruction_iterator.py
@@ -32,7 +32,6 @@ binja.log_info("START: 0x%x" % bv.start)
binja.log_info("ENTRY: 0x%x" % bv.entry_point)
binja.log_info("ARCH: %s" % bv.arch.name)
binja.log_info("\n-------- Function List --------")
-
""" print all the functions, their basic blocks, and their il instructions """
for func in bv.functions:
binja.log_info(repr(func))
@@ -41,8 +40,6 @@ for func in bv.functions:
for insn in block:
binja.log_info("\t\t{0}".format(insn))
-
-
""" print all the functions, their basic blocks, and their mc instructions """
for func in bv.functions:
binja.log_info(repr(func))
diff --git a/python/examples/jump_table.py b/python/examples/jump_table.py
index 6ee60ce5..2132c950 100644
--- a/python/examples/jump_table.py
+++ b/python/examples/jump_table.py
@@ -50,13 +50,15 @@ def find_jump_table(bv, addr):
# Collect the branch targets for any tables referenced by the clicked instruction
branches = []
for token in tokens:
- if InstructionTextTokenType(token.type) == InstructionTextTokenType.PossibleAddressToken: # Table addresses will be a "possible address" token
+ if InstructionTextTokenType(
+ token.type
+ ) == InstructionTextTokenType.PossibleAddressToken: # Table addresses will be a "possible address" token
tbl = token.value
print("Found possible table at 0x%x" % tbl)
i = 0
while True:
# Read the next pointer from the table
- data = bv.read(tbl + (i * addrsize), addrsize)
+ data = bv.read(tbl + (i*addrsize), addrsize)
if len(data) == addrsize:
if addrsize == 4:
ptr = struct.unpack("<I", data)[0]
diff --git a/python/examples/linear_mlil.py b/python/examples/linear_mlil.py
index 9be79ad1..e4df1765 100644
--- a/python/examples/linear_mlil.py
+++ b/python/examples/linear_mlil.py
@@ -1,5 +1,5 @@
# Copyright (c) 2019-2022 Vector 35 Inc
-#
+#
# 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
@@ -46,16 +46,28 @@ class LinearMLILView(TokenizedTextView):
# Sort basic blocks by IL instruction index
blocks = il.basic_blocks
- blocks.sort(key = lambda block: block.start)
+ blocks.sort(key=lambda block: block.start)
# Function header
result = []
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderStartLineType,
- self.function, None, DisassemblyTextLine([], self.function.start)))
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderLineType,
- self.function, None, DisassemblyTextLine(self.function.type_tokens, self.function.start)))
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderEndLineType,
- self.function, None, DisassemblyTextLine([], self.function.start)))
+ result.append(
+ LinearDisassemblyLine(
+ LinearDisassemblyLineType.FunctionHeaderStartLineType, self.function, None,
+ DisassemblyTextLine([], self.function.start)
+ )
+ )
+ result.append(
+ LinearDisassemblyLine(
+ LinearDisassemblyLineType.FunctionHeaderLineType, self.function, None,
+ DisassemblyTextLine(self.function.type_tokens, self.function.start)
+ )
+ )
+ result.append(
+ LinearDisassemblyLine(
+ LinearDisassemblyLineType.FunctionHeaderEndLineType, self.function, None,
+ DisassemblyTextLine([], self.function.start)
+ )
+ )
# Display IL instructions in order
lastAddr = self.function.start
@@ -64,20 +76,27 @@ class LinearMLILView(TokenizedTextView):
for block in il:
if lastBlock is not None:
# Blank line between basic blocks
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType,
- self.function, block, DisassemblyTextLine([], lastAddr)))
+ result.append(
+ LinearDisassemblyLine(
+ LinearDisassemblyLineType.CodeDisassemblyLineType, self.function, block, DisassemblyTextLine([], lastAddr)
+ )
+ )
for i in block:
lines, length = renderer.get_disassembly_text(i.instr_index)
lastAddr = i.address
lineIndex = 0
for line in lines:
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType,
- self.function, block, line))
+ result.append(
+ LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, self.function, block, line)
+ )
lineIndex += 1
lastBlock = block
- result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionEndLineType,
- self.function, lastBlock, DisassemblyTextLine([], lastAddr)))
+ result.append(
+ LinearDisassemblyLine(
+ LinearDisassemblyLineType.FunctionEndLineType, self.function, lastBlock, DisassemblyTextLine([], lastAddr)
+ )
+ )
return result
diff --git a/python/examples/mappedview.py b/python/examples/mappedview.py
index 18bef17f..645096f5 100644
--- a/python/examples/mappedview.py
+++ b/python/examples/mappedview.py
@@ -35,13 +35,14 @@ import traceback
use_default_loader_settings = True
+
class MappedView(BinaryView):
name = "Mapped (Python)"
long_name = "Mapped (Python)"
load_address = 0x100000
def __init__(self, data):
- BinaryView.__init__(self, parent_view = data, file_metadata = data.file)
+ BinaryView.__init__(self, parent_view=data, file_metadata=data.file)
@staticmethod
def is_valid_for_data(data):
@@ -74,7 +75,10 @@ class MappedView(BinaryView):
load_settings = registered_view.get_default_load_settings_for_data(view)
# Specify default load settings that can be overridden (from the UI).
- overrides = ["loader.architecture", "loader.platform", "loader.entryPointOffset", "loader.imageBase", "loader.segments", "loader.sections"]
+ overrides = [
+ "loader.architecture", "loader.platform", "loader.entryPointOffset", "loader.imageBase", "loader.segments",
+ "loader.sections"
+ ]
for override in overrides:
if load_settings.contains(override):
load_settings.update_property(override, json.dumps({'readOnly': False}))
@@ -84,11 +88,12 @@ class MappedView(BinaryView):
load_settings.update_property("loader.entryPointOffset", json.dumps({'default': 0}))
# Specify additional custom settings.
- load_settings.register_setting("loader.my_custom_arch.customLoadSetting",
- '{"title" : "My Custom Load Setting",\
+ load_settings.register_setting(
+ "loader.my_custom_arch.customLoadSetting", '{"title" : "My Custom Load Setting",\
"type" : "boolean",\
"default" : false,\
- "description" : "My custom load setting description."}')
+ "description" : "My custom load setting description."}'
+ )
return load_settings
@@ -116,7 +121,7 @@ class MappedView(BinaryView):
if load_settings is None:
if self.parse_only is True:
self.arch = Architecture['x86'] # type: ignore
- self.platform = Architecture['x86'].standalone_platform # type: ignore
+ self.platform = Architecture['x86'].standalone_platform # type: ignore
assert self.parent_view is not None
self.add_auto_segment(0, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable)
return True
@@ -126,10 +131,13 @@ class MappedView(BinaryView):
load_settings = self.__class__.get_load_settings_for_data(self.parent_view)
arch = load_settings.get_string("loader.architecture", self)
- self.arch = Architecture[arch] # type: ignore
- self.platform = Architecture[arch].standalone_platform # type: ignore
+ self.arch = Architecture[arch] # type: ignore
+ self.platform = Architecture[arch].standalone_platform # type: ignore
self.load_address = load_settings.get_integer("loader.imageBase", self)
- self.add_auto_segment(self.load_address, len(self.parent_view), 0, len(self.parent_view), SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
+ self.add_auto_segment(
+ self.load_address, len(self.parent_view), 0, len(self.parent_view),
+ SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable
+ )
if load_settings.contains("loader.entryPointOffset"):
self.entry_point_offset = load_settings.get_integer("loader.entryPointOffset", self)
self.add_entry_point(self.load_address + self.entry_point_offset)
@@ -156,4 +164,5 @@ class MappedView(BinaryView):
def perform_get_address_size(self):
return self.arch.address_size
+
MappedView.register()
diff --git a/python/examples/nds.py b/python/examples/nds.py
index e7192abf..7b53c31f 100644
--- a/python/examples/nds.py
+++ b/python/examples/nds.py
@@ -29,88 +29,92 @@ import traceback
def crc16(data):
- crc = 0xffff
- for ch in data:
- crc ^= ord(ch)
- for bit in range(0, 8):
- if (crc & 1) == 1:
- crc = (crc >> 1) ^ 0xa001
- else:
- crc >>= 1
- return crc
+ crc = 0xffff
+ for ch in data:
+ crc ^= ord(ch)
+ for bit in range(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
+ def __init__(self, data):
+ BinaryView.__init__(self, file_metadata=data.file, parent_view=data)
+ self.raw = data
- @staticmethod
- def is_valid_for_data(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
+ @staticmethod
+ def is_valid_for_data(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 # type: ignore
- self.hdr = self.raw.read(0, 0x160)
+ def init_common(self):
+ self.platform = Architecture["armv7"].standalone_platform # type: ignore
+ 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) # type: ignore
- return True
- except:
- log_error(traceback.format_exc())
- return False
+ 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) # type: ignore
+ 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) # type: ignore
- 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) # type: ignore
+ return True
+ except:
+ log_error(traceback.format_exc())
+ return False
- def perform_is_executable(self):
- return True
+ def perform_is_executable(self):
+ return True
- def perform_get_entry_point(self):
- return self.arm_entry_addr
+ def perform_get_entry_point(self):
+ return self.arm_entry_addr
class DSARM9View(DSView):
- name = "DSARM9"
- long_name = "DS ARM9 ROM"
+ name = "DSARM9"
+ long_name = "DS ARM9 ROM"
- def init(self):
- return self.init_arm9()
+ def init(self):
+ return self.init_arm9()
class DSARM7View(DSView):
- name = "DSARM7"
- long_name = "DS ARM7 ROM"
+ name = "DSARM7"
+ long_name = "DS ARM7 ROM"
- def init(self):
- return self.init_arm7()
+ def init(self):
+ return self.init_arm7()
DSARM9View.register()
diff --git a/python/examples/nes.py b/python/examples/nes.py
index 7e24d16b..7c7857a4 100644
--- a/python/examples/nes.py
+++ b/python/examples/nes.py
@@ -29,43 +29,43 @@ from binaryninja.function import 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)
-
+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
@@ -91,103 +91,151 @@ 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, # ZERO_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, # ZERO_DEST
+ 1, # ZERO_X
+ 1, # ZERO_X_DEST
+ 1, # ZERO_Y
+ 1 # ZERO_Y_DEST
]
-OperandTokens:List[Callable[[int], List[InstructionTextToken]]] = [
- 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
+OperandTokens: List[Callable[[int], List[InstructionTextToken]]] = [
+ 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
]
@@ -218,28 +266,28 @@ def load_zero_page_16(il, value):
OperandIL = [
- lambda il, value: None, # NONE
- lambda il, value: il.load(1, il.const_pointer(2, value)), # ABS
- lambda il, value: il.const(2, value), # ABS_DEST
- lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x")))), # ABS_X
- lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x"))), # ABS_X_DEST
- lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y")))), # ABS_Y
- lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y"))), # ABS_Y_DEST
- lambda il, value: il.reg(1, "a"), # ACCUM
- lambda il, value: il.const_pointer(2, value), # ADDR
- lambda il, value: il.const(1, value), # IMMED
- lambda il, value: indirect_load(il, value), # IND
- lambda il, value: il.load(1, load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x")))), # IND_X
- lambda il, value: load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x"))), # IND_X_DEST
- lambda il, value: il.load(1, il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y"))), # IND_Y
- lambda il, value: il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y")), # IND_Y_DEST
- lambda il, value: il.const_pointer(2, value), # REL
- lambda il, value: il.load(1, il.const_pointer(2, value)), # ZERO
- lambda il, value: il.const_pointer(2, value), # ZERO_DEST
- lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x")))), # ZERO_X
- lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x"))), # ZERO_X_DEST
- lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y")))), # ZERO_Y
- lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y"))) # ZERO_Y_DEST
+ lambda il, value: None, # NONE
+ lambda il, value: il.load(1, il.const_pointer(2, value)), # ABS
+ lambda il, value: il.const(2, value), # ABS_DEST
+ lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x")))), # ABS_X
+ lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "x"))), # ABS_X_DEST
+ lambda il, value: il.load(1, il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y")))), # ABS_Y
+ lambda il, value: il.add(2, il.const(2, value), il.zero_extend(2, il.reg(1, "y"))), # ABS_Y_DEST
+ lambda il, value: il.reg(1, "a"), # ACCUM
+ lambda il, value: il.const_pointer(2, value), # ADDR
+ lambda il, value: il.const(1, value), # IMMED
+ lambda il, value: indirect_load(il, value), # IND
+ lambda il, value: il.load(1, load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x")))), # IND_X
+ lambda il, value: load_zero_page_16(il, il.add(1, il.const(1, value), il.reg(1, "x"))), # IND_X_DEST
+ lambda il, value: il.load(1, il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y"))), # IND_Y
+ lambda il, value: il.add(2, load_zero_page_16(il, il.const(1, value)), il.reg(1, "y")), # IND_Y_DEST
+ lambda il, value: il.const_pointer(2, value), # REL
+ lambda il, value: il.load(1, il.const_pointer(2, value)), # ZERO
+ lambda il, value: il.const_pointer(2, value), # ZERO_DEST
+ lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x")))), # ZERO_X
+ lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "x"))), # ZERO_X_DEST
+ lambda il, value: il.load(1, il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y")))), # ZERO_Y
+ lambda il, value: il.zero_extend(2, il.add(1, il.const(1, value), il.reg(1, "y"))) # ZERO_Y_DEST
]
@@ -280,8 +328,7 @@ def get_p_value(il):
b = il.flag_bit(1, "b", 4)
v = il.flag_bit(1, "v", 6)
s = il.flag_bit(1, "s", 7)
- return il.or_expr(1, il.or_expr(1, il.or_expr(1, il.or_expr(1, il.or_expr(1,
- il.or_expr(1, c, z), i), d), b), v), s)
+ 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):
@@ -302,66 +349,80 @@ def rti(il):
InstructionIL = {
- "adc": lambda il, operand: il.set_reg(1, "a", il.add_carry(1, il.reg(1, "a"), operand, il.flag("c"), flags = "*")),
- "asl": lambda il, operand: il.store(1, operand, il.shift_left(1, il.load(1, operand), il.const(1, 1), flags = "czs")),
- "asl@": lambda il, operand: il.set_reg(1, "a", il.shift_left(1, operand, il.const(1, 1), flags = "czs")),
- "and": lambda il, operand: il.set_reg(1, "a", il.and_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "bcc": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_UGE), operand),
- "bcs": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_ULT), operand),
- "beq": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_E), operand),
- "bit": lambda il, operand: il.and_expr(1, il.reg(1, "a"), operand, flags = "czs"),
- "bmi": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NEG), operand),
- "bne": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NE), operand),
- "bpl": lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_POS), operand),
- "brk": lambda il, operand: il.system_call(),
- "bvc": lambda il, operand: cond_branch(il, il.not_expr(0, il.flag("v")), operand),
- "bvs": lambda il, operand: cond_branch(il, il.flag("v"), operand),
- "clc": lambda il, operand: il.set_flag("c", il.const(0, 0)),
- "cld": lambda il, operand: il.set_flag("d", il.const(0, 0)),
- "cli": lambda il, operand: il.set_flag("i", il.const(0, 0)),
- "clv": lambda il, operand: il.set_flag("v", il.const(0, 0)),
- "cmp": lambda il, operand: il.sub(1, il.reg(1, "a"), operand, flags = "czs"),
- "cpx": lambda il, operand: il.sub(1, il.reg(1, "x"), operand, flags = "czs"),
- "cpy": lambda il, operand: il.sub(1, il.reg(1, "y"), operand, flags = "czs"),
- "dec": lambda il, operand: il.store(1, operand, il.sub(1, il.load(1, operand), il.const(1, 1), flags = "zs")),
- "dex": lambda il, operand: il.set_reg(1, "x", il.sub(1, il.reg(1, "x"), il.const(1, 1), flags = "zs")),
- "dey": lambda il, operand: il.set_reg(1, "y", il.sub(1, il.reg(1, "y"), il.const(1, 1), flags = "zs")),
- "eor": lambda il, operand: il.set_reg(1, "a", il.xor_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "inc": lambda il, operand: il.store(1, operand, il.add(1, il.load(1, operand), il.const(1, 1), flags = "zs")),
- "inx": lambda il, operand: il.set_reg(1, "x", il.add(1, il.reg(1, "x"), il.const(1, 1), flags = "zs")),
- "iny": lambda il, operand: il.set_reg(1, "y", il.add(1, il.reg(1, "y"), il.const(1, 1), flags = "zs")),
- "jmp": lambda il, operand: jump(il, operand),
- "jsr": lambda il, operand: il.call(operand),
- "lda": lambda il, operand: il.set_reg(1, "a", operand, flags = "zs"),
- "ldx": lambda il, operand: il.set_reg(1, "x", operand, flags = "zs"),
- "ldy": lambda il, operand: il.set_reg(1, "y", operand, flags = "zs"),
- "lsr": lambda il, operand: il.store(1, operand, il.logical_shift_right(1, il.load(1, operand), il.const(1, 1), flags = "czs")),
- "lsr@": lambda il, operand: il.set_reg(1, "a", il.logical_shift_right(1, il.reg(1, "a"), il.const(1, 1), flags = "czs")),
- "nop": lambda il, operand: il.nop(),
- "ora": lambda il, operand: il.set_reg(1, "a", il.or_expr(1, il.reg(1, "a"), operand, flags = "zs")),
- "pha": lambda il, operand: il.push(1, il.reg(1, "a")),
- "php": lambda il, operand: il.push(1, get_p_value(il)),
- "pla": lambda il, operand: il.set_reg(1, "a", il.pop(1), flags = "zs"),
- "plp": lambda il, operand: set_p_value(il, il.pop(1)),
- "rol": lambda il, operand: il.store(1, operand, il.rotate_left_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags = "czs")),
- "rol@": lambda il, operand: il.set_reg(1, "a", il.rotate_left_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags = "czs")),
- "ror": lambda il, operand: il.store(1, operand, il.rotate_right_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags = "czs")),
- "ror@": lambda il, operand: il.set_reg(1, "a", il.rotate_right_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags = "czs")),
- "rti": lambda il, operand: rti(il),
- "rts": lambda il, operand: il.ret(il.add(2, il.pop(2), il.const(2, 1))),
- "sbc": lambda il, operand: il.set_reg(1, "a", il.sub_borrow(1, il.reg(1, "a"), operand, il.flag("c"), flags = "*")),
- "sec": lambda il, operand: il.set_flag("c", il.const(0, 1)),
- "sed": lambda il, operand: il.set_flag("d", il.const(0, 1)),
- "sei": lambda il, operand: il.set_flag("i", il.const(0, 1)),
- "sta": lambda il, operand: il.store(1, operand, il.reg(1, "a")),
- "stx": lambda il, operand: il.store(1, operand, il.reg(1, "x")),
- "sty": lambda il, operand: il.store(1, operand, il.reg(1, "y")),
- "tax": lambda il, operand: il.set_reg(1, "x", il.reg(1, "a"), flags = "zs"),
- "tay": lambda il, operand: il.set_reg(1, "y", il.reg(1, "a"), flags = "zs"),
- "tsx": lambda il, operand: il.set_reg(1, "x", il.reg(1, "s"), flags = "zs"),
- "txa": lambda il, operand: il.set_reg(1, "a", il.reg(1, "x"), flags = "zs"),
- "txs": lambda il, operand: il.set_reg(1, "s", il.reg(1, "x")),
- "tya": lambda il, operand: il.set_reg(1, "a", il.reg(1, "y"), flags = "zs")
+ "adc":
+ lambda il, operand: il.set_reg(1, "a", il.add_carry(1, il.reg(1, "a"), operand, il.flag("c"), flags="*")), "asl":
+ lambda il, operand: il.store(1, operand, il.shift_left(1, il.load(1, operand), il.const(1, 1), flags="czs")),
+ "asl@":
+ lambda il, operand: il.set_reg(1, "a", il.shift_left(1, operand, il.const(1, 1), flags="czs")), "and":
+ lambda il, operand: il.set_reg(1, "a", il.and_expr(1, il.reg(1, "a"), operand, flags="zs")), "bcc":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_UGE), operand), "bcs":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_ULT), operand), "beq":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_E), operand), "bit":
+ lambda il, operand: il.and_expr(1, il.reg(1, "a"), operand, flags="czs"), "bmi":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NEG), operand),
+ "bne":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_NE), operand), "bpl":
+ lambda il, operand: cond_branch(il, il.flag_condition(LowLevelILFlagCondition.LLFC_POS), operand), "brk":
+ lambda il, operand: il.system_call(), "bvc":
+ lambda il, operand: cond_branch(il, il.not_expr(0, il.flag("v")), operand), "bvs":
+ lambda il, operand: cond_branch(il, il.flag("v"), operand), "clc":
+ lambda il, operand: il.set_flag("c", il.const(0, 0)), "cld":
+ lambda il, operand: il.set_flag("d", il.const(0, 0)), "cli":
+ lambda il, operand: il.set_flag("i", il.const(0, 0)), "clv":
+ lambda il, operand: il.set_flag("v", il.const(0, 0)), "cmp":
+ lambda il, operand: il.sub(1, il.reg(1, "a"), operand, flags="czs"), "cpx":
+ lambda il, operand: il.sub(1, il.reg(1, "x"), operand, flags="czs"), "cpy":
+ lambda il, operand: il.sub(1, il.reg(1, "y"), operand, flags="czs"),
+ "dec":
+ lambda il, operand: il.store(1, operand, il.sub(1, il.load(1, operand), il.const(1, 1), flags="zs")), "dex":
+ lambda il, operand: il.set_reg(1, "x", il.sub(1, il.reg(1, "x"), il.const(1, 1), flags="zs")), "dey":
+ lambda il, operand: il.set_reg(1, "y", il.sub(1, il.reg(1, "y"), il.const(1, 1), flags="zs")), "eor":
+ lambda il, operand: il.set_reg(1, "a", il.xor_expr(1, il.reg(1, "a"), operand, flags="zs")), "inc":
+ lambda il, operand: il.store(1, operand, il.add(1, il.load(1, operand), il.const(1, 1), flags="zs")), "inx":
+ lambda il, operand: il.set_reg(1, "x", il.add(1, il.reg(1, "x"), il.const(1, 1), flags="zs")), "iny":
+ lambda il, operand: il.set_reg(1, "y", il.add(1, il.reg(1, "y"), il.const(1, 1), flags="zs")), "jmp":
+ lambda il, operand: jump(il, operand), "jsr":
+ lambda il, operand: il.call(operand), "lda":
+ lambda il, operand: il.set_reg(1, "a", operand, flags="zs"), "ldx":
+ lambda il, operand: il.set_reg(1, "x", operand, flags="zs"), "ldy":
+ lambda il, operand: il.set_reg(1, "y", operand, flags="zs"),
+ "lsr":
+ lambda il, operand: il.
+ store(1, operand, il.logical_shift_right(1, il.load(1, operand), il.const(1, 1), flags="czs")), "lsr@":
+ lambda il, operand: il.set_reg(1, "a", il.logical_shift_right(1, il.reg(1, "a"), il.const(1, 1), flags="czs")),
+ "nop":
+ lambda il, operand: il.nop(), "ora":
+ lambda il, operand: il.set_reg(1, "a", il.or_expr(1, il.reg(1, "a"), operand, flags="zs")), "pha":
+ lambda il, operand: il.push(1, il.reg(1, "a")), "php":
+ lambda il, operand: il.push(1, get_p_value(il)), "pla":
+ lambda il, operand: il.set_reg(1, "a", il.pop(1), flags="zs"), "plp":
+ lambda il, operand: set_p_value(il, il.pop(1)),
+ "rol":
+ lambda il, operand: il.
+ store(1, operand, il.rotate_left_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags="czs")), "rol@":
+ lambda il, operand: il.
+ set_reg(1, "a", il.rotate_left_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags="czs")), "ror":
+ lambda il, operand: il.
+ store(1, operand, il.rotate_right_carry(1, il.load(1, operand), il.const(1, 1), il.flag("c"), flags="czs")),
+ "ror@":
+ lambda il, operand: il.
+ set_reg(1, "a", il.rotate_right_carry(1, il.reg(1, "a"), il.const(1, 1), il.flag("c"), flags="czs")), "rti":
+ lambda il, operand: rti(il), "rts":
+ lambda il, operand: il.ret(il.add(2, il.pop(2), il.const(2, 1))), "sbc":
+ lambda il, operand: il.set_reg(1, "a", il.sub_borrow(1, il.reg(1, "a"), operand, il.flag("c"), flags="*")),
+ "sec":
+ lambda il, operand: il.set_flag("c", il.const(0, 1)), "sed":
+ lambda il, operand: il.set_flag("d", il.const(0, 1)), "sei":
+ lambda il, operand: il.set_flag("i", il.const(0, 1)), "sta":
+ lambda il, operand: il.store(1, operand, il.reg(1, "a")), "stx":
+ lambda il, operand: il.store(1, operand, il.reg(1, "x")), "sty":
+ lambda il, operand: il.store(1, operand, il.reg(1, "y")), "tax":
+ lambda il, operand: il.set_reg(1, "x", il.reg(1, "a"), flags="zs"), "tay":
+ lambda il, operand: il.set_reg(1, "y", il.reg(1, "a"), flags="zs"), "tsx":
+ lambda il, operand: il.set_reg(1, "x", il.reg(1, "s"), flags="zs"), "txa":
+ lambda il, operand: il.set_reg(1, "a", il.reg(1, "x"), flags="zs"), "txs":
+ lambda il, operand: il.set_reg(1, "s", il.reg(1, "x")), "tya":
+ lambda il, operand: il.set_reg(1, "a", il.reg(1, "y"), flags="zs")
}
@@ -372,33 +433,23 @@ class M6502(Architecture):
instr_alignment = 1
max_instr_length = 3
regs = {
- "a": RegisterInfo(RegisterName("a"), 1),
- "x": RegisterInfo(RegisterName("x"), 1),
- "y": RegisterInfo(RegisterName("y"), 1),
- "s": RegisterInfo(RegisterName("s"), 1)
+ "a": RegisterInfo(RegisterName("a"), 1), "x": RegisterInfo(RegisterName("x"), 1),
+ "y": RegisterInfo(RegisterName("y"), 1), "s": RegisterInfo(RegisterName("s"), 1)
}
stack_pointer = "s"
flags = ["c", "z", "i", "d", "b", "v", "s"]
flag_write_types = ["*", "czs", "zvs", "zs"]
flag_roles = {
- "c": FlagRole.SpecialFlagRole, # Not a normal carry flag, subtract result is inverted
- "z": FlagRole.ZeroFlagRole,
- "v": FlagRole.OverflowFlagRole,
- "s": FlagRole.NegativeSignFlagRole
+ "c": FlagRole.SpecialFlagRole, # Not a normal carry flag, subtract result is inverted
+ "z": FlagRole.ZeroFlagRole, "v": FlagRole.OverflowFlagRole, "s": FlagRole.NegativeSignFlagRole
}
flags_required_for_flag_condition = {
- LowLevelILFlagCondition.LLFC_UGE: ["c"],
- LowLevelILFlagCondition.LLFC_ULT: ["c"],
- LowLevelILFlagCondition.LLFC_E: ["z"],
- LowLevelILFlagCondition.LLFC_NE: ["z"],
- LowLevelILFlagCondition.LLFC_NEG: ["s"],
- LowLevelILFlagCondition.LLFC_POS: ["s"]
+ LowLevelILFlagCondition.LLFC_UGE: ["c"], LowLevelILFlagCondition.LLFC_ULT: ["c"],
+ LowLevelILFlagCondition.LLFC_E: ["z"], LowLevelILFlagCondition.LLFC_NE: ["z"],
+ LowLevelILFlagCondition.LLFC_NEG: ["s"], LowLevelILFlagCondition.LLFC_POS: ["s"]
}
flags_written_by_flag_write_type = {
- "*": ["c", "z", "v", "s"],
- "czs": ["c", "z", "s"],
- "zvs": ["z", "v", "s"],
- "zs": ["z", "s"]
+ "*": ["c", "z", "v", "s"], "czs": ["c", "z", "s"], "zvs": ["z", "v", "s"], "zs": ["z", "s"]
}
def decode_instruction(self, data, addr):
@@ -482,12 +533,16 @@ class M6502(Architecture):
return Architecture.get_flag_write_low_level_il(self, op, size, write_type, flag, operands, il)
def is_never_branch_patch_available(self, data, addr):
- if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (data[0:1] == b"\x90") or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
+ if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (
+ data[0:1] == b"\x90"
+ ) or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
return True
return False
def is_invert_branch_patch_available(self, data, addr):
- if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (data[0:1] == b"\x90") or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
+ if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (
+ data[0:1] == b"\x90"
+ ) or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
return True
return False
@@ -504,12 +559,16 @@ class M6502(Architecture):
return b"\xea" * len(data)
def never_branch(self, data, addr):
- if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (data[0:1] == b"\x90") or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
+ if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (
+ data[0:1] == b"\x90"
+ ) or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
return b"\xea" * len(data)
return None
def invert_branch(self, data, addr):
- if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (data[0:1] == b"\x90") or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
+ if (data[0:1] == b"\x10") or (data[0:1] == b"\x30") or (data[0:1] == b"\x50") or (data[0:1] == b"\x70") or (
+ data[0:1] == b"\x90"
+ ) or (data[0:1] == b"\xb0") or (data[0:1] == b"\xd0") or (data[0:1] == b"\xf0"):
return chr(ord(data[0:1]) ^ 0x20) + data[1:]
return None
@@ -523,8 +582,9 @@ class NESView(BinaryView):
name = "NES"
long_name = "NES ROM"
bank = None
+
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 # type: ignore
@classmethod
@@ -554,14 +614,20 @@ 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, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
+ self.add_auto_segment(
+ 0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable
+ )
# Add ROM mappings
assert self.__class__.bank is not None
- self.add_auto_segment(0x8000, 0x4000, self.rom_offset + (self.__class__.bank * 0x4000), 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
- self.add_auto_segment(0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
+ self.add_auto_segment(
+ 0x8000, 0x4000, self.rom_offset + (self.__class__.bank * 0x4000), 0x4000,
+ SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable
+ )
+ self.add_auto_segment(
+ 0xc000, 0x4000, self.rom_offset + self.rom_length - 0x4000, 0x4000,
+ SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable
+ )
nmi = struct.unpack("<H", self.read(0xfffa, 2))[0]
start = struct.unpack("<H", self.read(0xfffc, 2))[0]
@@ -605,9 +671,10 @@ class NESView(BinaryView):
self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4016, "JOY1"))
self.define_auto_symbol(Symbol(SymbolType.DataSymbol, 0x4017, "JOY2"))
- sym_files = [self.file.filename + ".%x.nl" % self.__class__.bank,
- self.file.filename + ".ram.nl",
- self.file.filename + ".%x.nl" % (self.rom_banks - 1)]
+ sym_files = [
+ self.file.filename + ".%x.nl" % self.__class__.bank, self.file.filename + ".ram.nl",
+ self.file.filename + ".%x.nl" % (self.rom_banks - 1)
+ ]
for f in sym_files:
if os.path.exists(f):
with open(f, "r") as f:
@@ -637,6 +704,7 @@ class NESView(BinaryView):
banks = []
for i in range(0, 32):
+
class NESViewBank(NESView):
bank = i
name = "NES Bank %X" % i
diff --git a/python/examples/notification_callbacks.py b/python/examples/notification_callbacks.py
index 015cd458..d3cbf26b 100644
--- a/python/examples/notification_callbacks.py
+++ b/python/examples/notification_callbacks.py
@@ -27,6 +27,7 @@ def reg_notif(view):
demo_notification = DemoNotification(view)
view.register_notification(demo_notification)
+
class DemoNotification(BinaryDataNotification):
def __init__(self, view):
self.view = view
@@ -100,4 +101,5 @@ class DemoNotification(BinaryDataNotification):
def type_field_ref_changed(self, *args):
log.log_info(inspect.stack()[0][3] + str(args))
+
PluginCommand.register("Register Notification", "", reg_notif)
diff --git a/python/examples/nsf.py b/python/examples/nsf.py
index 76a78f1c..5121d888 100644
--- a/python/examples/nsf.py
+++ b/python/examples/nsf.py
@@ -87,11 +87,14 @@ class NSFView(BinaryView):
log_info("Bank switching not implemented in this loader.")
# Add mapping for RAM and hardware registers, not backed by file contents
- self.add_auto_segment(0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable)
+ self.add_auto_segment(
+ 0, 0x8000, 0, 0, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable | SegmentFlag.SegmentExecutable
+ )
# Add ROM mappings
- self.add_auto_segment(0x8000, 0x4000, self.rom_offset, 0x4000,
- SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable)
+ self.add_auto_segment(
+ 0x8000, 0x4000, self.rom_offset, 0x4000, SegmentFlag.SegmentReadable | SegmentFlag.SegmentExecutable
+ )
self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.play_address, "_play"))
self.define_auto_symbol(Symbol(SymbolType.FunctionSymbol, self.init_address, "_init"))
diff --git a/python/examples/pe_stat.py b/python/examples/pe_stat.py
index f5a6d89f..2e3f7755 100755
--- a/python/examples/pe_stat.py
+++ b/python/examples/pe_stat.py
@@ -27,7 +27,7 @@ import sys
import binaryninja
from collections import defaultdict
-opc2count = defaultdict(lambda:0)
+opc2count = defaultdict(lambda: 0)
target = sys.argv[1]
print('opening %s' % target)
@@ -48,6 +48,5 @@ total = sum([x[1] for x in opc2count.items()])
print('op frequency %')
print('-- --------- -')
-for opc in sorted(opc2count.keys(), key=lambda x:opc2count[x], reverse=True):
- print(opc.ljust(8), str(opc2count[opc]).ljust(16), '%.1f%%'%(100.0*opc2count[opc]/total))
-
+for opc in sorted(opc2count.keys(), key=lambda x: opc2count[x], reverse=True):
+ print(opc.ljust(8), str(opc2count[opc]).ljust(16), '%.1f%%' % (100.0 * opc2count[opc] / total))
diff --git a/python/examples/print_syscalls.py b/python/examples/print_syscalls.py
index 0ed40fb9..9956636f 100644
--- a/python/examples/print_syscalls.py
+++ b/python/examples/print_syscalls.py
@@ -19,7 +19,6 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-
# Thanks to @theqlabs from arm.ninja for the nice writeup and idea for this plugin:
# http://arm.ninja/2016/03/08/intro-to-binary-ninja-api/
@@ -41,8 +40,7 @@ def print_syscalls(fileName):
register = calling_convention.int_arg_regs[0]
for func in bv.functions:
- syscalls = (il for il in chain.from_iterable(func.low_level_il)
- if il.operation == LowLevelILOperation.LLIL_SYSCALL)
+ 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))
diff --git a/python/examples/typelib_create.py b/python/examples/typelib_create.py
index 303fa350..2ac3855d 100755
--- a/python/examples/typelib_create.py
+++ b/python/examples/typelib_create.py
@@ -36,13 +36,16 @@ typelib.add_named_type('MyPointerType', Type.pointer(arch, Type.char()))
# typedef int MyTypedefType;
typelib.add_named_type('MyTypedefType', Type.int(4))
+
# example of typedef to typedef
# typedef MyTypedefType MySuperSpecialType;
-def create_named_type_reference(type_name:str, to_what:NamedTypeReferenceClass):
- return NamedTypeReferenceType.create(named_type_class=to_what, guid=None, name=type_name)
+def create_named_type_reference(type_name: str, to_what: NamedTypeReferenceClass):
+ return NamedTypeReferenceType.create(named_type_class=to_what, guid=None, name=type_name)
+
-typelib.add_named_type('MySuperSpecialType',
- create_named_type_reference('MySpecialType', NamedTypeReferenceClass.TypedefNamedTypeClass))
+typelib.add_named_type(
+ 'MySuperSpecialType', create_named_type_reference('MySpecialType', NamedTypeReferenceClass.TypedefNamedTypeClass)
+)
# We can demonstrate three type classes in the following example:
# StructureTypeClass, PointerTypeClass, NamedTypeReferenceClass
@@ -57,11 +60,11 @@ typelib.add_named_type('MySuperSpecialType',
# }
with StructureBuilder.builder(typelib, 'Rectangle') as struct_type:
- struct_type.append(Type.int(4), 'width')
- struct_type.append(Type.int(4), 'height')
- struct_type.append(Type.pointer(arch,
- create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass)),
- 'center')
+ struct_type.append(Type.int(4), 'width')
+ struct_type.append(Type.int(4), 'height')
+ struct_type.append(
+ Type.pointer(arch, create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass)), 'center'
+ )
# add a named type "Rectangle2":
# this type cannot be applied to variables until struct Point is declared
@@ -74,10 +77,9 @@ with StructureBuilder.builder(typelib, 'Rectangle') as struct_type:
# }
with StructureBuilder.builder(typelib, 'Rectangle2') as struct_type:
- struct_type.append(Type.int(4), 'width')
- struct_type.append(Type.int(4), 'height')
- struct_type.append(create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass),
- 'center')
+ struct_type.append(Type.int(4), 'width')
+ struct_type.append(Type.int(4), 'height')
+ struct_type.append(create_named_type_reference('Point', NamedTypeReferenceClass.StructNamedTypeClass), 'center')
# example: EnumerationTypeClass
enum_type = EnumerationBuilder.create([], None, arch=arch)
@@ -119,4 +121,3 @@ typelib.add_named_object('_MySuperComputation', ftype)
typelib.finalize()
print('writing test.bntl')
typelib.write_to_file('test.bntl')
-
diff --git a/python/examples/typelib_dump.py b/python/examples/typelib_dump.py
index 4beff0db..750ac78c 100755
--- a/python/examples/typelib_dump.py
+++ b/python/examples/typelib_dump.py
@@ -18,103 +18,106 @@ from binaryninja import typelibrary
#
# etc...
+
def obj2str(t, depth=0):
- indent = ' '*depth
- result = ''
+ indent = ' ' * depth
+ result = ''
+
+ if type(t) == binaryninja.types.StructureType:
+ result = '%sStructure\n' % (indent)
+ for m in t.members:
+ result += obj2str(m, depth + 1)
+ elif type(t) == binaryninja.types.StructureMember:
+ result = '%sStructureMember "%s"\n' % (indent, t._name)
+ result += type2str(t.type, depth + 1)
+ elif type(t) == binaryninja.types.FunctionParameter:
+ result = '%sFunctionParameter "%s"\n' % (indent, t.name)
+ result += type2str(t.type, depth + 1)
+ elif type(t) == binaryninja.types.NamedTypeReferenceType:
+ result = '%sNamedTypeReference %s\n' % (indent, repr(t))
+ elif type(t) == binaryninja.types.EnumerationType:
+ result = '%sEnumeration\n' % indent
+ for m in t.members:
+ result += obj2str(m, depth + 1)
+ elif type(t) == binaryninja.types.EnumerationMember:
+ result = '%sEnumerationMember %s==%d\n' % (indent, t.name, t.value)
+ elif t == None:
+ result = 'unimplemented'
+
+ return result
- if type(t) == binaryninja.types.StructureType:
- result = '%sStructure\n' % (indent)
- for m in t.members:
- result += obj2str(m, depth+1)
- elif type(t) == binaryninja.types.StructureMember:
- result = '%sStructureMember "%s"\n' % (indent, t._name)
- result += type2str(t.type, depth+1)
- elif type(t) == binaryninja.types.FunctionParameter:
- result = '%sFunctionParameter "%s"\n' % (indent, t.name)
- result += type2str(t.type, depth+1)
- elif type(t) == binaryninja.types.NamedTypeReferenceType:
- result = '%sNamedTypeReference %s\n' % (indent, repr(t))
- elif type(t) == binaryninja.types.EnumerationType:
- result = '%sEnumeration\n' % indent
- for m in t.members:
- result += obj2str(m, depth+1)
- elif type(t) == binaryninja.types.EnumerationMember:
- result = '%sEnumerationMember %s==%d\n' % (indent, t.name, t.value)
- elif t == None:
- result = 'unimplemented'
- return result
+def type2str(t: binaryninja.types.Type, depth=0):
+ indent = ' ' * depth
+ result = 'unimplemented'
-def type2str(t:binaryninja.types.Type, depth=0):
- indent = ' '*depth
- result = 'unimplemented'
+ assert isinstance(t, binaryninja.types.Type)
+ tc = t.type_class
- assert isinstance(t, binaryninja.types.Type)
- tc = t.type_class
+ if tc == TypeClass.VoidTypeClass:
+ result = '%sType class=Void\n' % indent
+ elif tc == TypeClass.BoolTypeClass:
+ result = '%sType class=Bool\n' % indent
+ elif tc == TypeClass.IntegerTypeClass:
+ result = '%sType class=Integer width=%d\n' % (indent, t.width)
+ elif tc == TypeClass.FloatTypeClass:
+ result = '%sType class=Float\n' % indent
+ elif tc == TypeClass.StructureTypeClass:
+ result = '%sType class=Structure\n' % indent
+ result += obj2str(t.structure, depth + 1)
+ elif tc == TypeClass.EnumerationTypeClass:
+ result = '%sType class=Enumeration\n' % indent
+ result += obj2str(t.enumeration, depth + 1)
+ elif tc == TypeClass.PointerTypeClass:
+ result = '%sType class=Pointer\n' % indent
+ result += type2str(t.target, depth + 1)
+ elif tc == TypeClass.ArrayTypeClass:
+ result = '%sType class=Array\n' % indent
+ elif tc == TypeClass.FunctionTypeClass:
+ result = '%sType class=Function\n' % indent
+ result += type2str(t.return_value, depth + 1)
+ for param in t.parameters:
+ result += obj2str(param, depth + 1)
+ elif tc == TypeClass.VarArgsTypeClass:
+ result = '%sType class=VarArgs\n' % indent
+ elif tc == TypeClass.ValueTypeClass:
+ result = '%sType class=Value\n' % indent
+ elif tc == TypeClass.NamedTypeReferenceClass:
+ result = '%sType class=NamedTypeReference\n' % indent
+ result += obj2str(t.named_type_reference, depth + 1)
+ elif tc == TypeClass.WideCharTypeClass:
+ result = '%sType class=WideChar\n' % indent
- if tc == TypeClass.VoidTypeClass:
- result = '%sType class=Void\n' % indent
- elif tc == TypeClass.BoolTypeClass:
- result = '%sType class=Bool\n' % indent
- elif tc == TypeClass.IntegerTypeClass:
- result = '%sType class=Integer width=%d\n' % (indent, t.width)
- elif tc == TypeClass.FloatTypeClass:
- result = '%sType class=Float\n' % indent
- elif tc == TypeClass.StructureTypeClass:
- result = '%sType class=Structure\n' % indent
- result += obj2str(t.structure, depth+1)
- elif tc == TypeClass.EnumerationTypeClass:
- result = '%sType class=Enumeration\n' % indent
- result += obj2str(t.enumeration, depth+1)
- elif tc == TypeClass.PointerTypeClass:
- result = '%sType class=Pointer\n' % indent
- result += type2str(t.target, depth+1)
- elif tc == TypeClass.ArrayTypeClass:
- result = '%sType class=Array\n' % indent
- elif tc == TypeClass.FunctionTypeClass:
- result = '%sType class=Function\n' % indent
- result += type2str(t.return_value, depth+1)
- for param in t.parameters:
- result += obj2str(param, depth+1)
- elif tc == TypeClass.VarArgsTypeClass:
- result = '%sType class=VarArgs\n' % indent
- elif tc == TypeClass.ValueTypeClass:
- result = '%sType class=Value\n' % indent
- elif tc == TypeClass.NamedTypeReferenceClass:
- result = '%sType class=NamedTypeReference\n' % indent
- result += obj2str(t.named_type_reference, depth+1)
- elif tc == TypeClass.WideCharTypeClass:
- result = '%sType class=WideChar\n' % indent
+ return result
- return result
if __name__ == '__main__':
- binaryninja._init_plugins()
+ binaryninja._init_plugins()
- if len(sys.argv) <= 1:
- raise Exception('supply typelib file')
+ if len(sys.argv) <= 1:
+ raise Exception('supply typelib file')
- fpath = sys.argv[-1]
- print(' reading: %s' % fpath)
+ fpath = sys.argv[-1]
+ print(' reading: %s' % fpath)
- tl = typelibrary.TypeLibrary.load_from_file(fpath)
- print(' name: %s' % tl.name)
- print(' arch: %s' % tl.arch)
- print(' guid: %s' % tl.guid)
- print('dependency_name: %s' % tl.dependency_name)
- print('alternate_names: %s' % tl.alternate_names)
- print(' platform_names: %s' % tl.platform_names)
- print('')
+ tl = typelibrary.TypeLibrary.load_from_file(fpath)
+ print(' name: %s' % tl.name)
+ print(' arch: %s' % tl.arch)
+ print(' guid: %s' % tl.guid)
+ print('dependency_name: %s' % tl.dependency_name)
+ print('alternate_names: %s' % tl.alternate_names)
+ print(' platform_names: %s' % tl.platform_names)
+ print('')
- print(' named_objects: %d' % len(tl.named_objects))
- for (key, val) in tl.named_objects.items():
- print('\t"%s" %s' % (str(key), str(val)))
+ print(' named_objects: %d' % len(tl.named_objects))
+ for (key, val) in tl.named_objects.items():
+ print('\t"%s" %s' % (str(key), str(val)))
- print('')
+ print('')
- print(' named_types: %d' % len(tl.named_types))
- for (key,val) in tl.named_types.items():
- line = 'typelib.named_types["%s"] =' % (str(key))
- print(line)
- print('-'*len(line))
- print(type2str(val))
+ print(' named_types: %d' % len(tl.named_types))
+ for (key, val) in tl.named_types.items():
+ line = 'typelib.named_types["%s"] =' % (str(key))
+ print(line)
+ print('-' * len(line))
+ print(type2str(val))
diff --git a/python/examples/ui_notifications.py b/python/examples/ui_notifications.py
index 9d423f77..4a708061 100644
--- a/python/examples/ui_notifications.py
+++ b/python/examples/ui_notifications.py
@@ -20,74 +20,74 @@
from binaryninjaui import *
+
class UINotification(UIContextNotification):
- def __init__(self):
- UIContextNotification.__init__(self)
- UIContext.registerNotification(self)
- print("py UIContext.registerNotification")
+ def __init__(self):
+ UIContextNotification.__init__(self)
+ UIContext.registerNotification(self)
+ print("py UIContext.registerNotification")
- def __del__(self):
- UIContext.unregisterNotification(self)
- print("py UIContext.unregisterNotification")
+ def __del__(self):
+ UIContext.unregisterNotification(self)
+ print("py UIContext.unregisterNotification")
- def OnContextOpen(self, context):
- print("py OnContextOpen")
+ def OnContextOpen(self, context):
+ print("py OnContextOpen")
- def OnContextClose(self, context):
- print("py OnContextClose")
+ def OnContextClose(self, context):
+ print("py OnContextClose")
- def OnBeforeOpenDatabase(self, context, metadata):
- print(f"py OnBeforeOpenDatabase {metadata.filename}")
- return True
+ def OnBeforeOpenDatabase(self, context, metadata):
+ print(f"py OnBeforeOpenDatabase {metadata.filename}")
+ return True
- def OnAfterOpenDatabase(self, context, metadata, data):
- print(f"py OnAfterOpenDatabase {metadata.filename} {data.name}")
- return True
+ def OnAfterOpenDatabase(self, context, metadata, data):
+ print(f"py OnAfterOpenDatabase {metadata.filename} {data.name}")
+ return True
- def OnBeforeOpenFile(self, context, file):
- print(f"py OnBeforeOpenFile {file.getFilename()}")
- return True
+ def OnBeforeOpenFile(self, context, file):
+ print(f"py OnBeforeOpenFile {file.getFilename()}")
+ return True
- def OnAfterOpenFile(self, context, file, frame):
- print(f"py OnAfterOpenFile {file.getFilename()} {frame.getShortFileName()}")
+ def OnAfterOpenFile(self, context, file, frame):
+ print(f"py OnAfterOpenFile {file.getFilename()} {frame.getShortFileName()}")
- def OnBeforeSaveFile(self, context, file, frame):
- print(f"py OnBeforeSaveFile {file.getFilename()} {frame.getShortFileName()}")
- return True
+ def OnBeforeSaveFile(self, context, file, frame):
+ print(f"py OnBeforeSaveFile {file.getFilename()} {frame.getShortFileName()}")
+ return True
- def OnAfterSaveFile(self, context, file, frame):
- print(f"py OnAfterSaveFile {file.getFilename()} {frame.getShortFileName()}")
+ def OnAfterSaveFile(self, context, file, frame):
+ print(f"py OnAfterSaveFile {file.getFilename()} {frame.getShortFileName()}")
- def OnBeforeCloseFile(self, context, file, frame):
- print(f"py OnBeforeCloseFile {file.getFilename()} {frame.getShortFileName()}")
- return True
+ def OnBeforeCloseFile(self, context, file, frame):
+ print(f"py OnBeforeCloseFile {file.getFilename()} {frame.getShortFileName()}")
+ return True
- def OnAfterCloseFile(self, context, file, frame):
- print(f"py OnAfterCloseFile {file.getFilename()} {frame.getShortFileName()}")
+ def OnAfterCloseFile(self, context, file, frame):
+ print(f"py OnAfterCloseFile {file.getFilename()} {frame.getShortFileName()}")
- def OnViewChange(self, context, frame, type):
- if frame:
- print(f"py OnViewChange {frame.getShortFileName()} / {type}")
- else:
- print("py OnViewChange")
+ def OnViewChange(self, context, frame, type):
+ if frame:
+ print(f"py OnViewChange {frame.getShortFileName()} / {type}")
+ else:
+ print("py OnViewChange")
- def OnAddressChange(self, context, frame, view, location):
- if frame:
- print(f"py OnAddressChange {frame.getShortFileName()} {location.getOffset()}")
- else:
- print(f"py OnAddressChange {location.getOffset()}")
+ def OnAddressChange(self, context, frame, view, location):
+ if frame:
+ print(f"py OnAddressChange {frame.getShortFileName()} {location.getOffset()}")
+ else:
+ print(f"py OnAddressChange {location.getOffset()}")
- def GetNameForFile(self, context, file, name):
- # This function only works in C++: Name is an out param (cpp: &name), and not modifiable by python.
- print(f"py GetNameForFile {file.getFilename()} {name}")
- return False
+ def GetNameForFile(self, context, file, name):
+ # This function only works in C++: Name is an out param (cpp: &name), and not modifiable by python.
+ print(f"py GetNameForFile {file.getFilename()} {name}")
+ return False
- def GetNameForPath(self, context, path, name):
- # This function only works in C++: Name is an out param (cpp: &name), and not modifiable by python.
- print(f"py GetNameForPath {path} {name}")
- return False
+ def GetNameForPath(self, context, path, name):
+ # This function only works in C++: Name is an out param (cpp: &name), and not modifiable by python.
+ print(f"py GetNameForPath {path} {name}")
+ return False
# Register as a global so it doesn't get destructed
notif = UINotification()
-