def _install_open_coverage_xref(self): PluginCommand.register_for_address( self.ACTION_COVERAGE_XREF, "Open the coverage xref window", self._open_coverage_xref, self._is_xref_valid )
def create_binja_menu(): # Binja does not really support menu in its GUI just yet PluginCommand.register_for_address( "gef : add breakpoint", "Add a breakpoint in gef at the specified location.", add_gef_breakpoint) PluginCommand.register_for_address( "gef : delete breakpoint", "Remove a breakpoint in gef at the specified location.", delete_gef_breakpoint) return
def register_gef_breakpoint_menu(): # Binja does not really support menu in its GUI just yet PluginCommand.register_for_address( "GEF\\Set breakpoint", "Add a breakpoint in gef at the specified location.", gef_add_breakpoint, is_valid=lambda view, addr: is_service_started()) PluginCommand.register_for_address( "GEF\\Delete breakpoint", "Remove a breakpoint in gef at the specified location.", gef_del_breakpoint, is_valid=lambda view, addr: is_service_started()) return
src = self.visit(expr.src) if src is not None: self.br.seek(src) return self.br.read8() def visit_LLIL_XOR(self, expr): left = self.visit(expr.left) right = self.visit(expr.right) if None not in (left, right): return left ^ right def visit_LLIL_REG(self, expr): src = expr.src return self.regs[src.name] def visit_LLIL_NORET(self, expr): log_alert("VM Halted.") def run_emulator(view): v = VMVisitor(view) for il in view.llil_instructions: v.visit(il) PluginCommand.register('Emulate VMArch', 'Emulate VMArch LLIL', run_emulator, lambda view: view.arch == Architecture['VMArch'])
def _install_open_coverage_overview(self): PluginCommand.register("Lighthouse - Coverage Overview", "Open the database code coverage overview", self.interactive_load_batch) logger.info("Installed the 'Coverage Overview' menu entry")
def _install_load_file(self): PluginCommand.register("Lighthouse - Load code coverage file...", "Load individual code coverage file(s)", self.interactive_load_file) logger.info("Installed the 'Code coverage file' menu entry")
from .coverage import function_coverage_start from .evm import EVM, EVMView from .flowgraph import render_flowgraphs from .annotator import annotate_all from .lookup4byte import (rename_all_functions, lookup_one_inst, update_cache_bn, lookup_all_push4) from .misc import dump_codecopy_data def is_valid_evm(view, function=None): return view.arch == Architecture['EVM'] PluginCommand.register(r"Ethersplay\Manticore Highlight", "EVM Manticore Highlight", function_coverage_start, is_valid=is_valid_evm) PluginCommand.register( r'Ethersplay\Render Flowgraphs', 'Render flowgraphs of every function, removing stack variable annotations', render_flowgraphs, is_valid=is_valid_evm) # non-upstream things PluginCommand.register("Ethersplay-contrib\\Annotate Instructions", "[EVM] Annotate Instructions", annotate_all, is_valid=is_valid_evm) PluginCommand.register(
import os import json from binaryninja import PluginCommand from .annotate import * PluginCommand.register_for_function("Annotate", "Annotate functions with arguments", annotate.run_plugin)
task.start() def command_label_tls(view): label_tls(view) def check_view_platform(view, *platforms): platform = view.platform if platform is None: return False return platform.name in platforms PluginCommand.register( 'Windows\\Scan for RTTI', 'Scans for MSVC RTTI', lambda view: command_scan_for_rtti(view), lambda view: check_view_platform(view, 'windows-x86', 'windows-x86_64')) PluginCommand.register_for_address( 'Windows\\Create vftable', 'Creates a vftable at the current address', lambda view, address: command_create_vtable(view, address), lambda view, address: check_view_platform(view, 'windows-x86', 'windows-x86_64')) PluginCommand.register( 'Windows\\Parse exception handlers', 'Create functions based on exception handlers', lambda view: command_parse_unwind_info(view), lambda view: check_view_platform(view, 'windows-x86_64')) PluginCommand.register( 'Windows\\Fix thiscall\'s',
log.log_info(inspect.stack()[0][3] + str(args)) def function_removed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def function_updated(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def data_var_added(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def data_var_updated(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def data_var_removed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def string_found(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def string_removed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_defined(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_undefined(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) PluginCommand.register("Register Notification", "", reg_notif)
def register_logger(address, func): if not __check_executor(): return executor.user_loggers[address] = func def reload_settings(): if not __check_executor(): return executor.bncache.settings = {} PluginCommand.register_for_address( "SENinja\\0 - Start symbolic execution", "create the first state for symbolic execution at current address", _async_start_se) PluginCommand.register_for_address( "SENinja\\1 - Change current state", "change current state with the deferred one at current address (if any)", _async_change_current_state) PluginCommand.register("SENinja\\2 - Step", "execute one instruction with the current state", _async_step) PluginCommand.register( "SENinja\\3 - Continue until branch", "execute instructions in the current state until a fork occurs", _async_continue_until_branch) PluginCommand.register_for_address( "SENinja\\4 - Continue until address", "execute instructions in the current state until the currently selected address is reached",
#from __future__ import print_function from binaryninja import PluginCommand from printSourceCode import function_source_code_start from coverage import function_coverage_start from evm import EVM, EVMView PluginCommand.register("EVM Source Code", "EVM Source Code Printer.", function_source_code_start) PluginCommand.register("EVM Manticore Highlight", "EVM Manticore Highlight", function_coverage_start) EVM.register() EVMView.register()
# Print warnings when our janky parser goes awry. if len(words)>0 and words[0]!="/*" and words[0]!="*/": print("#Warning in: %s\n"%words); log_error(traceback.format_exc()) def md380ldsymbols(view): """This loads an MD380Tools symbols file in GNU LD format.""" filename=get_open_filename_input("Select GNU LD symbols file from MD380Tools.") if filename: print("Opening: %s"%filename); importldsymbols(view,filename); else: print("Aborting."); PluginCommand.register("Load MD380 LD Symbols", "Load GNU LD symbols from MD380Tools", md380ldsymbols); def importr2symbols(bv,filename): """Janky shotgun parser to import Radare2 symbols file to Binary Ninja.""" f=open(filename,"r"); for l in f: words=l.strip().split(); try: if words[0][0]=="#": pass; elif words[0]=="f" and words[2]=="@": #f name @ 0xDEADBEEF name=words[1];
import time import hashlib import binaryninja from binaryninja import PluginCommandContext, PluginCommand from binaryninja import SymbolType, Symbol def do_nothing(bv,function): badnames = "" bn = [] nmap ={} for f in bv.functions: badnames+=f.name + "\n" bn.append(f.name) nmap[f.name] = f.start x = {"input":badnames} r = requests.post("https://demangler.com/raw", data=x) index = 0 lines = r.text.split("\n") for l in lines: if (index < len(bn)-1): name = bn[index] if l != name: #print(" {0:s}\n->{1:s}".format(l,bn[index])) address = nmap[name] symbol_type = SymbolType.FunctionSymbol symbol = l bv.define_user_symbol(Symbol(symbol_type, address, symbol)) index += 1 PluginCommand.register_for_address("Rename C++ functions", "Renames the functions by demangling", do_nothing)
import sys import os import time binaryninja_api_path = "/Applications/Binary Ninja.app/Contents/Resources/python" sys.path.append(binaryninja_api_path) import binaryninja from binaryninja import PluginCommandContext, PluginCommand bv = binaryninja.BinaryViewType.get_view_of_file("ConsoleApplication1-Virtual.bndb") print y bv = binaryninja.BinaryViewType["PE"].open("ConsoleApplication1-Virtual.exe") bv.update_analysis_and_wait() ctx = PluginCommandContext(bv) ctx = PluginCommandContext(bv) y = PluginCommand.get_valid_list(ctx)['Load PDB (BETA)'] y.execute(ctx) #for p in PluginCommand.get_valid_list(ctx): # print(p) # if p == 'Load PDB (BETA)' : # p.execute(ctx) #x = PluginCommand.get_valid_list(ctx) #PluginCommand.get_valid_list(ctx)['Load PDB (BETA)'].execute(ctx) #print(x) #x[0].execute(ctx) #x = PluginCommand.get_valid_list(ctx)['Load PDB (BETA)'].execute(ctx)
def symbol_added(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def symbol_updated(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def symbol_removed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def string_found(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def string_removed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_defined(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_undefined(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_ref_changed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) def type_field_ref_changed(self, *args): log.log_info(inspect.stack()[0][3] + str(args)) PluginCommand.register("Register Notification", "", reg_notif)
"""Returns true if a function has a 'strange loop' (ignore this, inside joke)""" for bb in fn.basic_blocks: if bb in bb.dominance_frontier: return True return False tags = [ \ {'emoji': '🍃', 'name': 'Leaf Function', 'description': 'Leaf function (does not call anything else)', 'fn': isleaf}, {'emoji': '🔄', 'name': 'Loop Function', 'description': 'Function contains a loop', 'fn': hasloop}, {'emoji': '🥾', 'name': 'Stub Function', 'description': 'Function is likely a stub (only contains one basic block and one call or indirect jump)', 'fn': isstub}, {'emoji': '🐘', 'name': 'Large Function', 'description': 'Function is "large" (IE, it has more than the blocks defined above)', 'fn': islarge}, {'emoji': '🤯', 'name': 'Complex Function', 'description': 'Function is "complex" (IE, it has a cyclomatic complexity greater than a defined constant)', 'fn': iscomplex}, {'emoji': '🌴', 'name': 'Switchy Function', 'description': 'Function contains a large switch statemen', 'fn': isswitchy}, ] def start(bv): init_tags(bv) for fn in bv.functions: for tagType in tags: if tagType['fn'](fn): fn.create_user_function_tag(bv.tag_types[tagType['name']], '', unique=True) #fn.name = fn.name + tagType['emoji'] PluginCommand.register("TagTeam", "Tag Functions with Emoji for Various Properties", start)
from .coverage import function_coverage_start from .evm import EVM, EVMView from .flowgraph import render_flowgraphs from .annotator import annotate_all from .lookup4byte import (rename_all_functions, lookup_one_inst, update_cache_bn, lookup_all_push4) from .misc import dump_codecopy_data, highlight_insts def is_valid_evm(view, function=None): return view.arch == Architecture['EVM'] PluginCommand.register(r"Ethersplay\Manticore Highlight", "EVM Manticore Highlight", function_coverage_start, is_valid=is_valid_evm) PluginCommand.register( r'Ethersplay\Render Flowgraphs', 'Render flowgraphs of every function, removing stack variable annotations', render_flowgraphs, is_valid=is_valid_evm) # non-upstream things PluginCommand.register("Ethersplay-contrib\\Annotate Instructions", "[EVM] Annotate Instructions", annotate_all, is_valid=is_valid_evm) PluginCommand.register(
#!/usr/bin/env python # author: Michal Melewski <*****@*****.**> # FSS similarity search plugin - version 1 from binaryninja import PluginCommand from modules import main plugin = main.Plugin() # register plugin PluginCommand.register_for_function("[FSS] Save hash", "Add function to search index", plugin.save_hash) # register plugin PluginCommand.register_for_function( "[FSS] Search for similar functions", "Run similarity search based on current function hash", plugin.find_hash)
def add_image_button(filename, size, fun=None, tooltip=None): """ Adds a pushbutton with an icon to the toolbar """ button = QtWidgets.QPushButton('', toolbar) button.setIcon(QtGui.QIcon(filename)) if fun is not None: button.clicked.connect(lambda: fun(get_binary_view())) if tooltip is not None: button.setToolTip(tooltip) button.setIconSize(QtCore.QSize(size[0], size[1])) toolbar.add_widget(button) def add_picker(pickeritems, callback): """ Adds a combobox widget to the toolbar """ picker = QtWidgets.QComboBox() for item in pickeritems: picker.addItem(item) picker.currentIndexChanged.connect(callback) toolbar.add_widget(picker) def set_bv(binary_view): """ Caches the binary view so that button callbacks can have access to it """ global global_binary_view global_binary_view = binary_view if not toolbar.isVisible(): toolbar.toggle() PluginCommand.register("Initialize Toolbar for this view", "", set_bv)
rules = [RULES_DIR] paths = Settings().get_string("yara.customRulesPath") for path in paths.split(";"): rules.append(path.strip()) ys = YaraScan(bv, directories=rules) ys.start() def scan_with_file(bv): filepath = get_open_filename_input("Open YARA rule", "YARA rules (*.yar *.yara)") if filepath: ys = YaraScan(bv, filepath=filepath.decode()) ys.start() def crypto_scan(bv): crypto_rules = RULES_DIR + os.sep + "crypto_signatures.yar" ys = YaraScan(bv, filepath=crypto_rules) ys.start() PluginCommand.register("YARA\\Scan", "Scan file using YARA rules", scan) PluginCommand.register("YARA\\Scan with File", "Scan file using a specific YARA rule", scan_with_file) PluginCommand.register( "YARA\\Scan for Crypto", "Scan file for known crypto constants using YARA rules", crypto_scan)
for specifier in specifiers[1:]: if not specifier: continue if specifier.startswith('d'): param_types.append(Type.int(4, sign=True)) elif specifier.startswith('s'): param_types.append(Type.pointer(view.arch, Type.char())) elif specifier.startswith('p'): param_types.append(Type.pointer(view.arch, Type.void())) else: log.log_warn( f'Unknown format specifier: {specifier}; skipping') param_types.append(Type.pointer(view.arch, Type.void())) param_idx = 1 params = [ FunctionParameter(Type.pointer(view.arch, Type.char()), 'fmt') ] for param in param_types: params.append(FunctionParameter(param, f'arg{param_idx}')) param_idx += 1 caller.set_call_type_adjustment(xref.address, Type.function(Type.int(4), params)) PluginCommand.register( 'Fix up printf signatures', 'Fix up printf signatures so that the variadic arguments are correctly typed', fix_printfs)
def setup_stack(view: BinaryView, function: LowLevelILFunction) -> None: emulator = view.session_data['emulator'] memory_view = view.session_data['emulator.memory.view'] map_start = 0x1000 map_len = 0x10000 while True: while memory_view.get_segment_at(map_start) is not None: map_start += 0x1000 if any(s.start > map_start and s.start < map_start + map_len for s in memory_view.segments): map_start += 0x1000 continue emulator.map_memory( map_start, map_len, SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable) break sp = map_start + map_len - view.address_size emulator.write_register(view.arch.stack_pointer, sp) PluginCommand.register_for_low_level_il_function( 'Emulator\\Setup stack', 'Setup Emulator Stack', setup_stack, lambda v, f: v.session_data.get('emulator') is not None)
] else: # By default, we just use the LLIL explanation # We append the line number if we're displaying a conditional. explain_window().description = [explain_llil(bv, llil) for llil in parse_il] # Display the MLIL and LLIL, dereferencing anything that looks like a hex number into a symbol if possible explain_window().llil = [dereference_symbols(bv, llil) for llil in llil_list] explain_window().mlil = [dereference_symbols(bv, mlil) for mlil in mlil_list] # Pass in the flags, straight from the API. We don't do much with these, but they might make things more clear explain_window().flags = [ ( func.get_flags_read_by_lifted_il_instruction(lifted.instr_index), func.get_flags_written_by_lifted_il_instruction(lifted.instr_index), lifted, ) for lifted in lifted_il_list ] # Display what information we can calculate about the program state before the instruction is executed try: explain_window().state = get_state(bv, addr) except AttributeError: log_error("No instruction state support for this architecture") explain_window().show() PluginCommand.register_for_address("Explain Instruction", "", explain_instruction)
#!/usr/bin/env python # author: carstein <*****@*****.**> # Annotate function with prototype import os import json from binaryninja import PluginCommand from modules import annotate # register plugin PluginCommand.register_for_function( "Annotate Functions", "Annotate standard libc functions with arguments", annotate.run_plugin)
from binaryninja import PluginCommand from .binja import import_data_in_background, export_data_in_background PluginCommand.register('bnida: Import analysis data', 'Import analysis data from JSON file', import_data_in_background) PluginCommand.register('bnida: Export analysis data', 'Export analysis data to a JSON file', export_data_in_background)
def _install_load_batch(self): PluginCommand.register("Lighthouse - Load code coverage batch...", "Load and aggregate code coverage files", self.interactive_load_batch) logger.info("Installed the 'Code coverage batch' menu entry")
""" """ from binaryninja import ( PluginCommand, ) from .server import ( rpyc_start, rpyc_stop, is_service_started, ) PluginCommand.register("RPyC\\Start service", "Start the RPyC server", rpyc_start, is_valid=lambda view: not is_service_started()) PluginCommand.register("RPyC\\Stop service", "Start the RPyC server", rpyc_stop, is_valid=lambda view: is_service_started())
code += " " value = str(ii) if str(ii.type) == "InstructionTextTokenType.PossibleAddressToken": last = int(str(ii), 16) if last in fmap: value = fmap[last] else: value = bv.get_symbol_at(last).name code += value f1.write(code) f1.write("\n") f1.close() # for block in f.low_level_il: # print(dir(block)) # for instr in block: # if first: # f1.write("{0:s}: {1:x}\n".format(name,instr.address)) # first = False #print instr.address, instr.instr_index, instr # {0:x} {1:d} instr.address, instr.instr_index, # f1.write("{0:s}\n".format(instr)) #print("END") # f1.close() #show_message_box("Do Something", "Congratulations! You have successfully done nothing.\n\n" + # "Pat yourself on the Rump.", MessageBoxButtonSet.OKButtonSet, MessageBoxIcon.ErrorIcon) PluginCommand.register_for_address("Function Writer", "Writes Function Data", do_nothing)
def get_coverage(view): tv = TraceVisualizer(view, None, live=False) if tv.workspace is None: tv.workspace = get_workspace() tv.visualize() c = CoverageHelper(view, tv) c.start() def clear_all(view): tv = TraceVisualizer(view, None) for addr in tv.highlighted: tv.highlight_block(addr, clear) tv.clear_stats() tv.workspace = None tv.live_update = False PluginCommand.register("ManticoreTrace: Highlight", "Highlight Manticore Execution Trace", viz_trace) PluginCommand.register("ManticoreTrace: BB Coverage", "Compute cumulative BB coverage for each function ", get_coverage) PluginCommand.register( "ManticoreTrace: Live Highlight", "Highlight Manticore Execution Trace at Real-Time", viz_live_trace, ) PluginCommand.register("ManticoreTrace: Clear", "Clear Manticore Trace Highlight", clear_all)
rpc.register_instance(Lobotomy(rpc, bv)) print("[*] Started lobotomy service (!)") while True: # Handle inbound requests rpc.handle_request() except Exception as e: ExceptionHandler(e) def start_thread(bv): """ Create a new thread that will run the lobotomy service """ global t global running print(bv) try: t = threading.Thread(target=start_lobotomy, args=[bv]) t.daemon = True t.start() if not running: running = True except Exception as e: ExceptionHandler(e) # Register plugin PluginCommand.register("jni", "Find all registered JNI functions", start_thread)
from binaryninja import PluginCommand, Architecture from .coverage import function_coverage_start from .evm import EVM, EVMView from .flowgraph import render_flowgraphs def is_valid_evm(view, function=None): return view.arch == Architecture['EVM'] PluginCommand.register(r"Ethersplay\Manticore Highlight", "EVM Manticore Highlight", function_coverage_start, is_valid=is_valid_evm) PluginCommand.register( r'Ethersplay\Render Flowgraphs', 'Render flowgraphs of every function, removing stack variable annotations', render_flowgraphs, is_valid=is_valid_evm) EVM.register() EVMView.register()
def register() -> None: PluginCommand.register( "Screenshot Ninja \\ Capture view image @ 1x...", "Save an image of the currently visible linear/graph view at 1x scaling", lambda bv: _ui_save_image(bv, False, 1), ) PluginCommand.register( "Screenshot Ninja \\ Capture view image @ 2x...", "Save an image of the currently visible linear/graph view at 2x scaling", lambda bv: _ui_save_image(bv, False, 2), ) PluginCommand.register( "Screenshot Ninja \\ Capture view image...", "Save an image of the currently visible linear/graph view at custom scaling", lambda bv: _ui_save_image(bv, False), ) PluginCommand.register( "Screenshot Ninja \\ Capture window image @ 1x...", "Save an image of the main window at 1x scaling", lambda bv: _ui_save_image(bv, True, 1), ) PluginCommand.register( "Screenshot Ninja \\ Capture window image @ 2x...", "Save an image of the main window at 2x scaling", lambda bv: _ui_save_image(bv, True, 2), ) PluginCommand.register( "Screenshot Ninja \\ Capture window image...", "Save an image of the main window at custom scaling", lambda bv: _ui_save_image(bv, True), )
"""Binary Ninja plugin for applying kernel symbols from /proc/kallsyms output """ from binaryninja import BinaryView, PluginCommand from .kallsyms import * def apply_kernel_symbols(view: BinaryView): """Registered plugin handler function """ kallsyms = KAllSyms(view) kallsyms.start() PluginCommand.register("kallsyms: Apply kernel symbols", "Apply kernel symbols from /proc/kallsyms output", apply_kernel_symbols)
return calculate_offset(vtable, bv, call_il.dest, defs.get(call_il.instr_index, {}), defs) def navigate_to_virtual_function(bv, addr): constructor = find_constructor(bv) if constructor is None: return vtable = find_vtable(bv, constructor.low_level_il) if vtable is None: log_alert("Couldn't find vtable for {}".format( constructor.symbol.full_name)) return function_pointer = find_function_offset(vtable, bv, addr) if function_pointer is None: log_alert("Couldn't find vtable offset for this call!") return bv.file.navigate(bv.file.view, function_pointer) PluginCommand.register_for_address( "Navigate to Virtual Function", ("Navigate to the virtual function called by " "an indirect call, given the class name"), navigate_to_virtual_function)
if ptr_s == 4: bv.define_data_var(addr, bv.parse_type_string('uint32_t x')[0]) if not isinstance(f, Symbol): s = Symbol(SymbolType.DataSymbol, addr, "ecall_table_size") bv.define_user_symbol(s) ecalls_count = unpack('I', bv.read(addr, 4))[0] else: bv.define_data_var(addr, bv.parse_type_string('uint64_t x')[0]) if not isinstance(f, Symbol): s = Symbol(SymbolType.DataSymbol, addr, "ecall_table_size") bv.define_user_symbol(s) ecalls_count = unpack('Q', bv.read(addr, 8))[0] log_info(f"identified {ecalls_count} ecalls") table_addr = addr + ptr_s table_type, _ = bv.parse_type_string( f"struct {_SGX_ECALL_TYPE_NAME} ecall_table[{ecalls_count}]") bv.define_data_var(table_addr, table_type) s = Symbol(SymbolType.DataSymbol, table_addr, "ecall_table") bv.define_user_symbol(s) PluginCommand.register("SGX\\find ecall table", "In a SGX binary, try to identify the ecall table", find_ecall_table)