def initialize_ui(): widget.register_dockwidget(BreakpointsWidget.DebugBreakpointsWidget, "Breakpoints", Qt.BottomDockWidgetArea, Qt.Horizontal, False) widget.register_dockwidget(RegistersWidget.DebugRegistersWidget, "Registers", Qt.RightDockWidgetArea, Qt.Vertical, False) widget.register_dockwidget(ThreadsWidget.DebugThreadsWidget, "Threads", Qt.BottomDockWidgetArea, Qt.Horizontal, False) widget.register_dockwidget(StackWidget.DebugStackWidget, "Stack", Qt.LeftDockWidgetArea, Qt.Vertical, False) widget.register_dockwidget(ModulesWidget.DebugModulesWidget, "Modules", Qt.BottomDockWidgetArea, Qt.Horizontal, False) # TODO: Needs adapter support # widget.register_dockwidget(ConsoleWidget.DebugConsoleWidget, "Debugger Console", Qt.BottomDockWidgetArea, Qt.Horizontal, False) PluginCommand.register_for_address( "Set Breakpoint", "sets breakpoint at right-clicked address", cb_bp_set, is_valid=require_adapter) PluginCommand.register_for_address( "Clear Breakpoint", "clears breakpoint at right-clicked address", cb_bp_clr, is_valid=require_adapter) ViewType.registerViewType(DebugView.DebugViewType())
def register_commands(): """ Register commands """ PluginCommand.register_for_address( "Resolve Shared Library Import", "Resolves an import from a shared library, and jumps to its definition.", action=resolve_imports, is_valid=is_valid, )
def register_commands(): from .deoptimization import ( annotate_operations_ending_at_address, annotate_operations_in_function, ) PluginCommand.register_for_address( "Deoptimize Operations - Line", "Uses z3 to deoptimize divisions and modulos ending at the specified line.", action=annotate_operations_ending_at_address, ) PluginCommand.register_for_function( "Deoptimize Operations - Function", "Uses z3 to deoptimize divisions and modulos through the current function.", action=annotate_operations_in_function, )
def init_module(): init_load_ops() init_store_ops() init_alu_ops() init_jmp_ops() init_ret_ops() init_misc_ops() #EtherTypeRenderer().register_type_specific() EtherTypeRenderer().register_generic() #for full_opcode in InstructionNames: # log('0x%x : %s' % (full_opcode, InstructionNames[full_opcode])) BPFArch.register() arch = Architecture['BPF'] arch.register_calling_convention(DefaultCallingConvention(arch, 'default')) arch.standalone_platform.default_calling_convention = arch.calling_conventions['default'] XTBPFView.register() BPFView.register() PluginCommand.register_for_address('BPF Annotate IP', 'Converts BPF K value to IP', annotate_ip_at)
typelib.add_platform(platform) typelib.finalize() return typelib def select_typelib(bv): libs = bv.platform.type_libraries choice = get_choice_input("Select Type Library", "Platform Libraries", [i.name for i in libs]) bv.add_type_library(libs[choice]) PluginCommand.register( "Type Manager\Generate Type Library [Single Platform]", "Generate a type library for a single platform.", generate_single_platform, ) PluginCommand.register( "Type Manager\Generate Type Library [All Platforms]", "Generate a type library for all Binary Ninja platforms.", generate_all_platforms, ) PluginCommand.register( "Type Manager\Load Type Library", "Load a type library for use in the binary view.", select_typelib, )
patch_opaque(self.bv, self) def patch_opaque_in_background(bv): background_task = PatchOpaqueInBackground(bv, "Patching opaque predicates") background_task.start() def main(): bv = BinaryViewType.get_view_of_file(sys.argv[1]) if bv is None: print("Couldn't open %s" % sys.argv[1]) return patch_opaque(bv) dbname = sys.argv[1] if not dbname.endswith(".bndb"): dbname += ".bndb" bv.create_database(dbname) if __name__ == "__main__": main() else: PluginCommand.register( "Patch Opaque Predicates", "Find branches which are unnecessary and remove them", patch_opaque_in_background)
param_name = param_name.decode("utf-8") func_params = [ param for param in func.parameter_vars if param.name == param_name ] force = False if len(func_params) != 1: log_error("Unable to determine method name argument") return for name, func in discover_names(func, func_params).items(): # Skip if named correctly if func.symbol.name == name: continue # Skip if we're not forcing and the user has named this already if not func.symbol.auto and not force: log_debug("Skipped %r due to no auto symbol" % name) continue log_info("Renaming %r to %r" % (func, name)) func.view.define_auto_symbol( Symbol(func.symbol.type, func.symbol.address, short_name=name)) PluginCommand.register_for_function( "Analysis\\Discover caller names by call parameters", "Renames all unique callers based on call parameters to the current function", do_discover_caller_names, )
from binaryninja.plugin import PluginCommand import insnslice, varslice PluginCommand.register_for_medium_level_il_instruction( "Slice Variable to Graph", "Creates a networkx graph containing all uses of this variable", varslice.show_graph) PluginCommand.register_for_medium_level_il_instruction( "Slice Instructions to Graph", "Creates a networkx graph containing all uses of this variable", insnslice.show_graph) PluginCommand.register_for_medium_level_il_function( "Graph Return variables", "Create a graph of all the possible return trees", varslice.graph_all_returns) PluginCommand.register_for_medium_level_il_function( "Graph Return Instructions", "Create a graph of all the possible return trees", insnslice.graph_all_returns)
from binaryninja.plugin import PluginCommand from .ief import ief_find_export_bg, ief_find_import_bg, ief_find_library_bg PluginCommand.register( 'Import Export Find\\Find binaries that import library named', 'find binaries that import a library named', ief_find_library_bg) PluginCommand.register_for_function( 'Import Export Find\\Find binaries that export current function', 'find binaries that export the current function', ief_find_export_bg) PluginCommand.register_for_function( 'Import Export Find\\Find binaries that import current function', 'find binaries that import the current function', ief_find_import_bg)
from binaryninja.plugin import PluginCommand from pdata_finder import PdataFinder from split_function_fixer import SplitFunctionFixer from xref_finder import XrefFinder PluginCommand.register("Function Finder - Fix Split Functions", "Combines unnecessarily split functions", lambda bv: SplitFunctionFixer(bv).start()) PluginCommand.register( "Function Finder - code xref", "Search for references to possible functions in executable segments", lambda bv: XrefFinder(bv).start()) PluginCommand.register("Function Finder - .pdata", "Search for functions using .pdata section", lambda bv: PdataFinder(bv).start())
return "str_" + "XXX" varname = "str_" varname += _RE_REPLACE_UNDERSCORE.sub("_", s) varname = _RE_COMPRESS_UNDERSCORE.sub("_", varname) return varname def define_str_var(bv, addr): a = get_address_from_inst(bv, addr) if not a: a = addr data = bv.read(a, MAX_STRING_LENGTH) if not data: log_alert("failed to read from 0x{:x}".format(a)) if b"\x00" in data: length = data.find(b"\x00") + 1 else: log_info("not a null-terminated string: {!r}".format(data)) log_alert("doesn't look like a null-terminated-string") return varname = get_string_varname(data[:length]) t = bv.parse_type_string("char {}[{}]".format(varname, length)) bv.define_user_data_var(a, t[0]) sym = binaryninja.types.Symbol('DataSymbol', a, varname[:21], varname) bv.define_user_symbol(sym) # Register commands for the user to interact with the plugin PluginCommand.register_for_address("Define string variable", "Define string variable", define_str_var)
print('WARNING: unfamiliar call operand in {}'.format(instruction)) continue symbol = bv.get_symbol_at(instruction.prefix_operands[2]) if symbol and symbol.type == SymbolType.ImportedFunctionSymbol: #print(symbol.name) #demangler.demangleImport(bv, instruction.prefix_operands[2]) #demangler.demangleImport(bv, symbol.name) name = symbol.name if name[:2] == '__': name = name[1:] try: result = demangler.demangleSymbolAsNode(bv, name) if not result: skipped.append(symbol.name) print('SKIPPING: {}'.format(symbol.name)) continue successful.append(symbol.name) print(result) #print(demangler.getNodeTreeAsString(result)) except Exception as e: logging.exception(e) print(len(skipped)) print(skipped) print(len(successful)) print(successful) PluginCommand.register("Define Objective-C classes", "Parses the objc_classlist section to define Objective C and Swift classes", define_classes) PluginCommand.register_for_address("Demangle Swift symbol", "Demangles the Swift symbol name at the given address", demangler.demangleAddress) PluginCommand.register_for_function("Demangle imported Swift symbols", "Demangles the imported Swift symbol names in the given function", demangleImportsInFunction)
contents = "## %s ##\n" % bv.file.filename contents += "- START: 0x%x\n\n" % bv.start contents += "- ENTRY: 0x%x\n\n" % bv.entry_point contents += "- ARCH: %s\n\n" % bv.arch.name contents += "### First 10 Functions ###\n" contents += "| Start | Name |\n" contents += "|------:|:-------|\n" for i in xrange(min(10, len(bv.functions))): contents += "| 0x%x | %s |\n" % (bv.functions[i].start, bv.functions[i].symbol.full_name) contents += "### First 10 Strings ###\n" contents += "| Start | Length | String |\n" contents += "|------:|-------:|:-------|\n" for i in xrange(min(10, len(bv.strings))): start = bv.strings[i].start length = bv.strings[i].length string = bv.read(start, length) contents += "| 0x%x |%d | %s |\n" % (start, length, string) return contents def display_bininfo(bv): interaction.show_markdown_report("Binary Info Report", get_bininfo(bv)) if __name__ == "__main__": print get_bininfo(None) else: PluginCommand.register("Binary Info", "Display basic info about the binary", display_bininfo)
def avoid_instr(bv, addr): # Highlight the instruction in red blocks = bv.get_basic_blocks_at(addr) for block in blocks: block.set_auto_highlight(HighlightColor(HighlightStandardColor.RedHighlightColor, alpha = 128)) block.function.set_auto_instr_highlight(addr, HighlightStandardColor.RedHighlightColor) # Add the instruction to the list associated with the current view bv.session_data.angr_avoid.add(addr) def solve(bv): if len(bv.session_data.angr_find) == 0: show_message_box("Angr Solve", "You have not specified a goal instruction.\n\n" + "Please right click on the goal instruction and select \"Find Path to This Instruction\" to " + "continue.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon) return # Start a solver thread for the path associated with the view s = Solver(bv.session_data.angr_find, bv.session_data.angr_avoid, bv) s.start() # Register commands for the user to interact with the plugin PluginCommand.register_for_address("Find Path to This Instruction", "When solving, find a path that gets to this instruction", find_instr) PluginCommand.register_for_address("Avoid This Instruction", "When solving, avoid paths that reach this instruction", avoid_instr) PluginCommand.register("Solve With Angr", "Attempt to solve for a path that satisfies the constraints given", solve)
from binaryninja.plugin import PluginCommand from binaryninja.log import log_error def write_breakpoint(view, start, length): """Sample function to show registering a plugin menu item for a range of bytes. Also possible: register register_for_address register_for_function """ bkpt_str = { "x86": "int3", "x86_64": "int3", "armv7": "bkpt", "aarch64": "brk #0", "mips32": "break"} if view.arch.name not in bkpt_str: log_error("Architecture %s not supported" % view.arch.name) return bkpt, err = view.arch.assemble(bkpt_str[view.arch.name]) if bkpt is None: log_error(err) return view.write(start, bkpt * length // len(bkpt)) PluginCommand.register_for_range("Convert to breakpoint", "Fill region with breakpoint instructions.", write_breakpoint)
contents += "| Start | Name |\n" contents += "|------:|:-------|\n" functions = list(bv.functions) for i in range(min(10, len(functions))): contents += "| 0x%x | %s |\n" % (functions[i].start, functions[i].symbol.full_name) contents += "### First 10 Strings ###\n" contents += "| Start | Length | String |\n" contents += "|------:|-------:|:-------|\n" for i in range(min(10, len(bv.strings))): start = bv.strings[i].start length = bv.strings[i].length string = bv.read(start, length) try: string = string.decode('utf8') except UnicodeDecodeError: pass contents += "| 0x%x |%d | %s |\n" % (start, length, string) return contents def display_bininfo(bv): interaction.show_markdown_report("Binary Info Report", get_bininfo(bv)) if __name__ == "__main__": print(get_bininfo(None)) else: PluginCommand.register("Binary Info", "Display basic info about the binary", display_bininfo)
def __init__(self, view): BackgroundTaskThread.__init__( self, initial_progress_text=self._PROGRESS_TEXT + "...", can_cancel=True) self._view = view self._total = 0 self._current = 0 def set_total(self, total): self._total = total def advance(self): self._current += 1 self.progress = "{} ({}/{})...".format(self._PROGRESS_TEXT, self._current, self._total) return not self.cancelled def run(self): try: analyze_cxx_abi(self._view, task=self) finally: self.finish() PluginCommand.register( 'Analyze Itanium C++ ABI...', 'Infer data types from C++ symbol names conforming to Itanium ABI.', lambda view: CxxAbiAnalysis(view).start())
data = bv.read(tbl + (i * addrsize), addrsize) if len(data) == addrsize: if addrsize == 4: ptr = struct.unpack("<I", data)[0] else: ptr = struct.unpack("<Q", data)[0] # If the pointer is within the binary, add it as a destination and continue # to the next entry if (ptr >= bv.start) and (ptr < bv.end): print "Found destination 0x%x" % ptr branches.append((arch, ptr)) else: # Once a value that is not a pointer is encountered, the jump table is ended break else: # Reading invalid memory break i += 1 # Set the indirect branch targets on the jump instruction to be the list of targets discovered func.set_user_indirect_branches(jump_addr, branches) # Create a plugin command so that the user can right click on an instruction referencing a jump table and # invoke the command PluginCommand.register_for_address("Process jump table", "Look for jump table destinations", find_jump_table)
def render_output(self, code): lexer = CLexer() style = NativeStyle() style.background_color = BG_COLOR formatter = HtmlFormatter(full=True, style='native', noclasses=True) colored_code = highlight(code, lexer, formatter) show_html_report('{}.c'.format(self._function.name), colored_code) def decompile_raw(view, function): try: retdec = RetDec(view, function) retdec.decompile_raw() except Exception as e: log.log_error('failed to decompile function: {}'.format(e)) def decompile_bin(view, function): try: retdec = RetDec(view, function) retdec.decompile_bin() except Exception as e: log.log_error('failed to decompile function: {}'.format(e)) PluginCommand.register_for_function('RetDec Offline Decompiler', 'Decompile-Fast', decompile_raw) PluginCommand.register_for_function( 'RetDec Offline Decompiler (Full Binary Analysis)', 'Decompile-Slow', decompile_bin)
log("Writing out {}".format(options.output_name), options.verbose) bv.create_database(options.output_name) return class ImportIDAInBackground(BackgroundTaskThread): def __init__(self, bv, options): global task BackgroundTaskThread.__init__(self, "Importing data from IDA", False) self.json_file = options.json_file self.options = options self.bv = bv task = self def run(self): (success, error_message) = import_ida(self.options.json_file, self.bv, self.options) if not success: log_error(error_message) def import_ida_in_background(bv): options = GetOptions(True) background_task = ImportIDAInBackground(bv, options) background_task.start() if __name__ == "__main__": main() else: PluginCommand.register("Import data from IDA", "Import data from IDA", import_ida_in_background)
# tell Binary Ninja we're a plugin from binaryninja.plugin import PluginCommand from . import thunk def on_select(bv, start, length): shellcode = bv.read(start, length) thunk.doit(shellcode) PluginCommand.register_for_range('call shellcode', 'call selected code (dangerous!)', on_select)
@db_required def display_bb_viewer(bv): dock_handler = None for wg in QApplication.allWidgets(): wg_win = wg.window() dock_handler = wg_win.findChild(DockHandler, "__DockHandler") if dock_handler: break if dock_handler is None: print("Could not find DockHandler") return dock_widget = BBViewerWidget("Basic Block viewer", dock_handler.parent(), bv, LOADED_DB) dock_handler.addDockWidget(dock_widget, Qt.RightDockWidgetArea, Qt.Vertical, True) PluginCommand.register("Wakare\\Load trace database", "Loads a trace database", db_load) PluginCommand.register_for_address("Wakare\\Branch xrefs from", "Displays xrefs from a branch", display_branch_xrefs) PluginCommand.register("Wakare\\Show basic block viewer", "Displays information about basic blocks", display_bb_viewer)
PM = PaperMachete() #print "Invoking Binary Ninja and analyzing file: {}".format(target) bv.add_analysis_option("linearsweep") print "Performing linear sweep..." #bv.update_analysis_and_wait() # Doesn't work on personal license print "Linear sweep complete. Collecting BNIL data..." analyze(bv, func_list) # Needed for converting specific functions to JSON # pretty printed json (pretty printed files are much larger than compact files!) target_json = json.dumps(PM, default=lambda o: o.__dict__, indent=4, sort_keys=True) # compact / minified json #target_json = json.dumps(PM, default=lambda o: o.__dict__) try: jf = None fullpath = os.path.join(tempfile.gettempdir(), 'data.json') jf = open(fullpath, "w") jf.write(target_json) jf.close() except IOError: print "ERROR: Unable to open/write to ~/tmp/data.json" return #target_json PluginCommand.register("Paper Machete", "JSON File", pmanalyze_binja)
self.binary.write(bv.file.raw.read(0, len(bv.file.raw))) self.binary.flush() def run(self): binary = pefile.PE(self.binary.name) names = dict() for entry in binary.DIRECTORY_ENTRY_IMPORT: for imp in entry.imports: names[imp.address] = "{}!{}".format( entry.dll[:-4], imp.name) for symbol in self.bv.get_symbols_of_type( SymbolType.ImportAddressSymbol): if "Ordinal_" in symbol.name and symbol.address in names: bv.define_user_symbol( Symbol(symbol.type, symbol.address, names[symbol.address])) r = Resolver(bv) r.start() def is_pe_file(bv): return bv.view_type == 'PE' PluginCommand.register( "Try resolve Ordinals", "Try to resolve names of ordinals that binary ninja could not resolve", resolve_ordinals, is_pe_file)
# x86_64 syscall table syscall_table = ["read","write","open","close","stat","fstat","lstat","poll","lseek","mmap","mprotect","munmap","brk","rt_sigaction","rt_sigprocmask","rt_sigreturn","ioctl","pread","pwrite","readv","writev","access","pipe","select","sched_yield","mremap","msync","mincore","madvise","shmget","shmat","shmctl","dup","dup","pause","nanosleep","getitimer","alarm","setitimer","getpid","sendfile","socket","connect","accept","sendto","recvfrom","sendmsg","recvmsg","shutdown","bind","listen","getsockname","getpeername","socketpair","setsockopt","getsockopt","clone","fork","vfork","execve","exit","wait","kill","uname","semget","semop","semctl","shmdt","msgget","msgsnd","msgrcv","msgctl","fcntl","flock","fsync","fdatasync","truncate","ftruncate","getdents","getcwd","chdir","fchdir","rename","mkdir","rmdir","creat","link","unlink","symlink","readlink","chmod","fchmod","chown","fchown","lchown","umask","gettimeofday","getrlimit","getrusage","sysinfo","times","ptrace","getuid","syslog","getgid","setuid","setgid","geteuid","getegid","setpgid","getppid","getpgrp","setsid","setreuid","setregid","getgroups","setgroups","setresuid","getresuid","setresgid","getresgid","getpgid","setfsuid","setfsgid","getsid","capget","capset","rt_sigpending","rt_sigtimedwait","rt_sigqueueinfo","rt_sigsuspend","sigaltstack","utime","mknod","uselib","personality","ustat","statfs","fstatfs","sysfs","getpriority","setpriority","sched_setparam","sched_getparam","sched_setscheduler","sched_getscheduler","sched_get_priority_max","sched_get_priority_min","sched_rr_get_interval","mlock","munlock","mlockall","munlockall","vhangup","modify_ldt","pivot_root","_sysctl","prctl","arch_prctl","adjtimex","setrlimit","chroot","sync","acct","settimeofday","mount","umount","swapon","swapoff","reboot","sethostname","setdomainname","iopl","ioperm","create_module","init_module","delete_module","get_kernel_syms","query_module","quotactl","nfsservctl","getpmsg","putpmsg","afs_syscall","tuxcall","security","gettid","readahead","setxattr","lsetxattr","fsetxattr","getxattr","lgetxattr","fgetxattr","listxattr","llistxattr","flistxattr","removexattr","lremovexattr","fremovexattr","tkill","time","futex","sched_setaffinity","sched_getaffinity","set_thread_area","io_setup","io_destroy","io_getevents","io_submit","io_cancel","get_thread_area","lookup_dcookie","epoll_create","epoll_ctl_old","epoll_wait_old","remap_file_pages","getdents","set_tid_address","restart_syscall","semtimedop","fadvise","timer_create","timer_settime","timer_gettime","timer_getoverrun","timer_delete","clock_settime","clock_gettime","clock_getres","clock_nanosleep","exit_group","epoll_wait","epoll_ctl","tgkill","utimes","vserver","mbind","set_mempolicy","get_mempolicy","mq_open","mq_unlink","mq_timedsend","mq_timedreceive","mq_notify","mq_getsetattr","kexec_load","waitid","add_key","request_key","keyctl","ioprio_set","ioprio_get","inotify_init","inotify_add_watch","inotify_rm_watch","migrate_pages","openat","mkdirat","mknodat","fchownat","futimesat","newfstatat","unlinkat","renameat","linkat","symlinkat","readlinkat","fchmodat","faccessat","pselect","ppoll","unshare","set_robust_list","get_robust_list","splice","tee","sync_file_range","vmsplice","move_pages","utimensat","epoll_pwait","signalfd","timerfd_create","eventfd","fallocate","timerfd_settime","timerfd_gettime","accept","signalfd","eventfd","epoll_create","dup","pipe","inotify_init","preadv","pwritev","rt_tgsigqueueinfo","perf_event_open","recvmmsg","fanotify_init","fanotify_mark","prlimit","name_to_handle_at","open_by_handle_at","clock_adjtime","syncfs","sendmmsg","setns","getcpu","process_vm_readv","process_vm_writev","kcmp","finit_module","sched_setattr","sched_getattr","renameat","seccomp","getrandom","memfd_create","kexec_file_load","bpf","execveat","userfaultfd","membarrier","mlock","copy_file_range","preadv","pwritev","pkey_mprotect","pkey_alloc","pkey_free","statx","io_pgetevents","rseq"] def print_syscalls(bv): # Print Syscall numbers for a provided file calling_convention = bv.platform.system_call_convention if calling_convention is None: log_error('Error: No syscall convention available for {:s}'.format(bv.platform)) return register = calling_convention.int_arg_regs[0] report = "### Syscalls for {}\n".format(bv.file.filename) for func in bv.functions: syscalls = (il for il in chain.from_iterable(func.low_level_il) if il.operation == LowLevelILOperation.LLIL_SYSCALL) for il in syscalls: value = func.get_reg_value_at(il.address, register).value report += "##### System call address: [{:#x}](binaryninja://?expr={:#x}) - {}\n".format(il.address, il.address, syscall_table[value]) if len(report) == 0: return "# No Syscalls Discovered in binary" return report def display_syscalls(bv): bv.show_markdown_report("Syscall Info Report", print_syscalls(bv)) PluginCommand.register("Syscall Finder", "Shows information about all the syscalls in the binary", display_syscalls)
addr, HighlightStandardColor.RedHighlightColor) # Add the instruction to the list associated with the current view bv.session_data.angr_avoid.add(addr) def solve(bv): if len(bv.session_data.angr_find) == 0: show_message_box( "Angr Solve", "You have not specified a goal instruction.\n\n" + "Please right click on the goal instruction and select \"Find Path to This Instruction\" to " + "continue.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon) return # Start a solver thread for the path associated with the view s = Solver(bv.session_data.angr_find, bv.session_data.angr_avoid, bv) s.start() # Register commands for the user to interact with the plugin PluginCommand.register_for_address( "Find Path to This Instruction", "When solving, find a path that gets to this instruction", find_instr) PluginCommand.register_for_address( "Avoid This Instruction", "When solving, avoid paths that reach this instruction", avoid_instr) PluginCommand.register( "Solve With Angr", "Attempt to solve for a path that satisfies the constraints given", solve)
if not psp_typelib: print("[PSP] Could not load type library") return if psp_typelib not in bv.type_libraries: bv.add_type_library(psp_typelib) # Now resolve symbols for sym in bv.get_symbols_of_type(SymbolType.ImportedFunctionSymbol): func = bv.get_function_at(sym.address) if not func: continue func_type = psp_typelib.get_named_object(func.name) if func_type is None: continue func.set_user_type(func_type) print("[PSP] Resolved type for {}".format(func.name)) PluginCommand.register("MHFU\\Map ovl file", "Map ovl file", map_ovl) PluginCommand.register("MHFU\\Unmap ovl file", "Unmap an ovl file", unmap_ovl) PluginCommand.register("MHFU\\Trace based function detection", "Detect functions based on ppsspp trace", trace_detect_function) PluginCommand.register("MHFU\\Resolve nid calls", "Resolve PSP api calls" , nid_resolve) PluginCommand.register("MHFU\\Apply pspsdk types", "Apply pspsdk type library", load_type_library)
# Perform lookup f = open(toc, "r") found = False for line in f: if line.startswith(lookupstr + ","): found = True break f.close() if (found): try: # Extract info result = line.split(",") print result[0] + " = " + result[1] # Open Intel proc manual to page for selected opcode subprocess.Popen([browser, '-url', manual + result[2]]) except: log_error("Couldn't find info for the selected opcode!") else: log_error("No table of contents entry for this opcode!") # Create a plugin command so that the user can right click on an instruction and invoke the command PluginCommand.register_for_address("Proc Manual", "Lookup asm instruction in proc manual", proc_manual)
def initialize_ui(): widget.register_dockwidget(BreakpointsWidget.DebugBreakpointsWidget, "Breakpoints", Qt.BottomDockWidgetArea, Qt.Horizontal, False) widget.register_dockwidget(RegistersWidget.DebugRegistersWidget, "Registers", Qt.RightDockWidgetArea, Qt.Vertical, False) widget.register_dockwidget(ThreadsWidget.DebugThreadsWidget, "Threads", Qt.BottomDockWidgetArea, Qt.Horizontal, False) widget.register_dockwidget(StackWidget.DebugStackWidget, "Stack", Qt.LeftDockWidgetArea, Qt.Vertical, False) widget.register_dockwidget(ModulesWidget.DebugModulesWidget, "Modules", Qt.BottomDockWidgetArea, Qt.Horizontal, False) widget.register_dockwidget(ConsoleWidget.DebugConsoleWidget, "Debugger Console", Qt.BottomDockWidgetArea, Qt.Horizontal, False) PluginCommand.register_for_address( "Debugger\\Toggle Breakpoint", "sets/clears breakpoint at right-clicked address", cb_bp_toggle, is_valid=valid_bp_toggle) PluginCommand.register("Debugger\\Process\\Run", "Start new debugging session", cb_process_run, is_valid=valid_process_run) PluginCommand.register("Debugger\\Process\\Restart", "Restart debugging session", cb_process_restart, is_valid=valid_process_restart) PluginCommand.register("Debugger\\Process\\Quit", "Terminate debugged process and end session", cb_process_quit, is_valid=valid_process_quit) # PluginCommand.register("Debugger\\Process\\Attach", "Attach to running process", cb_process_attach, is_valid=valid_process_attach) PluginCommand.register("Debugger\\Process\\Detach", "Detach from current debugged process", cb_process_detach, is_valid=valid_process_detach) PluginCommand.register("Debugger\\Process\\Settings", "Open adapter settings menu", cb_process_settings, is_valid=valid_process_settings) PluginCommand.register("Debugger\\Control\\Pause", "Pause execution", cb_control_pause, is_valid=valid_control_pause) PluginCommand.register("Debugger\\Control\\Resume", "Resume execution", cb_control_resume, is_valid=valid_control_resume) PluginCommand.register("Debugger\\Control\\Step Into (Assembly)", "Step into assembly", cb_control_step_into_asm, is_valid=valid_control_step_into_asm) PluginCommand.register("Debugger\\Control\\Step Into (IL)", "Step into IL", cb_control_step_into_il, is_valid=valid_control_step_into_il) PluginCommand.register("Debugger\\Control\\Step Over (Assembly)", "Step over function call", cb_control_step_over_asm, is_valid=valid_control_step_over_asm) PluginCommand.register("Debugger\\Control\\Step Over (IL)", "Step over function call", cb_control_step_over_il, is_valid=valid_control_step_over_il) PluginCommand.register("Debugger\\Control\\Step Return", "Step until current function returns", cb_control_step_return, is_valid=valid_control_step_return) ViewType.registerViewType(DebugView.DebugViewType())
def __init__(self, bv, options): global task BackgroundTaskThread.__init__(self, "Importing data from Polypyus", False) self.csv_file = options.csv_file self.options = options self.bv = bv task = self def run(self): (success, error_message) = import_pp(self.options.csv_file, self.bv, self.options) if not success: log_error(error_message) def import_pp_in_background(bv): options = GetOptions(True) background_task = ImportPPInBackground(bv, options) background_task.start() if __name__ == "__main__": main() else: PluginCommand.register( "Import data from Polypyus", "Import data from Polypyus", import_pp_in_background, )
state = State.get(bv) state.show_time = not state.show_time if state.show_time: log_info("Time Visualization Enabled (Blue)") else: log_info("Time Visualization Disabled (Blue)") state.color_now = True def toggle_visitors(bv): state = State.get(bv) state.show_visitors = not state.show_visitors if state.show_visitors: log_info("Visitor Visualization Enabled (Green)") else: log_info("Visitor Visualization Disabled (Green)") state.color_now = True def toggle_track(bv): state = State.get(bv) state.track_coverage = not state.track_coverage if state.track_coverage: log_info("Tracking Enabled") else: log_info("Tracking Disabled") PluginCommand.register('revsync\\Coverage: Toggle Tracking', 'Toggle Tracking', toggle_track) PluginCommand.register('revsync\\Coverage: Toggle Visits (RED)', 'Toggle Red', toggle_visits) PluginCommand.register('revsync\\Coverage: Toggle Time (BLUE)', 'Toggle Blue', toggle_time) PluginCommand.register('revsync\\Coverage: Toggle Visitors (GREEN)', 'Toggle Green', toggle_visitors) PluginCommand.register('revsync\\Load', 'load revsync!!!', revsync_load)
from binaryninja.plugin import PluginCommand from binaryninja.log import log_error def write_breakpoint(view, start, length): """Sample function to show registering a plugin menu item for a range of bytes. Also possible: register register_for_address register_for_function """ bkpt_str = { "x86": "int3", "x86_64": "int3", "armv7": "bkpt", "aarch64": "brk #0", "mips32": "break"} if view.arch.name not in bkpt_str: log_error("Architecture %s not supported" % view.arch.name) return bkpt, err = view.arch.assemble(bkpt_str[view.arch.name]) if bkpt is None: log_error(err) return view.write(start, bkpt * length // len(bkpt)) PluginCommand.register_for_range("Convert to breakpoint", "Fill region with breakpoint instructions.", write_breakpoint)
for i, line in enumerate(block.lines): output += ' <tspan id="instr-{address}" x="{x}" y="{y}">'.format(x=x + 6, y=y + 6 + (i + 0.7) * heightconst, address=hex(line.address)[:-1]) hover = instruction_data_flow(function, line.address) output += '<title>{hover}</title>'.format(hover=hover) for token in line.tokens: # TODO: add hover for hex, function, and reg tokens output += '<tspan class="{tokentype}">{text}</tspan>'.format(text=escape(token.text), tokentype=InstructionTextTokenType(token.type).name) output += '</tspan>\n' output += ' </text>\n' output += ' </g>\n' # Edges are rendered in a seperate chunk so they have priority over the # basic blocks or else they'd render below them for edge in block.outgoing_edges: points = "" x, y = edge.points[0] points += str(x * widthconst) + "," + str(y * heightconst + 12) + " " for x, y in edge.points[1:-1]: points += str(x * widthconst) + "," + str(y * heightconst) + " " x, y = edge.points[-1] points += str(x * widthconst) + "," + str(y * heightconst + 0) + " " edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format(type=BranchType(edge.type).name, points=points) output += ' ' + edges + '\n' output += ' </g>\n' output += '</svg></html>' return output PluginCommand.register_for_function("Export to SVG", "Exports an SVG of the current function", save_svg)
for edge in block.outgoing_edges: points = "" x, y = edge.points[0] points += str( x * widthconst) + "," + str(y * heightconst + 12) + " " for x, y in edge.points[1:-1]: points += str(x * widthconst) + "," + str( y * heightconst) + " " x, y = edge.points[-1] points += str( x * widthconst) + "," + str(y * heightconst + 0) + " " if edge.back_edge: edges += ' <polyline class="back_edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format( type=BranchType(edge.type).name, points=points) else: edges += ' <polyline class="edge {type}" points="{points}" marker-end="url(#arrow-{type})"/>\n'.format( type=BranchType(edge.type).name, points=points) output += ' ' + edges + '\n' output += ' </g>\n' output += '</svg>' output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring}.</p>'.format( filename=origname, timestring=time.strftime("%c")) output += '</html>' return output PluginCommand.register_for_function("Export to SVG", "Exports an SVG of the current function", save_svg)
while True: # Read the next pointer from the table data = bv.read(tbl + (i * addrsize), addrsize) if len(data) == addrsize: if addrsize == 4: ptr = struct.unpack("<I", data)[0] else: ptr = struct.unpack("<Q", data)[0] # If the pointer is within the binary, add it as a destination and continue # to the next entry if (ptr >= bv.start) and (ptr < bv.end): print "Found destination 0x%x" % ptr branches.append((arch, ptr)) else: # Once a value that is not a pointer is encountered, the jump table is ended break else: # Reading invalid memory break i += 1 # Set the indirect branch targets on the jump instruction to be the list of targets discovered func.set_user_indirect_branches(jump_addr, branches) # Create a plugin command so that the user can right click on an instruction referencing a jump table and # invoke the command PluginCommand.register_for_address("Process jump table", "Look for jump table destinations", find_jump_table)