Skip to content

Repository files navigation

idalib-cli️ idalib-cli

Agent-native CLI for the IDA Pro IDALib — every command takes one -d/--db flag, every answer is JSON.

English · 中文

IDA Pro 9.1 idalib-rs 0.6.1 v0.9.1 Apache-2.0


✨ Features

  • 🗄️ Stateless — pass -d/--db <PATH> (a binary or an .i64); no daemon, no session bookkeeping.
  • 💾 Persistent IDB state — the IDB file is the state: comments, bookmarks, names and analysis survive across processes.
  • 🧩 Full IDALib coverage — segments, functions, CFG, disassembly, Hex-Rays decompilation, strings, names, xrefs, entries, metadata, comments, bookmarks, FLIRT signatures.
  • batch & parallel — run many commands with one IDB open; fan a command out to many databases concurrently (glob supported).
  • 🤖 Agent-first — one JSON document on stdout, errors on stderr; skills included for Codex / Claude Code / OpenCode.

🚀 Install

Prerequisites: IDA Pro 9.1 (licensed, launched once) · IDA 9.1 SDK unpacked (build time only) · Rust + LLVM/Clang (bindgen requirements)

export IDADIR="/Applications/IDA Professional 9.1.app/Contents/MacOS"  # IDA install dir
export IDASDKDIR=/path/to/idasdk91                                     # unpacked SDK (absolute path!)

git clone <this-repo> && cd idalib-cli
cargo install --path .

idalib-cli info    # ✅ verify tool version, IDA version, license

The SDK is needed at build time only; the binary links your local IDA libraries at runtime. Dev checks without an SDK: cargo test --no-default-features --features stub-idalib.

🎮 Commands & usage

Every command needs -d/--db <PATH> — an IDB file (.i64) or a binary (an IDB is created next to it on first use). Addresses accept 0x401000 or 401000. Output is always one JSON document; errors go to stderr with a non-zero exit code.

Database

Command Description
idalib-cli -d <bin-or-i64> db info Resolved paths, IDB state, size

Query

Command Description
idalib-cli -d <db> meta Filetype, compiler, bitness
idalib-cli -d <db> processor Processor info
idalib-cli -d <db> segments All segments
idalib-cli -d <db> segments-by-range -a <ea> Segment containing an address
idalib-cli -d <db> functions [-u] Function list (-u = skip lib/thunk)
idalib-cli -d <db> function -a <ea> One function: CFG, blocks, xrefs
idalib-cli -d <db> disasm -a <ea> [-n N] Disassemble N instructions (default 8)
idalib-cli -d <db> decompile -a <ea> [--all-blocks] Hex-Rays pseudo-code
idalib-cli -d <db> insn -a <ea> Single instruction (+ group/is_call/is_ret classification)
idalib-cli -d <db> strings String list
idalib-cli -d <db> names Named locations
idalib-cli -d <db> xrefs [-a <ea>] [--all] [--from] Xrefs to an address (default) or from it (--from), or all
idalib-cli -d <db> find --text <s> Search text hits
idalib-cli -d <db> find --imm 0x1337 Search immediate-value hits
idalib-cli -d <db> find --pattern 554889e5 Search a hex byte pattern
idalib-cli -d <db> bytes -a <ea> [-n N] [--width byte|word|dword|qword] Raw bytes (hexdump) or little-endian integers
idalib-cli -d <db> entries Entry points

Edit (persisted in the IDB)

Command Description
idalib-cli -d <db> comments get|set|append|remove -a <ea> [-c "text"] Comments
idalib-cli -d <db> bookmarks list|add|get|remove -a <ea> [-d "desc"] Bookmarks
idalib-cli -d <db> rename -a <ea> -n <name> Rename a function / data label
idalib-cli -d <db> set-type -a <ea> -t "int f(int, char *);" Apply a C type declaration (function prototype / data type)
idalib-cli -d <db> signatures --make [--only-pat] Generate FLIRT signatures

Combine

Command Description
idalib-cli -d <db> batch -- <op> [<op>...] Sequential ops, IDB opened once
idalib-cli parallel -d <list|glob> [--jobs N] -- <op> One op across many DBs, subprocess each
idalib-cli info [--version|--ida|--all] Tool / IDA version, license

Scenario walkthroughs

🔎 Triage an unknown binary

idalib-cli -d ./sample meta            # what is it? (filetype/compiler/bitness)
idalib-cli -d ./sample segments        # memory layout
idalib-cli -d ./sample strings         # quick hints
idalib-cli -d ./sample functions -u    # user code only

🔍 Dig into a function

idalib-cli -d ./sample function -a 0x401000       # CFG + blocks + xrefs
idalib-cli -d ./sample decompile -a 0x401000      # read the pseudo-code
idalib-cli -d ./sample disasm -a 0x401000 -n 20   # or the raw instructions
idalib-cli -d ./sample xrefs -a 0x401000 --all    # who calls it

