You can use ropper to look at information about files in different file formats and you can find ROP and JOP gadgets to build chains for different architectures. Ropper supports ELF, MachO and the PE file format. Other files can be opened in RAW format. The following architectures are supported:

  • x86 / x86_64
  • Mips / Mips64
  • ARM (also Thumb Mode)/ ARM64
  • PowerPC / PowerPC64

Ropper is inspired by ROPgadget, but should be more than a gadgets finder. So it is possible to show information about a binary like header, segments, sections etc. Furthermore it is possible to edit the binaries and edit the header fields, but currently this is not fully implemented and in a experimental state. For disassembly ropper uses the awesome Capstone Framework.

Now you can generate rop chain automatically (auto-roper)  for execve and mprotect syscall.

usage: Ropper.py [-h] [-v] [--console] [-f <file>] [-r] [--db <dbfile>]
                 [-a <arch>] [--section <section>] [--string [<string>]]
                 [--hex] [--disassemble <address:length>] [-i] [-e]
                 [--imagebase] [-c] [-s] [-S] [--imports] [--symbols]
                 [--set <option>] [--unset <option>] [-I <imagebase>] [-p]
                 [-j <reg>] [--stack-pivot] [--inst-count <n bytes>]
                 [--search <regex>] [--quality <quality>] [--filter <regex>]
                 [--opcode <opcode>] [--type <type>] [--detailed] [--all]
                 [--chain <generator>] [-b <badbytes>] [--nocolor]

You can use ropper to display information about binary files in different file formats
    and you can search for gadgets to build rop chains for different architectures

supported filetypes:
  ELF
  PE
  Mach-O
  Raw

supported architectures:
  x86 [x86]
  x86_64 [x86_64]
  MIPS [MIPS, MIPS64]
  ARM/Thumb [ARM, ARMTHUMB]
  ARM64 [ARM64]
  PowerPC [PPC, PPC64]

available rop chain generators:
  execve (execve[=<cmd>], default /bin/sh) [Linux x86, x86_64]
  mprotect  (mprotect=<address>:<size>) [Linux x86, x86_64]
  virtualprotect (virtualprotect=<address iat vp>:<size>) [Windows x86]

optional arguments:
  -h, --help            show this help message and exit
  -v, --version         Print version
  --console             Starts interactive commandline
  -f <file>, --file <file>
                        The file to load
  -r, --raw             Loads the file as raw file
  --db <dbfile>         The dbfile to load
  -a <arch>, --arch <arch>
                        The architecture of the loaded file
  --section <section>   The data of the this section should be printed
  --string [<string>]   Looks for the string <string> in all data sections
  --hex                 Prints the selected sections in a hex format
  --disassemble <address:length>
                        Disassembles instruction at address <address>
                        (0x12345678:L3). The count of instructions to
                        disassemble can be specified (0x....:L...)
  -i, --info            Shows file header [ELF/PE/Mach-O]
  -e                    Shows EntryPoint
  --imagebase           Shows ImageBase [ELF/PE/Mach-O]
  -c, --dllcharacteristics
                        Shows DllCharacteristics [PE]
  -s, --sections        Shows file sections [ELF/PE/Mach-O]
  -S, --segments        Shows file segments [ELF/Mach-O]
  --imports             Shows imports [ELF/PE]
  --symbols             Shows symbols [ELF]
  --set <option>        Sets options. Available options: aslr nx
  --unset <option>      Unsets options. Available options: aslr nx
  -I <imagebase>        Uses this imagebase for gadgets
  -p, --ppr             Searches for 'pop reg; pop reg; ret' instructions
                        [only x86/x86_64]
  -j <reg>, --jmp <reg>
                        Searches for 'jmp reg' instructions (-j reg[,reg...])
                        [only x86/x86_64]
  --stack-pivot         Prints all stack pivot gadgets
  --inst-count <n bytes>
                        Specifies the max count of instructions in a gadget
                        (default: 10)
  --search <regex>      Searches for gadgets
  --quality <quality>   The quality for gadgets which are found by search (1 =
                        best)
  --filter <regex>      Filters gadgets
  --opcode <opcode>     Searchs for opcodes (e.g. ffe4 or ffe? or ff??)
  --type <type>         Sets the type of gadgets [rop, jop, sys, all]
                        (default: all)
  --detailed            Prints gadgets more detailed
  --all                 Does not remove duplicate gadgets
  --chain <generator>   Generates a ropchain [generator=parameter]
  -b <badbytes>, --badbytes <badbytes>
                        Set bytes which should not contains in gadgets
  --nocolor             Disables colored output

