Skip to main content
Glama
tools.py12.1 kB
from typing import Dict, List import binaryninja as bn import base64 import json def _get_function_blocks(function) -> List[Dict]: blocks = [] for block in function.basic_blocks: for instruction in block.disassembly_text: blocks.append( {"address": instruction.address, "instruction": str(instruction)} ) return blocks def get_functions(bv, cursor=None, limit=100): """Get functions in the current binary with cursor-based pagination Args: bv: Binary view cursor: Opaque pagination cursor (default: None for first page) limit: Maximum number of functions to return (default: 100) """ if not bv: return {"error": "No binary view available"} try: # Get all functions functions = list(bv.functions) if not functions: return {"error": "No functions found"} total_functions = len(functions) # Validate limit if limit <= 0: limit = 100 # Determine starting offset from cursor offset = 0 if cursor: try: # Decode cursor (base64-encoded JSON) cursor_data = json.loads(base64.b64decode(cursor).decode("utf-8")) offset = cursor_data.get("offset", 0) except Exception as e: return {"error": f"Invalid cursor: {str(e)}"} # Validate offset if offset < 0: offset = 0 elif offset >= total_functions: offset = max(0, total_functions - 1) # Apply pagination end_offset = min(offset + limit, total_functions) paginated_functions = functions[offset:end_offset] # Create next cursor if there are more results next_cursor = None if end_offset < total_functions: cursor_data = {"offset": end_offset} next_cursor = base64.b64encode( json.dumps(cursor_data).encode("utf-8") ).decode("utf-8") functions_list = [] for f in paginated_functions: functions_list.append( { "name": f.name, "address": f.start, "size": f.total_bytes, "address_ranges": str(f.address_ranges), } ) result = { "functions": functions_list, "total": total_functions, "count": len(functions_list), } # Add pagination metadata if next_cursor: result["nextCursor"] = next_cursor return result except Exception as e: return {"error": str(e)} def get_binary_info(bv): """Get binary information such as architecture, size, segments, etc.""" if not bv: return {"error": "No binary view available"} try: # Basic binary information info = { "file": { "filename": bv.file.filename, "file_size": bv.file.raw.length, "modified": bv.file.modified, }, "binary": { "view_type": bv.view_type, "arch": str(bv.arch), "platform": str(bv.platform), "entry_point": bv.entry_point, "start": bv.start, "end": bv.end, "length": bv.end - bv.start, "executable": bv.executable, "endianness": ( "little_endian" if bv.arch.endianness == bn.Endianness.LittleEndian else "big_endian" ), "address_size": bv.address_size, "function_count": len(list(bv.functions)), }, } # Segments information segments = [] for segment in bv.segments: segments.append( { "start": segment.start, "end": segment.end, "length": segment.length, "data_length": segment.data_length, "data_offset": segment.data_offset, "readable": segment.readable, "writable": segment.writable, "executable": segment.executable, } ) info["segments"] = segments # Sections information sections = [] for section in bv.sections.values(): sections.append( { "name": section.name, "start": section.start, "end": section.end, "length": section.length, "type": str(section.type), "align": section.align, "entry_size": section.entry_size, "linked_section": section.linked_section, "info_section": section.info_section, "semantics": str(section.semantics), } ) info["sections"] = sections return info except Exception as e: return {"error": str(e)} def get_function_assembly(bv, function_name): """Get function assembly code""" if not bv: return {"error": "No binary view available"} try: functions = bv.get_functions_by_name(function_name) if not functions: return {"error": f"Function '{function_name}' not found"} function = functions[0] blocks = _get_function_blocks(function) return { "function": function.name, "size": function.total_bytes, "start": function.start, "language_representation": "assembly", "blocks": blocks, } except Exception as e: return {"error": str(e)} def get_function_decompiled(bv, function_name): """Get function decompiled code""" if not bv: return {"error": "No binary view available"} try: functions = bv.get_functions_by_name(function_name) if not functions: return {"error": f"Function '{function_name}' not found"} function = functions[0] hlil = function.hlil if not hlil: return {"error": "Failed to get HLIL for function"} return { "function": function.name, "size": function.total_bytes, "start": function.start, "language_representation": "High Level Intermediate Language", "blocks": _get_function_blocks(hlil), } except Exception as e: return {"error": str(e)} def get_symbols_by_name(bv, symbol_name): if not bv: return {"error": "No binary view available"} try: symbols = bv.get_symbols_by_name(symbol_name) if not symbols: return {"error": f"Global variable '{symbol_name}' not found"} symbols_info = [] for symbol in symbols: symbols_info.append( { "name": symbol.name, "address": f"{symbol.address:#x}", "type": str(symbol.type) if hasattr(symbol, "type") else "unknown", } ) return {"symbols": symbols_info} except Exception as e: return {"error": str(e)} def get_current_function_assembly(bv): if not bv: return {"error": "No binary view available"} try: # Get current function functions = bv.get_functions_containing(bv.offset) if not functions: return {"error": "No function at current position"} current_function = functions[0] blocks = _get_function_blocks(current_function) return { "function": current_function.name, "size": current_function.total_bytes, "start": current_function.start, "language_representation": "assembly", "blocks": blocks, } except Exception as e: return {"error": str(e)} def get_current_function_decompiled(bv): """Get decompiled code of current function""" if not bv: return {"error": "No binary view available"} try: # Get current function functions = bv.get_functions_containing(bv.offset) if not functions: return {"error": "No function at current position"} current_function = functions[0] # Get decompiled code (HLIL) hlil = current_function.hlil if not hlil: return {"error": "Failed to get HLIL for function"} return { "function": current_function.name, "size": current_function.total_bytes, "start": current_function.start, "language_representation": "High Level Intermediate Language", "blocks": _get_function_blocks(hlil), } except Exception as e: return {"error": str(e)} def rename_function(bv, function_name, new_name): """Rename a function""" if not bv: return {"error": "No binary view available"} try: functions = bv.get_functions_by_name(function_name) if not functions: return {"error": f"Function '{function_name}' not found"} function = functions[0] except Exception as e: return {"error": str(e)} bv.navigate(bv.view, function.start) function.name = new_name return {"success": f"Function '{function_name}' renamed to '{new_name}'"} def rename_current_function(bv, new_name): """Rename the current function""" if not bv: return {"error": "No binary view available"} functions = bv.get_functions_containing(bv.offset) if not functions: return {"error": "No function at current position"} function = functions[0] old_name = function.name function.name = new_name return {"success": f"Function '{old_name}' renamed to '{new_name}'"} def rename_function_variable(bv, function_name, variable_name, new_name): """Rename a variable in specified function""" if not bv: return {"error": "No binary view available"} functions = bv.get_functions_by_name(function_name) if not functions: return {"error": f"Function '{function_name}' not found"} function = functions[0] bv.navigate(bv.view, function.start) variable = function.get_variable_by_name(variable_name) if not variable: return { "error": f"Variable '{variable_name}' not found in function '{function_name}'" } variable.name = new_name return { "success": f"Variable '{variable_name}' in function '{function_name}' renamed to '{new_name}'" } def set_function_variable_type(bv, function_name, variable_name, new_type): """Set the type of a variable in specified function""" if not bv: return {"error": "No binary view available"} functions = bv.get_functions_by_name(function_name) if not functions: return {"error": f"Function '{function_name}' not found"} function = functions[0] bv.navigate(bv.view, function.start) variable = function.get_variable_by_name(variable_name) if not variable: return { "error": f"Variable '{variable_name}' not found in function '{function_name}'" } variable.set_type_async(new_type) function.reanalyze() return { "success": f"Variable '{variable_name}' in function '{function_name}' type set to '{new_type}'" } def set_comment_at(bv, address, comment): """Set a comment at a specific address""" if not bv: return {"error": "No binary view available"} if isinstance(address, str): if address.startswith("0x"): address = int(address, 16) else: address = int(address) bv.navigate(bv.view, address) try: bv.set_comment_at(address, comment) return {"success": f"Comment set at address {address:#x}"} except Exception as e: return {"error": str(e)}

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rsprudencio/binja_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server