Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
ghidra_svr_bridge — Binary Ninja plugin that syncs analysis bidirectionally with a Ghidra Server repository, via a Java bridge subprocess. | Kitploit
Tools/GitHubGitHub/gmh5225/ghidra_svr_bridge
Static AnalysisCode AnalysisReverse EngineeringScripting & AutomationUtilities & FrameworksBinary Analysis
GitHubgmh5225/ghidra_svr_bridge

ghidra_svr_bridge

Binary Ninja plugin that syncs analysis bidirectionally with a Ghidra Server repository, via a Java bridge subprocess.

View Repository
252 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

binja-ghidra

A Binary Ninja plugin that connects to a Ghidra Server repository and imports its analysis — symbols, function names, and comments — directly into an open Binary Ninja binary view.

What it does

Ghidra and Binary Ninja each have strengths. This plugin lets you use both on the same binary without manually copying names or comments between them. Connect to a running Ghidra Server, browse its repositories, and double-click any project file to pull its analysis into the currently open BN view.

Sync goes both directions.

BN ← Ghidra (import)BN → Ghidra (checkin)
Symbols (labels, function names)✓✓
Comments (EOL/PRE/POST/PLATE/REP)✓✓
Function signatures (return type, calling convention)✓✓
Function parameters (rename, retype, add)✓✓
Data types (struct/union/enum/typedef + pointer/array)✓✓
Equates (constant names + references)✓✓
Bookmarks✓✓
Typed data items✓✓
Function flags (thunk, no-return, inline)✓ as BN tags—
Local variables (storage-aware)✓partial — register-storage mapping not implemented

Architecture

Binary Ninja (C++ plugin)
    │  TCP / newline-delimited JSON
    ▼
ghidra-bridge-*.jar  (Java, runs as a subprocess)
    │  Java RMI / SSL
    ▼
Ghidra Server  (ghidraSvr, running on the network)

The plugin spawns a Java subprocess (the "bridge") on load. The bridge holds the RMI connection to the Ghidra Server and speaks a simple JSON protocol back to the plugin over a local TCP socket. This keeps all Java/RMI code out of the C++ process and lets the JVM start in the background while BN finishes loading.

The bridge JVM also initialises Ghidra's Application framework at startup so the write path can use Ghidra's high-level program-model APIs (ProgramDB, DataTypeManager, SymbolTable, FunctionManager) rather than raw db.Table.putRecord() writes — see Checkin write path below.

Components

PathLanguageRole
plugin/C++ / Qt6Binary Ninja sidebar plugin
bridge/Java 17Ghidra RMI client + JSON bridge server

Plugin (C++):

  • plugin.cpp — registers settings and the sidebar widget; eagerly starts the bridge JVM on load
  • GhidraConnection.cpp — singleton; manages bridge lifecycle and all RMI-backed operations
  • BridgeProcess.cpp — launches the bridge JAR as a subprocess with stdout/stderr pipes; reads the READY port=N handshake line
  • BridgeClient.cpp — TCP client; sends JSON requests, receives responses, dispatches async events
  • SyncEngine.cpp — applies a GhidraDbExport to a BinaryView (symbols, comments, flags)
  • ui/ProjectPanel.cpp — sidebar widget: repo tree, connect dialog, activity log
  • ui/ConnectDialog.cpp — host/port/user/password dialog

Bridge (Java):

  • BridgeMain.java — argument parsing; initialises UniversalIdGenerator and the Ghidra Application framework; starts the TCP server; prints READY port=N to stdout
  • BridgeServer.java — accepts one TCP client connection and hands it a BridgeConnection
  • BridgeConnection.java — JSON request dispatcher; serialises Ghidra API responses to JSON; handles opCheckin (creates a new program version on the server)
  • GhidraSession.java — authenticated RMI session; wraps RemoteRepositoryServerHandle
  • EventStreamer.java — background thread per open repo; pushes RepositoryChangeEvents to the plugin as async JSON events
  • DatabaseExporter.java — read path: extracts symbol/comment/function-flag/data-type/equate/bookmark tables from a ManagedBufferFileHandle (Ghidra's remote DB buffer) via raw db.jar access
  • ProgramApplier.java — write path: opens the buffer file as a real ProgramDB and applies all BN-side changes through Ghidra's high-level APIs (see Checkin write path below)
  • DatabaseImporter.java — legacy raw-write helpers kept only as a test seam; production apply(...) delegates to ProgramApplier

Checkin write path

opCheckin opens the program's managed buffer file in write mode, constructs a ProgramDB over it, and applies BN-side changes through Ghidra's program-model APIs. Raw db.Table.putRecord() writes are avoided — they were the source of every checkin-corruption bug we ever hit:

Wrong-tier writeFailure mode
setIntValue(col, longTypeId) on Function Data tableIntField.setLongValue silently l2i-truncates → StackPurge corrupted on every signature update
setByteValue(col, isUnion) on V5V6 Composite Data Typescolumn is BooleanField in Ghidra 12.x → IllegalFieldAccessException ("Illegal field access")
setIntValue(col, 0) on V2 Typedef Flags columncolumn is ShortField → same crash, different schema
Writing composite header without component-settings rowsCompositeEditorModel.cloneAllComponentSettings throws ArrayIndexOutOfBoundsException when struct is opened in Ghidra
Writing PARAMETER symbol with SYM_ADDR_COL = RAM addressAddress is not a VariableAddress thrown by FunctionDB.loadSymbolBasedVariables on any function access
Passing null DBChangeSet to DBHandle.save()server writes a 0-byte change-data file → next checkout fails with EOFException in ProgramContentHandler.loadProgramChangeSet

ProgramApplier doesn't have these traps because it routes through DataTypeManager.addDataType, SymbolTable.createLabel, Listing.setComment, Function.setReturnType, etc. — APIs that maintain Ghidra's interlocking-table invariants automatically. It also runs a cleanupBadVariableSymbols pass at the start of every checkin to purge corruption left in the database by older bridge versions.

server-package/CleanupBadVariableSymbols.java is a standalone GhidraScript that runs the same cleanup via analyzeHeadless — useful when a file is too corrupted to open in the Ghidra GUI.

Testing

./test.sh          # macOS / Linux: tiers 0-3 (C++ unit + BN-headless + Java)
test.bat           # Windows equivalent
test.bat --parity  # cross-DB parity tier only (C++ BN tests + gradlew parityTest)
test.bat --e2e     # live Ghidra-server E2E (starts a local ghidraSvr)

The suite is organised in five tiers. Tiers 2–4 exist to prove one property: the same compatible data ends up stored in both the .bndb and the Ghidra program database (the compatibility matrix at the top of this README).

TierWhatWhereGate
0Pure unit testsplugin/test/*.cpp (binja-ghidra-tests), bridge *Test.javaalways
1Ghidra-DB round-tripbridge *RoundTripTest.java (ProgramApplier against a real ProgramDB)needs ghidra.home / GHIDRA_HOME
2BN BinaryView/.bndb round-tripplugin/test/bn/ (binja-ghidra-bn-tests; headless binaryninjacore)SKIPs cleanly without a headless-capable BN license (BN_LICENSE env honoured)
3Cross-DB parityCanonicalParityTest (C++ and Java) against the shared goldens in testdata/parity/fixtures/with tiers 1+2
4Live-server E2Ebridge LiveServerE2ETest — boots a real ghidraSvr in a temp dir, seeds via analyzeHeadless, drives checkout → export → checkin → re-export over RMItest.bat --e2e (sets GHIDRA_E2E=1)
Download Tool