# binary-ninja-mcp-analysis

Provides Binary Ninja IL documentation and MCP server usage guidance for binary analysis and reverse engineering

- **Kind:** skill
- **Source:** https://github.com/SpecterOps/skills
- **Page:** https://forefy.com/skills/30a3d23a-1378-432d-8eb0-bea27716614c
- **API (JSON + files):** https://forefy.com/api/asr/30a3d23a-1378-432d-8eb0-bea27716614c

---

## SKILL.md

---
name: binary-ninja-mcp-analysis
description: Provides Binary Ninja IL documentation and MCP server usage guidance for binary analysis and reverse engineering
license: MIT
metadata:
  author: xpn
  version: "0.1.0"
  category: security
---

# Binary Ninja Analysis Skill

## When to Use

Use this skill when working with Binary Ninja via the BinjaMCP server to analyze binaries. This includes:

- Loading and analyzing binary files (ELF, PE, Mach-O, etc.)
- Decompiling functions and understanding decompiler output
- Reading or interpreting Binary Ninja Intermediate Language (BNIL) output at any level (LLIL, MLIL, HLIL)
- Reverse engineering functions, understanding control flow, or tracing data flow
- Annotating binaries (renaming functions/variables, setting comments, applying types)
- Searching for strings, imports, exports, or cross-references
- Understanding the structure of a binary (sections, segments, symbols)

## When NOT to Use

Do not use this skill when the task does not involve binary analysis or reverse engineering with Binary Ninja. If you are writing Binary Ninja plugins in Python (not using the MCP server), this skill's MCP tool reference may not apply but the BNIL documentation is still relevant.

You must never use this skill unless the MCP server is available and the task involves interacting with Binary Ninja's analysis capabilities. If the task is purely theoretical or does not involve Binary Ninja, this skill is not appropriate.

## Runtime Requirements

Codex should be configured directly with a `mcp_servers.binary_ninja_mcp` entry for `fosdickio/binary_ninja_mcp`. Use `command = "npx"` and `args = ["-y", "binary-ninja-mcp", "--host", "localhost", "--port", "9009"]` unless the Binary Ninja plugin is listening elsewhere. This plugin does not install, start, or wrap the Binary Ninja MCP server. Verify the Binary Ninja MCP tools are visible under `/mcp` before using live analysis workflows.

## Terminology

- **BNIL** - Binary Ninja Intermediate Language. The family of ILs used by Binary Ninja.
- **LLIL** - Low Level IL. Closest to assembly; operates on registers, flags, and memory addresses.
- **MLIL** - Medium Level IL. Translates registers to variables, associates types, propagates constants.
- **HLIL** - High Level IL. Decompiler output with recovered control flow (if/while/for/switch).
- **SSA** - Static Single Assignment. IL form where each variable is written exactly once; versions track modifications.
- **BinaryView (bv)** - Top-level analysis object representing a loaded binary.
- **Function** - A function identified by Binary Ninja, accessed by its start address.
- **BasicBlock** - A straight-line sequence of instructions with one entry and one exit.
- **Cross-reference (xref)** - A reference from one address to another (code or data).

## MCP Server Overview

The BinjaMCP server exposes tools for interacting with Binary Ninja. Tools are grouped as:

| Category | Tools | Purpose |
|----------|-------|---------|
| Lifecycle | `load_binary`, `list_loaded_binaries`, `close_binary` | Load/manage binaries |
| Functions | `list_functions`, `search_functions`, `get_function_info`, `get_function_type` | Discover and inspect functions |
| IL / Decompilation | `decompile_function`, `get_hlil`, `get_mlil`, `get_llil`, `get_disassembly` | View code at different abstraction levels |
| Strings | `list_strings`, `search_strings` | Find string data |
| Cross-refs | `get_xrefs_to`, `get_xrefs_from`, `get_function_callers`, `get_function_callees` | Trace references and call graphs |
| Imports/Exports | `list_imports`, `search_imports`, `list_exports` | Inspect symbol tables |
| Structure | `list_sections`, `list_segments` | Understand binary layout |
| Annotation | `rename_function`, `rename_variable`, `set_comment`, `set_function_comment`, `set_function_type` | Annotate the binary |
| Variables/Data | `list_variables`, `list_data_variables`, `get_data_var_at`, `get_basic_blocks` | Inspect variables, globals, CFG |
| Raw Data | `read_bytes` | Read raw memory |

## Choosing an IL Level

- **HLIL** (`decompile_function` / `get_hlil`): Best for initial understanding. Recovers if/while/for/switch. Use for vulnerability analysis, logic review, and getting a high-level picture. Note: tree-based, so nested expressions can hide instructions.
- **MLIL** (`get_mlil`): Best for precise analysis. Variables have types, constants are propagated, call parameters are resolved. Less folding than HLIL so easier to iterate linearly. Preferred for data flow tracing.
- **LLIL** (`get_llil`): Best for low-level analysis. Shows register/flag operations, stack manipulation. Use when you need to understand exact instruction semantics or flag behavior.
- **Disassembly** (`get_disassembly`): Raw native instructions. Use when IL abstractions lose important detail (e.g., specific instruction encodings, alignment).

## Recommended Analysis Workflow

1. **Load**: `load_binary` to open the target
2. **Survey**: `list_functions` + `list_imports` + `list_strings` to understand scope
3. **Target**: `search_functions` or `search_strings` to find areas of interest
4. **Analyze**: `decompile_function` for initial understanding, then `get_mlil` or `get_llil` for precision
5. **Trace**: `get_xrefs_to` / `get_function_callers` to understand how a function is reached
6. **Annotate**: `rename_function`, `rename_variable`, `set_comment` to document findings
7. **Iterate**: Use cross-references and call graphs to follow the analysis deeper

## Context Efficiency Tips

- Use `search_functions` / `search_strings` / `search_imports` instead of listing everything
- Start with `decompile_function` (HLIL pseudo-C) before falling back to lower ILs
- Use `get_function_info` to get metadata (size, callers, callees) before reading full IL
- Use pagination (`offset`/`limit`) on `list_functions` and `list_strings` for large binaries
- Prefer `get_function_callers`/`get_function_callees` over raw xref queries for call graph analysis

## References

For detailed information on specific areas, consult the [Reference Index](./references/INDEX.md).

Key references:

* [Reference Index](./references/INDEX.md) - Master index of all documentation
* [BNIL Overview](./references/bnil-overview.md) - IL family overview, notation, and reading guide
* [LLIL Reference](./references/bnil-llil.md) - Low Level IL instruction set
* [MLIL Reference](./references/bnil-mlil.md) - Medium Level IL instruction set, variables, and types
* [HLIL Reference](./references/bnil-hlil.md) - High Level IL instruction set with control flow recovery
* [Important Concepts](./references/concepts.md) - BinaryView, IL walking, SSA, mapping between ILs
* [Cookbook](./references/cookbook.md) - Common analysis recipes and patterns
* [Annotations](./references/annotations.md) - Symbols, types, tags, and type application
* [MCP Tools Reference](./references/mcp-tools.md) - Complete reference for all BinjaMCP server tools

