Skip to main content
Glama

BinAssistMCP

by jtang613
utils.py6.02 kB
""" Utility functions for BinAssistMCP This module provides common utility functions used across the project. """ from pathlib import Path from typing import Optional from .logging import log try: import binaryninja as bn BINJA_AVAILABLE = True except ImportError: BINJA_AVAILABLE = False def extract_binary_name(binary_view) -> str: """Extract a clean name from a Binary Ninja BinaryView Args: binary_view: Binary Ninja BinaryView object Returns: Clean name string suitable for use as an identifier """ if not BINJA_AVAILABLE or not binary_view: return "unknown" try: # Try to get filename from the file object if hasattr(binary_view, 'file') and hasattr(binary_view.file, 'filename'): filename = binary_view.file.filename if filename: return Path(filename).name # Try to get name directly from binary view if hasattr(binary_view, 'name') and binary_view.name: return binary_view.name # Try to get name from file object if hasattr(binary_view, 'file') and hasattr(binary_view.file, 'original_filename'): original_filename = binary_view.file.original_filename if original_filename: return Path(original_filename).name except Exception as e: log.log_debug(f"Failed to extract name from binary view: {e}") return "unknown" def sanitize_identifier(name: str) -> str: """Sanitize a name to be safe for use as an identifier Args: name: Input name string Returns: Sanitized name safe for use in URLs, filenames, etc. """ if not name or not isinstance(name, str): return "unnamed" # Replace problematic characters invalid_chars = '/\\:*?"<>| \t\n\r' for char in invalid_chars: name = name.replace(char, '_') # Remove leading/trailing dots and underscores name = name.strip('_.') # Ensure non-empty result if not name: name = "unnamed" # Ensure it starts with a letter or underscore (identifier rules) if name and not (name[0].isalpha() or name[0] == '_'): name = f"bin_{name}" return name def format_address(address: int, width: Optional[int] = None) -> str: """Format an address as a hex string Args: address: Integer address width: Optional width for zero-padding Returns: Formatted hex address string """ if width: return f"0x{address:0{width}x}" else: return f"0x{address:x}" def parse_address(address_str: str) -> Optional[int]: """Parse an address string to integer Args: address_str: Address string (hex or decimal) Returns: Integer address or None if parsing fails """ if not address_str: return None try: # Try hex format first if address_str.startswith('0x') or address_str.startswith('0X'): return int(address_str, 16) # Try decimal format if address_str.isdigit(): return int(address_str) # Try pure hex without prefix return int(address_str, 16) except ValueError: log.log_debug(f"Failed to parse address: {address_str}") return None def format_size(size_bytes: int) -> str: """Format a size in bytes to human-readable format Args: size_bytes: Size in bytes Returns: Human-readable size string """ if size_bytes < 1024: return f"{size_bytes} B" elif size_bytes < 1024 * 1024: return f"{size_bytes / 1024:.1f} KB" elif size_bytes < 1024 * 1024 * 1024: return f"{size_bytes / (1024 * 1024):.1f} MB" else: return f"{size_bytes / (1024 * 1024 * 1024):.1f} GB" def truncate_string(text: str, max_length: int = 100, suffix: str = "...") -> str: """Truncate a string to a maximum length Args: text: Input text max_length: Maximum length suffix: Suffix to add when truncating Returns: Truncated string """ if not text or len(text) <= max_length: return text return text[:max_length - len(suffix)] + suffix def safe_get_attribute(obj, attr_path: str, default=None): """Safely get a nested attribute from an object Args: obj: Object to get attribute from attr_path: Dot-separated attribute path (e.g., "file.filename") default: Default value if attribute not found Returns: Attribute value or default """ try: attrs = attr_path.split('.') result = obj for attr in attrs: if hasattr(result, attr): result = getattr(result, attr) else: return default return result except Exception: return default def validate_binary_view(binary_view) -> bool: """Validate that a binary view is usable Args: binary_view: Binary Ninja BinaryView object Returns: True if valid, False otherwise """ if not BINJA_AVAILABLE or not binary_view: return False try: # Try to access basic properties _ = binary_view.file _ = binary_view.start _ = binary_view.end return True except Exception as e: log.log_debug(f"Binary view validation failed: {e}") return False def ensure_absolute_path(path: str) -> Path: """Ensure a path is absolute Args: path: Input path string Returns: Absolute Path object """ path_obj = Path(path) if path_obj.is_absolute(): return path_obj else: return Path.cwd() / path_obj

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/jtang613/BinAssistMCP'

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