mcpField
I
idapython

idapython

github.com/allthingsidaDevelopment4949 installsUpdated 3w ago
Repository

About idapython

idapython documents running Python snippets and files inside IDA through SQL. It is for users who need IDA SDK access, custom algorithms, UI automation, or reuse of existing scripts, with configurable output limits and persistent isolated namespaces.

Key features

  1. 01Run Python snippets and files through SQL
  2. 02Isolate and persist sandbox namespaces
  3. 03Set an optional output byte limit
  4. 04Return Python exceptions as SQL errors

Use cases

  1. 01Call IDA SDK APIs absent from idasql
  2. 02Run complex algorithms or custom matching
  3. 03Automate the IDA interface
  4. 04Reuse existing Python scripts

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/allthingsida/idasql-skills --skill idapython

After installing, type/idapythonin Claude Code to confirm it loaded.

Bundled filesagents/openai.yaml

Details

From the project README

Python Execution SQL Functions

FunctionDescription
idapython_snippet(code[, sandbox])Execute Python snippet and return captured output text
idapython_file(path[, sandbox])Execute Python file and return captured output text
Runtime Guard

Python execution is disabled by default. Enable it with:

PRAGMA idasql.enable_idapython = 1;

Captured print output is unbounded by default. To bound a runaway or very chatty snippet (so it can't exhaust memory / the response), set an optional byte cap; 0 restores unbounded:

PRAGMA idasql.idapython_output_max = 65536;  -- cap captured output at 64 KiB
PRAGMA idasql.idapython_output_max = 0;      -- unbounded (default)

Output past the cap is dropped with a ...[idapython output truncated at N bytes]... marker.

To confirm the current values of enable_idapython and idapython_output_max (and the other runtime controls), SELECT * FROM runtime_settings WHERE scope = 'idasql' — a read-only discovery view over the PRAGMA idasql.* surface. See the connect skill.

Examples
SELECT idapython_snippet('print("hello from idapython")');
SELECT idapython_file('C:/temp/script.py');
SELECT idapython_snippet('counter = globals().get("counter", 0) + 1; print(counter)', 'alpha');
Notes
  • Disabled by default until pragma is enabled
  • Python exceptions propagate as SQL errors
  • sandbox isolates/persists Python globals by sandbox key
Two Python Contexts (Important)
  • Host-side Python client (outside IDA): use requests.post(.../query, data=sql) to send SQL over HTTP. The body may be one statement or a semicolon-separated script; every response uses the canonical results[] envelope (a single statement is an array of one — read results[i].rows). Use this for loops, bulk updates, and automation orchestration. See connect skill HTTP client patterns.
  • IDAPython via SQL (inside IDA): use idapython_snippet() / idapython_file() when you need direct IDA SDK APIs in-process.

Example contrast:

# Host-side Python (outside IDA): sends SQL over HTTP
import requests
requests.post("http://127.0.0.1:8080/query", data="SELECT COUNT(*) FROM funcs")
-- IDAPython (inside IDA): executes Python in IDA runtime
SELECT idapython_snippet('import idaapi; print(idaapi.get_kernel_version())');
Sandbox Behavior

Each sandbox key creates an isolated Python namespace:

  • Variables set in one sandbox are not visible in another
  • The same sandbox key reuses its namespace across calls (state persists within a session)
  • Without a sandbox key, code runs in the default global namespace
Error Propagation

When a Python script raises an exception, it propagates as a SQL error:

-- This will return an error: "NameError: name 'undefined_var' is not defined"
SELECT idapython_snippet('print(undefined_var)');

When to Use IDAPython vs SQL

Use CaseBest ToolWhy
Query/filter/aggregate dataSQLJOINs, CTEs, GROUP BY, window functions — SQL is purpose-built for this
Cross-table analysisSQLJOINing funcs, xrefs, strings, ctree is natural in SQL
Reporting and countingSQLCOUNT, SUM, AVG, GROUP_CONCAT — no Python loop needed
Complex algorithmsIDAPythonGraph algorithms, custom pattern matching, ML pipelines
IDA SDK APIs not in idasqlIDAPythonSome IDA SDK features aren't exposed as SQL tables/functions
UI automationIDAPythonOpening views, navigating cursor, triggering IDA actions
Existing scriptsIDAPythonReuse existing .py scripts without rewriting in SQL

General rule: Start with SQL. If you find yourself wanting nested loops, recursive algorithms, or IDA APIs that aren't exposed via idasql, reach for idapython_snippet() as a bridge.


Practical Use Cases

Run a custom analysis script
-- Enable Python execution first
PRAGMA idasql.enable_idapython = 1;

-- Run a script that collects custom metrics
SELECT idapython_snippet('
import idautils, idc
count = 0
for func_addr in idautils.Functions():
    if idc.get_func_attr(func_addr, idc.FUNCATTR_FLAGS) & 0x4:  # FUNC_LIB
        count += 1
print(f"Library functions: {count}")
');
Access IDA SDK APIs not exposed through idasql
-- Example: get processor-specific register names
SELECT idapython_snippet('
import ida_idp
for i in range(ida_idp.ph_get_regnames().__len__()):
    name = ida_idp.ph_get_regnames()[i]
    if name:
        print(f"{i}: {name}")
');
Bridge pattern: Python produces JSON, SQL processes it

When you need Python's power for extraction but SQL's power for analysis:

-- Python extracts data as JSON
SELECT idapython_snippet('
import json, idautils, idc
result = []
for addr in idautils.Functions():
    flags = idc.get_func_attr(addr, idc.FUNCATTR_FLAGS)
    if flags & 0x4:  # FUNC_LIB
        result.append({"addr": addr, "name": idc.get_func_name(addr)})
print(json.dumps(result))
');

-- Then process the JSON output in SQL using json_each()
-- (copy the output from above into the query)

See Also

  • Check the relevant SQL skill first (disassembly, decompiler, types, data, xrefs, annotations, debugger) — fall through to IDAPython only when no SQL surface exists for the task.
  • functions — the SQL function catalog; verify a scalar/helper doesn't already exist before scripting.

Comments

Markdown supported