## agents

```

```

## agents/openai.yaml

```yaml
interface:
  display_name: Binary Ninja MCP Analysis
  short_description: "Analyze binaries with Binary Ninja IL and MCP tools."
  icon_small: ./assets/icon.svg
  icon_large: ./assets/icon.png
  brand_color: '#00B36B'
  default_prompt: Use $binary-ninja-mcp-analysis for this workflow.
policy:
  allow_implicit_invocation: true
```

## assets

```

```

## assets/icon.png

```

```

## assets/icon.svg

```

```

## references

```

```

## references/INDEX.md

# Reference Index

Master index of all Binary Ninja analysis reference documents.

| Document | Description | When to Reference |
|----------|-------------|-------------------|
| [BNIL Overview](./bnil-overview.md) | IL family hierarchy, reading notation (size specifiers, comparisons, macros), visitor APIs | When you need to understand IL output notation or decide which IL level to use |
| [LLIL Reference](./bnil-llil.md) | Complete Low Level IL instruction set grouped by category | When reading `get_llil` output or analyzing register/flag-level operations |
| [MLIL Reference](./bnil-mlil.md) | Complete Medium Level IL instruction set, Variable and Type object documentation | When reading `get_mlil` output or working with variables and types |
| [HLIL Reference](./bnil-hlil.md) | Complete High Level IL instruction set including control flow recovery | When reading `decompile_function` / `get_hlil` output |
| [Important Concepts](./concepts.md) | BinaryView, walking ILs, IL mapping, SSA, instruction vs expression index, analysis limits | When you need to understand core BN concepts or how ILs relate to each other |
| [Cookbook](./cookbook.md) | Common analysis recipes: navigation, IL access, call graphs, variables, xrefs, types | When you need patterns for common analysis tasks |
| [Annotations](./annotations.md) | Symbols, tags, types (creation and application), function signatures, data variables | When annotating binaries: renaming, typing, commenting |
| [MCP Tools Reference](./mcp-tools.md) | Complete reference for all BinjaMCP server tools with parameters and usage patterns | When you need to know what tools are available and how to call them |

## references/annotations.md

# Annotations Reference

## Symbols

Rename a function:
```python
func.name = "newName"
```

Create and apply a symbol:
```python
sym = Symbol(SymbolType.FunctionSymbol, addr, "myName")
bv.define_user_symbol(sym)
```

Symbol types:
| Type | Description |
|------|-------------|
| `FunctionSymbol` | Function in current binary |
| `ImportAddressSymbol` | Import Address Table entry |
| `ImportedFunctionSymbol` | Function not in current binary |
| `DataSymbol` | Data in current binary |
| `ImportedDataSymbol` | Data not in current binary |
| `ExternalSymbol` | External data/code |
| `LibraryFunctionSymbol` | Shared library function |
| `SymbolicFunctionSymbol` | Abstract function |
| `LocalLabelSymbol` | Local label |

## Tags

### Create a tag type
```python
bv.create_tag_type("Vulnerability", "!!")
```

### Data tags (at any address)
```python
bv.add_tag(addr, "Vulnerabilities", "buffer overflow")
```

### Function tags (labels entire function)
```python
func.add_tag("Important", "needs code-review")
```

### Address tags (labels specific instruction)
```python
func.add_tag("Bug", "off-by-one error", addr)
```

## Types

### Creating Types

**Via parser (convenient but slow):**
```python
bv.parse_type_string("uint64_t")  # returns (Type, name)
```

**Integer types:**
```python
Type.int(4)              # 4-byte signed
Type.int(8, False)       # 8-byte unsigned
```

**Pointer types:**
```python
Type.pointer(bv.arch, Type.int(4))
Type.pointer(bv.arch, Type.void(), const=True)
```

**Array types:**
```python
Type.array(Type.int(4), 10)  # array of 10 ints
```

**Function types:**
```python
Type.function(Type.void(), [])
Type.function(Type.int(4), [('buf', Type.pointer(bv.arch, Type.char())), ('len', Type.int(4))])
```

**Structures:**
```python
# Anonymous
Type.structure(members=[(Type.int(4), 'x'), (Type.int(4), 'y')])

# Named (registered with BinaryView)
bv.define_user_type('Point', Type.structure(members=[
    (Type.int(4), 'x'),
    (Type.int(4), 'y')
]))

# Reference a named type
ntr = Type.named_type_from_registered_type(bv, 'Point')
bv.define_user_type('Line', Type.structure(members=[
    (ntr, 'start'),
    (ntr, 'end')
]))
```

**Unions:**
```python
Type.structure(members=[(Type.int(4), 'i'), (Type.float(4), 'f')],
               type=StructureVariant.UnionStructureType)
```

**Enumerations:**
```python
Type.enumeration(members=[('NONE', 0), ('READ', 1), ('WRITE', 2)])
bv.define_user_type('Access', Type.enumeration(members=[('NONE', 0), ('READ', 1), ('WRITE', 2)]))
```

### Modifying Existing Types
```python
with Type.builder(bv, 'MyStruct') as s:
    s.append(Type.int(2))  # add new field
```

### Applying Types

**To a function:**
```python
func.type = Type.function(Type.void(), [])
```

**To a parameter:**
```python
func.parameter_vars[0].type = Type.pointer(bv.arch, Type.char())
```

**To a data variable:**
```python
bv.get_data_var_at(addr).type = Type.int(4)
# Or create one if none exists:
bv.define_user_data_var(addr, "char*")
```

### Accessing Types
```python
bv.types['Elf64_Header']                    # lookup by name
bv.get_type_by_name('Elf64_Header')         # alternative lookup
header = bv.get_data_var_at(bv.start)       # typed data variable
header['ident']['signature'].value           # access struct fields
```

### Named Type References

In Binary Ninja, struct/enum names are separate from definitions (like C). To reference a named type inside another type:
```python
ntr = Type.named_type_from_registered_type(bv, 'ExistingType')
# Use ntr as a member type in another struct
```

## Signature Libraries

Binary Ninja matches statically-compiled functions against signature libraries, auto-renaming matched functions. Signatures load from:
- `$INSTALL_DIR/signatures/$PLATFORM`
- `$USER_DIR/signatures/$PLATFORM`

The signature matcher runs automatically after analysis (configurable via `analysis.signatureMatcher.autorun`).

## references/bnil-hlil.md

# HLIL Instruction Reference

High Level IL is Binary Ninja's decompiler output. It recovers high-level language constructs (if/while/for/switch), folds expressions, and eliminates dead code. Tree-based with significant nesting.

