Skip to content
This repository
tag: 4.5.0-RC8
Fetching contributors…

Cannot retrieve contributors at this time

executable file 174 lines (139 sloc) 4.175 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
#!/usr/bin/env ruby
# -*- coding: binary -*-
#
# $Id$
#
# This tool will collect, export, and import ROP gadgets
# from various file formats (PE, ELF, Macho)
# $Revision$
#

msfbase = __FILE__
while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end

$:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib')))
require 'fastlib'
require 'msfenv'



$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']

require 'rex'
require 'rex/ropbuilder'
require 'rex/ui/text/output/stdio'
require 'rex/ui/text/color'
require 'optparse'

def opt2i(o)
o.index("0x")==0 ? o.hex : o.to_i
end

opts = {}
color = true

opt = OptionParser.new
opt.banner = "Usage #{$PROGRAM_NAME} <option> [targets]"
opt.separator('')
opt.separator('Options:')

opt.on('-d', '--depth [size]', 'Number of maximum bytes to backwards disassemble from return instructions') do |d|
opts[:depth] = opt2i(d)
end

opt.on('-s', '--search [regex]', 'Search for gadgets matching a regex, match intel syntax or raw bytes') do |regex|
opts[:pattern] = regex
end

opt.on('-n', '--nocolor', 'Disable color. Useful for piping to other tools like the less and more commands') do
color = false
end

opt.on('-x', '--export [filename]', 'Export gadgets to CSV format') do |csv|
opts[:export] = csv
end

opt.on('-i', '--import [filename]', 'Import gadgets from previous collections') do |csv|
opts[:import] = csv
end

opt.on('-v', '--verbose', 'Output very verbosely') do
opts[:verbose] = true
end

opt.on_tail('-h', '--help', 'Show this message') do
puts opt
exit(1)
end

begin
opt.parse!
rescue OptionParser::InvalidOption
puts "Invalid option, try -h for usage"
exit(1)
end

if opts.empty? and (ARGV.empty? or ARGV.nil?)
puts "no options"
puts opt
exit(1)
end

# set defaults
opts[:depth] ||= 5

gadgets = []

if opts[:import].nil?
files = []
ARGV.each do |file|
if(File.directory?(file))
dir = Dir.open(file)
dir.entries.each do |ent|
path = File.join(file, ent)
next if not File.file?(path)
files << File.join(path)
end
else
files << file
end
end

ropbuilder = Rex::RopBuilder::RopCollect.new

files.each do |file|
ret, retn = []
ropbuilder = Rex::RopBuilder::RopCollect.new(file)
ropbuilder.print_msg("Collecting gadgets from %bld%cya#{file}%clr\n", color)
retn = ropbuilder.collect(opts[:depth], "\xc2") # retn
ret = ropbuilder.collect(opts[:depth], "\xc3") # ret
ropbuilder.print_msg("Found %grn#{ret.count + retn.count}%clr gadgets\n\n", color)

# compile a list of all gadgets from all files
ret.each do |gadget|
gadgets << gadget
if opts[:verbose]
ropbuilder.print_msg("#{gadget[:file]} gadget: %bld%grn#{gadget[:address]}%clr\n", color)
ropbuilder.print_msg("#{gadget[:disasm]}\n", color)
end
end

retn.each do |gadget|
gadgets << gadget
if opts[:verbose]
ropbuilder.print_msg("#{gadget[:file]} gadget: %bld%grn#{gadget[:address]}%clr\n", color)
ropbuilder.print_msg("#{gadget[:disasm]}\n", color)
end
end

end

ropbuilder.print_msg("Found %bld%grn#{gadgets.count}%clr gadgets total\n\n", color)
end

if opts[:import]

ropbuilder = Rex::RopBuilder::RopCollect.new()
ropbuilder.print_msg("Importing gadgets from %bld%cya#{opts[:import]}\n", color)
gadgets = ropbuilder.import(opts[:import])

gadgets.each do |gadget|
ropbuilder.print_msg("gadget: %bld%cya#{gadget[:address]}%clr\n", color)
ropbuilder.print_msg(gadget[:disasm] + "\n", color)
end

ropbuilder.print_msg("Imported %grn#{gadgets.count}%clr gadgets\n", color)
end

if opts[:pattern]
matches = ropbuilder.pattern_search(opts[:pattern])
if opts[:verbose]
ropbuilder.print_msg("Found %grn#{matches.count}%clr matches\n", color)
end
end

if opts[:export]
ropbuilder.print_msg("Exporting %grn#{gadgets.count}%clr gadgets to %bld%cya#{opts[:export]}%clr\n", color)
csv = ropbuilder.to_csv(gadgets)

if csv.nil?
exit(1)
end

begin
fd = File.new(opts[:export], 'w')
fd.puts csv
fd.close
rescue
puts "Error writing #{opts[:export]} file"
exit(1)
end
ropbuilder.print_msg("%bld%redSuccess!%clr gadgets exported to %bld%cya#{opts[:export]}%clr\n", color)
end
Something went wrong with that request. Please try again.