Work with functions, basic blocks, and disassembly in Binary Ninja
The Function class represents a function in a binary. It provides access to basic blocks, IL representations, variables, calling conventions, and more.
# Get IL representationsllil = func.llil # Low Level ILmlil = func.mlil # Medium Level IL hlil = func.hlil # High Level IL# SSA formsllil_ssa = func.llil.ssa_formmlil_ssa = func.mlil.ssa_formhlil_ssa = func.hlil.ssa_form# Get IL at specific addressllil_instr = func.get_low_level_il_at(0x401000)mlil_instr = func.get_medium_level_il_at(0x401000)hlil_instr = func.get_high_level_il_at(0x401000)
# Get all variablesfor var in func.vars: print(f"{var.name}: {var.type}")# Get parametersfor param in func.parameter_vars: print(f"Parameter: {param.name}: {param.type}")# Rename variablevar = func.vars[0]var.name = "buffer"# Set variable typevar.type = Type.array(Type.char(), 256)# Access variable propertiesprint(f"Source type: {var.source_type}")print(f"Storage: {var.storage}")
# Get callersfor caller_ref in func.callers: caller = caller_ref.function print(f"Called from {caller.name} @ {caller_ref.address:#x}")# Get callees for callee in func.callees: print(f"Calls {callee.name} @ {callee.start:#x}")# Call sitesfor call_site in func.call_sites: print(f"Call at {call_site.address:#x}")
# Get code references TO this functionfor ref in func.code_refs: print(f"Referenced from {ref.address:#x}") if ref.function: print(f" in function {ref.function.name}")# Get code references FROM this function for addr in func.code_refs_from: print(f"References {addr:#x}")
from binaryninja.function import DisassemblySettingsfrom binaryninja.enums import DisassemblyOption# Create settingssettings = DisassemblySettings()settings.set_option(DisassemblyOption.ShowAddress, True)settings.set_option(DisassemblyOption.ShowVariableTypes, True)settings.width = 80# Get disassembly textfor block in func: for line in block.get_disassembly_text(settings): print(line)
# Via basic blocksfor block in func: for instr_tokens, addr in block: instr_text = ''.join(t.text for t in instr_tokens) print(f"{addr:#x}: {instr_text}")# Via LLILfor block in func.llil: for instr in block: print(f"{instr.address:#x}: {instr}")
# HLIL instructionsfor instr in func.hlil.instructions: print(instr) # Access operands for operand in instr.operands: if isinstance(operand, HighLevelILInstruction): print(f" Operand: {operand}")# MLIL instructionsfor instr in func.mlil.instructions: # Check instruction type from binaryninja.commonil import Constant, Call if isinstance(instr, Call): print(f"Call to {instr.dest}") elif isinstance(instr, Constant): print(f"Constant: {instr.value}")
from binaryninja import AdvancedILFunctionList# Parallel IL generation (50-75% faster)for func in AdvancedILFunctionList(bv, preload_limit=400): analyze_hlil(func.hlil)# For subset of functionsinteresting_funcs = [f for f in bv.functions if 'crypt' in f.name]for func in AdvancedILFunctionList(bv, functions=interesting_funcs): process(func.mlil)
def find_dangerous_calls(bv): """Find calls to potentially dangerous functions.""" dangerous = ['strcpy', 'sprintf', 'gets', 'system', 'exec'] results = [] for func in bv.functions: for callee in func.callees: if any(d in callee.name.lower() for d in dangerous): # Find call sites for ref in callee.callers: if ref.function == func: results.append({ 'caller': func.name, 'callee': callee.name, 'address': ref.address }) return results# Usagefor result in find_dangerous_calls(bv): print(f"{result['caller']} calls {result['callee']} " f"at {result['address']:#x}")