## Key Differences from MLIL

1. **Control flow recovery** -- while, do-while, for, switch/case, break, continue
2. **Expression folding** -- multiple MLIL statements collapsed into single expressions
3. **No `.output` on HLIL_CALL** -- return values appear as `inst.right` of `HighLevelILVarInit` or `HighLevelILVarAssign`
4. **Struct fields and array indexing** -- `HLIL_STRUCT_FIELD`, `HLIL_ARRAY_INDEX`, `HLIL_DEREF_FIELD`

## Important: Tree Structure

HLIL is heavily tree-based. Naive iteration over top-level instructions will miss nested calls, comparisons, and operations. Use the `traverse` API or `visit` methods for thorough analysis.

## Control Flow

- `HLIL_JUMP` -- Branch to `dest` address
- `HLIL_CALL` -- Call `dest` with `params` (no `output` -- returns via assignment)
- `HLIL_TAILCALL` -- Tail call to `dest` with `params`
- `HLIL_SYSCALL` -- System call with `params`
- `HLIL_RET` -- Return to caller
- `HLIL_NORET` -- Unreachable code marker
- `HLIL_IF` -- Conditional: `condition` -> `true`/`false` branch
- `HLIL_GOTO` -- Branch to IL label
- `HLIL_WHILE` -- While loop
- `HLIL_DO_WHILE` -- Do-while loop
- `HLIL_FOR` -- For loop
- `HLIL_SWITCH` -- Switch statement
- `HLIL_CASE` -- Case within switch
- `HLIL_BREAK` -- Break from loop/switch
- `HLIL_CONTINUE` -- Continue to next loop iteration

## Variable Reads and Writes

- `HLIL_VAR_DECLARE` -- Declaration of `var`
- `HLIL_VAR_INIT` -- Initialize `dest` variable with `src` expression
- `HLIL_ASSIGN` -- Set `dest` to `src` expression
- `HLIL_ASSIGN_UNPACK` -- Destructuring assignment
- `HLIL_VAR` -- Variable reference
- `HLIL_VAR_PHI` -- PHI node for variable versions
- `HLIL_MEM_PHI` -- Memory PHI
- `HLIL_ADDRESS_OF` -- Address of variable `src`

## Memory Access

- `HLIL_DEREF` -- Dereference `src` (pointer read)
- `HLIL_DEREF_FIELD` -- Dereference with field offset
- `HLIL_STRUCT_FIELD` -- Access struct field
- `HLIL_ARRAY_INDEX` -- Array element access
- `HLIL_SPLIT` -- Split pair `high`:`low`

## Constants

- `HLIL_CONST` -- Constant integer
- `HLIL_CONST_DATA` -- Constant data reference
- `HLIL_CONST_PTR` -- Constant pointer
- `HLIL_EXTERN_PTR` -- External symbol pointer
- `HLIL_FLOAT_CONST` -- Floating point constant
- `HLIL_IMPORT` -- Imported address
- `HLIL_LOW_PART` -- `size` bytes from low end of `src`

## Arithmetic Operations

- `HLIL_ADD` / `HLIL_ADC` -- Add / Add with carry
- `HLIL_SUB` / `HLIL_SBB` -- Subtract / Subtract with borrow
- `HLIL_AND` / `HLIL_OR` / `HLIL_XOR` -- Bitwise AND/OR/XOR
- `HLIL_LSL` / `HLIL_LSR` / `HLIL_ASR` -- Shifts
- `HLIL_ROL` / `HLIL_ROR` / `HLIL_RLC` / `HLIL_RRC` -- Rotations
- `HLIL_MUL` / `HLIL_MULU_DP` / `HLIL_MULS_DP` -- Multiply
- `HLIL_DIVU` / `HLIL_DIVS` / `HLIL_DIVU_DP` / `HLIL_DIVS_DP` -- Divide
- `HLIL_MODU` / `HLIL_MODS` / `HLIL_MODU_DP` / `HLIL_MODS_DP` -- Modulus
- `HLIL_NEG` / `HLIL_NOT` -- Negate/Complement
- `HLIL_SX` / `HLIL_ZX` -- Sign/Zero extend
- `HLIL_ADD_OVERFLOW` -- Overflow of addition
- `HLIL_BOOL_TO_INT` -- Bool to integer

## Floating Point

- `HLIL_FADD` / `HLIL_FSUB` / `HLIL_FMUL` / `HLIL_FDIV` -- FP arithmetic
- `HLIL_FSQRT` / `HLIL_FNEG` / `HLIL_FABS` -- FP operations
- `HLIL_FLOAT_TO_INT` / `HLIL_INT_TO_FLOAT` / `HLIL_FLOAT_CONV` -- Conversions
- `HLIL_ROUND_TO_INT` / `HLIL_FLOOR` / `HLIL_CEIL` / `HLIL_FTRUNC` -- Rounding

## Comparisons

- `HLIL_CMP_E` / `HLIL_CMP_NE` -- Equal / Not equal
- `HLIL_CMP_SLT` / `HLIL_CMP_ULT` -- Signed/Unsigned less than
- `HLIL_CMP_SLE` / `HLIL_CMP_ULE` -- Signed/Unsigned less than or equal
- `HLIL_CMP_SGE` / `HLIL_CMP_UGE` -- Signed/Unsigned greater than or equal
- `HLIL_CMP_SGT` / `HLIL_CMP_UGT` -- Signed/Unsigned greater than
- `HLIL_TEST_BIT` -- Test if bit
- `HLIL_FCMP_E` / `HLIL_FCMP_NE` / `HLIL_FCMP_LT` / `HLIL_FCMP_LE` / `HLIL_FCMP_GE` / `HLIL_FCMP_GT`
- `HLIL_FCMP_O` (ordered) / `HLIL_FCMP_UO` (unordered)

## Miscellaneous

- `HLIL_NOP` -- No operation
- `HLIL_BP` -- Breakpoint
- `HLIL_TRAP` -- Trap with `vector`
- `HLIL_INTRINSIC` -- Architecture intrinsic
- `HLIL_UNDEF` -- Undefined behavior
- `HLIL_UNIMPL` / `HLIL_UNIMPL_MEM` -- Unimplemented
- `HLIL_BLOCK` -- Block of statements
- `HLIL_LABEL` -- Label target
- `HLIL_UNREACHABLE` -- Unreachable code

## references/bnil-llil.md

# LLIL Instruction Reference

Low Level IL is the closest IL to native assembly. Registers, flags, and memory operations are preserved. Instructions form expression trees -- operands can be composed of sub-operations.

Example tree for `eax = eax + ecx * 4`:
```
    =
   / \
 eax  +
     / \
   eax  *
       / \
     ecx  4
```

## Key Properties of LowLevelILInstruction

