intellicrack.bridges.ghidra

Ghidra bridge for static analysis and decompilation.

This module provides integration with Ghidra for advanced static analysis, decompilation, and reverse engineering capabilities using ghidra_bridge.

prepare_remote_script(code)[source]

Dedent a Jython script and rewrite it to capture its trailing result as a sentinel.

The Ghidra bridge transports user scripts to a remote Jython interpreter where they are run via Python’s exec(), which discards the value of any trailing expression statement. This helper rewrites such scripts so the trailing result is preserved on the remote interpreter as a uniquely named global variable, suitable for retrieval via a follow-up remote_eval.

Two shapes are recognised:

  • The final top-level statement is a bare expression (ast.Expr), such as a trailing variable reference or literal. It is rewritten in place into an assignment to the sentinel, preserving evaluation order and side effects exactly.

  • The final top-level statement is an if/else chain or a try block whose tail, on every reachable path, assigns the same single variable (see _find_trailing_result_name()). A sentinel = <variable> assignment is appended after the script so that variable’s final value is captured without altering the script’s original control flow.

Parameters:

code (str) – Jython source as authored at the call site.

Returns:

Tuple of (rewritten Jython source, sentinel variable name or None when no trailing result could be captured).

Return type:

tuple[str, str | None]

Raises:

ToolError – If the Jython source fails to parse.

class GhidraBridge[source]

Bases: _GhidraBridgeAnalysisMixin

Bridge for Ghidra reverse engineering suite.

Composed from the _GhidraBridgeBase core class together with topical mixin classes that inherit linearly so cross-references resolve through normal MRO. Each mixin groups one surface area (core lifecycle and binary loading, bookmarking and structure editing, call-tree analysis and references) so no single class definition exceeds the public method limit. The final class exposes the full Ghidra feature set including call-tree exploration, decompiler configuration, program metadata, external references, thunk handling, and bookmark/label management.

async shutdown()[source]

Shutdown Ghidra and cleanup resources.

Closes the active ghidra_bridge RPC client (preventing socket leaks), terminates the headless subprocess, closes the kill-on-close job object handle created for it in start_headless(), joins the stdout/stderr drain threads, and removes the bridge script under a process-wide lock to prevent races with concurrent start_headless invocations.

Return type:

None

async get_function_body(address)[source]

Get address ranges, thunk status, and size for a function.

Parameters:

address (int) – Address within the function.

Returns:

Dict with name, address, is_thunk, thunked_function, ranges, and total_size.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async get_call_tree(address, direction='callees', depth=3)[source]

Get recursive call tree for callees, callers, or both.

Parameters:
  • address (int) – Root function address.

  • direction (str) – Tree direction: ‘callees’, ‘callers’, or ‘both’.

  • depth (int) – Maximum recursion depth.

Returns:

Recursive call tree dict with function, address, direction, and children.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async get_calling_conventions()[source]

List all calling conventions defined in the compiler spec.

Returns:

List of calling convention name strings.

Return type:

list[str]

Raises:

ToolError – If Ghidra is not connected.

async get_instruction_flow(address)[source]

Get control flow information for a single instruction.

Parameters:

address (int) – Instruction address.

Returns:

Dict with address, mnemonic, flow_type, fall_through, and flows.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async get_instruction_pcode(address)[source]

Get raw per-instruction P-code ops, independent of decompilation.

Reads P-code directly off the Instruction object in the Listing via Instruction.getPcode(), so it is available even when full decompilation fails, times out, or the function has no recognized boundaries at all.

Parameters:

address (int) – Instruction address.

Returns:

Dict with address, mnemonic, and a list of raw P-code operation dicts (opcode, mnemonic, output, inputs).

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async disassemble_range(start_address, end_address)[source]

Convert undefined bytes into instructions over an address range.

Wraps Ghidra’s DisassembleCommand, the programmatic form of the Listing’s “Disassemble” (D) action, following flows the same way the GUI action does.

Parameters:
  • start_address (int) – Start of the range to disassemble.

  • end_address (int) – End of the range to disassemble (inclusive).

Returns:

Dict with start, end, instructions_created, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the command is rejected by Ghidra.

async clear_code_bytes(start_address, end_address)[source]

Undefine instructions back to raw bytes over an address range.

Wraps Listing.clearCodeUnits, the programmatic form of the Listing’s “Clear Code Bytes” (C) action. Clearing an already-undefined range is a harmless no-op in Ghidra, so this still reports success in that case.