example uses:
  [Generic]
  ropper.py
  ropper.py --file /bin/ls --console

  [Informations]
  ropper.py --file /bin/ls --info
  ropper.py --file /bin/ls --imports
  ropper.py --file /bin/ls --sections
  ropper.py --file /bin/ls --segments
  ropper.py --file /bin/ls --set nx
  ropper.py --file /bin/ls --unset nx

  [Gadgets]
  ropper.py --file /bin/ls --inst-count 5
  ropper.py --file /bin/ls --search "sub eax" --badbytes 000a0d
  ropper.py --file /bin/ls --search "sub eax" --detail
  ropper.py --file /bin/ls --filter "sub eax"
  ropper.py --file /bin/ls --inst-count 5 --filter "sub eax"
  ropper.py --file /bin/ls --opcode ffe4
  ropper.py --file /bin/ls --opcode ffe?
  ropper.py --file /bin/ls --opcode ??e4
  ropper.py --file /bin/ls --detailed
  ropper.py --file /bin/ls --ppr --nocolor
  ropper.py --file /bin/ls --jmp esp,eax
  ropper.py --file /bin/ls --type jop
  ropper.py --file /bin/ls --chain execve=/bin/sh
  ropper.py --file /bin/ls --chain execve=/bin/sh --badbytes 000a0d
  ropper.py --file /bin/ls --chain mprotect=0xbfdff000:0x21000

  [Search]
  ?		any character
  %		any string

  Example:

  ropper.py --file /bin/ls --search "mov e?x"
  0x000067f1: mov edx, dword ptr [ebp + 0x14]; mov dword ptr [esp], edx; call eax
  0x00006d03: mov eax, esi; pop ebx; pop esi; pop edi; pop ebp; ret ;
  0x00006d6f: mov ebx, esi; mov esi, dword ptr [esp + 0x18]; add esp, 0x1c; ret ;
  0x000076f8: mov eax, dword ptr [eax]; mov byte ptr [eax + edx], 0; add esp, 0x18; pop ebx; ret ;

  ropper.py --file /bin/ls --search "mov [%], edx"
  0x000067ed: mov dword ptr [esp + 4], edx; mov edx, dword ptr [ebp + 0x14]; mov dword ptr [esp], edx; call eax;
  0x00006f4e: mov dword ptr [ecx + 0x14], edx; add esp, 0x2c; pop ebx; pop esi; pop edi; pop ebp; ret ;
  0x000084b8: mov dword ptr [eax], edx; ret ;
  0x00008d9b: mov dword ptr [eax], edx; add esp, 0x18; pop ebx; ret ;

  ropper.py --file /bin/ls --search "mov [%], edx" --quality 1
  0x000084b8: mov dword ptr [eax], edx; ret ;
  

Using ropper in scripts

#!/usr/bin/env python
from ropper import RopperService

# not all options need to be given
options = {'color' : False,     # if gadgets are printed, use colored output: default: False
            'badbytes': '00',   # bad bytes which should not be in addresses or ropchains; default: ''
            'all' : False,      # Show all gadgets, this means to not remove double gadgets; default: False
            'inst_count' : 6,   # Number of instructions in a gadget; default: 6
            'type' : 'all',     # rop, jop, sys, all; default: all
            'detailed' : False} # if gadgets are printed, use detailed output; default: False

rs = RopperService(options)

##### change options ######
rs.options.color = True
rs.options.badbytes = '00'
rs.options.badbytes = ''
rs.options.all = True


##### open binaries ######
# it is possible to open multiple files
rs.addFile('test-binaries/ls-x86')
rs.addFile('ls', bytes=open('test-binaries/ls-x86','rb').read()) # other possiblity
rs.addFile('ls_raw', bytes=open('test-binaries/ls-x86','rb').read(), raw=True, arch='x86')

##### close binaries ######
rs.removeFile('ls')
rs.removeFile('ls_raw')


# Set architecture of a binary, so it is possible to look for gadgets for a different architecture
# It is useful for ARM if you want to look for ARM gadgets or Thumb gadgets
# Or if you opened a raw file
ls = 'test-binaries/ls-x86'
rs.setArchitectureFor(name=ls, arch='x86')
rs.setArchitectureFor(name=ls, arch='x86_64')
rs.setArchitectureFor(name=ls, arch='ARM')
rs.setArchitectureFor(name=ls, arch='ARMTHUMB')
rs.setArchitectureFor(name=ls, arch='ARM64')
rs.setArchitectureFor(name=ls, arch='MIPS')
rs.setArchitectureFor(name=ls, arch='MIPS64')
rs.setArchitectureFor(name=ls, arch='PPC')
rs.setArchitectureFor(name=ls, arch='PPC64')
rs.setArchitectureFor(name=ls, arch='x86')


##### load gadgets ######

# load gadgets for all opened files
rs.loadGadgetsFor() 

# load gadgets for only one opened file
ls = 'test-binaries/ls-x86'
rs.loadGadgetsFor(name=ls)

# change gadget type
rs.options.type = 'jop'
rs.loadGadgetsFor() 

rs.options.type = 'rop'
rs.loadGadgetsFor() 

# change instruction count
rs.options.inst_count = 10
rs.loadGadgetsFor() 

##### print gadgets #######
rs.printGadgetsFor() # print all gadgets
rs.printGadgetsFor(name=ls)

##### Get gadgets ######
gadgets = rs.getFileFor(name=ls).gadgets


