National Cyber Warfare Foundation (NCWF)login

ROPgadget for cataloguing ROP gadgets across ELF, PE, Mach-O and raw binaries


0 user ratings
2026-10-09 13:28:06
milo
Red Team (CNA)
"ROPgadget

ROPgadget enumerates return-oriented-programming gadgets across nine CPU architectures, giving authorized researchers a fast inventory of code-reuse primitives during exploit development and mitigation research.








ToolJonathanSalwan/ROPgadget — gadget search engine for ROP/JOP/SYS primitives built on the Capstone disassembler
CategoryBinary analysis / exploit development tooling (Python)
Primary UseEnumerating and filtering ROP, JOP, and syscall gadgets in ELF/PE/Mach-O/raw binaries during authorized exploit research and CTF-style lab work
Safe UseIntended for authorized penetration tests, vulnerability research on binaries you own or are licensed to test, CTF challenges, and academic study of code-reuse mitigations
Telemetry NotePurely local static analysis — it only reads files on disk and produces no network traffic, so defenders observing it should focus on where its output appears (research reports, shellcode development trees) rather than on runtime indicators

ROPgadget by JonathanSalwan is one of the canonical utilities in the binary-exploitation toolbox: it scans a target executable for short instruction sequences ending in a control-transfer instruction — the eponymous gadgets — that an attacker could theoretically chain together. What elevates it above hobby scripts is its breadth: the tool parses ELF, PE, Mach-O, and raw binary formats across x86, x86-64, ARM, ARM64, MIPS, PowerPC, Sparc, RISC-V 64, and RISC-V Compressed architectures. That cross-platform coverage, combined with roughly 4,400 stars on GitHub, makes it a fixture in both exploit-development labs and university courses on memory-corruption defenses.


The architectural heart of the tool is its reliance on Capstone, the widely used multi-architecture disassembly framework. ROPgadget does not implement its own instruction decoding; instead it feeds executable segments to Capstone and drives the disassembler as a search backend. This is a deliberate design choice documented in the README: source installs require Capstone to be installed first, with the project pointing users at capstone-engine/capstone and its COMPILE.TXT for cross-compilation onto platforms like Windows, iOS, Android, and Cygwin. The practical consequence is that gadget quality and architecture support track Capstone itself, and misaligned or mid-instruction gadget discovery inherits Capstone's decoding semantics.


Installation is deliberately frictionless. The README's primary path is PyPI: sudo -H python3 -m pip install ROPgadget, after which ROPgadget --help is available from $PATH. The alternative is a source checkout, usable either as a standalone script via python3 ROPgadget.py --help or installed into site-packages with setup.py install. Both routes are local, dependency-light, and consistent with the tool's role as a quick lab utility rather than a heavyweight analysis framework — a contrast with pipeline-oriented alternatives like ropper or framework-embedded gadget finders.


The interface is a classic single-binary CLI with a rich flag surface. The core invocation is ROPgadget --binary , which walks executable segments and prints every discovered gadget with its address and instruction sequence. From there the flag set shapes the search space: --depth controls how deep the engine disassembles backward from branch instructions (default 10 bytes), --only restricts output to specified mnemonics like mov|ret, and --filter suppresses unwanted ones such as xchg|add|sub. The --re flag accepts a regular expression for arbitrary matching, giving researchers a flexible query language over the gadget corpus.


Several flags exist specifically to model real-world constraints during authorized exploit development. --badbytes rejects gadgets whose addresses contain forbidden bytes — the classic mechanism for dealing with truncated copy functions or input filters — and accepts range syntax like 00|01-1f|7f|42. --range narrows the scan to an address window, useful when only a known executable region is reachable. --offset applies a slide or rebasing to gadget addresses, as in the README's example against a library loaded at 0xdeadbeef00000000, reflecting how gadget addresses must be adjusted for ASLR-relative planning in a lab environment.


