forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 23
/
msfelfscan
executable file
·135 lines (105 loc) · 2.86 KB
/
msfelfscan
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
#!/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/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|
begin
Rex::Arch::X86.reg_number(o)
rescue
puts "Invalid register \"#{o}\""
exit(1)
end
}
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.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('-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_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
elf = Rex::ElfParsey::Elf.new_from_file(file, true)
rescue Rex::ElfParsey::ElfHeaderError
if $!.message == 'Invalid magic number'
$stderr.puts("Skipping #{file}: #{$!}")
next
end
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