metasploit-framework/msfelfscan

128 lines
3.1 KiB
Ruby

#!/usr/bin/env ruby
# $Id$
msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
$:.unshift(File.join(File.dirname(msfbase), 'lib'))
require 'rex/elfparsey'
require 'rex/elfscan'
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| Rex::Arch::X86.reg_number(o) }
worker = Rex::ElfScan::Scanner::JmpRegScanner
param['args'] = regnums
end
opt.on('-p', '--poppopret', 'Search for pop+pop+ret combinations') do |t|
worker = Rex::ElfScan::Scanner::PopPopRetScanner
param['args'] = t
end
opt.on('-r', '--regex [regex]', 'Search for regex match') do |t|
worker = Rex::ElfScan::Scanner::RegexScanner
param['args'] = t
end
#opt.on('-a', '--analyze-address [address]', 'Display the code at the specified address') do |t|
# worker = Rex::ElfScan::Search::DumpRVA
# param['args'] = opt2i(t)
#end
#opt.on('-b', '--analyze-offset [offset]', 'Display the code at the specified offset') do |t|
# worker = Rex::ElfScan::Search::DumpOffset
# param['args'] = opt2i(t)
#end
#opt.on('-f', '--fingerprint', 'Attempt to identify the packer/compiler') do |t|
# worker = Rex::ElfScan::Analyze::Fingerprint
# param['database'] = File.join(File.dirname(__FILE__), 'data', 'msfpescan', 'identify.txt')
#end
#opt.on('-i', '--info', 'Display detailed information about the image') do |t|
# worker = Rex::ElfScan::Analyze::Information
#end
#opt.on('-R', '--ripper [directory]', 'Rip all module resources to disk ') do |t|
# worker = Rex::ElfScan::Analyze::Ripper
# param['dir'] = t
#end
#opt.on('--context-map [directory]', 'Generate context-map files') do |t|
# worker = Rex::ElfScan::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::ElfParsey::ElfMemDump
#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('-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
end
opt.parse!
if (! worker)
puts opt
exit(0)
end
ARGV.each do |file|
param['file'] = file
begin
elf = Rex::ElfParsey::Elf.new_from_file(file, true)
rescue Rex::ElfParsey::ElfHeaderError
next if $!.message == 'Invalid magic number'
raise $!
rescue Errno::ENOENT
$stderr.puts("File does not exist: #{file}")
next
end
if (param['imagebase'])
elf.base_addr = param['imagebase'];
end
o = worker.new(elf)
o.scan(param)
elf.close
end