Parameters:
  • start_address (int) – Start of the range to clear.

  • end_address (int) – End of the range to clear (inclusive).

Returns:

Dict with start, end, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the remote call fails.

async create_data_type(category, name, type_kind, fields=None)[source]

Create a new data type in the type manager.

Parameters:
  • category (str) – Category path (e.g. /MyTypes).

  • name (str) – Data type name.

  • type_kind (str) – Kind of data type: enum, union, typedef, or function_def.

  • fields (list[dict[str, Any]] | None) – Field definitions for enum/union (list of dicts with name and value/type/size).

Returns:

Dict with name, kind, size, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or type creation fails.

async get_data_type_tree(category_path=None, max_depth=32)[source]

Browse the full Data Type Manager tree: categories and every data type kind.

Unlike get_structures(), which only surfaces structures via DataTypeManager.getAllStructures(), this walks the category tree itself (Category.getCategories()/ Category.getDataTypes()) so enums, unions, typedefs, and function-definitions are included alongside structures.

Parameters:
  • category_path (str | None) – Category path to root the browse at (e.g. /MyTypes); omit for the DTM root category.

  • max_depth (int) – Maximum recursion depth into subcategories.

Returns:

Recursive dict of categories, subcategories, and data types of every kind.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or category_path does not name an existing category.

async import_c_header(header_path, include_paths=None)[source]

Parse a C header file and add its declared types to the program’s data type manager.

Dispatches to Ghidra’s CParserUtils.parseHeaderFiles with the current program’s own DataTypeManager as the parse target, so every type the header declares is added directly to the open program instead of to a separate archive. The supplied path is lexically normalised and verified to exist as a regular file before any value is forwarded to Ghidra, and the parse runs inside a Ghidra transaction that is rolled back if parsing fails. A non-None result from parseHeaderFiles does not by itself mean the parse succeeded, so the returned CParseResults record’s own successful() accessor is read explicitly rather than treating “no exception raised” as success.

Parameters:
  • header_path (str) – Path to the .h file to parse.

  • include_paths (list[str] | None) – Additional include directories for the parser.

Returns:

Dict with path, types_added, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, header_path is empty, cannot be resolved, does not exist, is not a regular file, or Ghidra fails to parse the header.

async export_data_type_archive(archive_path)[source]

Export every data type in the program’s type manager to a new .gdt archive file.

Creates a new FileDataTypeManager archive and copies every data type from the current program’s own DataTypeManager into it via DataTypeManager.addDataType, then saves and closes the archive. The current program is never mutated by this operation (only read from), so no Ghidra transaction is opened against it; the archive’s own internal transaction handling inside addDataType/save() is sufficient.

Parameters:

archive_path (str) – Destination .gdt file path.

Returns:

Dict with path, types_exported, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the archive cannot be created, populated, or saved.

async import_data_type_archive(archive_path)[source]

Import every data type from an existing .gdt archive file into the program’s type manager.

Opens the archive read-only via FileDataTypeManager.openFileArchive and copies every data type it contains into the current program’s own DataTypeManager via addDataType. The copy runs inside a Ghidra transaction against the current program; the archive itself is opened read-only and is never written back to.

Parameters:

archive_path (str) – Source .gdt file path.

Returns:

Dict with path, types_imported, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the archive cannot be opened or read.

async create_data(address, data_type)[source]

Create a data item at an address using a named data type.

Parameters:
  • address (int) – Address to create data at.

  • data_type (str) – Data type name.

Returns:

Dict with address, type, size, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or creation fails.

async configure_analysis(analyzer_name, *, enabled, options=None)[source]

Enable or disable a Ghidra analyzer and optionally set options.

Parameters:
  • analyzer_name (str) – Analyzer name.

  • enabled (bool) – Whether to enable or disable the analyzer.

  • options (dict[str, Any] | None) – Optional dict of analyzer option overrides.

Returns:

Dict with analyzer, enabled, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or configuration fails.

async set_decompiler_options(simplification=None, max_instructions=None, *, extra=None)[source]

Configure decompiler simplification style and/or instruction limit.

Stores supplied values on the bridge instance so subsequent decompilation calls reuse the same configuration for the life of the session, or until overwritten by another call to this method. Passing None for a value leaves the previously stored value in place. Additional key/value options can be supplied via extra and are persisted and applied verbatim to DecompileOptions.setOption when present.

