Hex-Rays Blog: IDA Pro Tutorials & Reverse Engineering Tips

What's new in the IDA Domain API?

Written by Michal Sobon | Jun 1, 2026

What's new in the IDA Domain API?

It has been a while since our first post about the IDA Domain API, our open-source Python API designed to make scripting in IDA simpler, more consistent, and more approachable.

Since last year's launch, the project has kept moving. With the recent v0.5.0 release, the API covers most of the everyday scripting surface in IDA.

This post highlights the most important additions and compares a few examples with equivalent IDAPython snippets. IDAPython is still there, the point of the Domain API is to make the common cases read like normal Python, so scripts are easier to write, review, and maintain.

Design principles

The Domain API exposes popular IDA functionality through objects that match the reverse engineering concepts you already work with: functions, instructions, operands, imports, pseudocode, microcode, and so on. The goal is to avoid forcing every script to start with low-level SDK details before it can answer a simple question.

At the same time, the Domain API is intentionally compatible with IDAPython. When you need something that is not wrapped yet, you can still call IDAPython directly.

For SDK objects returned by the Domain API, you can often pass the object straight to IDAPython:

For wrapped objects, use the raw_* property to reach the underlying IDAPython object:

New modules

Microcode

The new microcode module exposes IDA's microcode as a regular Python object. You can iterate a micro block array, walk instructions, ask high-level questions about operands, and use named enums instead of magic integers.

For example, here is a small snippet that finds every call instruction in a function and prints the call site and callee address.

Click and drag, I'm interactive.

Pseudocode

The pseudocode module gives Python-friendly access to Hex-Rays decompiler output. It wraps the decompiled function, exposes the C tree as iterable expressions and statements, and gives typed accessors for common constructs such as calls, numbers, comparisons, control-flow blocks, and returns.

Here is a simple example that walks a function and prints every numeric constant recovered by the decompiler.

Imports

The imports module gives you a unified view of every external symbol the binary pulls in. Imports are returned as plain Python data objects, so you can iterate, filter, and look them up by name or address without rewriting the same enumeration callback each time.

This snippet prints every imported symbol as module!name.

Flowcharts

The flowchart module exposes a function's control-flow graph as a regular Python object. You can iterate basic blocks, walk their instructions, and follow successors or predecessors with normal Python iterators.

The example below counts instructions in each basic block of a function.

Exceptions

Error handling is also becoming more consistent. Instead of mixing sentinel values, and failed lookups, the Domain API now raises Python exceptions from the shared IdaDomainError hierarchy.

For example:

Feedback

The Domain API is meant to grow with real-world scripting needs, so feedback is especially valuable now. If something still requires too much boilerplate, if a wrapper feels awkward, or if an IDAPython pattern should have a clearer Domain API equivalent, we would like to hear about it.

The project is open source, and we welcome user contributions too — whether that's filing an issue, sending a pull request with a new wrapper, improving documentation, or sharing example scripts.

Ready to try it?