Last active
August 1, 2025 04:25
-
-
Save psifertex/6fbc7532f536775194edd26290892ef7 to your computer and use it in GitHub Desktop.
Revisions
-
psifertex revised this gist
Aug 1, 2025 . 2 changed files with 138 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ # Decrease variadic function parameters # def find_call_in_instruction(instr): if isinstance(instr, Localcall): return instr if hasattr(instr, 'operands'): for operand in instr.operands: if hasattr(operand, 'operation'): result = find_call_in_instruction(operand) if result: return result return None # Use the current address directly addr = here call_instr = find_call_in_instruction(current_il_instruction) if not call_instr: log_error("No call instruction found at current position") else: target_addr = None if hasattr(call_instr.dest, 'value'): target_addr = call_instr.dest.value.value elif hasattr(call_instr.dest, 'constant'): target_addr = call_instr.dest.constant if not target_addr: log_error("Cannot determine target function address") else: target_func = bv.get_function_at(target_addr) if not target_func: log_error("Cannot find target function") else: func_type = target_func.type if not func_type.has_variable_arguments.value: log_error("Target function is not variadic") else: # Check for existing call type adjustment existing_adjustment = current_function.get_call_type_adjustment(addr) if existing_adjustment is None: log_error("No existing call type adjustment to decrease") else: # Use the existing adjustment builder = existing_adjustment.mutable_copy() current_params = list(builder.parameters) # Count only the added variadic parameters (those beyond the original function's parameter count) original_param_count = len(func_type.parameters) if len(current_params) <= original_param_count: log_error("No variadic parameters to remove") else: removed_param = current_params.pop() builder.parameters = current_params # If we're back to original params, remove the adjustment if len(current_params) == original_param_count: current_function.set_call_type_adjustment(addr, None) log_info(f"Removed parameter '{removed_param.name}' from variadic function call at 0x{addr:x} (reset to original)") else: # Finalize the type builder to get an immutable Type object finalized_type = builder.immutable_copy() current_function.set_call_type_adjustment(addr, finalized_type) log_info(f"Removed parameter '{removed_param.name}' from variadic function call at 0x{addr:x} (remaining: {len(current_params)} params)") # Wait for analysis to complete current_function.analyze() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,69 @@ # Increase variadic function parameters # from time import sleep def find_call_in_instruction(instr): if isinstance(instr, Localcall): return instr if hasattr(instr, 'operands'): for operand in instr.operands: if hasattr(operand, 'operation'): result = find_call_in_instruction(operand) if result: return result return None # Use the current address directly addr = here call_instr = find_call_in_instruction(current_il_instruction) if not call_instr: log_error("No call instruction found at current position") else: target_addr = None if hasattr(call_instr.dest, 'value'): target_addr = call_instr.dest.value.value elif hasattr(call_instr.dest, 'constant'): target_addr = call_instr.dest.constant if not target_addr: log_error("Cannot determine target function address") else: target_func = bv.get_function_at(target_addr) if not target_func: log_error("Cannot find target function") else: func_type = target_func.type if not func_type.has_variable_arguments.value: log_error("Target function is not variadic") else: # Check for existing call type adjustment existing_adjustment = current_function.get_call_type_adjustment(addr) if existing_adjustment is not None: # Use the existing adjustment as base builder = existing_adjustment.mutable_copy() else: # Use the original function type as base builder = func_type.mutable_copy() # Get current parameter count current_param_count = len(builder.parameters) new_param_num = current_param_count + 1 new_param_name = f"arg{new_param_num}" void_ptr_type = Type.pointer(bv.arch, Type.void()) new_param = FunctionParameter(void_ptr_type, new_param_name) # Get current params and append new one params = list(builder.parameters) params.append(new_param) builder.parameters = params # Finalize the type builder to get an immutable Type object finalized_type = builder.immutable_copy() current_function.set_call_type_adjustment(addr, finalized_type) current_function.analyze() log_info(f"Added parameter '{new_param_name}' to variadic function call at 0x{addr:x} (total: {len(params)} params)") -
psifertex revised this gist
Jun 19, 2025 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,4 +7,7 @@ from binaryninjaui import UIContext action = "About..." ctx = UIContext.activeContext() view = ctx.getCurrentView() handler = view.actionHandler() execute_on_main_thread_and_wait(lambda: handler.executeAction(action)) -
psifertex revised this gist
Apr 15, 2025 . 1 changed file with 42 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,42 @@ # rename from logs # # Extract function name from log calls (credit: whitequark https://gist.github.com/whitequark/03594daa69710089b55720cee688d556#file-log_func_rename-py) logger = "LogFuncRename" def log_func_rename(log_function, name_index): func_votes = defaultdict(lambda: defaultdict(lambda: 0)) for call_site in log_function.caller_sites: if not isinstance(call_site.hlil.operands[0], HighLevelILConstPtr): continue if call_site.hlil.operands[0].constant != log_function.start: continue if name_index >= len(call_site.hlil.instruction_operands): log_warn(f"Call site {call_site.address:#x}: Too few operands", logger) continue name_param = call_site.hlil.instruction_operands[name_index] if isinstance(name_param, HighLevelILConstPtr): name, _ = name_param.string func_votes[call_site.function][name] += 1 else: log_warn(f"Call site {call_site.address:#x}: Non-constant name argument", logger) for caller, votes in func_votes.items(): if len(votes) == 1: func_name = next(iter(votes.keys())) log_info(f"Function {caller.start:#x}: Unanimously renaming to {func_name}", logger) elif len(votes) > 1: func_name, _ = max(votes.items(), key=lambda x: x[1]) other_func_names = set(votes.keys()) - {func_name} log_info(f"Function {caller.start:#x}: Renaming by majority to {func_name} " f"(potentially inlined: {', '.join(other_func_names)})", logger) caller.name = func_name log_func_f = AddressField("Name or address of logging function", current_view) name_index_f = IntegerField("Zero-based index of caller name parameter") if get_form_input([log_func_f, name_index_f], "Logging function parameters"): log_func = current_view.get_function_at(log_func_f.result) if log_func is None: log_error(f"No function at address {log_func_f.result:#x}", logger) else: log_func_rename(log_func, name_index_f.result) Comment -
psifertex revised this gist
Apr 3, 2025 . 1 changed file with 17 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ # demangle this # # demangle all functions and add an extra "this" parameter # First, open the file with the demangle types disabled, then run this snippet. for f in bv.functions: demangleResult = demangle_gnu3(bv.arch,f.symbol.raw_name) demangleType = demangleResult[0] if demangleType is not None: # we have type info, insert void* as first param if isinstance(demangleType, FunctionType): returnType = demangleType.return_value newParams = [Type.pointer(bv.arch, Type.void())] + demangleType.parameters newType = FunctionType.create(ret = returnType, params = newParams) f.type = newType print(f"Replaced {f} type with {newType}") -
psifertex revised this gist
Mar 19, 2025 . 1 changed file with 31 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,19 +5,29 @@ import json from PySide6.QtGui import QGuiApplication settings = json.loads(binaryninja.Settings().serialize_schema()) header = """|Category|Setting|Description|Type|Default|Scope|Key| |---|---|---|---|---|---|---| """ table = "" excludeEnum = [ "analysis.unicode.blocks", "python.interpreter", "ui.theme.name", "files.universal.architecturePreference", "ui.sidebar.defaultWidgets", "ui.view.graph.carousel", "ui.view.graph.il", "ui.view.linear.carousel", "ui.view.linear.il"] allscope = set(["SettingsProjectScope", "SettingsUserScope", "SettingsResourceScope"]) # Build temp structure to group entries by cat table_entries = [] cat_entries = {} for category in sorted(settings): for setting in sorted(settings[category]['settings']): title = settings[category]['settings'][setting]['title'] description = settings[category]['settings'][setting]['description'] typ = settings[category]['settings'][setting]['type'] key = settings[category]['settings'][setting]['key'] cat = key.split(".")[0] if (key.count(".") > 1): cat += "." + key.split(".")[1] default = settings[category]['settings'][setting]['default'] if isinstance(default, list): default = "[" + ', '.join(["`%s`" % x for x in sorted(default)]) + "]" @@ -31,15 +41,32 @@ else: scope = allscope scope = "[" + ', '.join(["`%s`" % x for x in sorted(scope)]) + "]" entry = f"|{cat}|{title}|{description}|`{typ}`|{default}|{scope}|<a id='{key}'>{key}</a>|\n" # Store sub-entries with their parent sub_entries = [] if settings[category]['settings'][setting].get("enum") and key not in excludeEnum: for idx, enum in enumerate(settings[category]['settings'][setting]["enum"]): if settings[category]['settings'][setting].get("enumDescriptions"): description = " enum: " + settings[category]['settings'][setting]["enumDescriptions"][idx] else: description = " " sub_entries.append(f"| | |{description}|`enum`|`{enum}`| | |\n") # Add to our categorized entries if cat not in cat_entries: cat_entries[cat] = [] cat_entries[cat].append((entry, sub_entries)) # Sort by cat and build the final table for cat in sorted(cat_entries.keys()): for entry, sub_entries in cat_entries[cat]: table += entry for sub_entry in sub_entries: table += sub_entry table = header + table show_markdown_report("Settings Documentation", "Below table added to the clipboard:\n\n"+table) log_info("Saving result to the clipboard.") clip = QGuiApplication.clipboard() -
psifertex revised this gist
Nov 20, 2024 . 1 changed file with 7 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,21 +2,10 @@ # # Adapt as necessary to save to file for example, though File / Export will also work def c_source(func): lines = func.pseudo_c_if_available.get_linear_lines(func.hlil.root) return '\n'.join(map(str, lines)) proto = f'{" ".join(map(str,current_function.type.get_tokens_before_name()))} {current_function.name}{ "".join(map(str,current_function.type.get_tokens_after_name()))}' print(proto) print(c_source(current_function)) -
psifertex revised this gist
Jul 25, 2024 . 1 changed file with 27 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ # Copy types with offsets included # # Requested by a customer who wanted to be able to copy structures simila to how they are shown in the UI with hex offsets import binaryninjaui import PySide6 typeName = interaction.get_text_line_input("Type", "Type to copy:").decode('utf8') typeVar = bv.get_type_by_name(typeName) if not typeVar: # check libraries for lib in bv.type_libraries: typeVar = lib.get_named_type(typeName) if typeVar: break if typeVar: lines = "" for line in typeVar.get_lines(bv, typeName): lines += f"{hex(line.offset)} {str(line)}\n" clip = PySide6.QtGui.QGuiApplication.clipboard() clip.setText(lines) else: log_info(f"Could not find a type with the name {typeName}") -
psifertex revised this gist
Feb 19, 2024 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,15 +12,15 @@ excludeEnum = [ "analysis.unicode.blocks", "python.interpreter", "ui.theme"] allscope = set(["SettingsProjectScope", "SettingsUserScope", "SettingsResourceScope"]) for category in sorted(settings): for setting in sorted(settings[category]['settings']): title = settings[category]['settings'][setting]['title'] description = settings[category]['settings'][setting]['description'] typ = settings[category]['settings'][setting]['type'] key = settings[category]['settings'][setting]['key'] default = settings[category]['settings'][setting]['default'] if isinstance(default, list): default = "[" + ', '.join(["`%s`" % x for x in sorted(default)]) + "]" else: default = f"`{str(default)}`" if default == "``": @@ -30,7 +30,7 @@ scope = allscope - set(settings[category]['settings'][setting]['ignore']) else: scope = allscope scope = "[" + ', '.join(["`%s`" % x for x in sorted(scope)]) + "]" table += f"|{category}|{title}|{description}|`{typ}`|{default}|{scope}|<a id='{key}'>{key}</a>|\n" if settings[category]['settings'][setting].get("enum") and key not in excludeEnum: for idx, enum in enumerate(settings[category]['settings'][setting]["enum"]): -
psifertex revised this gist
Feb 12, 2024 . 1 changed file with 38 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,38 @@ # apply function types to structure parameters # # Lets you select a struct to automatically search type libraries for function signatures to apply type information # Thanks @d0mnik! Original code: https://gist.github.com/d0mnik/1ee595605fc7c9a39364fdbfb660f268 from binaryninja import * api_call_protos = {} type_to_parse = get_text_line_input("Enter structure name to parse:", "Struct Parser") if type_to_parse is None: exit() struct_name = type_to_parse.decode() if bv.get_type_by_name(struct_name) is None: show_message_box(f"Struct Parser", "Struct with specified name not found!") exit() for typelib in bv.type_libraries: for name, obj in typelib.named_objects.items(): if not isinstance(obj, FunctionType): # filter for function calls continue api_call_protos[name.name[0]] = obj mut: StructureBuilder = bv.get_type_by_name(struct_name).mutable_copy() for member_idx, member in enumerate(mut.members): for name, proto in api_call_protos.items(): if name.lower() not in member.name.lower(): continue # replace the prototype proto_pointer = PointerType.create(bv.arch, proto) mut.replace(member_idx, proto_pointer, member.name) break bv.define_user_type(struct_name, mut) -
psifertex revised this gist
Sep 20, 2023 . 1 changed file with 1 addition and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,5 +19,4 @@ def c_source(bv, func): lines += str(line) + '\n' return lines print(c_source(bv, current_function)) -
psifertex revised this gist
Sep 20, 2023 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,7 @@ for repo in repos: html += f'''$(document).ready( function () {{ $('#{repo}').DataTable({{ "paging": false, "info": false, "searching": false, "order": [[2, "desc"], [0, "asc"]] @@ -43,7 +43,7 @@ ''' for repo in ["community", "official"]: html += f'''<h3>{repo.capitalize()} Plugins</h3> <table id="{repo}" class="sortable" cellspacing="0" width="100%"> <thead> <tr> @@ -68,7 +68,7 @@ html += f'''</tbody> </table> <hr /> ''' html += ''' </div> -
psifertex revised this gist
Sep 20, 2023 . 1 changed file with 2 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,3 @@ # Highlight with theme-aware colors any "dangerous" functions: # Note that prefixed versions like "_system" will not be highlighted using this sample code. @@ -10,9 +8,10 @@ for fnname in dangerous + sus: if fnname in dangerous: color = HighlightStandardColor.RedHighlightColor if fnname in sus: color = HighlightStandardColor.OrangeHighlightColor for sym in bv.get_symbols_by_name(fnname): for ref in bv.get_code_refs(sym.address): log_info(f"Highlighting dangerous call at {hex(ref.address)}") ref.function.set_user_instr_highlight(ref.address, color) -
psifertex revised this gist
Aug 22, 2023 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,6 +6,7 @@ def c_source(bv, func): lines = '' settings = DisassemblySettings() settings.set_option(DisassemblyOption.ShowAddress, False) settings.set_option(DisassemblyOption.WaitForIL, True) obj = lineardisassembly.LinearViewObject.language_representation(bv, settings) cursor_end = lineardisassembly.LinearViewCursor(obj) cursor_end.seek_to_address(func.highest_address) -
psifertex revised this gist
Jun 13, 2023 . 3 changed files with 21 additions and 2 deletions.There are no files selected for viewing
File renamed without changes.File renamed without changes.This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -44,10 +44,29 @@ def qicon(): button.setIcon(ico2) button.setText("PlayPause") msg_box.exec_() # Since Snippets now run on background threads, UI code needs to explicitly ensure that it is run on the main thread. #execute_on_main_thread(qpixmap2) #execute_on_main_thread(qpixmap) #execute_on_main_thread(basic) #execute_on_main_thread(qicon) from binaryninjaui import (UIAction, UIActionHandler) from binaryninja import log_info from PySide6.QtWidgets import QDialog, QLabel, QVBoxLayout def qd(context): dialog = QDialog(parent=context.widget) dialog.setWindowTitle("Hello Dialog") label = QLabel("Hello text") layout = QVBoxLayout() layout.addWidget(label) dialog.setLayout(layout) dialog.show() execute_on_main_thread_and_wait(lambda: qd(uicontext)) # Note: outside of snippets you would use: # UIAction.registerAction("Simple") # UIActionHandler.globalActions().bindAction("Simple", UIAction(qd)) # but snippets can provide the same UI context necessary to parent a QDialog -
psifertex revised this gist
May 21, 2023 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ # new file from selection # # Opens the current selections contents into a new file / new tab # To modify it for a new tab import tempfile from binaryninjaui import UIContext -
psifertex revised this gist
May 9, 2023 . 2 changed files with 32 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ # componentize cpp # # Using the components API to sort CPP symbols into class hierarchies def ___sortCPPSymbols(): bv.begin_undo_actions() cpp_comp = bv.get_component_by_path("C++ Classes") if not cpp_comp: cpp_comp = bv.create_component("C++ Classes") for func in bv.functions: if len(demangle_gnu3(bv.arch, func.name)[1]) < 2 or isinstance(demangle_gnu3(bv.arch, func.name)[1], str): continue namespace = demangle_gnu3(bv.arch, func.name)[1][0] comp = bv.get_component_by_path("C++ Classes/" + namespace) if comp is None: comp = bv.create_component(namespace, cpp_comp) comp.add_function(func) bv.commit_undo_actions() ___sortCPPSymbols() This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,14 @@ # componentize sections # # Using the components API to sort symbols in different sections into folders def ___sortSymbolsBySectionName(): bv.begin_undo_actions() for func in bv.functions: sects = bv.get_sections_at(func.start) for sect in sects: comp = bv.get_component_by_path(sect.name) if comp is None: comp = bv.create_component(sect.name) comp.add_function(func) bv.commit_undo_actions() ___sortSymbolsBySectionName() -
psifertex revised this gist
May 9, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,7 +5,7 @@ # build list of all unimplemented opcodes opcodes={} for f in bv.functions: for t in f.tags: # tuple of (arch, address, tag) data = t[2].data if "unimplemented" in data: opcode = data.split('"')[1] -
psifertex revised this gist
May 2, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ from binaryninja import log_info from PySide6.QtCore import QSettings settings = QSettings() history = settings.value("script/history") for line in history: log_info(line) -
psifertex revised this gist
May 2, 2023 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,7 +4,7 @@ import binaryninjaui #needed to load PySide from binaryninja import log_info from PySide6.QtCore import QSettings settings = QtCore.QSettings() history = settings.value("script/history") -
psifertex revised this gist
Mar 30, 2023 . 1 changed file with 3 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,11 +4,7 @@ # Use the command-palette (CMD/CTL-P) to find action descriptions # Not compatible with headless of course from binaryninjaui import UIContext action = "About..." execute_on_main_thread_and_wait(lambda: UIContext.activeContext().getCurrentActionHandler().executeAction(action)) -
psifertex revised this gist
Mar 27, 2023 . 1 changed file with 30 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,30 @@ # batch example # # Intended to be run from the CLI, not as a snippet # Remove these top lines to run headlessly (requires a commercial license) #!/usr/bin/env python3 import binaryninja import glob import filetype import os from tabulate import tabulate from collections import defaultdict binaryninja.disable_default_log() for file in glob.glob("./**/*", recursive=True): if os.path.isfile(file): guess = filetype.guess(file) if guess and guess.extension == "elf": print(f"Filename: {file}") try: with binaryninja.load(file, update_analysis=False) as bv: # Imports don't require analysis, otherwise remove update_analysis param syms = [] for sym in bv.get_symbols_of_type(binaryninja.SymbolType.ImportAddressSymbol): syms.append([sym.name, hex(sym.address)]) print(tabulate(syms, headers=["Import Name", "Offset"])) except: print("Invalid architecture.") print("\n") -
psifertex revised this gist
Mar 9, 2023 . 1 changed file with 29 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,29 @@ # show exports # # Open a new tab with a list of all exports, can be slow for extremely large files, modify to dump an external html for a perf improvement import time def genRow(sym, exportType): return f"<tr><td><a href=\"binaryninja:?expr={hex(sym.address)}\">{hex(sym.address)}</a></td><td>{sym.short_name}</td><td>{exportType}</td></tr>\n" begin = time.time() # [ Offset, Symbol, Type] html = "<h1>Exports</h1>\n\n" html += "<table><tr><th>Offset</th><th>Name</th><th>Type</th></tr>\n" html += f"<tr><td>{hex(bv.entry_point)}</td><td>{bv.entry_function.name}</td><td>Entry</td></tr>\n" for sym in bv.get_symbols_of_type(SymbolType.FunctionSymbol): if sym.binding == SymbolBinding.GlobalBinding: html += genRow(sym, "Export Function") for sym in bv.get_symbols_of_type(SymbolType.DataSymbol): if sym.binding == SymbolBinding.GlobalBinding: html += genRow(sym, "Export Data Var") html += "</table>" lines = len(html.split("\n")) generated=time.time() log_info(f"Lines: {lines}") log_info(f"Time: {generated - begin}") bv.show_html_report("Exports", html) render = time.time() log_info(f"Render: {render - generated }") -
psifertex revised this gist
Mar 7, 2023 . 1 changed file with 12 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,12 @@ # history dump # # Dump the entire history of the scripting console of this instance of Binary Ninja to the log import binaryninjaui #needed to load PySide from binaryninja import log_info from PySide6 import QSettings settings = QtCore.QSettings() history = settings.value("script/history") for line in history: log_info(line) -
psifertex revised this gist
Jan 31, 2023 . 1 changed file with 25 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,25 @@ # make const # # Make the selected variable const def make_const(token, fn): if token.localVarValid: var = Variable.from_core_variable(fn, token.localVar) varType = var.type.mutable_copy() if isinstance(varType, PointerBuilder): print("got here") varType.target.const = True else: varType.const = True var.type = varType print(f"Made {repr(var)} have type {repr(var.type)}") elif current_token.type == InstructionTextTokenType.CodeSymbolToken: #TODO pass else: log_warn("Unhandled token") if not current_token or not current_function: log_warn("No valid variable token selected") else: make_const(current_token, current_function) -
psifertex revised this gist
Jan 16, 2023 . 1 changed file with 5 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -45,8 +45,9 @@ def qicon(): button.setText("PlayPause") msg_box.exec_() # Since Snippets now run on background threads, UI code needs to explicitly ensure that it is run on the main thread. #execute_on_main_thread(qpixmap2) #execute_on_main_thread(qpixmap) #execute_on_main_thread(basic) execute_on_main_thread(qicon) -
psifertex revised this gist
Oct 18, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ # Bare-bones script with no error checking to load a .map file created by IDA import re pattern = re.compile(r"\d+:([0-9A-Fa-f]+)\s+(.+)$") mapfile = get_open_filename_input("map file:", "All Files (*)") if mapfile is not None and os.access(mapfile, os.R_OK): with open(mapfile, "r+", encoding="utf-8") as f: -
psifertex revised this gist
Oct 18, 2022 . 1 changed file with 19 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,19 @@ # load ida map # # Bare-bones script with no error checking to load a .map file created by IDA import re pattern = re.compile(r"\d+:([0-9A-Fa-f]+)\s+(.+)") mapfile = get_open_filename_input("map file:", "All Files (*)") if mapfile is not None and os.access(mapfile, os.R_OK): with open(mapfile, "r+", encoding="utf-8") as f: for line in f.readlines(): matching = pattern.search(line) if not matching: continue addr = int(matching.group(1), 16) fnname = matching.group(2) if bv.get_function_at(addr): bv.define_user_symbol(Symbol(SymbolType.FunctionSymbol, addr, fnname)) else: bv.define_user_symbol(Symbol(SymbolType.DataSymbol, addr, fnname)) -
psifertex revised this gist
Oct 17, 2022 . 4 changed files with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,5 +10,5 @@ # Alternate implementation that copies as a file offset (requires above lines #offset=s.data_offset + offset clip = PySide6.QtGui.QGuiApplication.clipboard() clip.setText('%x' % (fileoffset)) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,7 +3,7 @@ # Snippet that generates https://docs.binary.ninja/getting-started.html#all-settings import json from PySide6.QtGui import QGuiApplication settings = json.loads(binaryninja.Settings().serialize_schema()) table = """|Category|Setting|Description|Type|Default|Scope|Key| |---|---|---|---|---|---|---| This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,5 +4,5 @@ dword = int.from_bytes(bv.read(here, 4), "big" if bv.endianness == Endianness.BigEndian else "little") clip = PySide6.QtGui.QGuiApplication.clipboard() clip.setText('%x' % (dword)) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,7 @@ # Simple PySide UI elements/testing # import binaryninjaui from PySide6 import QtWidgets, QtGui, QtWidgets, QtCore def basic(): popout = QtWidgets.QDialog() -
psifertex revised this gist
Sep 28, 2022 . 1 changed file with 23 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ # unlifted opcodes # # Script to summarize frequency of unlifted opcodes for a given binary # build list of all unimplemented opcodes opcodes={} for f in bv.functions: for t in f.address_tags: # tuple of (arch, address, tag) data = t[2].data if "unimplemented" in data: opcode = data.split('"')[1] if opcode in opcodes.keys(): opcodes[opcode].append(t[1]) else: opcodes[opcode] = [t[1]] # print them out, sorted by number of occurrences keys = list(opcodes.keys()) for key in sorted(opcodes, key=lambda x: len(opcodes[x]), reverse=True): if len(opcodes[key]) <= 5: print(f"{len(opcodes[key])}: {key}: [{', '.join(hex(x) for x in opcodes[key])}]") else: print(f"{len(opcodes[key])}: {key}: [{', '.join(hex(x) for x in opcodes[key][0:5])}, ...]") -
psifertex revised this gist
Sep 20, 2022 . 1 changed file with 18 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ # highlight dangerous calls # # Highlight with theme-aware colors any "dangerous" functions: # Note that prefixed versions like "_system" will not be highlighted using this sample code. dangerous = ["strcpy", "gets"] sus = ["printf", "system", "exec"] for fnname in dangerous + sus: if fnname in dangerous: color = HighlightStandardColor.RedHighlightColor if fname in sus: color = HighlightStandardColor.OrangeHighlightColor for sym in bv.get_symbols_by_name(fnname): for ref in bv.get_code_refs(sym.address): ref.function.set_user_instr_highlight(ref.address, color)
NewerOlder