ROPNinja is a modern ROP gadget explorer for Binary Ninja: fast enough to keep in your sidebar, clean enough to use in split panes, and built to feel native instead of bolted on.
It started as a transformative fork of binja_rop by m4ul3r, with inspiration from binjago. The current direction is a sidebar-first Binary Ninja workflow for exploit development, reverse engineering, CTFs, and binary triage.
- Native Binary Ninja sidebar widget with split-pane support.
- Uses the currently open BinaryView, so it behaves like a real workspace tool.
- Syntax-highlighted gadget rendering using Binary Ninja token colors.
- Category dropdown for all gadgets, pops, moves, calls, stack pivots, branches, and
leave. - Text and regex filtering across gadget text and addresses.
- Horizontally scrollable gadget chains with the address column pinned in place.
- Multi-row selection with
Ctrl+C/Cmd+Caddress copying plus right-click copy formats. - Architecture-aware search for x86 / x86-64 and AArch64 views.
- Starred gadgets for marking interesting finds, with a subtle configurable address tint.
- Per-view gadget caching so reopening or auto-finding with the same search settings is instant.
- Optional short address display that strips leading zeroes.
- Optional auto-find when the sidebar or split pane opens.
- Configurable gadget backtracking, deduplication, jump gadgets, and
leavegadgets. - Faster bounded scanning over executable ranges, with decoded-instruction caching and cancellation support.
Clone this repository into your Binary Ninja plugins directory, then restart Binary Ninja.
macOS:
git clone https://github.com/alessaba/ROPNinja.git "$HOME/Library/Application Support/Binary Ninja/plugins/ROPNinja"Linux:
git clone https://github.com/alessaba/ROPNinja.git "$HOME/.binaryninja/plugins/ROPNinja"Windows PowerShell:
git clone https://github.com/alessaba/ROPNinja.git "$env:APPDATA\Binary Ninja\plugins\ROPNinja"Open the ROPNinja sidebar button after Binary Ninja restarts.
- macOS:
$HOME/Library/Application Support/Binary Ninja/plugins/ROPNinja - Linux:
$HOME/.binaryninja/plugins/ROPNinja - Windows:
%APPDATA%\Binary Ninja\plugins\ROPNinja
ROPNinja is pure Python and uses Binary Ninja's bundled Qt/PySide UI APIs, so it does not require platform-specific dependencies.
- Open a binary in Binary Ninja.
- Click the
ROPNinjasidebar icon, or open it as a split pane. - Press
Findto discover gadgets for the current BinaryView, or enable auto-find in settings to start searches as soon as the UI opens. - Filter with the dropdown or search field; toggle
.*for regex search. - Select one or more rows and press
Ctrl+C/Cmd+C, or right-click a row, to copy addresses, chain snippets, gadget text, or structured formats. - Double-click a gadget to navigate to its address.
ROPNinja registers clean ropninja.* settings:
ropninja.maxPreviousBytes: maximum bytes to walk backward from a return instruction.ropninja.deduplicateGadgets: hide duplicate gadget text.ropninja.includeBranches: include gadgets containingjmpor conditional jumps.ropninja.includeLeave: include gadgets containingleave.ropninja.stripAddressZeros: display compact addresses in the sidebar.ropninja.autoFindOnOpen: automatically search when the sidebar or split pane is shown.ropninja.starredAddressColor: tint color for addresses of starred gadgets.
When auto-find is enabled, ROPNinja hides the manual Find button and gives the filter/category controls the extra room.
ROPNinja reads the architecture of the current BinaryView and adapts how gadgets are found:
- x86 / x86-64: byte-granular backtracking from
ret(c3),bnd ret(f2 c3), andretf(cb). - AArch64: backtracking from the return group (
ret xN,retaa,retab) at 4-byte instruction alignment. Withropninja.includeBranchesenabled, indirect branches (br,blr, and their pointer-authentication variants) end gadgets too, since those are legitimate JOP tails. - Other architectures fall back to the x86 rules.
ropninja.maxPreviousBytes keeps its byte meaning, so the default of 32 bytes reaches 8 instructions back on AArch64.
Category names stay the same on every architecture; the instructions they match do not:
| Category | AArch64 |
|---|---|
| POP gadgets | pop, ldp, ldr, and ldur from [sp] |
| MOV gadgets | mov, movz, movk, and movn |
| CALL gadgets | bl, blr, blraa, and blrab |
| Stack pivots | instructions that write to sp |
| Branches | b, br, cbz, tbz, and friends |
| Leave | mov sp, x29, the AArch64 frame teardown |
eret is left alone: it returns through exception state rather than the stack, so it neither ends nor breaks a gadget.
The gadget finder is covered by a unit test suite that runs without Binary Ninja: it decodes instructions with capstone behind a small stand-in for the Binary Ninja API, and checks the finder against an independent brute-force enumeration.
python3 -m unittest discover -s testsRequires pip install capstone.
Classic ROP hunting usually wants short, predictable chains ending in ret. Jump instructions are useful for JOP or special control-flow tricks, and leave is valuable for stack pivots, but both can add a lot of noise to everyday ROP searches.
ROPNinja keeps them off by default to preserve signal, then exposes them as explicit settings when you want the extra surface.
ROPNinja is actively being shaped into a first-class Binary Ninja ROP workflow. The current focus is:
- richer gadget classification,
- better copy/export formats,
- 32-bit ARM / Thumb support alongside the existing x86 and AArch64 search,
- keyboard-first table navigation,
- and tighter Binary Ninja UI integration.
- Original project:
binja_ropby m4ul3r. - Inspiration:
binjagoby zznop. - Refactor and current direction: Alessaba.
MIT. See LICENSE.