idax
Safe, idiomatic Rust bindings for the IDA Pro SDK via the idax C++ wrapper library.
idax provides a concept-driven, fully opaque interface to IDA's analysis engine. All unsafe FFI is encapsulated — users of this crate never write unsafe code. Types that hold SDK resources implement Drop for automatic cleanup.
Prerequisites
- IDA Pro installed in a standard location (see IDA discovery below)
- Rust 2024 edition (nightly or stable 1.85+)
- CMake and a C++23 compiler (the build script compiles the C++ layer automatically)
Installation
[]
= "0.3"
That's it. No build.rs in your crate, no environment variables, no manual library setup. Just cargo run.
IDA discovery
The build script automatically locates your IDA installation:
$IDADIRenvironment variable (explicit override)- macOS: scans
/Applications/IDA*.app/Contents/MacOS(newest version first) - Linux: scans
/opt/idapro*,/opt/ida-*,/opt/ida, then~/ida*
If the IDA SDK isn't available locally, it will be fetched automatically during the build. You can override this with the $IDASDK environment variable.
Runtime: cargo run vs direct execution
cargo run / cargo test — works out of the box. The build script symlinks the real IDA dynamic libraries into the build output directory, and Cargo automatically adds that directory to the dynamic library search path (DYLD_FALLBACK_LIBRARY_PATH on macOS, LD_LIBRARY_PATH on Linux).
Direct execution (running the compiled binary outside of Cargo) requires the IDA libraries to be discoverable by the dynamic linker. Options:
# Option 1: Set the library path (recommended for development)
DYLD_LIBRARY_PATH=/Applications/IDA\ Professional\ 9.3.app/Contents/MacOS LD_LIBRARY_PATH=/opt/idapro
# Option 2: Add an RPATH to the binary (recommended for deployment)
# Option 3: Place the binary next to the IDA libraries
Quick start
use ;
Module overview
The crate is organized into modules that mirror the C++ ida:: namespace hierarchy. Every module covers a distinct analysis domain:
Core
| Module | Domain | Key capabilities |
|---|---|---|
[error] |
Error handling | Error (category + code + message + context), Result<T>, Status |
[address] |
Address primitives | Address (u64), Range, predicates (is_code, is_data, ...), navigation (next_head, prev_head), iterators (HeadIterator, PredicateIterator) |
[database] |
Database lifecycle | init, open, open_binary, save, close, metadata queries (input_file_path, input_md5, image_base, processor_name, ...), import enumeration, snapshots |
Analysis objects
| Module | Domain | Key capabilities |
|---|---|---|
[segment] |
Segments | CRUD (at, by_name, by_index, create, remove), properties (set_name, set_permissions, set_bitness, resize, move), traversal (next, prev), comments |
[function] |
Functions | CRUD, chunks (chunks, add_tail, remove_tail), stack frames (frame, frame_variable_by_name, define_stack_variable), register variables, callers/callees, item_addresses, code_addresses |
[instruction] |
Instructions | decode, create, text, operand introspection (operand_text, operand_byte_width, operand_register_name), operand formatting (set_operand_hex, set_operand_offset, set_operand_struct_offset_*), xref conveniences (code_refs_from, call_targets, is_call, is_jump), navigation (next, prev) |
[data] |
Byte-level I/O | Read (read_byte .. read_qword, read_bytes, read_string, read_typed), write, patch, originals, define (define_byte .. define_struct, undefine), find_binary_pattern |
[name] |
Naming | get, set, force_set, remove, demangled, resolve, all_user_defined, properties (is_public, is_weak) |
[xref] |
Cross-references | refs_from, refs_to, code/data ref variants, range variants, add_code, add_data, remove_code, remove_data |
[comment] |
Comments | Regular/repeatable (get, set, append, remove), anterior/posterior lines (add_anterior, set_anterior_lines, anterior_lines, ...), render |
[entry] |
Entry points | count, by_index, by_ordinal, add, rename, forwarders |
[fixup] |
Fixups / relocations | at, set, remove, in_range, iteration (first, next, prev), custom fixup handler registration |
[search] |
Search | text, binary_pattern, immediate, next_code, next_data, next_unknown, next_error, next_defined |
Type system
| Module | Domain | Key capabilities |
|---|---|---|
[types] |
Type introspection & construction | TypeInfo (RAII handle with Drop), primitives (void, int8 .. uint64, float32, float64), compound types (pointer_to, array_of, create_struct, create_union, function_type, enum_type), introspection (is_pointer, pointee_type, members, ...), application (apply, retrieve, save_as), type libraries (load_library, import) |
Advanced
| Module | Domain | Key capabilities |
|---|---|---|
[decompiler] |
Hex-Rays decompiler | decompile / decompile_range returning DecompiledFunction (RAII), pseudocode (pseudocode_lines, pseudocode_text), ctree traversal (ctree_items, find_ctree_item_at), microcode (microcode returning MicrocodeFunction), ctree/microcode modification, event subscriptions (on_decompiled, on_ctree_modified, ...) |
[debugger] |
Debugger control | Process lifecycle (start, attach, detach, suspend, resume, step_*, terminate), breakpoints (add_breakpoint, remove_breakpoint, enable_breakpoint, breakpoints), memory (read_memory, write_memory), registers (register_value, set_register_value), threads, appcall (call_function), module/exception/event subscriptions, custom executor registration |
[storage] |
Netnode storage | Node (RAII handle), typed value stores: altval (set_altval / altval), supval (set_supval / supval), hashval (set_hashval / hashval), blob (set_blob / blob), create / open / remove |
[lumina] |
Lumina server | pull, push |
[analysis] |
Auto-analysis | is_enabled, set_enabled, is_idle, wait, schedule, schedule_range, schedule_function, cancel, revert_decisions |
[event] |
IDB event subscriptions | Typed callbacks for segment/function/rename/patch/comment events, filtered subscriptions, ScopedSubscription (RAII unsubscribe on drop) |
Extension points
| Module | Domain | Key capabilities |
|---|---|---|
[plugin] |
Plugin lifecycle | Action registration (register_action / register_action_ex), menu/toolbar/popup attachment, ActionContext for context-aware handlers |
[loader] |
Loader modules | InputFileHandle (seek, read, filename), LoadFlags decode/encode, file_to_database, memory_to_database, set_processor, abort_load |
[processor] |
Processor modules | Processor trait (5 required + 15 optional methods), InstructionFeature / RegisterInfo / AssemblerInfo types |
[graph] |
Custom graphs | Graph (RAII handle), GraphCallback trait for interactive event handling, flow_chart for function CFG extraction |
[ui] |
UI utilities | message, warning, error, info dialogs, ask_* input prompts, ChooserImpl trait for custom list dialogs, widget management, timer scheduling, clipboard, UI event subscriptions |
[lines] |
Color tags | strip_color_tags, has_color_tags |
[diagnostics] |
Logging | log, log_error, performance_counter, reset_performance_counter, dump_performance_counters, is_verbose, set_verbose |
Error handling
All fallible operations return idax::Result<T> (alias for std::result::Result<T, idax::Error>) or idax::Status (alias for Result<()>). The Error type carries:
category—ErrorCategoryenum:Validation,NotFound,Conflict,Unsupported,SdkFailure,Internalcode— numeric error code (0 when unspecified)message— human-readable descriptioncontext— additional context (e.g. which SDK function failed)
use ;
use ErrorCategory;
match at
RAII / Drop
Types that hold SDK resources implement Drop for automatic cleanup:
| Type | Module | Releases |
|---|---|---|
TypeInfo |
types |
Opaque type handle |
Node |
storage |
Netnode handle |
DecompiledFunction |
decompiler |
Decompilation result |
Graph |
graph |
Interactive graph handle |
ScopedSubscription |
event, decompiler, debugger |
Unsubscribes on drop |
Architecture
Your Rust code
|
[ idax ] safe, idiomatic Rust API
|
[ idax-sys ] raw extern "C" FFI bindings (generated by bindgen)
|
[ C shim ] idax_shim.h / idax_shim.cpp (thin C bridge)
|
[ libidax.a ] idax C++ wrapper library
|
[ IDA SDK ] ida.dylib / ida.so / ida.dll
License
MIT