# Performing Return Oriented Programming

Methodology for building Return-Oriented Programming (ROP) chains to bypass NX/DEP by...

- Repository: https://github.com/xalgorix/xalgorix (1285 stars)
- Category: Engineering
- License: Apache-2.0
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add xalgorix/xalgorix --skill performing-return-oriented-programming -g -a claude-code -y`
Codex: `npx skills add xalgorix/xalgorix --skill performing-return-oriented-programming -g -a codex -y`
Cursor: `npx skills add xalgorix/xalgorix --skill performing-return-oriented-programming -g -a cursor -y`
Gemini CLI: `npx skills add xalgorix/xalgorix --skill performing-return-oriented-programming -g -a gemini-cli -y`

## Description

Methodology for building Return-Oriented Programming (ROP) chains to bypass NX/DEP by reusing existing code gadgets, covering gadget discovery, calling-convention argument setup, ret2libc, ret2syscall (execve), one_gadget, stack alignment, JOP, and stack pivoting across x86/x64/ARM64 during authorized engagements.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Performing Return-Oriented Programming

## When to Use

- During authorized exploitation when you control the saved return address (via stack overflow, write-what-where, etc.)
  but **NX/DEP** prevents executing injected shellcode on the stack.
- When you need to call an existing function (`system`, `execve`, `mprotect`) or invoke a syscall with attacker-chosen
  arguments by chaining small `...; ret` gadgets.
- When choosing between ret2libc (call a libc function), ret2syscall (raw `sys_execve`, common in static binaries),
  ret2dlresolve, SROP (when gadgets are scarce), or stack pivoting (off-by-one / short overflows).
- On ARM64 targets where `ret` jumps to `x30` and instructions cannot be entered mid-instruction, requiring JOP or
  pivot-based approaches.

## Critical: Concepts/Steps Most Often Missed

- **16-byte stack alignment on x86-64.** The SysV ABI requires `RSP` be 16-byte aligned at a `call`. libc functions use
  SSE (`movaps`) and will `SIGSEGV` if misaligned. If `system()` crashes inside libc, insert a bare `ret` gadget before
  it to realign. This is the single most common reason a "correct" chain crashes.
- **Argument passing differs by arch/ABI.** x86 cdecl pushes args on the stack (right-to-left); x86-64 SysV uses
  `RDI, RSI, RDX, RCX, R8, R9`; Windows x64 uses `RCX, RDX, R8, R9`. You need `pop rdi; ret`-style gadgets to load
  registers, not just stack values.
- **The function needs a return slot.** After `system` you must place a return address (e.g. `exit`) or the chain
  crashes on `system`'s own return. CTFs often get away with garbage, real targets do not.
- **ARM64 entry-point pitfall.** When jumping to a function via ROP on ARM64, jump to the function's *second*
  instruction to avoid re-storing the stack pointer and looping forever.
- **NUL bytes and bad chars in gadget addresses.** A `pop rdi; ret` gadget at `0x400686` is fine, but addresses with
  NULs break string-copy overflows. Pick alternate gadgets or use ret2dlresolve/SROP.

The rest: https://github.com/xalgorix/xalgorix/blob/HEAD/internal/tools/skills/data/binary-exploitation/performing-return-oriented-programming/SKILL.md