Parameters:
  • simplification (str | None) – Simplification style name (e.g. ‘normalize’, ‘jumptable’, ‘decompile’). When None the currently stored value is preserved.

  • max_instructions (int | None) – Maximum instructions per function for decompiler. When None the currently stored value is preserved.

  • extra (dict[str, Any] | None) – Optional dict of additional key/value decompiler options. Keys and values are merged into the persisted configuration and then applied to Ghidra.

Returns:

Dict with simplification, max_instructions, extra options, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or configuration fails.

property decompiler_options: dict[str, Any]

The persisted decompiler options configured on this bridge.

Returns:

Dict with simplification, max_instructions, and a copy of the extra options map.

Return type:

dict[str, Any]

async create_memory_block(name, start, size, permissions='r')[source]

Create a new initialized memory block.

Parameters:
  • name (str) – Block name.

  • start (int) – Start address.

  • size (int) – Block size in bytes.

  • permissions (str) – Permission string using r/w/x characters.

Returns:

Dict with name, start, size, permissions, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or block creation fails.

async remove_memory_block(name)[source]

Remove a memory block from the program.

Parameters:

name (str) – Name of the memory block to remove.

Returns:

Dict with name and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, no block with name exists, or the removal fails.

async split_memory_block(name, split_address)[source]

Split a memory block into two blocks at an address.

The original block is truncated to end just before split_address, and a new block covering the remainder is created by Ghidra’s Memory.split.

Parameters:
  • name (str) – Name of the memory block to split.

  • split_address (int) – Address at which to split the block. This address becomes the start of the new (second) block.

Returns:

Dict with name, split_address, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, no block with name exists, split_address is not inside the block, or the split fails.

async move_memory_block(name, new_start)[source]

Move a memory block to a different start address.

Parameters:
  • name (str) – Name of the memory block to move.

  • new_start (int) – New start address for the block.

Returns:

Dict with name, new_start, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, no block with name exists, or the move fails (e.g. the target range overlaps an existing block).

async rename_memory_block(name, new_name)[source]

Rename an existing memory block.

Parameters:
  • name (str) – Current name of the memory block.

  • new_name (str) – New name for the block.

Returns:

Dict with name, previous_name, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, no block with name exists, or the rename fails (e.g. renaming an overlay block without exclusive access).

async set_memory_block_comment(name, comment)[source]

Set or replace the comment on an existing memory block.

Parameters:
  • name (str) – Name of the memory block.

  • comment (str) – Comment text to set on the block.

Returns:

Dict with name, comment, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, no block with name exists, or setting the comment fails.

async join_memory_blocks(name1, name2)[source]

Join two contiguous memory blocks into one.

Parameters:
  • name1 (str) – Name of the first (lower-addressed) memory block.

  • name2 (str) – Name of the second (higher-addressed) memory block.

Returns:

Dict with the joined block name and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, either block does not exist, or the join fails (e.g. blocks are not contiguous or compatible).

async get_comments(address, range_size=256)[source]

Get all comments in an address range.

Parameters:
  • address (int) – Start address.

  • range_size (int) – Number of bytes to scan.

Returns:

List of comment dicts with address, type, and comment text.

Return type:

list[dict[str, Any]]

Raises:

ToolError – If Ghidra is not connected.

async get_all_comments()[source]

Get all comments in the entire program.

Returns:

List of comment dicts with address, type, and comment text.

Return type:

list[dict[str, Any]]

Raises:

ToolError – If Ghidra is not connected.

async create_program_tree(tree_name)[source]

Create an additional named program tree.

Wraps Listing.createRootModule(treeName). The new root module’s own name defaults to the program’s name (not tree_name) per the Ghidra API – tree_name is purely the tree’s identifier as used by Listing.getRootModule/ getTreeNames elsewhere in this bridge.

Parameters:

tree_name (str) – Name for the new program tree.

Returns:

Dict with tree_name, root_name, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, a tree with this name already exists, or tree creation otherwise fails.

async get_program_tree()[source]

Get the program tree module and fragment hierarchy.

Recursively walks every module under every root, returning the complete tree of submodules and fragments, plus each fragment’s address ranges so callers can navigate the layout without issuing additional RPC calls. A depth cap prevents runaway recursion on pathological inputs.

Returns:

Dict with trees list. Each tree has name and root (recursive module node). A module node has name, type (“module”), and children. A fragment node has name, type (“fragment”), and ranges (list of {start, end} offsets).

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the RPC fails.

async edit_program_tree(tree_name, operation, parent_module, child_name, new_name=None)[source]