Beyond pure ROP, the tool runs three parallel engines that can be toggled independently: --norop disables the ROP search, --nojop disables the jump-oriented-programming engine, and --nosys disables syscall-gadget discovery. --callPreceded filters to gadgets preceded by a call instruction — relevant when a technique needs the stack layout a call site implies — and --multibr permits multiple branch instructions inside a gadget, expanding coverage at the cost of semantics that are harder to reason about. The --thumb flag switches the ARM search into Thumb mode, an important distinction because Thumb gadgets have different alignment and encoding properties than their ARM-mode counterparts.


Two features deserve particular attention from a workflow perspective. First, --ropchain enables automatic ROP chain generation: given a binary, the tool attempts to assemble a working chain (the classic demonstration being a call to system with a controlled argument) rather than merely listing primitives. Second, --mipsrop is a purpose-built MIPS helper with named gadget categories — stackfinder, system, tails, lia0, registers — acknowledging that MIPS gadget hunting has architecture-specific idioms that generic filtering handles poorly. Both are documented with examples in the README's usage block, and both are strictly analysis-time features operating on local files.


Format-agnostic scanning is handled through the --rawArch, --rawMode, and --rawEndian flags, which let the user declare x86|arm|arm64|sparc|mips|ppc|riscv, a 32/64 or arm/thumb mode, and endianness for headerless firmware blobs. This matters in embedded research, where a dumped flash image is not a parsed ELF but still contains enumerable code. The --memstr flag complements this by searching each byte across readable segments — the README's /bin/sh example is the textbook illustration of locating string data bytewise even when it is not null-terminated or contiguous in an obvious way.


Output control is also well considered: --dump prints the raw gadget bytes alongside disassembly, --align ALIGN normalizes gadget addresses to a byte alignment, --all preserves duplicate gadgets that are otherwise deduplicated, and --silent suppresses per-gadget printing during analysis. An interactive --console mode turns the tool into a session where queries can be iterated without re-scanning, which is materially faster when triaging a large binary. String and opcode search via --string (with regex-like m..n patterns) and --opcode c9c3 round out the toolkit for locating data and instruction sequences in the image.


The contribution section reads like an honest roadmap and doubles as a statement of current limitations: system gadget support is wanted for PPC, Sparc, and ARM64 via Gadgets.addSYSGadgets(), RISC-V 32-bit is not yet supported, bad-byte handling during chain generation is incomplete, and big-endian Mach-O handling lags the ELF implementation. For a maintainer evaluating whether to adopt the tool, these gaps are worth knowing — an ARM64 target, for instance, will not yield syscall-gadget inventory today. Licensing is BSD-style per LICENSE_BSD.txt, though GitHub metadata reports NOASSERTION, so commercial redistributors should read the file directly.


From a defensive standpoint, ROPgadget is best understood as a measurement instrument. Compiler and hardening work — non-executable stacks, ASLR, control-flow integrity — is ultimately validated by asking exactly the question this tool answers: what code-reuse primitives remain in a hardened build? Running it against before-and-after binaries quantifies whether a mitigation genuinely shrank the gadget surface, and its output feeds academic tooling that studies gadget density as a security metric. For blue teams, familiarity with gadget enumeration is less about detection — the tool is silent and local — and more about understanding what an adversary's post-exploitation research phase looks like on a vulnerable target they have lawful access to.


In sum, ROPgadget occupies a stable niche it has held for years: a Python-based, Capstone-powered, multi-architecture gadget finder with just enough automation (--ropchain, --mipsrop) to accelerate authorized exploit research without hiding its mechanics. It is not a framework and does not try to be; it is the command you reach for when the question is simply 'what is in this binary.' For vulnerability researchers, CTF participants, and mitigation engineers working on code they are authorized to analyze, it remains a reference implementation worth knowing at the flag level.



Official project repository for JonathanSalwan/ROPgadget.

Download Tool

Educational analysis for authorized security professionals. Use only in controlled, authorized environments.






Source: OffensiveSec
Source Link: https://www.offsecblog.com/2026/10/ropgadget-for-cataloguing-rop-gadgets.html


Comments
new comment
Nobody has commented yet. Will you be the first?
 
Forum
Red Team (CNA)



Copyright 2012 through 2026 - National Cyber Warfare Foundation - All rights reserved worldwide.