diff options
| author | KyleMiles <krm504@nyu.edu> | 2022-01-27 22:43:28 -0500 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2022-01-28 00:24:06 -0500 |
| commit | 6812c973c9fa9b4ad642ab81856c05f87bd6fcc4 (patch) | |
| tree | dace4156d03148bcaf02df138ab4e0d93e61bc6f /python/examples | |
| parent | 519c9db22367f2659d1a54599fab47e6313be06e (diff) | |
Format All Files
Diffstat (limited to 'python/examples')
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 = { - "'": "'", - ">": ">", - "<": "<", - '"': """, - ' ': " " +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 = {"'": "'", ">": ">", "<": "<", '"': """, ' ': " "} + 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() - |