##### search pop pop ret ######
pprs = rs.searchPopPopRet(name=ls) # looks for ppr only in 'test-binaries/ls-x86'
pprs = rs.searchPopPopRet()        # looks for ppr in all opened files
for file, ppr in pprs.items():
    for p in ppr:
        print p

##### load jmp reg ######
jmp_regs = rs.searchJmpReg(name=ls, regs=['esp', 'eax']) # looks for jmp reg only in 'test-binaries/ls-x86'
jmp_regs = rs.searchJmpReg(regs=['esp', 'eax'])
jmp_regs = rs.searchJmpReg()                             # looks for jmp esp in all opened files
for file, jmp_reg in jmp_regs.items():
    for j in jmp_reg:
        print j


##### search opcode ######
ls = 'test-binaries/ls-x86'
gadgets_dict = rs.searchOpcode(opcode='ffe4', name=ls)
gadgets_dict = rs.searchOpcode(opcode='ffe?')
gadgets_dict = rs.searchOpcode(opcode='??e4')

for file, gadgets in gadgets_dict.items():
    for g in gadgets:
        print g

##### search instructions ######
ls = 'test-binaries/ls-x86'
for file, gadget in rs.search(search='mov e?x', name=ls):
    print file, gadget

for file, gadget in rs.search(search='mov [e?x%]'):
    print file, gadget    

result_dict = rs.searchdict(search='mov eax')
for file, gadgets in result_dict.items():
    print file
    for gadget in gadgets:
        print gadget

##### assemble instructions ######
hex_string = rs.asm('jmp esp')
print '"jmp esp" assembled to hex string =', hex_string
raw_bytes = rs.asm('jmp esp', format='raw')
print '"jmp esp" assembled to raw bytes =', raw_bytes
string = rs.asm('jmp esp', format='string')
print '"jmp esp" assembled to string =',string
arm_bytes = rs.asm('bx sp', arch='ARM')
print '"bx sp" assembled to hex string =', arm_bytes

##### disassemble bytes #######
arm_instructions = rs.disasm(arm_bytes, arch='ARM')
print arm_bytes, 'disassembled to "%s"' % arm_instructions

# Change the imagebase, this also change the imagebase for all loaded gadgets of this binary
rs.setImageBaseFor(name=ls, imagebase=0x0)

# reset image base
rs.setImageBaseFor(name=ls, imagebase=None)

gadgets = rs.getFileFor(name=ls).gadgets

# gadget address
print hex(gadgets[0].address)

# get instruction bytes of gadget
print bytes(gadgets[0].bytes).encode('hex')

# remove all gadgets containing bad bytes in address
rs.options.badbytes = '000a0d'  # gadgets are filtered automatically

Download

https://github.com/sashs/Ropper (v1.11.0, 29.10.2017)

Changelog

v1.11.0 -  Many Bugfixes
        -  Semantic Search feature (only Python2, BETA)
        -  Support for Big Endian (Mips, Mips64, ARM)
v1.9.5  -  Use of multiprocessing during gadget search only on linux 
v1.9.4  -  Possibility to install ropper via pip without installing capstone when capstone wasn't installed via pip
v1.9.3  -  Use of badbytes in ropchain generators
	-  Bugfix: Incomplete ropchain using python3, although needed gadgets are available
v1.9.2  -  Print gadget addresses +1 for ARMTHUMB
v1.9.1  -  Bugfix: Invalid Characters in Opcode
v1.9.0  -  Performance Improvements
        -  Support for Keystone added (asm-command and instruction search)
        -  Bugfixes
v1.8.0  -  Add support for syscall gadgets
	-  Change implementation to filebytes module
	-  Add ropchain generator for x86_64 (execve, mprotect)
	-  Bugfixes
v1.7.3  -  Bugfixes
v1.7.2  -  Bugfixes
v1.7.1  -  Prepare ropper for using in scripts
        -  Refactoring
        -  Bugfixes
v1.7.0  -  Better ARM support
        -  Bugfixes
v1.6.0  -  Open multiple files and use all gadgets for search and ropchain
           Add simple disassembler support
           Add hex output of sections similar xxd
           Add virtualprotect ropchain generator
           Add string search in data sections
           Bugfixes
v1.5.4  -  Bugfixes
v1.5.3  -  Make sqlite support optional
v1.5.2  -  Bugfixes
v1.5.1  -  Bugfixes
v1.5.0  -  Better performance
           Sqlite support
           Progress
           Bugfixes
v1.4.3  -  Search syntax changed
           Bugfixes
v1.4.0  -  Add raw file format support
           Port to python 3
           Add change arch support
           Bugfixes
v1.3.0  -  PowerPC and ARM Thumb support
           colored output
           Bugfixes
v1.2.1  -  Bugfixes
v1.2.0  -  Rop Chain Generators added
           Bugfixes
v1.1.0  -  ARM Support
           Mach-O Support
           Bugfixes
v1.0.3  -  Bugfix; ppr search
           Bugfix: Info message after file loading failed
v1.0.2  -  Bugfix: gadgetsearch
v1.0.1  -  Bugfix: set aslr on elf files

Screenshots