[GH-ISSUE #1551] Feature: Add support for Binary Ninja as an analysis backend #524

Open
opened 2026-10-15 18:25:50 +00:00 by bsakaguchi · 8 comments
Owner

Originally created by @peter-research on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1551

Summary

REA already integrates Hopper, Ghidra and IDA. Binary Ninja is a popular commercial/open-core reverse-engineering platform with a solid Python API and headless capabilities.

Motivation

  • Broader tool coverage for users who already own Binary Ninja licenses.
  • Binary Ninja’s intermediate language and type system can complement existing backends.
  • Headless mode would fit REA’s agent-driven workflow well.

Proposed approach

  • New backend registration similar to existing Ghidra/Hopper providers.
  • Prefer Binary Ninja’s Python API / headless interface.
  • Keep the same evidence + limitations reporting model.

I can help prototype the adapter if maintainers are interested.

Originally created by @peter-research on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1551 ## Summary REA already integrates Hopper, Ghidra and IDA. Binary Ninja is a popular commercial/open-core reverse-engineering platform with a solid Python API and headless capabilities. ## Motivation - Broader tool coverage for users who already own Binary Ninja licenses. - Binary Ninja’s intermediate language and type system can complement existing backends. - Headless mode would fit REA’s agent-driven workflow well. ## Proposed approach - New backend registration similar to existing Ghidra/Hopper providers. - Prefer Binary Ninja’s Python API / headless interface. - Keep the same evidence + limitations reporting model. I can help prototype the adapter if maintainers are interested.
Author
Owner

@0xdevalias commented on GitHub (Oct 11, 2026):

I would also really love to see Binary Ninja integration as a backend; though headless mode isn't available in the free / personal ($199) licences (starts at commercial: $1799). The plugin API is available in personal and above, but not free.

There is also the official Binary Ninja MCP; where the GUI version runs in all versions seemingly; and the headless version follows the same availability of headless in general:

<!-- gh-comment-id:6103926698 --> @0xdevalias commented on GitHub (Oct 11, 2026): I would also really love to see Binary Ninja integration as a backend; though headless mode isn't available in the free / personal ($199) licences (starts at commercial: $1799). The plugin API is available in personal and above, but not free. - https://binary.ninja/purchase/#non-commercial There is also the official Binary Ninja MCP; where the GUI version runs in all versions seemingly; and the headless version follows the same availability of headless in general: - https://docs.binary.ninja/guide/mcp.html
Author
Owner

@psifertex commented on GitHub (Oct 13, 2026):

https://github.com/morluto/rea/pull/784 seems to address this but it's not clear to my why it was closed.

<!-- gh-comment-id:6146910865 --> @psifertex commented on GitHub (Oct 13, 2026): https://github.com/morluto/rea/pull/784 seems to address this but it's not clear to my why it was closed.
Author
Owner

@kennedyoliveira commented on GitHub (Oct 14, 2026):

Interested in this one, seems the binary ninja mcp is probably the best way to support this, since it does not require a commercial license.

<!-- gh-comment-id:6179245024 --> @kennedyoliveira commented on GitHub (Oct 14, 2026): Interested in this one, seems the binary ninja mcp is probably the best way to support this, since it does not require a commercial license.
Author
Owner

@psifertex commented on GitHub (Oct 19, 2026):

I'm curious why the proposed implementation is read-only? Does that mirror the other tools? Likewise, I don't understand the concern with the expression evaluator?

<!-- gh-comment-id:6277764248 --> @psifertex commented on GitHub (Oct 19, 2026): I'm curious why the proposed implementation is read-only? Does that mirror the other tools? Likewise, I don't understand the concern with the expression evaluator?
Author
Owner

@ewrogers commented on GitHub (Oct 22, 2026):

I've continued this work in https://github.com/morluto/rea/pull/5794, building on @BigLongs0's #4886 and preserving the original commit attribution.

It uses the MCP server built into the Binary Ninja 6 GUI, including Personal editions, so it doesn't need the headless API. REA reads the file already open in Binary Ninja. It changes the shared active-view selection and restores it when the session closes, but doesn't save or close the analyst's database.

The current revision passed all eight production CLI/MCP verifier checks on macOS ARM64 with Binary Ninja Personal 6.0.10905. That covers function switching, selection restoration, and unchanged input bytes. The PR also includes fixes and regression tests for byte identity after edits, startup pagination, and setup timeout handling.

Maintainer approval for the new provider is still pending. Sharing the current PR here so people following this issue can find it and weigh in on the GUI MCP approach.

<!-- gh-comment-id:6332301235 --> @ewrogers commented on GitHub (Oct 22, 2026): I've continued this work in https://github.com/morluto/rea/pull/5794, building on @BigLongs0's #4886 and preserving the original commit attribution. It uses the MCP server built into the Binary Ninja 6 GUI, including Personal editions, so it doesn't need the headless API. REA reads the file already open in Binary Ninja. It changes the shared active-view selection and restores it when the session closes, but doesn't save or close the analyst's database. The current revision passed all eight production CLI/MCP verifier checks on macOS ARM64 with Binary Ninja Personal 6.0.10905. That covers function switching, selection restoration, and unchanged input bytes. The PR also includes fixes and regression tests for byte identity after edits, startup pagination, and setup timeout handling. Maintainer approval for the new provider is still pending. Sharing the current PR here so people following this issue can find it and weigh in on the GUI MCP approach.
Author
Owner

@ihabontop commented on GitHub (Oct 24, 2026):

I'd like to ask for the maintainer scope decision CONTRIBUTING requires before a headless Binary Ninja provider moves toward integration. It complements, rather than replaces, the GUI MCP adapter in #5794: #5794 attaches to a file the analyst already has open in the GUI; this one starts an owned headless interpreter and analyzes the file from scratch, so it needs no GUI but does need a license edition that permits headless use (Vector35 documents that as Commercial, Ultimate and headless licenses).

Prototype: draft #7041 (branch feat/binary-ninja-headless on my fork).

Proposed behavior and boundaries

  • Provider id binary-ninja-headless, module src/binaryNinjaHeadless/, chosen to avoid a case-only collision with #5794's src/binaryNinja/ on Windows and macOS filesystems.
  • Discovery reads only the filesystem: BINARY_NINJA_INSTALL_DIR (default probed at the vendor install root on Windows/macOS), REA_BINARY_NINJA_PYTHON (defaults to the Windows bundled CPython), REA_BINARY_NINJA_STARTUP_TIMEOUT_MS (180 s default). No interpreter starts during doctor or selection.
  • On the first request REA starts python -I -u bridge/binaryninja/rea_binaryninja_bridge.py --api-dir <install>/python as an owned process (existing spawnOwnedProviderProcess + ProviderProcessSupervisor) with BN_DISABLE_USER_PLUGINS, BN_DISABLE_REPOSITORY_PLUGINS and BN_DISABLE_USER_SETTINGS set, speaks NDJSON over stdio, and keeps Binary Ninja's own log on stderr.
  • The bridge loads with update_analysis=False, hashes the Raw parent view and requires it to equal the admitted SHA-256 and the view type to match the admitted format before update_analysis_and_wait(). No .bndb is created or saved; close releases the view and REA stops the process.
  • Read-only operations: list_documents, list_procedures, search_procedures, list_strings, search_strings, procedure_address, procedure_pseudo_code (Pseudo C), procedure_assembly, read_function_instructions, procedure_callers, procedure_callees, xrefs, resolve_containing_procedure, analyze_function (shared dossier with body ranges, locals, comments, basic blocks, incoming/outgoing reference edges and unresolved call sites). cachePolicy: live; the profile commits the installation facts, not the engine version.
  • Effects advertised: launches a process, writes only Binary Ninja's own user directory, no UI, no network from REA.

Open questions for maintainers

  1. Is a second Binary Ninja provider (headless, owned analysis) acceptable alongside #5794's attached GUI adapter, or should both become modes of one binary-ninja provider? I kept them separate so neither blocks the other.
  2. list_segments: the segment output contract only admits Hopper and Ghidra provenance literals. Should it be extended with a Binary Ninja provenance, or should segments stay out until a provider-neutral provenance exists?
  3. Engine version in the profile: a probe at profile resolution would allow snapshot replay; is the extra ~1 s interpreter start at open_binary acceptable, or should results stay live?

Verification so far

Adapter tests use a Node fixture speaking the bridge protocol; the bridge has Python unit tests against a fake binaryninja module; npm run check:fast passes. One real-engine run by hand on Windows 11 x64 with Binary Ninja 6.0.10905 and the shipped where.exe: decompile, function --detail complete, analyze, search and trace through the production CLI all parsed against the built Evidence schemas and output contracts (~5.8 s wall clock cold per one-shot run, ~2.6 s of it load + auto-analysis). MCP parity, Linux/macOS, ELF/Mach-O targets and other releases are unverified; a verify:binary-ninja-headless lane modeled on the IDA verifier is the proposed next step.

<!-- gh-comment-id:6389505485 --> @ihabontop commented on GitHub (Oct 24, 2026): I'd like to ask for the maintainer scope decision CONTRIBUTING requires before a **headless** Binary Ninja provider moves toward integration. It complements, rather than replaces, the GUI MCP adapter in #5794: #5794 attaches to a file the analyst already has open in the GUI; this one starts an owned headless interpreter and analyzes the file from scratch, so it needs no GUI but does need a license edition that permits headless use (Vector35 documents that as Commercial, Ultimate and headless licenses). **Prototype:** draft #7041 (branch `feat/binary-ninja-headless` on my fork). **Proposed behavior and boundaries** - Provider id `binary-ninja-headless`, module `src/binaryNinjaHeadless/`, chosen to avoid a case-only collision with #5794's `src/binaryNinja/` on Windows and macOS filesystems. - Discovery reads only the filesystem: `BINARY_NINJA_INSTALL_DIR` (default probed at the vendor install root on Windows/macOS), `REA_BINARY_NINJA_PYTHON` (defaults to the Windows bundled CPython), `REA_BINARY_NINJA_STARTUP_TIMEOUT_MS` (180 s default). No interpreter starts during doctor or selection. - On the first request REA starts `python -I -u bridge/binaryninja/rea_binaryninja_bridge.py --api-dir <install>/python` as an owned process (existing `spawnOwnedProviderProcess` + `ProviderProcessSupervisor`) with `BN_DISABLE_USER_PLUGINS`, `BN_DISABLE_REPOSITORY_PLUGINS` and `BN_DISABLE_USER_SETTINGS` set, speaks NDJSON over stdio, and keeps Binary Ninja's own log on stderr. - The bridge loads with `update_analysis=False`, hashes the Raw parent view and requires it to equal the admitted SHA-256 and the view type to match the admitted format before `update_analysis_and_wait()`. No `.bndb` is created or saved; close releases the view and REA stops the process. - Read-only operations: `list_documents`, `list_procedures`, `search_procedures`, `list_strings`, `search_strings`, `procedure_address`, `procedure_pseudo_code` (Pseudo C), `procedure_assembly`, `read_function_instructions`, `procedure_callers`, `procedure_callees`, `xrefs`, `resolve_containing_procedure`, `analyze_function` (shared dossier with body ranges, locals, comments, basic blocks, incoming/outgoing reference edges and unresolved call sites). `cachePolicy: live`; the profile commits the installation facts, not the engine version. - Effects advertised: launches a process, writes only Binary Ninja's own user directory, no UI, no network from REA. **Open questions for maintainers** 1. Is a second Binary Ninja provider (headless, owned analysis) acceptable alongside #5794's attached GUI adapter, or should both become modes of one `binary-ninja` provider? I kept them separate so neither blocks the other. 2. `list_segments`: the segment output contract only admits Hopper and Ghidra provenance literals. Should it be extended with a Binary Ninja provenance, or should segments stay out until a provider-neutral provenance exists? 3. Engine version in the profile: a probe at profile resolution would allow snapshot replay; is the extra ~1 s interpreter start at `open_binary` acceptable, or should results stay live? **Verification so far** Adapter tests use a Node fixture speaking the bridge protocol; the bridge has Python unit tests against a fake `binaryninja` module; `npm run check:fast` passes. One real-engine run by hand on Windows 11 x64 with Binary Ninja 6.0.10905 and the shipped `where.exe`: `decompile`, `function --detail complete`, `analyze`, `search` and `trace` through the production CLI all parsed against the built Evidence schemas and output contracts (~5.8 s wall clock cold per one-shot run, ~2.6 s of it load + auto-analysis). MCP parity, Linux/macOS, ELF/Mach-O targets and other releases are unverified; a `verify:binary-ninja-headless` lane modeled on the IDA verifier is the proposed next step.
Author
Owner

@ewrogers commented on GitHub (Oct 25, 2026):

Thanks for keeping the GUI adapter in mind. Separate providers seem reasonable to me, since they have different workflows and license requirements. Happy to coordinate if the maintainer prefers a shared provider.

<!-- gh-comment-id:6399823853 --> @ewrogers commented on GitHub (Oct 25, 2026): Thanks for keeping the GUI adapter in mind. Separate providers seem reasonable to me, since they have different workflows and license requirements. Happy to coordinate if the maintainer prefers a shared provider.
Author
Owner

@morluto commented on GitHub (Oct 26, 2026):

Also linking #7095, another request for Binary Ninja integration, which I closed as a duplicate so the discussion can stay here. The GUI proposal #5794 and headless proposal #7041 remain separate open scope discussions.

<!-- gh-comment-id:6428348758 --> @morluto commented on GitHub (Oct 26, 2026): Also linking #7095, another request for Binary Ninja integration, which I closed as a duplicate so the discussion can stay here. The GUI proposal #5794 and headless proposal #7041 remain separate open scope discussions.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#524
No description provided.