📝 Annotate findings (survives across processes/agents)

idalib-cli -d ./sample comments set -a 0x401000 -c "parses config, see 0x402100"
idalib-cli -d ./sample bookmarks add -a 0x401000 -d "entry point"
idalib-cli -d ./sample comments get -a 0x401000    # verify

⚡ Bulk analysis of many samples

# first pass: create IDBs + overview for every sample
idalib-cli parallel -d "./samples/*.bin" -- "batch -- meta functions -u"

# deep pass: decompile one hot function in every IDB
idalib-cli parallel -d "./samples/*.i64" --jobs 8 -- "decompile -a 0x401000"

🔎 Search & inspect raw data

idalib-cli -d ./sample find --text "MAGIC"            # string hits
idalib-cli -d ./sample find --imm 0x1337              # immediate-value hits
idalib-cli -d ./sample find --pattern 554889e5        # byte pattern (prologue)
idalib-cli -d ./sample bytes -a 0x401000 -n 32        # hexdump
idalib-cli -d ./sample bytes -a 0x401000 --width qword -n 4
idalib-cli -d ./sample xrefs -a 0x401000 --from       # outgoing refs (calls)
idalib-cli -d ./sample rename -a 0x401000 -n decrypt  # label it
idalib-cli -d ./sample set-type -a 0x401000 -t "int f(const char *, int);"  # set prototype

🤖 Agent-friendly batched inspection (one JSON doc)

idalib-cli -d ./sample batch -- "meta" "segments" "functions -u" "decompile -a 0x401000"

Agent workflow guide: skills/idalib-cli/SKILL.md; a runnable end-to-end example in examples/workflow.sh.

Sample output (decompile)
{
  "id": 7,
  "start": "0x401000",
  "end": "0x401080",
  "size": 128,
  "name": "main",
  "blocks": 3,
  "decompiled": true,
  "pseudocode": "int __cdecl main(...) { ... }"
}

⚙️ Configuration

Optional ~/.idapro/idalib-cli/config.toml (base dir: $IDALIB_CLI_HOME):

Field Description
idadir IDA install dir (default: auto-detected)
idb_dir Where new IDBs are created (default: next to the binary)
default_db Used when -d is omitted
save Save the IDB after each command (default true)
auto_analyse Run full auto-analysis when creating an IDB (default true)

❓ FAQ

Where does the IDB go when I pass a binary?

Next to the binary: ./target.bin./target.bin.i64. Set idb_dir in the config to change the location.

What do batch / parallel actually do?

batch opens the IDB once and runs every op against that handle (saves once at the end) — best when you need several facts about one database. parallel spawns one subprocess per database (IDALib is not thread-safe, so isolation is by process) with a worker pool capped by --jobs — best for many samples. -d accepts a single path, a comma-separated list, or a glob (*.i64).

Can two processes use the same IDB at once?

Don't. One process per IDB at a time. parallel respects this by spawning one subprocess per database; for manual multi-agent work, give each agent its own -d target.

Why does building require the IDA SDK?

idalib-rs generates its FFI bindings at compile time by parsing the SDK headers (bindgen). The SDK ships only with your Hex-Rays license and is never redistributed or embedded — the built binary links your own IDA installation at runtime.

📁 Project structure

idalib-cli/
├── src/
│   ├── cli.rs            # clap definitions; every command + -d/--db
│   ├── ops/              # metadata, comments, bookmarks, db, batch, parallel, ...
│   ├── session/          # config.toml handling
│   └── helpers/          # JSON output views
├── stubs/idalib/         # dev-only API stub (SDK-free checks, never shipped)
├── tests/                # integration tests
├── skills/idalib-cli/   # single agent skill (workflow guide)
└── examples/workflow.sh  # runnable end-to-end example

🌿 Versions & branches

Tool versions are x.y.z; one dev + one release branch per minor:

Ref Purpose Example
main latest development (merge target of v*_dev)
v0.9_dev development branch for tool 0.9.x current work
v0.9_release stable branch for tool 0.9.x (fixes only) backports
v0.9.1 (tag) release point current release
Tool version Compatible IDA idalib-rs
0.9.x 9.1 0.6.1 (pinned =0.6.1)
next (v0.10_*) new IDA version bumped dependency

Supporting a new IDA version = bump the idalib dependency, update [package.metadata.ida] in Cargo.toml, open a new branch line (v0.10_*).

📄 License

Distributed under the Apache License 2.0. The license field in Cargo.toml declares MIT OR Apache-2.0 for compatibility with idalib-rs dependencies; this repository ships the Apache-2.0 text only. Never commit or redistribute the IDA SDK.


English · 中文

About

A IDA CLI tool built on Rust, idalib-rs, and idalib. Supports batch and concurrent IDA analysis processes, design for stateless, agent first, skill first, and automation first. Reduce AI understanding and friction costs, make agents to efficiently execute complex binary analysis tasks.

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages