Claude
Skills
Sign in
Back

ida-plugin-development

Included with Lifetime
$97 forever

Develop plugins for IDA Pro in Python, using idiomatic patterns, lessons, and tricks, including the Python Domain API (ida-domain). Use when creating both GUI (Qt) and background plugins for inspecting and rendering things program structure, functions, disassembly, cross-references, and strings.

Backend & APIsscripts

What this skill does


# Developing IDA Pro plugins

Use this skill when developing plugins for IDA Pro using Python.

IDA's UI and analysis passes can be almost completely replaced through plugins.
There's a lot of power (and a lot of complexity), so its important to follow known patterns.
This document lists tips and tricks for creating new plugins for modern versions of IDA.

Key concepts covered in this document:
- [Use the IDA Domain API](#use-the-ida-domain-api) - prefer the high-level Pythonic interface
- [Plugin Manager Integration](#plugin-manager-integration) - packaging and distribution
- [Plugin Entry Point](#plugin-entry-point) - version checking and conditional loading
- [Hook Registration](#hook-registration) - pairwise register/unregister pattern
- [Cross-Plugin Communication via IDC Functions](#cross-plugin-communication-via-idc-functions) - invoke plugin functionality from scripts/other plugins
- [Save/Load state from netnodes](#saveload-state-from-netnodes) - persist plugin data in IDB
- [Respond to current address and selection change](#respond-to-current-address-and-selection-change) - UI location hooks
- [Find widgets by prefix](#find-widgets-by-prefix) - managing multiple widget instances
- [Context Menu Entries](#context-menu-entries-send-to-foo-and-send-to-foo-a) - "Send to Foo" patterns
- [User Defined Prefix](#user-defined-prefix) - add contextual markers in disassembly
- [Viewer Hints](#viewer-hints) - hover popups with context
- [Overriding rendering](#overriding-rendering) - custom colors and mnemonics
- [Custom Viewers](#custom-viewers) - tagged lines with clickable addresses


## Use the IDA Domain API

Always prefer the IDA Domain API over the legacy low-level IDA Python SDK. The Domain API provides a clean, Pythonic interface that is easier to use and understand.
However, there will be some things that the Domain API doesn't cover, especially around plugin registration and GUI handling.

Right now: read this intro guide: https://ida-domain.docs.hex-rays.com/getting_started/index.md 

Always refer to the documentation rather than doing introspection, because the documentation explains concepts, not just symbol names.
To fetch specific API documentation, use URLs like:
- `https://ida-domain.docs.hex-rays.com/ref/functions/index.md` - Function analysis API
- `https://ida-domain.docs.hex-rays.com/ref/xrefs/index.md` - Cross-reference API
- `https://ida-domain.docs.hex-rays.com/ref/strings/index.md` - String analysis API

Available API modules: `bytes`, `comments`, `database`, `entries`, `flowchart`, `functions`, `heads`, `hooks`, `instructions`, `names`, `operands`, `segments`, `signature_files`, `strings`, `types`, `xrefs`
URL pattern: https://ida-domain.docs.hex-rays.com/ref/{module}/index.md

You can always ask a subagent to answer a question by exploring the documentation and summarizing its findings.

### Key Database Properties

```python
with Database.open(path, ida_options) as db:
    db.minimum_ea      # Start address
    db.maximum_ea      # End address
    db.metadata        # Database metadata
    db.architecture    # Target architecture

    db.functions       # All functions (iterable)
    db.strings         # All strings (iterable)
    db.segments        # Memory segments
    db.names           # Symbols and labels
    db.entries         # Entry points
    db.types           # Type definitions
    db.comments        # All comments
    db.xrefs           # Cross-reference utilities
    db.bytes           # Byte manipulation
    db.instructions    # Instruction access
```

### Common Analysis Tasks

#### List Functions

```python
func: func_t
for func in db.functions:
    name = db.functions.get_name(func)
    print(f"{hex(func.start_ea)}: {name} ({func.size} bytes)")
```

Interesting `func_t` properties:
```python
class func_t:
    name: str
    flags: int
    start_ea: int
    end_ea: int
    size: int
    does_return: bool
    referers: list[int]  # function start addresses
    addresses: list[int]
    frame_object: tinfo_t
    prototype: tinfo_t
```


#### Cross-references
```python
for xref in db.xrefs.to_ea(target_addr):
    print(f"Referenced from {hex(xref.from_ea)} (type: {xref.type.name})")

for xref in db.xrefs.from_ea(source_addr):
    print(f"References {hex(xref.to_ea)}")

for xref in db.xrefs.calls_to_ea(func_addr):
    print(f"Called from {hex(xref.from_ea)}")
```

`XrefInfo` type:
```python
XrefInfo(
    from_ea: int,
    to_ea: int,
    is_code: bool,
    type: XrefType,
    user: bool,
)
```

#### Read data
```python
db.bytes.get_byte_at(addr)
db.bytes.get_bytes_at(addr)
db.bytes.get_cstring_at(addr)
db.bytes.get_word_at(addr)
db.bytes.get_dword_at(addr)
db.bytes.get_qword_at(addr)
db.bytes.get_disassembly_at(addr)
db.bytes.get_flags_at(addr)
```


## Plugin Manager Integration

Plugins must be compatible with the Hex-Rays Plugin Manager.

Making your plugin available via Plugin Manager offers several benefits:

- simplified plugin installation
- improved plugin discoverability through the central index
- easy Python dependency management

The key points to make your IDA plugin available via Plugin Manager are:

- Add `ida-plugin.json`
- Package your plugin into a ZIP archive (via source archives or GitHub Actions)
- Publish releases on GitHub

A complete `ida-plugin.json` example:

```json
{
  "IDAMetadataDescriptorVersion": 1,
  "plugin": {
    "name": "ida-terminal-plugin",
    "entryPoint": "index.py",
    "version": "1.0.0",
    "idaVersions": ">=9.2",
    "platforms": [
      "windows-x86_64",
      "linux-x86_64",
      "macos-x86_64",
      "macos-aarch64",
    ],
    "description": "A lightweight terminal integration for IDA Pro that lets you open a fully functional terminal within the IDA GUI.\nQuickly access shell commands, scripts, or tooling without leaving your reversing environment.",
    "license": "MIT",
    "logoPath": "ida-plugin.png",
    "categories": [
      "ui-ux-and-visualization"
    ],
    "keywords": [
      "terminal",
      "shell",
      "cli",
    ],
    "pythonDependencies": [
      "pydantic>=2.12"
    ],
    "urls": {
      "repository": "https://github.com/williballenthin/idawilli"
    },
    "authors": [{
      "name": "Willi Ballenthin",
      "email": "[email protected]"
    }],
    "settings": [
      {
        "key": "theme",
        "type": "string",
        "required": true,
        "default": "darcula",
        "name": "color theme",
        "documentation": "the color theme name, picked from https://windowsterminalthemes.dev/",
      }
    ]
  }
}
```

Before completing your work, review the following resources for packaging hints:

- https://hcli.docs.hex-rays.com/reference/plugin-repository-architecture/
- https://hcli.docs.hex-rays.com/reference/plugin-packaging-and-format/
- https://hcli.docs.hex-rays.com/reference/packaging-your-existing-plugin/

Use the script `./scripts/hcli-package.py` to invoke HCLI in a consistent way and lint the current plugin.

## Use ida-settings for configuration values

ida-settings is a Python library used by IDA Pro plugins to fetch configuration values from the shared settings infrastructure.

During plugin installation, the plugin manager prompts users for the configuration values and stores them in `ida-config.json`.
Subsequently, users can invoke HCLI (or later, the IDA Pro GUI) to update their configuration.
ida-settings is the library that plugins use to fetch the configuration values.

For example:

```python
import ida_settings
api_key = ida_settings.get_current_plugin_setting("openai_key")
```

Note that this must be called from within the plugin (`plugin_t` or `plugmod_t`), not a callback or hook;
capture an instance of the plugin settings and pass it around as necessary:

```python
class Hooks(idaapi.IDP_Hooks):
    def __init__(self, settings):
        super().__init__()
        self.settings = settings
        
    def ev_get_bg_color(self, color, ea):
        mnem = ida_ua.print_insn_mnem(ea)

        if mnem 

Related in Backend & APIs