前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Ropper:一款功能强大的代码文件搜索和处理工具

Ropper:一款功能强大的代码文件搜索和处理工具

作者头像
FB客服
发布2023-08-08 15:35:34
7510
发布2023-08-08 15:35:34
举报
文章被收录于专栏:FreeBuf
关于Ropper

Ropper是一款功能强大的代码文件搜索和处理工具,该工具能够帮助广大研究人员以不同的文件格式显示有关文件的信息,并查找用于构建不同体系结构(x86/x86_64、ARM/ARM64、MIPS、PowerPC、SPARC64)的rop链的Gadget。

值得一提的是,Ropper基于著名的Capstone框架实现了其反汇编功能。

工具安装

由于该工具基于Python开发,因此我们首先要在本地设备上安装并配置好Python环境以及pip工具。

首先,广大研究人员可以使用下列命令将该项目源码克隆至本地:

代码语言:javascript
复制

git clone https://github.com/sashs/Ropper.git

使用PyPi安装Capstone

代码语言:javascript
复制

$ sudo pip install capstone

使用PyPi安装filebytes

代码语言:javascript
复制

$ sudo pip install filebytes

使用PyPi安装Keystone

代码语言:javascript
复制
$ sudo pip install keystone-engine

接下来,运行工具安装脚本并执行Ropper即可:

代码语言:javascript
复制

$ python setup.py install

$ ropper

除此之外,我们也可以直接使用pip来安装Ropper:

代码语言:javascript
复制

$ pip install ropper

当然了,如果你不想安装的话,也可以直接执行Ropper脚本文件:

代码语言:javascript
复制
$ ./Ropper.py

当前可能的限制

代码语言:javascript
复制


reg == reg     -  分配寄存器给寄存器

reg == number  -  分配数字给寄存器

reg == [reg]   -  分配内存给寄存器

reg += number/reg/[reg]

reg -= number/reg/[reg]

reg *= number/reg/[reg]

reg /= number/reg/[reg]

(向右滑动,查看更多)

限制样例

代码语言:javascript
复制
eax==1 !ebx    - set eax to 1 and look for gadgets which does not clobber ebx

(向右滑动,查看更多)

工具使用

代码语言:javascript
复制


usage: Ropper.py [-h] [-v] [--console] [-f <file>] [-r] [-a <arch>]

                 [--section <section>] [--string [<string>]] [--hex]

                 [--asm <asm> [H|S|R] [<asm> [H|S|R] ...]] [--disasm <opcode>]

                 [--disassemble-address <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>] [--opcode <opcode>]

                 [--instructions <instructions>] [--type <type>] [--detailed]

                 [--all] [--cfg-only] [--chain <generator>] [-b <badbytes>]

                 [--nocolor] [--clear-cache]



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]

  SPARC [SPARC64]



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

  -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

  --asm <asm> [H|S|R] [<asm> [H|S|R] ...]

                        A string to assemble and a format of the output

                        (H=HEX, S=STRING, R=RAW, default: H)

  --disasm <opcode>     Opcode to disassemble (e.g. ffe4, 89c8c3, ...)

  --disassemble-address <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: 6)

  --search <regex>      Searches for gadgets

  --quality <quality>   The quality for gadgets which are found by search (1 =

                        best)

  --opcode <opcode>     Searches for opcodes (e.g. ffe4 or ffe? or ff??)

  --instructions <instructions>

                        Searches for instructions (e.g. "jmp esp", "pop eax;

                        ret")

  --type <type>         Sets the type of gadgets [rop, jop, sys, all]

                        (default: all)

  --detailed            Prints gadgets more detailed

  --all                 Does not remove duplicate gadgets

  --cfg-only            Filters out gadgets which fail the Microsoft CFG

                        check. Only for PE files which are compiled with CFG

                        check enabled (check DllCharachteristics) [PE]

  --chain <generator>   Generates a ropchain [generator parameter=value[

                        parameter=value]]

  -b <badbytes>, --badbytes <badbytes>

                        Set bytes which should not contains in gadgets

  --nocolor             Disables colored output

  --clear-cache         Clears the cache

(向右滑动,查看更多)

工具使用样例

常用方法

代码语言:javascript
复制


./Ropper.py

  ./Ropper.py --file /bin/ls --console

(向右滑动,查看更多)

信息收集

代码语言:javascript
复制


./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

  ./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

  ./Ropper.py --file /bin/ls --chain "execve cmd=/bin/sh" --badbytes 000a0d

  ./Ropper.py --file /bin/ls --chain "mprotect address=0xbfdff000 size=0x21000"

  ./Ropper.py --file /bin/ls /lib/libc.so.6 --console

(向右滑动,查看更多)

汇编/反汇编

代码语言:javascript
复制


./Ropper.py --asm "jmp esp"

  ./Ropper.py --asm "mov eax, ecx; ret"

  ./Ropper.py --disasm ffe4

(向右滑动,查看更多)

数据搜索

代码语言:javascript
复制


./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 ;; ret ;

(向右滑动,查看更多)

在脚本中使用Ropper

代码语言:javascript
复制
代码语言:javascript
复制
#!/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='SPARC64')

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

(向右滑动,查看更多)

工具运行截图

许可证协议

本项目的开发与发布遵循BSD-3-Clause开源许可证协议。

项目地址

Ropper:https://github.com/sashs/ropper

http://www.capstone-engine.org/

http://scoding.de/ropper

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-07-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 工具安装
  • 当前可能的限制
  • (向右滑动,查看更多)
    • 限制样例
    • (向右滑动,查看更多)
    • 工具使用
    • (向右滑动,查看更多)
    • 工具使用样例
      • 常用方法
      • (向右滑动,查看更多)
        • 信息收集
        • (向右滑动,查看更多)
          • 汇编/反汇编
          • (向右滑动,查看更多)
            • 数据搜索
            • (向右滑动,查看更多)
            • 在脚本中使用Ropper
            • (向右滑动,查看更多)
            • 工具运行截图
            • 许可证协议
            • 项目地址
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档