A powerful command-line interface for IDA Pro, built in Rust using idalib-rs.
- Single binary - No Python, no pip, no environment setup
- Fast startup - No interpreter overhead
- JSON output - Easy to parse programmatically, pipe to
jq - Full IDA power - Decompilation, disassembly, type system, cross-references
- Hex-Rays support - Decompile to pseudocode
- Persistent mutations - Rename, patch, comment changes are saved to IDB
- IDA Pro 9.2+ with valid license
IDADIRenvironment variable set to IDA installation path- Rust toolchain + clang (for building from source)
# Set environment
export IDADIR=/opt/ida-pro-9.2
export IDALIB_SDK=/opt/ida-pro-9.2/idasdk_pro92
# Build
cargo build --release
# Binary at ./target/release/ida-cliexport IDADIR=/opt/ida-pro-9.2
# Basic info
ida-cli -i binary.exe info
# List functions
ida-cli -i binary.exe functions list --limit 10
# Decompile a function
ida-cli -i binary.exe decompile main
# Search strings
ida-cli -i binary.exe strings --pattern "error"| Command | Description |
|---|---|
info |
Database metadata (arch, entry point, file type) |
functions list |
List functions with optional regex filter |
functions info <target> |
Detailed function information |
decompile <target> |
Hex-Rays decompilation to pseudocode |
disassemble <target> |
Disassemble function or address range |
xrefs <target> |
Cross-references to/from target |
strings |
List strings with optional regex filter |
bytes <addr> <size> |
Read raw bytes at address |
search <pattern> |
Search for text, bytes, or immediates |
segments |
List segments |
rename <target> <name> |
Rename function or address |
comment <addr> <text> |
Set comment at address |
type list |
List all types in local type library |
type struct <name> |
Show structure definition |
type enum <name> |
Show enumeration definition |
type get <target> |
Get type at address |
type set <target> <decl> |
Set type at address |
frame info <func> |
Stack frame layout |
frame vars <func> |
Stack variables |
frame sp <func> <addr> |
SP delta at address |
patch byte <addr> <val> |
Patch single byte |
patch bytes <addr> <hex> |
Patch multiple bytes |
patch revert <addr> |
Revert patch |
patch list |
List all patches |
patch original <addr> <size> |
Read original bytes |
idc eval <expr> |
Evaluate IDC expression |
idc run <script> |
Run IDC script file |
debugger info |
Show debugger configuration |
All examples use Warcraft III Reforged (48MB PE64 executable).
$ ida-cli -i "Warcraft III.exe" info{
"success": true,
"data": {
"filename": "Warcraft III.exe",
"bits": 64,
"entry_point": "0x141f7a1e0",
"min_address": "0x140001000",
"max_address": "0x142e87000",
"processor": "metapc",
"file_type": "PE"
}
}$ ida-cli -i "Warcraft III.exe" functions list --limit 5{
"success": true,
"data": [
{ "name": "nullsub_1788", "address": "0x140001950", "size": 1 },
{ "name": "nullsub_2595", "address": "0x140001fd0", "size": 2 },
{ "name": "TlsCallback_0", "address": "0x140004070", "size": 4469 },
{ "name": "sub_1400051F0", "address": "0x1400051f0", "size": 15 },
{ "name": "sub_1400070A0", "address": "0x1400070a0", "size": 1738 }
]
}$ ida-cli -i "Warcraft III.exe" strings --pattern "Warcraft" --limit 5{
"success": true,
"data": [
{ "address": "0x1420f98b0", "value": "Warcraft III", "length": 13 },
{ "address": "0x1420fb768", "value": "Warcraft III Error Output", "length": 26 },
{ "address": "0x1420fbec8", "value": "Warcraft III Launcher.exe", "length": 26 },
{ "address": "0x14210a310", "value": "Warcraft III", "length": 13 },
{ "address": "0x14210c888", "value": "Telemetry.ProgramName=Warcraft III", "length": 35 }
]
}$ ida-cli -i "Warcraft III.exe" decompile TlsCallback_0{
"success": true,
"data": {
"function": "TlsCallback_0",
"address": "0x140004070",
"pseudocode": "void __fastcall TlsCallback_0(__int64 a1, __int64 a2, __int64 a3, ...) {\n JUMPOUT(0x1400040A6LL);\n}\n"
}
}$ ida-cli -i "Warcraft III.exe" disassemble 0x140001950 -n 3{
"success": true,
"data": {
"function": "nullsub_1788",
"start_address": "0x140001950",
"instructions": [
{ "address": "0x140001950", "bytes": "c3", "itype": 159, "size": 1 }
]
}
}$ ida-cli -i "Warcraft III.exe" type list{
"success": true,
"data": {
"count": 13,
"types": [
{ "ordinal": 1, "name": "_GUID", "definition": "_GUID", "kind": "struct" },
{ "ordinal": 2, "name": "GUID", "definition": "GUID", "kind": "struct" },
{ "ordinal": 3, "name": "RUNTIME_FUNCTION", "definition": "RUNTIME_FUNCTION", "kind": "struct" },
{ "ordinal": 4, "name": "UNWIND_INFO_HDR", "definition": "UNWIND_INFO_HDR", "kind": "struct" }
]
}
}$ ida-cli -i "Warcraft III.exe" type struct _GUID{
"success": true,
"data": {
"name": "_GUID",
"size": 16,
"member_count": 4,
"members": [
{ "name": "Data1", "offset": 0, "size": 4, "type_name": "unsigned int" },
{ "name": "Data2", "offset": 4, "size": 2, "type_name": "unsigned __int16" },
{ "name": "Data3", "offset": 6, "size": 2, "type_name": "unsigned __int16" },
{ "name": "Data4", "offset": 8, "size": 8, "type_name": "unsigned __int8[8]" }
]
}
}$ ida-cli -i "Warcraft III.exe" debugger info{
"success": true,
"data": {
"available": false,
"address_size": 0,
"platform": "",
"debugger_count": 6,
"available_debuggers": ["bochs", "pin", "gdb", "win32", "xnu", "replay"],
"note": "Note: No debugger is currently loaded. Full debugger functionality requires interactive IDA mode"
}
}# Patch a single byte
$ ida-cli -i binary.i64 patch byte 0x401000 0x90{
"success": true,
"data": { "address": "0x401000", "value": "0x90" }
}# List all patches
$ ida-cli -i binary.i64 patch list{
"success": true,
"data": {
"count": 1,
"patches": [
{ "address": "0x401000", "original": "0x55", "patched": "0x90" }
]
}
}$ ida-cli -i "Warcraft III.exe" idc eval "GetFunctionName(0x140004070)"{
"success": true,
"data": {
"expression": "GetFunctionName(0x140004070)",
"result": "TlsCallback_0",
"type": "string"
}
}All commands return JSON with consistent structure:
Success:
{
"success": true,
"data": { ... }
}Error:
{
"success": false,
"error": "error message"
}# Get all function names
ida-cli -i binary.exe functions list | jq -r '.data[].name'
# Count functions
ida-cli -i binary.exe functions list | jq '.data | length'
# Find functions matching pattern
ida-cli -i binary.exe functions list --pattern "init" | jq '.data[].address'#!/bin/bash
# Batch decompile all functions matching pattern
for addr in $(ida-cli -i "$1" functions list --pattern "$2" | jq -r '.data[].address'); do
ida-cli -i "$1" decompile "$addr" | jq -r '.data.pseudocode' > "decomp_${addr}.c"
doneimport subprocess
import json
def ida_cli(idb_path, *args):
result = subprocess.run(
["ida-cli", "-i", idb_path] + list(args),
capture_output=True, text=True,
env={**os.environ, "IDADIR": "/opt/ida-pro-9.2"}
)
return json.loads(result.stdout)
# Get binary info
info = ida_cli("binary.exe", "info")
print(f"Entry point: {info['data']['entry_point']}")
# List functions
funcs = ida_cli("binary.exe", "functions", "list", "--limit", "100")
for f in funcs['data']:
print(f"{f['address']}: {f['name']}")ida-cli (Rust CLI)
└── idalib (Rust safe wrappers)
└── idalib-sys (FFI bindings via autocxx)
└── IDA SDK 9.x (C++ headers)
└── libidalib.so / libida.so
MIT