bn
An agent-friendly CLI for the Binary Ninja database already open in your GUI. Read decompilation, assembly, references, and types; run unrestricted in-process Python; apply mutations with preview and live verification. The GUI companion works with a personal license and requires no headless license.
Install
uv tool install bn-cli
bn plugin install
bn skill install
The last two commands link the packaged plugin into Binary Ninja and the skill into $CODEX_HOME/skills (default ~/.codex/skills). Use --mode copy for standalone copies. Restart Binary Ninja after installing or upgrading the plugin; restart Codex to discover a newly installed skill.
Upgrade with uv tool upgrade bn-cli. Reload Python plugins or restart Binary Ninja after code changes: Restart Bridge alone restarts the socket with the already-loaded Python code.
Start with a target
bn target list
bn decompile player_update --target crimsonland.exe.bndb
With exactly one open view, omit --target. With several, use the returned selector; omission fails instead of silently choosing a GUI tab. --target works anywhere in the command, and BN_TARGET sets a shell default. Use --target active only to deliberately follow the selected GUI tab.
Common reads
bn function search player
bn function search --regex 'attach|detach'
bn function info player_update
bn function info player_update --locals
bn decompile player_update
bn il player_update --view mlil --ssa
bn disasm player_update
bn disasm 0x401234 --count 20
bn disasm 0x401234 --end 0x401280
bn xrefs player_update
bn refs player_update
bn callsites crt_rand --within bonus_pick_random_type
bn address info global_player+0x308
bn data read global_player+0x308 --type u32 --count 4
bn struct show Player
bn types show Player
bn search text crt_rand --view hlil --max-results 50
Function reads accept a name or an address inside a function. Address reads also accept symbols and symbol+offset. Function lists/searches support --min-address and --max-address.
function info returns a compact summary; --locals or local list expands variables with stable IDs. xrefs finds inbound references; refs finds outbound references. callsites recovers native call addresses and exact post-call return addresses, with optional local HLIL/branch context. See the callsite reference for scoped and caller-static workflows.
Linear disasm --count/--end works without function analysis; --end is exclusive. Results report unmapped or undecodable stopping points. For analyzed-function windows, use --before-instructions/--after-instructions. Legacy --before/--after still select instruction windows without --match; with --match, they consistently mean text-line context.
Whole-database search text and search constant have a five-second default analysis budget and report incomplete results. Increase their --timeout explicitly when needed; function search does not take that option.
For the full command surface, use bn --help. Use scoped help or machine-readable discovery for details:
bn disasm --help
bn schema disasm
bn schema function info
Schema output defines common arguments once and references them from each command, with per-command defaults. It requires no live bridge.
Output and bundles
Read commands default to text; mutations, setup, and bundles default to JSON.
| Option | Behavior |
|---|---|
--format json / ndjson |
Complete structured stdout by default |
--out <path> |
Write the full result; return its artifact envelope |
--spill |
Explicitly allow large structured results to become artifact envelopes |
--no-spill |
Stream complete text for pipelines |
--match <regex> |
Keep matching text with optional --before/--after context |
--tokens |
Request optional token counts in artifact metadata |
Text above 40,000 bytes spills to a unique file, leaving a short preview on stdout and metadata on stderr. Explicit structured spills return an envelope on stdout. Artifact metadata includes path, format, bytes, SHA-256, and a summary. Normal output needs no tokenizer; install the bn-cli[tokens] extra for exact artifact counts. Unavailable tokenization produces a warning without losing the artifact.
bn decompile player_update --match 'health|damage' --before 2 --after 3
bn bundle function player_update projectile_update --include decompile,disasm --out /tmp/functions.json
Bundles default to decompile, disassembly, and outbound references. Select decompile,mlil,llil,disasm,locals,comments,xrefs,refs, or all for full export. HLIL appears only once. Multiple identifiers are deduplicated; per-function errors preserve successful reads and produce a nonzero exit status.
Python
bn py runs Python with unrestricted bn/binaryninja and bv/current_view access. bn py exec remains an alias. Use --code for one-liners, --script for saved files, or pipe multiline code with a quoted heredoc:
bn py <<'PY'
f = function("player_update")
result = {"address": hex(f.start), "instructions": sum(1 for _ in f.hlil.instructions)}
PY
Helpers include address, function, functions_containing, typed read_u*/read_i*, read_ptr, read_f32, read_f64, and read_cstr. BN iterators may need materialization. Both stdout and result are returned; non-JSON results use repr with a warning. Syntax errors are caught locally; runtime errors retain the in-process traceback. Raw Python writes do not inherit built-in mutation rollback or verification.
Mutations
bn symbol rename sub_401000 player_update --preview
bn proto set player_update 'void player_update(Player* self)' --preview
bn struct field set Player 0x308 movement_flag_selector uint32_t --preview
bn types declare --file /path/to/types.h --preview
Preview applies, refreshes, verifies, captures diffs, then reverts. Omit --preview to commit a verified change. Failures roll back; results distinguish verified, noop, unsupported, and verification_failed, with requested/observed state where relevant. Use IDs from local list for local edits. Type imports preserve the source path for relative includes; declarations with no named types to persist report a no-op.
Read back the relevant prototype/type and decompile after changes. types show and struct show are authoritative when HLIL still displays stale __offset(...) expressions. bn refresh refreshes analysis but may not eliminate every presentation artifact.
Troubleshooting and development
bn doctor checks discovery, capabilities, installed code, and stale loaded plugin versions. If no targets appear, open a database and check that the companion is loaded. A socket Operation not permitted under Codex indicates sandbox access; run the authorized bn command outside that sandbox. Avoid reinstalling the plugin to fix a permission denial.
uv sync --locked
uv run pytest
uv run bn --help
uv run python scripts/release.py --check
uv build
For editable development, use uv tool install -e .. To prepare a release, run uv run python scripts/release.py <version>, update CHANGELOG.md, commit, and push the matching v<version> tag. CI tests Python 3.12/3.14, verifies the wheel, publishes to PyPI, and creates the GitHub release. The CLI and companion must use the same protocol version; restart/reload the companion after upgrades.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bn_cli-0.15.0.tar.gz.
File metadata
- Download URL: bn_cli-0.15.0.tar.gz
- Upload date:
- Size: 55.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ac66c5b31a04a8f73d7802ef11303281244006c972d3f0a52bbebf12da850be
|
|
| MD5 |
e44a522b1fd2febfcc427ac9050c6a6b
|
|
| BLAKE2b-256 |
b07b3508c1c619821a712c8457cdbec0524ff72333bca6eff8760bc9295496be
|
Provenance
The following attestation bundles were made for bn_cli-0.15.0.tar.gz:
Publisher:
publish.yml on banteg/bn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bn_cli-0.15.0.tar.gz -
Subject digest:
6ac66c5b31a04a8f73d7802ef11303281244006c972d3f0a52bbebf12da850be - Sigstore transparency entry: 2716276235
- Sigstore integration time:
-
Permalink:
banteg/bn@bd910329547303c787a68fcd8309e83ab1be6590 -
Branch / Tag:
refs/tags/v0.15.0 - Owner: https://github.com/banteg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bd910329547303c787a68fcd8309e83ab1be6590 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bn_cli-0.15.0-py3-none-any.whl.
File metadata
- Download URL: bn_cli-0.15.0-py3-none-any.whl
- Upload date:
- Size: 62.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
50f36f52bd34e6869a1fcf83048687ccfb9d11430141aa3a00f3475dad02b446
|
|
| MD5 |
bbce02af3d20ea7e2ca2b9442b0f32c4
|
|
| BLAKE2b-256 |
efe118b3aa53c52b36f5c505a6e798e8834475010e2ef1f425ad3712820eaa39
|
Provenance
The following attestation bundles were made for bn_cli-0.15.0-py3-none-any.whl:
Publisher:
publish.yml on banteg/bn
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bn_cli-0.15.0-py3-none-any.whl -
Subject digest:
50f36f52bd34e6869a1fcf83048687ccfb9d11430141aa3a00f3475dad02b446 - Sigstore transparency entry: 2716276357
- Sigstore integration time:
-
Permalink:
banteg/bn@bd910329547303c787a68fcd8309e83ab1be6590 -
Branch / Tag:
refs/tags/v0.15.0 - Owner: https://github.com/banteg
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@bd910329547303c787a68fcd8309e83ab1be6590 -
Trigger Event:
push
-
Statement type: