Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

executable file 201 lines (156 sloc) 4.421 kb
#!/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 'fastlib'
require 'msfenv'
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
require 'rex/peparsey'
require 'rex/pescan'
require 'rex/arch/x86'
require 'optparse'
def opt2i(o)
o.index("0x")==0 ? o.hex : o.to_i
end
#
# Right now this program is a bit shakey...
#
# - It tries to error on the side of caution, so it will try for a
# false negative vs a false positive.
# - It doesn't account for the entire PE image neccesairly
# - It wouldn't find hits that overlap sections
# - etc etc
#
opt = OptionParser.new
opt.banner = "Usage: #{$PROGRAM_NAME} [mode] <options> [targets]"
opt.separator('')
opt.separator('Modes:')
worker = nil
param = {}
pe_klass = Rex::PeParsey::Pe
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::PeScan::Scanner::JmpRegScanner
param['args'] = regnums
end
opt.on('-p', '--poppopret', 'Search for pop+pop+ret combinations') do |t|
worker = Rex::PeScan::Scanner::PopPopRetScanner
param['args'] = t
end
opt.on('-r', '--regex [regex]', 'Search for regex match') do |t|
worker = Rex::PeScan::Scanner::RegexScanner
param['args'] = t
end
opt.on('-a', '--analyze-address [address]', 'Display the code at the specified address') do |t|
worker = Rex::PeScan::Search::DumpRVA
param['args'] = opt2i(t)
end
opt.on('-b', '--analyze-offset [offset]', 'Display the code at the specified offset') do |t|
worker = Rex::PeScan::Search::DumpOffset
param['args'] = opt2i(t)
end
opt.on('-f', '--fingerprint', 'Attempt to identify the packer/compiler') do |t|
worker = Rex::PeScan::Analyze::Fingerprint
param['database'] = File.join(File.dirname(msfbase), 'data', 'msfpescan', 'identify.txt')
end
opt.on('-i', '--info', 'Display detailed information about the image') do |t|
worker = Rex::PeScan::Analyze::Information
end
opt.on('-R', '--ripper [directory]', 'Rip all module resources to disk ') do |t|
worker = Rex::PeScan::Analyze::Ripper
param['dir'] = t
end
opt.on('--context-map [directory]', 'Generate context-map files') do |t|
worker = Rex::PeScan::Analyze::ContextMapDumper
param['dir'] = t
end
opt.separator('')
opt.separator('Options:')
opt.on('-M', '--memdump', 'The targets are memdump.exe directories') do |t|
pe_klass = Rex::PeParsey::PeMemDump
end
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('-D', '--disasm', 'Disassemble the bytes at this address') do |t|
param['disasm'] = true
end
opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase') do |t|
param['imagebase'] = opt2i(t)
end
opt.on('-F', '--filter-addresses [regex]', 'Filter addresses based on a regular expression') do |t|
param['filteraddr'] = 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
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
files.each do |file|
$stdout.puts ""
param['file'] = file
begin
pe = pe_klass.new_from_file(file, true)
rescue ::Interrupt
raise $!
rescue Rex::PeParsey::FileHeaderError
next if $!.message == "Couldn't find the PE magic!"
raise $!
rescue Errno::ENOENT
$stdout.puts("File does not exist: #{file}")
next
rescue ::Rex::PeParsey::SkipError
next
rescue ::Exception => e
$stdout.puts "[#{file}] #{e.class}: #{e}"
next
end
if (param['imagebase'])
pe.image_base = param['imagebase'];
end
o = worker.new(pe)
o.scan(param)
pe.close
end
$stdout.puts ""
Jump to Line
Something went wrong with that request. Please try again.