- `address` -- virtual address of the corresponding assembly instruction
- `instr_index` -- unique index of this IL instruction (distinct from address due to many-to-many mapping)
- `operation` -- enumeration value (e.g., `LowLevelILOperation.LLIL_SET_REG`)
- `operands` -- list of all operands
- `src` -- source operand
- `dest` -- destination operand
- `size` -- size of operation in bytes

## Registers, Constants & Flags

- `LLIL_REG` -- Register terminal
- `LLIL_CONST` -- Constant integer terminal
- `LLIL_SET_REG` -- Set register to result of `src` expression
- `LLIL_SET_REG_SPLIT` -- Set a pair of registers as one double-sized register
- `LLIL_SET_FLAG` -- Set flag to result of `src` expression

## Memory Load & Store

- `LLIL_LOAD` -- Load value from memory
- `LLIL_STORE` -- Store value to memory
- `LLIL_PUSH` -- Store to stack, adjust stack pointer by sizeof(value)
- `LLIL_POP` -- Load from stack, adjust stack pointer by sizeof(value)

## Control Flow & Conditionals

- `LLIL_JUMP` -- Branch to address from IL expression
- `LLIL_JUMP_TO` -- Jump table: expression + list of possible targets
- `LLIL_CALL` -- Call function at address from IL expression
- `LLIL_TAILCALL` -- Tail call with `dest`, `params`, `output`
- `LLIL_RET` -- Return to caller
- `LLIL_NORET` -- Marks unreachable code after non-returning call
- `LLIL_SYSCALL` -- System call
- `LLIL_IF` -- Conditional: if `condition` then true_label else false_label
- `LLIL_GOTO` -- Branch to IL label (not address)
- `LLIL_FLAG_COND` -- Flag condition expression

### Comparison Operations
- `LLIL_CMP_E` -- equal
- `LLIL_CMP_NE` -- not equal
- `LLIL_CMP_SLT` / `LLIL_CMP_ULT` -- signed/unsigned less than
- `LLIL_CMP_SLE` / `LLIL_CMP_ULE` -- signed/unsigned less than or equal
- `LLIL_CMP_SGE` / `LLIL_CMP_UGE` -- signed/unsigned greater than or equal
- `LLIL_CMP_SGT` / `LLIL_CMP_UGT` -- signed/unsigned greater than

## Arithmetic & Logical

- `LLIL_ADD` / `LLIL_ADC` -- Add / Add with carry
- `LLIL_SUB` / `LLIL_SBB` -- Subtract / Subtract with borrow
- `LLIL_AND` / `LLIL_OR` / `LLIL_XOR` -- Bitwise AND/OR/XOR
- `LLIL_LSL` / `LLIL_LSR` / `LLIL_ASR` -- Logical shift left/right, Arithmetic shift right
- `LLIL_ROL` / `LLIL_ROR` -- Rotate left/right
- `LLIL_RLC` / `LLIL_RRC` -- Rotate left/right with carry
- `LLIL_MUL` -- Multiply (single precision)
- `LLIL_MULU_DP` / `LLIL_MULS_DP` -- Unsigned/Signed multiply (double precision)
- `LLIL_DIVU` / `LLIL_DIVS` -- Unsigned/Signed divide (single precision)
- `LLIL_DIVU_DP` / `LLIL_DIVS_DP` -- Unsigned/Signed divide (double precision)
- `LLIL_MODU` / `LLIL_MODS` -- Unsigned/Signed modulus (single precision)
- `LLIL_MODU_DP` / `LLIL_MODS_DP` -- Unsigned/Signed modulus (double precision)
- `LLIL_NEG` -- Sign negation
- `LLIL_NOT` -- Bitwise complement
- `LLIL_TEST_BIT` -- Test if bit `right` is set in `left`
- `LLIL_BOOL_TO_INT` -- Convert bool to integer

## Floating Point

- `LLIL_FLOAT_CONST` -- FP constant
- `LLIL_FADD` / `LLIL_FSUB` / `LLIL_FMUL` / `LLIL_FDIV` -- FP arithmetic
- `LLIL_FSQRT` / `LLIL_FNEG` / `LLIL_FABS` -- FP square root/negate/absolute
- `LLIL_FLOAT_TO_INT` / `LLIL_INT_TO_FLOAT` / `LLIL_FLOAT_CONV` -- FP conversions
- `LLIL_ROUND_TO_INT` / `LLIL_FLOOR` / `LLIL_CEILING` / `LLIL_FTRUNC` -- FP rounding

### FP Comparisons
- `LLIL_FCMP_E` / `LLIL_FCMP_NE` / `LLIL_FCMP_LT` / `LLIL_FCMP_LE` / `LLIL_FCMP_GE` / `LLIL_FCMP_GT`
- `LLIL_FCMP_O` (ordered) / `LLIL_FCMP_UO` (unordered)

## Special Instructions

- `LLIL_NOP` -- No operation
- `LLIL_BP` -- Breakpoint
- `LLIL_TRAP` -- Trap/interrupt
- `LLIL_SX` -- Sign extend
- `LLIL_ZX` -- Zero extend
- `LLIL_LOW_PART` -- `size` bytes from the low end of `src`
- `LLIL_UNDEF` -- Undefined behavior
- `LLIL_UNIMPL` -- Unimplemented instruction
- `LLIL_UNIMPL_MEM` -- Unimplemented memory access
- `LLIL_EXTERN_PTR` -- Synthesized pointer to external data
- `LLIL_INTRINSIC` -- Architecture intrinsic (e.g., AES instructions) with `output`, `params`, `intrinsic`
- `LLIL_MEM_PHI` -- Memory PHI for SSA (memory modifications across basic block merges)

## references/bnil-mlil.md

# MLIL Instruction Reference

Medium Level IL translates registers to variables, associates types, resolves call parameters, propagates constants, and eliminates some dead code. Stack operations are abstracted away.

## Key Differences from LLIL

1. Registers are now **variables** (with names like `rax`, `var_260`)
2. Stack concept is removed -- stack accesses become variable references
3. Variables have **types** associated with them
4. Call sites have inferred **parameters** and **return values**
5. Constants are **propagated** through data flow
6. Some **dead code** is eliminated

## The Variable Object

Variables represent a single storage location within a function scope.

### Properties
- `source_type` -- Storage location: `StackVariableSourceType`, `RegisterVariableSourceType`, or `FlagVariableSourceType`
- `storage` -- For register vars: register index. For stack vars: stack offset.
- `index` -- Unique identifier across analysis passes
- `type` -- The `Type` object associated with this variable

### Variable Naming Convention
- `RegisterVariableSourceType` -> register name (e.g., `rax`, `rbx`)
- `StackVariableSourceType` -> `var_` + hex of negative stack offset (e.g., `var_260`)
- Reuse of a storage location appends a version counter (e.g., `rax_1`, `rax_2`)

## The Type System

