123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- #!/usr/bin/env ruby
- # -*- coding: binary -*-
- #
- # $Id$
- # $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 'msfenv'
- $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
- require 'rex/machparsey'
- require 'rex/machscan'
- require 'rex/arch/x86'
- require 'optparse'
- def opt2i(o)
- o.index("0x")==0 ? o.hex : o.to_i
- end
- opt = OptionParser.new
- opt.banner = "Usage: #{$PROGRAM_NAME} [mode] <options> [targets]"
- opt.separator('')
- opt.separator('Modes:')
- worker = nil
- param = {}
- opt.on('-j', '--jump [regA,regB,regC]', 'Search for jump equivalent instructions') do |t|
- # take csv of register names (like eax,ebx) and convert
- # them to an array of register numbers
- regnums = t.split(',').collect { |o|
- begin
- Rex::Arch::X86.reg_number(o)
- rescue
- puts "Invalid register \"#{o}\""
- exit(1)
- end
- }
- worker = Rex::MachScan::Scanner::JmpRegScanner
- param['args'] = regnums
- end
- opt.on('-p', '--poppopret', 'Search for pop+pop+ret combinations') do |t|
- worker = Rex::MachScan::Scanner::PopPopRetScanner
- param['args'] = t
- end
- opt.on('-r', '--regex [regex]', 'Search for regex match') do |t|
- worker = Rex::MachScan::Scanner::RegexScanner
- param['args'] = t
- end
- opt.separator('')
- opt.separator('Options:')
- opt.on('-A', '--after [bytes]', 'Number of bytes to show after match (-a/-b)') do |t|
- param['after'] = opt2i(t)
- end
- opt.on('-B', '--before [bytes]', 'Number of bytes to show before match (-a/-b)') do |t|
- param['before'] = opt2i(t)
- end
- opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase') do |t|
- param['imagebase'] = opt2i(t)
- 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 (! worker)
- puts opt
- exit(1)
- end
- ARGV.each do |file|
- param['file'] = file
- begin
- mach = Rex::MachParsey::Mach.new_from_file(file, true)
- o = worker.new(mach)
- o.scan(param)
- mach.close
- rescue Rex::MachParsey::MachHeaderError
- $stderr.puts("File is not a Mach-O binary, trying Fat..\n")
- fat = Rex::MachParsey::Fat.new_from_file(file, true)
- o = worker.new(fat)
- o.scan(param)
- fat.close
- rescue Errno::ENOENT
- $stderr.puts("File does not exist: #{file}")
- next
- end
- end
|