Create, delete, rename, or reparent a module/fragment in a program tree.

Wraps ProgramModule.createModule, ProgramModule.createFragment, ProgramModule.reparent, ProgramModule.removeChild, and Group.setName to give write access to the program tree hierarchy that get_program_tree() only reads. move_child is implemented with ProgramModule.reparent, not ProgramModule.moveChild: the latter only reorders a child that is already directly under the module it is called on and never changes that child’s parent, so it cannot move a child across parents.

Parameters:
  • tree_name (str) – Name of the program tree to modify (as returned by get_program_tree’s trees[].name).

  • operation (str) – One of create_module, create_fragment, move_child, delete, or rename. create_module/create_fragment create child_name as a new child of parent_module. move_child looks up every module that currently parents the existing module or fragment named child_name (a child may legitimately have more than one parent in a program tree) and reparents it under parent_module, removing it from each of those other parents so it ends up a direct child of parent_module and nowhere else. delete removes the existing module or fragment named child_name from its direct parent parent_module. rename renames the existing module or fragment named child_name to new_name.

  • parent_module (str) – Name of the existing module that will contain (or already contains, for move_child/ delete) the child.

  • child_name (str) – Name of the module/fragment to create, move, delete, or rename.

  • new_name (str | None) – New name for the child when operation is rename; required for rename, unused otherwise.

Returns:

Dict with tree_name, operation, child_name, and success. Also includes new_name when operation is rename.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, operation is unrecognized, new_name is missing for rename, the tree does not exist, parent_module does not exist or names a fragment rather than a module, child_name does not exist, names parent_module itself, would create a cycle by moving a module under one of its own descendants, names the tree’s parentless root module, delete targets a non-empty module, or the mutation otherwise fails.

async get_properties(address)[source]

Get user-defined properties stored at an address.

Parameters:

address (int) – Address to query.

Returns:

Dict with address and properties map.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async diff_programs(other_program_path)[source]

Compare the current program with another program file.

Parameters:

other_program_path (str) – Path to the other program file.

Returns:

Dict with difference count and details list.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or comparison fails.

async set_color(address, color)[source]

Set a background color on a code unit at an address.

Uses Ghidra’s ColorizingService when available so the color participates in Ghidra’s persistent colorization store, falling back to an IntPropertyMap entry in the user property manager so the color survives reload even when no colorizing service is registered.

In headless mode (SystemUtilities.isInHeadlessMode() true), the IntPropertyMap fallback has no visual effect and no consumer in the Ghidra UI - it would be a silent no-op. This method therefore raises ToolError when the ColorizingService is not available and the bridge is running headless, instead of returning success: True.

Parameters:
  • address (int) – Address to colorize.

  • color (int) – RGB color as integer (0xRRGGBB).

Returns:

Dict with address, color, backend used, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, neither colorization backend can persist the color, or the bridge is running headless without an interactive ColorizingService.

async set_program_metadata(name=None, image_base=None)[source]

Set program name and/or image base address.

After Program.setName / Program.setImageBase return, the bridge re-queries getName() and getImageBase().getOffset() via remote_eval and verifies each requested change is observable on the live program.

Parameters:
  • name (str | None) – New program name, or None to leave unchanged.

  • image_base (int | None) – New image base address, or None to leave unchanged.

Returns:

Dict with name, image_base, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the write fails, or the readback does not reflect the requested changes.

async execute_script_with_params(code, params=None)[source]

Execute Jython code with a JSON params dict injected as a local variable.

Parameters:
  • code (str) – Jython code to execute in Ghidra.

  • params (dict[str, Any] | None) – Parameters injected as the ‘params’ variable in the script.

Returns:

String result of script execution.

Return type:

str

async get_thunk_info(address)[source]

Query thunk status and resolved target for a function.

Parameters:

address (int) – Function address.

Returns:

Dict with address, is_thunk, thunked_function, and thunked_address.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected.

async create_function_tag(name, comment='')[source]

Create a function tag in the program’s tag manager.

Parameters:
  • name (str) – Tag name.

  • comment (str) – Optional tag comment.

Returns:

Dict with name, comment, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the tag manager refuses to create the tag.

async set_function_tags(address, tag_name, operation)[source]

Add or remove a function tag on a specific function.

Parameters:
  • address (int) – Function entry address.

  • tag_name (str) – Name of the tag to add or remove.

  • operation (str) – One of add or remove.

Returns:

