Top Related Projects
Fast and lightweight x86/x86-64 disassembler and code generation library
Low-latency machine code generation
Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
Quick Overview
rp is a fast and flexible x64/x86 ROP gadget finder for Windows, Linux, and macOS. It's designed to assist security researchers and exploit developers in finding useful code sequences (gadgets) for Return-Oriented Programming (ROP) techniques. rp can analyze both 32-bit and 64-bit executables and supports various output formats.
Pros
- Fast performance due to efficient implementation in C++
- Cross-platform support (Windows, Linux, macOS)
- Flexible search capabilities with customizable options
- Supports both x86 and x64 architectures
Cons
- Limited to x86 and x64 architectures
- Requires some knowledge of assembly and ROP techniques to use effectively
- May produce a large number of results, requiring manual filtering
Getting Started
-
Clone the repository:
git clone https://github.com/0vercl0k/rp.git
-
Build the project:
cd rp mkdir build && cd build cmake .. make
-
Run rp on a target binary:
./rp-lin -f /path/to/binary -r 5
This example searches for ROP gadgets in the specified binary, limiting the results to gadgets with a maximum of 5 instructions.
Competitor Comparisons
Fast and lightweight x86/x86-64 disassembler and code generation library
Pros of Zydis
- More comprehensive disassembly support for x86/x86-64 instructions
- Actively maintained with regular updates and bug fixes
- Extensive documentation and examples for easier integration
Cons of Zydis
- Larger codebase and potentially higher memory footprint
- Steeper learning curve for basic usage compared to rp
- Focused solely on x86/x86-64, while rp supports multiple architectures
Code Comparison
Zydis:
ZydisDecoder decoder;
ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64);
ZydisDecodedInstruction instruction;
ZydisDecoderDecodeBuffer(&decoder, data, length, &instruction);
rp:
import rp
dis = rp.rp_disasm(b"\x90\x90\x90", 0)
for i in dis:
print(i)
The code snippets demonstrate the basic usage of both libraries for disassembling instructions. Zydis requires more setup but offers finer control, while rp provides a simpler interface for quick disassembly tasks.
Low-latency machine code generation
Pros of asmjit
- More comprehensive and feature-rich JIT assembler library
- Supports multiple architectures (x86, x64, ARM, AArch64)
- Actively maintained with regular updates and improvements
Cons of asmjit
- Larger codebase and potentially steeper learning curve
- May be overkill for simpler assembly tasks
- Requires more setup and configuration for basic use cases
Code Comparison
rp example:
from rp import rp
gadgets = rp.rp(open('binary', 'rb').read(), arch='x86')
for gadget in gadgets:
print(gadget)
asmjit example:
#include <asmjit/asmjit.h>
using namespace asmjit;
JitRuntime rt;
CodeHolder code;
code.init(rt.environment());
x86::Assembler a(&code);
a.mov(x86::eax, 42);
a.ret();
typedef int (*Func)(void);
Func fn;
Error err = rt.add(&fn, &code);
Summary
rp is a simpler, Python-based tool focused on ROP gadget finding, while asmjit is a more comprehensive C++ JIT assembler library. rp is easier to use for basic tasks, but asmjit offers more flexibility and supports multiple architectures. The choice between them depends on the specific requirements of your project and your familiarity with the respective languages and tools.
Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
Pros of Capstone
- Multi-architecture support: Capstone supports a wide range of architectures, including x86, ARM, MIPS, and more
- Extensive documentation and community support
- Actively maintained with regular updates and bug fixes
Cons of Capstone
- Larger codebase and potentially higher resource usage
- Steeper learning curve for beginners due to its comprehensive feature set
- May be overkill for simple disassembly tasks
Code Comparison
Capstone:
#include <capstone/capstone.h>
csh handle;
cs_insn *insn;
size_t count;
if (cs_open(CS_ARCH_X86, CS_MODE_64, &handle) == CS_ERR_OK) {
count = cs_disasm(handle, code, code_size, address, 0, &insn);
}
rp:
from rp import rp
disassembler = rp.rp(arch='x64')
instructions = disassembler.disasm(code, address)
for instruction in instructions:
print(instruction)
The code examples demonstrate that Capstone requires more setup and uses a C-style API, while rp offers a simpler Python interface for basic disassembly tasks. Capstone provides more control and options, but rp is more straightforward for quick disassembly needs.
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Pros of Keystone
- Supports a wider range of architectures (x86, ARM, MIPS, PowerPC, etc.)
- More actively maintained with frequent updates
- Extensive documentation and API bindings for multiple programming languages
Cons of Keystone
- Larger codebase and more complex to integrate
- Slower assembly process due to its comprehensive nature
- Steeper learning curve for beginners
Code Comparison
Keystone:
from keystone import *
ks = Ks(KS_ARCH_X86, KS_MODE_32)
encoding, count = ks.asm("mov eax, 1")
rp:
from rp import rp
asm = rp.assemble("mov eax, 1", arch="x86")
Summary
Keystone is a more comprehensive and widely-supported assembler engine, offering support for multiple architectures and extensive documentation. However, it may be overkill for simpler projects and has a steeper learning curve. rp, on the other hand, is more lightweight and easier to use for basic x86/x64 assembly tasks, but lacks the broad architecture support and extensive features of Keystone.
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
Pros of Unicorn
- More comprehensive and versatile CPU emulation framework
- Supports a wider range of architectures (x86, ARM, MIPS, SPARC, etc.)
- Larger community and more extensive documentation
Cons of Unicorn
- Steeper learning curve due to its complexity
- Potentially slower for simple emulation tasks
- Requires more setup and configuration
Code Comparison
Unicorn example:
from unicorn import *
from unicorn.x86_const import *
# Initialize emulator in X86-32bit mode
mu = Uc(UC_ARCH_X86, UC_MODE_32)
# Map memory for this emulation
mu.mem_map(ADDRESS, 2 * 1024 * 1024)
rp example:
from rp import *
# Initialize emulator
emu = rp.Emulator()
# Map memory
emu.map(0x1000, 0x1000)
Summary
Unicorn is a more powerful and versatile CPU emulation framework, supporting multiple architectures and offering extensive features. However, it may be overkill for simpler tasks and has a steeper learning curve. rp, on the other hand, is more focused on x86/x64 emulation and provides a simpler interface, making it easier to use for specific reverse engineering tasks but with limited architecture support compared to Unicorn.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
rp++: a fast ROP gadget finder for PE/ELF/Mach-O x86/x64/ARM/ARM64 binaries
Overview
rp++ or rp is a C++ ROP gadget finder for PE/ELF/Mach-O executables and x86/x64/ARM/ARM64 architectures.
Finding ROP gadgets
To find ROP gadget you need to specify a file with the --file
/ -f
option and use the --rop
/ -r
option specifying the maximum the number of instructions in the gadget:
You can customize the base address of the module with the --va
option (if you pass a base of 0
, then you get relative offsets) and you can also use the --raw
option to analyze raw code dumps.
Finding pointers
Oftentimes when building ROP chains, you might need to find pointers to integers with specific values. To look for those, you can use the --search-int
option like in the below:
Other times, you might need to find pointers to specific strings. To look for those, you can use the --search-hexa
option like in the below:
You can also use the --va
option to specify your own base address.
Build
You can find shell scripts in src/build for every supported platforms; below is the Linux example:
src/build$ chmod u+x ./build-release.sh && ./build-release.sh
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
[...]
[16/16] Linking CXX executable rp-lin-x64
Authors
- Axel '0vercl0k' Souchet
Top Related Projects
Fast and lightweight x86/x86-64 disassembler and code generation library
Low-latency machine code generation
Capstone disassembly/disassembler framework for ARM, ARM64 (ARMv8), Alpha, BPF, Ethereum VM, HPPA, LoongArch, M68K, M680X, Mips, MOS65XX, PPC, RISC-V(rv32G/rv64G), SH, Sparc, SystemZ, TMS320C64X, TriCore, Webassembly, XCore and X86.
Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
Unicorn CPU emulator framework (ARM, AArch64, M68K, Mips, Sparc, PowerPC, RiscV, S390x, TriCore, X86)
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot