forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 3
/
msfmachscan
executable file
·117 lines (92 loc) · 2.44 KB
/
msfmachscan
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
#!/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/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