Type objects have a `type_class` property from the `TypeClass` enumeration:

| TypeClass | Description |
|-----------|-------------|
| `VoidTypeClass` | Unknown/void type |
| `BoolTypeClass` | Boolean (0 or !0) |
| `IntegerTypeClass` | Integer with sign, width, display type |
| `FloatTypeClass` | IEEE754 floating point (up to 10 bytes) |
| `PointerTypeClass` | Pointer with `target`/`element_type` property |
| `ArrayTypeClass` | Array with `element_type`, `count`, `width` |
| `FunctionTypeClass` | Function with `return_value`, `parameters`, `calling_convention`, `can_return` |
| `StructureTypeClass` | Struct/class/union with `members` list (each has `name`, `offset`, `type`) |
| `EnumerationTypeClass` | Enumeration with `members` (each has `name`, `value`) |
| `NamedTypeReferenceClass` | Symbolic reference to another type (like C typedef) |
| `WideCharTypeClass` | Unicode character |
| `VarArgsTypeClass` | Variadic function parameter marker |
| `ValueTypeClass` | Constant value (used in demangling) |

All types have a `confidence` property used for type inference.

## Control Flow Instructions

- `MLIL_JUMP` -- Branch to `dest` address
- `MLIL_JUMP_TO` -- Jump table: `dest` expression + `targets` list
- `MLIL_CALL` -- Call `dest` with `params`, returning `output`
- `MLIL_CALL_UNTYPED` -- Call where stack resolution failed (no params/output list)
- `MLIL_TAILCALL` -- Tail call to `dest` with `params` and `output`
- `MLIL_TAILCALL_UNTYPED` -- Tail call without resolved params
- `MLIL_RET` -- Return to caller
- `MLIL_NORET` -- Unreachable (after non-returning call)
- `MLIL_IF` -- Conditional: `condition` -> `true`/`false` branch
- `MLIL_GOTO` -- Branch to IL instruction id
- `MLIL_SYSCALL` -- System call with `params` and `output`
- `MLIL_SYSCALL_UNTYPED` -- System call without resolved params
- `MLIL_CALL_OUTPUT` -- Return values `dest` from a call
- `MLIL_CALL_PARAM` -- Parameter set `src` for a call
- `MLIL_RET_HINT` -- Indirect jump (internal analysis only)

## Variable Reads and Writes

- `MLIL_SET_VAR` -- Set variable `dest` to expression `src`
- `MLIL_SET_VAR_FIELD` -- Set variable `dest` at `offset` to `src`
- `MLIL_SET_VAR_SPLIT` -- Set pair `high`:`low` to `src`
- `MLIL_SET_VAR_ALIASED` -- Set aliased variable `prev` to `src`
- `MLIL_SET_VAR_ALIASED_FIELD` -- Set field at `offset` of aliased variable
- `MLIL_VAR` -- Variable reference `src`
- `MLIL_VAR_FIELD` -- Variable + offset: `src`, `offset`
- `MLIL_VAR_SPLIT` -- Split pair `high`:`low` as single expression
- `MLIL_VAR_ALIASED` -- Aliased variable reference
- `MLIL_VAR_ALIASED_FIELD` -- Aliased variable field
- `MLIL_VAR_PHI` -- PHI node combining variable versions at block merge
- `MLIL_MEM_PHI` -- Memory PHI for memory modifications across paths
- `MLIL_LOAD` -- Read `size` bytes from memory address `src`
- `MLIL_LOAD_STRUCT` -- Read from struct: `src` + `offset`
- `MLIL_STORE` -- Store `src` to memory at `dest`
- `MLIL_STORE_STRUCT` -- Store to struct: `dest` + `offset` from `src`
- `MLIL_ADDRESS_OF` -- Address of variable `src`
- `MLIL_ADDRESS_OF_FIELD` -- Address of variable `src` at `offset`
- `MLIL_LOW_PART` -- `size` bytes from low end of `src`

## Constants

- `MLIL_CONST` -- Constant integer
- `MLIL_CONST_DATA` -- Constant data reference
- `MLIL_CONST_PTR` -- Constant used as pointer
- `MLIL_EXTERN_PTR` -- External symbol: `constant` + `offset`
- `MLIL_FLOAT_CONST` -- Floating point constant
- `MLIL_IMPORT` -- Imported address constant

## Arithmetic Operations

- `MLIL_ADD` / `MLIL_ADC` -- Add / Add with carry
- `MLIL_SUB` / `MLIL_SBB` -- Subtract / Subtract with borrow
- `MLIL_AND` / `MLIL_OR` / `MLIL_XOR` -- Bitwise AND/OR/XOR
- `MLIL_LSL` / `MLIL_LSR` / `MLIL_ASR` -- Shifts
- `MLIL_ROL` / `MLIL_ROR` / `MLIL_RLC` / `MLIL_RRC` -- Rotations
- `MLIL_MUL` / `MLIL_MULU_DP` / `MLIL_MULS_DP` -- Multiply (single/double precision)
- `MLIL_DIVU` / `MLIL_DIVS` / `MLIL_DIVU_DP` / `MLIL_DIVS_DP` -- Divide
- `MLIL_MODU` / `MLIL_MODS` / `MLIL_MODU_DP` / `MLIL_MODS_DP` -- Modulus
- `MLIL_NEG` / `MLIL_NOT` -- Negate/Complement
- `MLIL_SX` / `MLIL_ZX` -- Sign/Zero extend
- `MLIL_ADD_OVERFLOW` -- Overflow of addition
- `MLIL_BOOL_TO_INT` -- Bool to integer conversion

## Floating Point

- `MLIL_FADD` / `MLIL_FSUB` / `MLIL_FMUL` / `MLIL_FDIV` -- FP arithmetic
- `MLIL_FSQRT` / `MLIL_FNEG` / `MLIL_FABS` -- FP operations
- `MLIL_FLOAT_TO_INT` / `MLIL_INT_TO_FLOAT` / `MLIL_FLOAT_CONV` -- Conversions
- `MLIL_ROUND_TO_INT` / `MLIL_FLOOR` / `MLIL_CEIL` / `MLIL_FTRUNC` -- Rounding

## Comparisons

- `MLIL_CMP_E` / `MLIL_CMP_NE` -- Equal / Not equal
- `MLIL_CMP_SLT` / `MLIL_CMP_ULT` -- Signed/Unsigned less than
- `MLIL_CMP_SLE` / `MLIL_CMP_ULE` -- Signed/Unsigned less than or equal
- `MLIL_CMP_SGE` / `MLIL_CMP_UGE` -- Signed/Unsigned greater than or equal
- `MLIL_CMP_SGT` / `MLIL_CMP_UGT` -- Signed/Unsigned greater than
- `MLIL_TEST_BIT` -- Test if bit `right` is set in `left`
- `MLIL_FCMP_E` / `MLIL_FCMP_NE` / `MLIL_FCMP_LT` / `MLIL_FCMP_LE` / `MLIL_FCMP_GE` / `MLIL_FCMP_GT` -- FP comparisons
- `MLIL_FCMP_O` (ordered) / `MLIL_FCMP_UO` (unordered)

