ropnroll
ropnroll is a command-line tool and Python library for finding return-oriented programming (ROP) and jump-oriented programming (JOP) gadgets in binaries. It supports instruction-pattern and semantic searches, builds function-call and syscall chains, and can check generated chains with Unicorn emulation.
Use it to inspect binary mitigations, find gadgets with specific register effects, and assemble chains for exploit-development research and CTF challenges.
Installation
Requires Python 3.10 or newer. Install from PyPI in a virtual environment:
python -m venv .venv
source .venv/bin/activate
python -m pip install ropnroll
ropnroll --help
On Windows, activate the environment with .venv\Scripts\Activate.ps1 in
PowerShell. Capstone, LIEF, Unicorn, and Rich are installed automatically.
If you use uv, you can run the CLI without a persistent installation:
uvx ropnroll --help
Quick start
Replace ./target with the path to a binary you want to inspect.
# Report binary mitigations, such as NX, PIE, and RELRO.
ropnroll security ./target
# List up to 20 gadgets.
ropnroll scan ./target --limit 20
# Find x86-64 gadgets by instruction text.
ropnroll scan ./target --regex 'pop rdi'
# Find x86-64 gadgets by their effect on registers.
ropnroll search ./target --query 'rdi=rax+8'
scan prints gadget addresses and disassembly. search uses emulation to infer
register effects; the query above asks for a gadget that sets rdi to rax + 8.
Matches depend on the instructions available in your binary.
Run ropnroll <command> --help for command options.
Commands
| Command | Purpose |
|---|---|
security |
Report binary mitigations. |
scan |
List gadgets, optionally filtered by an instruction regex. |
search |
Search for register or memory effects using semantic queries. |
pivot |
Find stack-pivot gadgets. |
jop |
Find JOP dispatcher gadgets. |
call |
Build a chain that calls a function by symbol or address. |
syscall |
Build a chain for a syscall number and arguments. |
srop |
Build a Linux x86-64 sigreturn-oriented execve chain. |
onegadget |
Search for execution paths that reach execve in emulation. |
libcid |
Identify a libc build using symbol offsets via libc.rip. |
Build and export a chain
For a binary that contains the exit symbol and suitable gadgets:
ropnroll call ./target --target exit --args 0 --verify --emit json --out chain.json
--target accepts a symbol name or numeric address. --args accepts
comma-separated integers. --verify prints an emulation report; inspect that
report before using the output. Export formats are json, raw, c, and
pwntools. Use --out to save a payload separately from console diagnostics.
You can pool gadgets from multiple binaries:
ropnroll search ./target ./libc.so.6 --query 'rdi=rax+8'
call, syscall, srop, pivot, and jop also accept multiple paths.
Addresses come from the loaded images; the CLI does not automatically discover
a running process's ASLR bases. Pointer arguments must refer to valid memory in
the intended target. The Python API provides live-process loading through
ropnroll.orchestrate on Linux.
Identify libc
Supply offsets relative to libc's base, rather than absolute runtime addresses:
ropnroll libcid --symbol system=0x58750 --symbol read=0x11bd20
These are illustrative offsets; replace them with values from your libc.
This command requires internet access and sends the supplied symbol offsets to
libc.rip. Add --download ./libc.so.6 to download the first matching build.
Supported targets and limitations
| Target | Scope |
|---|---|
| Linux x86-64 ELF | Primary target for scanning, semantic analysis, chain building, and verification. |
| Windows x86 / x86-64 PE | Loading, mitigation reporting, and scanning; calling-convention support is implemented. |
| x86 ELF (32-bit) | Scanner support; end-to-end chain coverage is limited. |
| ARM32, ARM64, MIPS32, MIPS64 | Scanner and semantic-engine implementations; not covered by real-binary architecture tests. |
| RISC-V, PowerPC, Thumb | Unsupported. |
- SROP is limited to Linux x86-64. Its verifier simulates sigreturn semantics.
onegadgetis limited to x86/x86-64 and uses syscall stubs, not a full OS.- Semantic effects are inferred from a finite set of emulation trials, not formally proved for every possible input.
- Chain search has depth and work limits and may fail even when a chain exists.
- Chain verification uses the first supplied image; it does not fully validate chains spanning multiple images or guarantee success in a live process.
Development
git clone https://github.com/jordanallred/ropnroll.git
cd ropnroll
python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
python -m pytest -q
For the Linux integration tests, use an x86-64 Linux environment with GCC and system libc available. Tests that require missing fixtures or tools may skip. The repository also includes Windows PE fixtures for loader and scanner tests.
The live-process example
shows how to build and deliver a chain against the included vulnerable test
program. It requires Linux x86-64, GCC, pwntools (python -m pip install pwntools), and access to /proc/<pid>/maps.
Help and contributions
Report bugs or suggest improvements in GitHub Issues. For bug reports, include the command, full error output, Python and ropnroll versions, and the target's architecture and file format. Include a minimal reproducer when possible.
Pull requests are welcome. Include relevant tests for behavior changes and run the test suite before submitting.
Metadata
Release files for ropnroll 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| ropnroll-0.1.1.tar.gz | 53.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| ropnroll-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 110.8 kB
Release files / ropnroll-0.1.1.tar.gz
| Download URL | ropnroll-0.1.1.tar.gz |
|---|---|
| Size | 53.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0b0853387048f4d807f929016c1a802a895a858980139c71485d3e791eee7e72
|
|
BLAKE2b-256 checksum How to use checksums |
dbb69457c23a455bef137bd64b903ed4456ff342f291b54559e12aa74e69b5cf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency logRelease files / ropnroll-0.1.1-py3-none-any.whl
| Download URL | ropnroll-0.1.1-py3-none-any.whl |
|---|---|
| Size | 57.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ee305d0c8028bd0c869ccc9c77e2e240d35e891cc5c2b09d639641ac7b0ee2d
|
|
BLAKE2b-256 checksum How to use checksums |
104a296bd92a54bfd7f252935f4c721ec6f11c086d823377b51845f353deec33
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 22, 2026.
Transparency log