Dict with address, tag_name, operation, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, operation is unrecognized, the function is not found, or the mutation fails.

async get_function_tags(address=None)[source]

List function tags: every tag in the program, or one function’s tags.

Parameters:

address (int | None) – Function address to list tags for; omit to list every tag registered in the program’s tag manager.

Returns:

List of tag dicts with name and comment.

Return type:

list[dict[str, Any]]

Raises:

ToolError – If Ghidra is not connected.

async get_external_references(address)[source]

Get external (imported) references from an address.

Parameters:

address (int) – Address to query.

Returns:

List of external reference dicts with address, external_name, library, and type.

Return type:

list[dict[str, Any]]

Raises:

ToolError – If Ghidra is not connected.

async add_external_function(library, name, address=None)[source]

Add an external function to the external symbol table.

Parameters:
  • library (str) – Library name.

  • name (str) – Function name.

  • address (int | None) – Optional address to link the external function to.

Returns:

Dict with library, name, address, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or operation fails.

async create_overlay_space(name)[source]

Create a new overlay address space.

Parameters:

name (str) – Overlay space name.

Returns:

Dict with name and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or creation fails.

async add_bookmark(address, category, comment, bookmark_type='Note')[source]

Add a bookmark at an address (explicit mutator alias).

Mirrors create_bookmark() while wrapping the call in a Ghidra transaction so the mutation can be rolled back if the bookmark manager rejects the request.

Parameters:
  • address (int) – Address to bookmark.

  • category (str) – Bookmark category.

  • comment (str) – Bookmark comment text.

  • bookmark_type (str) – Bookmark type (Note, Analysis, Error, Warning, Info).

Returns:

Dict with address, category, comment, bookmark_type, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the RPC fails.

async remove_bookmark(address, category=None, bookmark_type=None)[source]

Remove one or more bookmarks at an address.

When category and/or bookmark_type are provided, only bookmarks matching those fields are removed. When both are None, every bookmark at the address is removed.

Parameters:
  • address (int) – Address whose bookmarks should be removed.

  • category (str | None) – Optional category filter.

  • bookmark_type (str | None) – Optional type filter.

Returns:

Dict with address, number of bookmarks removed, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the RPC fails, or no matching bookmark existed.

async add_label(address, name, *, primary=False)[source]

Add a new label at an address.

Parameters:
  • address (int) – Address for the label.

  • name (str) – Label name.

  • primary (bool) – When True the label is marked primary.

Returns:

Dict with address, name, primary flag, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the label cannot be created.

async remove_label(address, name)[source]

Remove a named label at an address.

Parameters:
  • address (int) – Address whose label should be removed.

  • name (str) – Label name to remove.

Returns:

Dict with address, name, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the RPC fails, or the label is not found.

async promote_symbol_to_primary(address, name)[source]

Promote an already-existing symbol at an address to primary.

Looks up the named symbol among every symbol already defined at address and calls Symbol.setPrimary() on it – the programmatic form of the Symbol Table window’s “Set Primary” action. Unlike add_label()’s creation-time primary=True flag, this method never creates a symbol; it only acts on one SymbolTable.getSymbols already returns.

Parameters:
  • address (int) – Address of the symbol.

  • name (str) – Name of the existing symbol to promote.

Returns:

Dict with address, name, already_primary, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the RPC fails, or no symbol named name exists at address.

async add_thunk(address, thunked_address)[source]

Mark a function as a thunk forwarding to another function.

Parameters:
  • address (int) – Address of the thunk function.

  • thunked_address (int) – Address of the target (thunked) function.

Returns:

Dict with address, thunked_address, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, either function does not exist, or the operation fails.

async remove_thunk(address)[source]

Clear the thunk relationship on a function.

Parameters:

address (int) – Address of the thunk function.

Returns:

Dict with address and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the function does not exist, or the function is not a thunk.

async add_external_reference(from_addr, library, name)[source]

Add an external reference from an address to a named symbol.

Parameters:
  • from_addr (int) – Source address of the external reference.

  • library (str) – External library name.

  • name (str) – External function or symbol name.

Returns:

Dict with from_addr, library, name, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected or the reference cannot be added.

async remove_external_reference(from_addr)[source]

Remove every external reference originating from an address.

Parameters:

from_addr (int) – Source address whose external references should be removed.

Returns:

Dict with from_addr, removed count, and success.

Return type:

dict[str, Any]

Raises:

ToolError – If Ghidra is not connected, the RPC fails, or no external references were present at the address.