## Miscellaneous

- `MLIL_NOP` -- No operation
- `MLIL_BP` -- Breakpoint
- `MLIL_TRAP` -- Trap with `vector`
- `MLIL_INTRINSIC` -- Architecture intrinsic
- `MLIL_FREE_VAR_SLOT` -- Free register stack slot
- `MLIL_UNDEF` -- Undefined behavior
- `MLIL_UNIMPL` / `MLIL_UNIMPL_MEM` -- Unimplemented (with optional memory access)

## references/bnil-overview.md

# BNIL Overview

The Binary Ninja Intermediate Language (BNIL) is a family of tree-based, architecture-independent intermediate representations used throughout Binary Ninja.

## IL Hierarchy

The analysis pipeline lifts native instructions through progressively higher abstractions:

```
Native Assembly
  -> Lifted IL (raw translation from native semantics)
    -> LLIL (NOPs removed, flags folded into conditionals)
      -> LLIL SSA
        -> Mapped MLIL (translation layer, rarely needed)
          -> MLIL (registers -> variables, types, constants propagated)
            -> MLIL SSA
              -> HLIL (control flow recovery, dead code elimination, expression folding)
                -> HLIL SSA
```

Each layer can have different instructions -- an instruction present at one level may not exist at another.

## When to Use Each Level

| Level | Use When |
|-------|----------|
| **HLIL** | Understanding logic, vulnerability analysis, initial triage. Recovers if/while/for/switch. Tree-based with heavy folding. |
| **MLIL** | Precise data flow analysis. Variables have types, call parameters resolved, constants propagated. Less nesting than HLIL. |
| **LLIL** | Low-level semantics: register operations, flag behavior, stack manipulation. One-to-many mapping from assembly. |
| **Disassembly** | Raw instructions. Specific encodings, alignment, instruction-level detail. |

## Reading IL Notation

### Comparisons
All comparisons are explicitly signed or unsigned:
- `s<=`, `s>=`, `s<`, `s>` -- signed comparisons
- `u<=`, `u>=`, `u<`, `u>` -- unsigned comparisons

### Bitwise Operations
- `&&` -- standard bitwise operators
- `sx` -- sign-extend
- `zx` -- zero-extend

### Size Specifiers

Integer sizes:
- `.b` -- Byte (1 byte)
- `.w` -- Word (2 bytes)
- `.d` -- Dword (4 bytes)
- `.q` -- Qword (8 bytes)

Floating point sizes:
- `.h` -- Half (2 bytes)
- `.s` -- Single (4 bytes)
- `.d` -- Double (8 bytes)
- `.t` -- Ten (10 bytes)
- `.o` -- Oword (16 bytes)

Floating point operations are prefixed with `f`: `f*`, `f/`, `f+`, `f-`

### Variable Offsets
`:$offset` syntax indicates how many bits from the bottom of a variable the expression references.

Example: `sx.q(rax_2:0.d)` = lower 32 bits of variable `rax_2`, sign-extended to 64-bit.

### Macros

- `COMBINE(a, b)` -- Value twice the width, upper half `a`, lower half `b`. For 32-bit a,b: `(a << 32) | b`
- `LOWx(a)` -- Lower `x` bits of value `a` (size `2*x`). E.g., `LOWD(a)` = `a & 0xFFFFFFFF`
- `HIGHx(a)` -- Upper `x` bits of value `a`. E.g., `HIGHD(a)` = `a >> 32`
- `ROR(a, b)`, `ROL(a, b)` -- Rotate right/left value `a` by `b` bits
- `RRC(a, b)`, `RLC(a, b)` -- Rotate right/left with carry
- `TEST_BIT(a, b)` -- Test if bit `b` is set in `a`, equivalent to `(a & b) == b`
- `FCMP_O(a, b)` -- Floating point ordered comparison (both not NaN)
- `FCMP_UO(a, b)` -- Floating point unordered comparison (either is NaN)

## Using the API with ILs

### Checking Instruction Types
Use `isinstance()` with IL instruction classes:

```python
for h in current_hlil.instructions:
    if isinstance(h, Call):
        print(f"{h} is a Call")
    if isinstance(h, LocalCall):
        print(f"{h} has {len(h.params)} parameters")
```

### Visitors (for tree-based ILs)
Because BNIL is tree-based, naive iteration can miss nested expressions. Use visitor APIs:

- `visit` -- visits instructions only (not operands)
- `visit_all` -- visits instructions and their operands
- `visit_operands` -- visits operands only

Visitor callback receives: `(operand_name, inst, instr_type_name, parent)`

```python
def visitor(operand_name, inst, instr_type_name, parent):
    match inst:
        case Arithmetic(right=Constant()):
            print(f"{inst.address:#x} {inst}")

current_hlil.root.visit(visitor)
```

### Traverse API (HLIL)
The `traverse` API is preferred for HLIL pattern matching:

```python
def find_calls(i) -> int:
    match i:
        case HighLevelILCall():
            return len(i.params)

list(current_hlil.traverse(find_calls))
```

## references/concepts.md

# Important Concepts

## BinaryView

The top-level analysis object in Binary Ninja, representing a loaded binary. Think of it as what an OS does when loading an executable: memory mappings, sections, segments, functions, and metadata.

Key hierarchy: `BinaryView` -> `Function` -> `BasicBlock` -> `Instruction`

Some BinaryViews have parent views -- the analysis view includes memory mappings via segments/sections, while `parent_view` is the raw on-disk file.

## Walking ILs

### Iterating Instructions

LLIL and MLIL can be iterated linearly with reasonable safety:
```python
for func in bv.functions:
    for block in func.mlil:
        for instr in block:
            print(instr)
```

Or more directly:
```python
for inst in bv.mlil_instructions:
    if isinstance(inst, Localcall):
        print(inst.params)
```

### HLIL Tree Traversal

HLIL is heavily tree-based. Simple iteration **will miss nested expressions**. Use `traverse`:
```python
def find_strcpy(i, targets) -> str:
    match i:
        case HighLevelILCall(dest=HighLevelILConstPtr(constant=c)) if c in targets:
            return str(i.params[1].constant_data.data)

for result in current_hlil.traverse(find_strcpy, target_addrs):
    print(result)
```

## Mapping Between ILs

Translation between each IL layer is **many-to-many**. One assembly instruction may produce multiple LLIL instructions, and multiple MLIL instructions may collapse into one HLIL expression.

