modules/home/programs/cli-agents/shared/skills/ida-plugin-dev/SKILL.md
IDA Pro plugin development - SDK setup, CMake build patterns, Python plugin structure, Nix packaging, and common gotchas for IDA 9.x.
npx skillsauth add not-matthias/dotfiles-nix ida-plugin-devInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Patterns for developing IDA Pro plugins (C++ and Python), building against the IDA SDK, and packaging for NixOS.
def PLUGIN_ENTRY(*args, **kwargs):
"""IDA calls this to load the plugin."""
return create_plugin(*args, **kwargs)
# Handle non-IDA environments gracefully
try:
import idaapi
HAS_IDA = True
except ImportError:
HAS_IDA = False
create_plugin()
ida-plugin.json){
"IDAMetadataDescriptorVersion": 1,
"plugin": {
"name": "My Plugin",
"entryPoint": "src/my_plugin/plugin.py",
"categories": ["api-scripting-and-automation"],
"description": "Does X",
"idaVersions": ">=8.3"
}
}
Requirements: Python 3.11+, IDA Pro 8.3+ (IDA Free not supported).
pyproject.toml[build-system]
requires = ["setuptools>=61.2"]
build-backend = "setuptools.build_meta"
[project]
name = "my-ida-plugin"
version = "1.0.0"
requires-python = ">=3.11"
dependencies = ["idapro>=0.0.7"]
[project.scripts]
my-plugin = "my_plugin.server:main"
CMakeLists.txtcmake_minimum_required(VERSION 3.15)
project(my_plugin CXX)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error -Wno-format-security")
set(IDA_SDK_DIR "" CACHE PATH "Path to IDA SDK")
if(NOT IDA_SDK_DIR OR NOT EXISTS "${IDA_SDK_DIR}")
message(FATAL_ERROR "IDA_SDK_DIR not set")
endif()
list(APPEND CMAKE_MODULE_PATH "${IDA_SDK_DIR}/cmake")
include(ida-sdk)
add_ida_plugin(my_plugin
src/plugin.cpp
)
{stdenv, cmake, ninja, clang, ida-sdk-source}: stdenv.mkDerivation {
pname = "ida-my-plugin";
version = "1.0.0";
src = fetchFromGitHub { ... };
nativeBuildInputs = [cmake ninja clang];
# Critical: IDA SDK is read-only in Nix store — must copy to $TMPDIR
preConfigure = ''
export TMP_SDK=$TMPDIR/ida-sdk
cp -r ${ida-sdk-source} $TMP_SDK
chmod -R u+w $TMP_SDK
'';
cmakeFlags = [
"-DIDA_SDK_DIR=$TMP_SDK"
"-DCMAKE_BUILD_TYPE=Release"
"-DCMAKE_CXX_FLAGS=-Wno-error -Wno-format-security"
];
installPhase = ''
mkdir -p $out/plugins
cp *.so $out/plugins/
'';
}
Gotcha: The Nix store is read-only. IDA's CMake scripts write into the SDK directory during configuration. Always copy to $TMPDIR and chmod -R u+w before configuring.
# pkgs/ida-pro/ida-sdk-source.nix
{stdenv, fetchFromGitHub}: stdenv.mkDerivation rec {
pname = "ida-sdk-source";
version = "9.3";
src = fetchFromGitHub {
owner = "HexRaysSA";
repo = "ida-sdk";
rev = "v${version}";
hash = "sha256-...";
fetchSubmodules = true; # Required
};
dontBuild = true;
dontConfigure = true;
installPhase = ''
mkdir -p $out
cp -r $src/* $out/
cd $out
ln -s src/include include
ln -s src/lib lib
ln -s src/cmake cmake
'';
}
SDK structure: src/include/ (headers like ida.hpp, idp.hpp), src/lib/ (link libs), src/cmake/ (CMake modules).
{stdenv, fetchurl}: stdenv.mkDerivation {
pname = "ida-my-script";
version = "1.0.0";
src = fetchurl {
url = "https://github.com/.../releases/download/.../plugin.py";
sha256 = "...";
};
dontUnpack = true;
dontBuild = true;
installPhase = ''
mkdir -p $out/plugins
cp ${src} $out/plugins/plugin.py
'';
}
IDA Pro 9.x requires Qt6. Common missing libraries on NixOS:
runtimeDependencies = with pkgs; [
libGL libxkbcommon libxcb
qt6.qtbase qt6.qtwayland
glib gtk3 libdrm
libkrb5 openssl.out curl.out
xorg.libX11
];
If IDA fails to start:
# Quick test — add libraries one by one
nix-shell -p libGL libxkbcommon libxcb qt6.qtbase glib xorg.libX11 \
--run "ida64"
# Python plugin via MCP Inspector
npx -y @modelcontextprotocol/inspector
# Opens http://localhost:5173
# HTTP (if plugin exposes RPC on :13337)
curl -X POST http://localhost:13337/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"call_tool","params":{"name":"my_tool","params":{}}}'
# C++ plugin: verify .so was created
cmake --build . --verbose
ls -la *.so
| Error | Cause | Fix |
|-------|-------|-----|
| IDA SDK dir is read-only | Nix store immutable | Copy SDK to $TMPDIR, chmod -R u+w |
| libGL.so.1: not found | Missing OpenGL | Add libGL to runtimeDependencies |
| idaapi import fails outside IDA | No IDA Python env | Guard with try: import idaapi |
| Plugin .so not found after build | CMake target name mismatch | Check add_ida_plugin() target name |
| IDA Python version mismatch | Wrong Python in PATH | Use pythonForIDA with rpyc |
pkgs/ida-pro/ in this dotfiles repodocumentation
Save notes, journal entries, and research to the personal-notes Obsidian vault (personal-vault-v2). Use when the user asks to 'save note', 'save to notes', 'write to personal notes', 'save to daily notes', 'note this down', or wants to persist findings/analysis to their personal vault.
documentation
Use whenever the user asks to address, fix, resolve, review, or respond to pull-request comments or review feedback.
development
Apply Not Matthias's Rust-first personal coding style. Use whenever the user explicitly asks to apply or review their code style, make Rust match their preferences, perform a style pass, or simplify/refactor according to their conventions. Inspect only task-touched code, honor local project conventions first, and make only safe opt-out style edits.
development
Guide for writing ast-grep rules to perform structural code search and analysis. Use when users need to search codebases using Abstract Syntax Tree (AST) patterns, find specific code structures, or perform complex code queries that go beyond simple text search. This skill should be used when users ask to search for code patterns, find specific language constructs, or locate code with particular structural characteristics.