- `hlil_inst.llil` -- single (approximate) mapping down
- `hlil_inst.llils` -- **all** LLIL instructions that contributed (most correct)
- `hlil_inst.mlil` -- single mapping down
- `hlil_inst.mlils` -- all contributing MLIL instructions

Addresses in ILs are approximate and can change between analysis runs.

## Operating on IL vs Native

Scripts should operate on ILs (richer information). However, some operations (comments, tags) work on native addresses:
```python
bv.set_comment_at(address, "my comment")  # native address, IL-agnostic
```

## Instruction Index vs Expression Index

Both are integers, both unique per-function and per-IL level, but they are **distinct**:
- **Instruction Index** -- unique index for top-level IL instructions
- **Expression Index** -- unique index for expressions (including nested sub-expressions in the tree)

They start at 0 independently and must not be confused.

## Static Single Assignment (SSA)

In SSA form, variables are write-once. Each modification creates a new **version** (shown as `var#N`).

- `eax#1 = 5` -- version 1
- `eax#2 = eax#1 + 3` -- version 2 references version 1

When paths merge, a **PHI function** (`Phi`) aggregates versions:
- `eax#3 = Phi(eax#1, eax#2)` -- could be either version

### SSA Use Cases
- **Uninitialized variable detection**: SSA var read at version 0 that isn't a function argument
- **Data flow tracing**: Walk back through SSA definitions to find where a value originated
- **Inter-procedural analysis**: Build on SSA to trace values across function boundaries

### SSA API
```python
hlil_ssa_vars = func.hlil.ssa_vars
def_inst = func.hlil.ssa_form.get_ssa_var_definition(ssa_var)  # single definition
use_insts = func.hlil.ssa_form.get_ssa_var_uses(ssa_var)       # potentially many uses
```

## When IL APIs Return None

Binary Ninja caches generated IL (configurable via `analysis.limits.cacheSize`). Normally accessing `.llil` transparently generates IL if not cached. However, `None` is returned when analysis limits are triggered.

- `func.llil_if_available` -- returns IL only if already cached (no generation)
- `func.analysis_skip_reason` -- query why analysis was skipped
- `func.analysis_skip_override` -- override limits (**dangerous**)

## Function Sizing

No explicit `.size` property on functions. Two approaches:
- `func.total_bytes` -- sum of all basic block lengths (may double-count overlapping bytes)
- `func.highest_address - func.lowest_address` -- address range span

Functions end when all basic blocks terminate via: return, noreturn call, invalid instruction, branch to existing block, or interrupt.

## Auto vs User

API methods with `_auto_` are for automatic analysis (re-run on each open). Methods with `_user_` persist in the database and survive re-analysis. User actions are undoable. When annotating interactively or via scripts, use `_user_` variants.

## references/cookbook.md

# Cookbook

Common analysis recipes and patterns for working with Binary Ninja.

## Loading & Navigation

### Load a binary (headless)
```python
from binaryninja import load
with load('/bin/ls') as bv:
    print(f"{bv.arch.name}: {hex(bv.entry_point)}")
```

### Get all functions
```python
for func in bv.functions:
    print(func.name, hex(func.start), func.return_type)
```

### Find a function
```python
func = bv.get_functions_by_name("main")[0]     # by name (may return multiple)
func = bv.get_function_at(addr)                 # exact start address
func = bv.get_functions_containing(addr)[0]     # contains address
```

### Largest function
```python
max(bv.functions, key=lambda x: x.total_bytes)
```

## IL & Decompilation

### Access all IL forms
```python
for func in bv.functions:
    llil     = func.llil          # Low Level IL
    llil_ssa = func.llil.ssa_form # LLIL SSA
    mlil     = func.mlil          # Medium Level IL
    mlil_ssa = func.mlil.ssa_form # MLIL SSA
    hlil     = func.hlil          # High Level IL (decompilation)
    hlil_ssa = func.hlil.ssa_form # HLIL SSA
```

### Iterate all decompiled instructions
```python
for func in bv.functions:
    for inst in func.hlil.instructions:
        print(f"{inst.address} : {inst}")

# Or across entire binary:
for inst in bv.hlil_instructions:
    print(f"{inst.address} : {inst}")
```

### Map between IL levels
```python
hlil_inst = func.hlil[0]
hlil_inst.mlil    # approximate single MLIL mapping
hlil_inst.mlils   # all contributing MLIL instructions (most accurate)
hlil_inst.llil    # approximate single LLIL mapping
hlil_inst.llils   # all contributing LLIL instructions
```

## Call Graph Analysis

### Callers and callees
```python
func.callers    # list of functions that call this function
func.callees    # list of functions called by this function
```

### All call sites into a function
```python
for site in func.caller_sites:
    print(site.address, site.hlil)
```

### All calls made by a function
```python
for site in func.call_sites:
    print(site.address, site.hlil)
```

### Most connected function
```python
max(bv.functions, key=lambda x: len(x.callers + x.callees))
```

## Cross-References
```python
# HLIL cross-references of a function's callers
for ref in func.caller_sites:
    print(ref.hlil)
```

## Variables & Parameters

### Access variables
```python
all_vars      = func.vars               # all variables
hlil_vars     = func.hlil.vars          # variables used in HLIL
aliased_vars  = func.hlil.aliased_vars  # aliased variables
param_vars    = func.parameter_vars     # function parameters
```

### Stack variable info
```python
var = hlil_vars[0]
if var.source_type == StackVariableSourceType:
    print(var.storage)                    # stack offset
    print(var.offset_to_next_variable)    # distance to next var
    print(abs(var.type.width))            # type-based size
```

### SSA: find definition and uses
```python
ssa_vars = func.hlil.ssa_vars
def_inst = func.hlil.ssa_form.get_ssa_var_definition(ssa_vars[0])
use_insts = func.hlil.ssa_form.get_ssa_var_uses(ssa_vars[0])
```

### Query possible values of a call parameter
```python
for ref in func.caller_sites:
    if isinstance(ref.hlil, Call) and len(ref.hlil.params) >= 3:
        print(ref.hlil.params[2].possible_values)
```

## Pattern Matching with Traverse

### Find all calls to a specific function
```python
def find_calls(i, target_addr) -> str:
    match i:
        case HighLevelILCall(dest=HighLevelILConstPtr(constant=c)) if c == target_addr:
            return str(i)

for result in current_hlil.traverse(find_calls, target_addr):
    print(result)
```

### Collect all call targets
```python
def collect_targets(i) -> int:
    match i:
        case HighLevelILCall(dest=HighLevelILConstPtr(constant=c)):
            return c

targets = set(hex(a) for a in current_hlil.traverse(collect_targets))
```

### Count parameters per call
```python
def param_counter(i) -> int:
    match i:
        case HighLevelILCall():
            return len(i.params)

list(current_hlil.traverse(param_counter))
```

## Annotations & Types

### Rename a function
```python
func.name = "newName"
```

### Change function type signature
```python
func.type = Type.function(Type.void(), [])
func.type = Type.function(Type.int(4), [('buf', Type.pointer(bv.arch, Type.char())), ('len', Type.int(4))])
```

### Change parameter type
```python
func.parameter_vars[0].type = Type.pointer(bv.arch, Type.char())
```

### Create and apply a struct
```python
bv.define_user_type('MyStruct', Type.structure(members=[
    (Type.int(4), 'field_0'),
    (Type.pointer(bv.arch, Type.char()), 'name'),
    (Type.int(8), 'size')
]))
```

### Apply type to data variable
```python
bv.define_user_data_var(addr, "char*")
bv.get_data_var_at(addr).type = Type.int(4)
```

### Tags and bookmarks
```python
bv.add_tag(addr, "Crashes", "buffer overflow here")
func.add_tag("Important", "needs code-review")
func.add_tag("Bug", "off-by-one", addr)
```

## references/mcp-tools.md

# MCP Tools Reference

Complete reference for all BinjaMCP server tools. All address parameters accept hex strings (e.g., `'0x1000'`). Most tools accept an optional `file_path` parameter; when omitted, the most recently loaded binary is used.

## Binary Lifecycle

### `load_binary`
Load a binary file into Binary Ninja for analysis.
- `file_path: str` -- Absolute path to the binary file
- Returns: Summary (arch, platform, entry point, function count, segments)

### `list_loaded_binaries`
List all currently loaded binaries.
- No parameters
- Returns: List of loaded file paths

### `close_binary`
Close a binary and free resources.
- `file_path: str` -- Path of the binary to close

## Function Discovery

### `list_functions`
List functions in the binary (paginated).
- `offset: int = 0` -- Starting index
- `limit: int = 100` -- Max results
- Returns: Table of address, name, size

### `search_functions`
Search functions by name (case-insensitive substring).
- `query: str` -- Search string
- Returns: Up to 100 matching functions with address and name

### `get_function_info`
Detailed metadata about a function.
- `address: str` -- Hex address of function
- Returns: Name, address range, size, basic block count, is_exported, is_thunk, type, comment, callers, callees

### `get_function_type`
Get the full type signature of a function (return type, parameters, calling convention).
- `address: str` -- Hex address of function
- Returns: Function prototype string and detailed parameter info

## IL & Decompilation

### `decompile_function`
Decompile to pseudo-C using HLIL.
- `address: str` -- Hex address of function
- Returns: Pseudo-C decompilation (falls back to HLIL text)

### `get_hlil`
Get High Level IL representation.
- `address: str` -- Hex address
- Returns: HLIL text (address: instruction per line)

### `get_mlil`
Get Medium Level IL representation.
- `address: str` -- Hex address
- Returns: MLIL text (address: instruction per line)

### `get_llil`
Get Low Level IL representation.
- `address: str` -- Hex address
- Returns: LLIL text (address: instruction per line)

### `get_disassembly`
Get native disassembly.
- `address: str` -- Hex start address
- `length: int = 64` -- Bytes to disassemble (if inside a function, disassembles full function)
- Returns: Disassembly lines with addresses

## Strings

### `list_strings`
List strings in the binary (paginated).
- `offset: int = 0` -- Starting index
- `limit: int = 100` -- Max results
- `min_length: int = 4` -- Minimum string length
- Returns: Table of address, type, value

### `search_strings`
Search strings by content (case-insensitive substring).
- `query: str` -- Search string
- Returns: Matching strings with address and value

## Cross-References & Call Graph

### `get_xrefs_to`
Get references TO an address (who references this).
- `address: str` -- Target hex address
- Returns: Code and data references pointing to this address

### `get_xrefs_from`
Get references FROM an address (what this references).
- `address: str` -- Source hex address
- Returns: Addresses referenced from this location

### `get_function_callers`
Get functions that call a given function.
- `address: str` -- Hex address of the target function
- Returns: List of calling functions with address and name

### `get_function_callees`
Get functions called by a given function.
- `address: str` -- Hex address of the calling function
- Returns: List of called functions with address and name

## Imports & Exports

### `list_imports`
List all imported symbols.
- Returns: Table of address, type, name

### `search_imports`
Search imported symbols by name (case-insensitive substring).
- `query: str` -- Search string
- Returns: Matching imports with address and name

### `list_exports`
List all exported symbols.
- Returns: Table of address, name

## Binary Structure

### `list_sections`
List sections in the binary.
- Returns: Table of name, address range, size, semantics

### `list_segments`
List memory segments.
- Returns: Table of address range, size, rwx permissions

## Variables & Data

### `list_variables`
List local variables for a function.
- `address: str` -- Hex address of the function
- Returns: Table of variable name, type, source_type, storage

### `list_data_variables`
List global data variables in the binary (paginated).
- `offset: int = 0` -- Starting index
- `limit: int = 100` -- Max results
- Returns: Table of address, type, name/symbol

### `get_data_var_at`
Get type and value information for a data variable at a specific address.
- `address: str` -- Hex address
- Returns: Type, value, and symbol information

### `get_basic_blocks`
List basic blocks for a function.
- `address: str` -- Hex address of the function
- Returns: Table of block start, end, size, and outgoing edge targets

## Annotation

### `rename_function`
Rename a function.
- `address: str` -- Hex address of function
- `new_name: str` -- New name
- Returns: Confirmation with old and new names

### `rename_variable`
Rename a local variable within a function.
- `function_address: str` -- Hex address of the containing function
- `old_name: str` -- Current variable name
- `new_name: str` -- New variable name
- Returns: Confirmation message

### `set_comment`
Set a comment at an address.
- `address: str` -- Hex address
- `comment: str` -- Comment text (empty string to remove)

### `set_function_comment`
Set a comment on a function.
- `address: str` -- Hex address of function
- `comment: str` -- Comment text (empty string to remove)

### `set_function_type`
Set or change a function's type signature.
- `address: str` -- Hex address of function
- `type_string: str` -- C-style function type (e.g., `"int foo(char* buf, int len)"`)
- Returns: Confirmation with old and new type

## Raw Data

### `read_bytes`
Read raw bytes from the binary.
- `address: str` -- Hex address
- `length: int = 64` -- Bytes to read (max 4096)
- Returns: Hex dump with hex + ASCII columns

## Usage Tips

- **Start broad, narrow down**: Use `search_*` tools before `list_*` to avoid large outputs
- **HLIL first**: `decompile_function` gives the most readable output; drop to MLIL/LLIL when precision matters
- **Paginate large results**: `list_functions` and `list_strings` support `offset`/`limit`
- **Function lookup is fuzzy**: Most tools accepting a function address will also work with addresses *inside* the function (falls back to `get_functions_containing`)
- **Annotate as you go**: Use `rename_function`, `rename_variable`, and `set_comment` to build understanding incrementally

