root/framework3/trunk/msfpescan

Revision 5717, 3.5 kB (checked in by hdm, 2 days ago)

Add disassembly mode to msfpescan for -a

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/env ruby
2
3 msfbase = File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__
4 $:.unshift(File.join(File.dirname(msfbase), 'lib'))
5 $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
6
7 require 'rex/peparsey'
8 require 'rex/pescan'
9 require 'rex/arch/x86'
10 require 'optparse'
11
12 def opt2i(o)
13         o.index("0x")==0 ? o.hex : o.to_i
14 end
15
16
17 #
18 # Right now this program is a bit shakey...
19 #
20 # - It tries to error on the side of caution, so it will try for a
21 #   false negative vs a false positive.
22 # - It doesn't account for the entire PE image neccesairly
23 # - It wouldn't find hits that overlap sections
24 # - etc etc
25 #
26
27 opt = OptionParser.new
28
29 opt.banner = "Usage: #{$PROGRAM_NAME} [mode] <options> [targets]"
30 opt.separator('')
31 opt.separator('Modes:')
32
33 worker = nil
34 param  = {}
35
36 pe_klass = Rex::PeParsey::Pe
37
38 opt.on('-j', '--jump [regA,regB,regC]', 'Search for jump equivalent instructions') do |t|
39         # take csv of register names (like eax,ebx) and convert
40         # them to an array of register numbers
41         regnums = t.split(',').collect { |o| Rex::Arch::X86.reg_number(o) }
42         worker = Rex::PeScan::Scanner::JmpRegScanner
43         param['args'] = regnums
44 end
45
46 opt.on('-p', '--poppopret', 'Search for pop+pop+ret combinations') do |t|
47         worker = Rex::PeScan::Scanner::PopPopRetScanner
48         param['args'] = t
49 end
50
51 opt.on('-r', '--regex [regex]', 'Search for regex match') do |t|
52         worker = Rex::PeScan::Scanner::RegexScanner
53         param['args'] = t
54 end
55
56 opt.on('-a', '--analyze-address [address]', 'Display the code at the specified address') do |t|
57         worker = Rex::PeScan::Search::DumpRVA
58         param['args'] = opt2i(t)
59 end
60
61 opt.on('-b', '--analyze-offset [offset]', 'Display the code at the specified offset') do |t|
62         worker = Rex::PeScan::Search::DumpOffset
63         param['args'] = opt2i(t)
64 end
65
66 opt.on('-f', '--fingerprint', 'Attempt to identify the packer/compiler') do |t|
67         worker = Rex::PeScan::Analyze::Fingerprint
68         param['database'] = File.join(File.dirname(msfbase), 'data', 'msfpescan', 'identify.txt')
69 end
70
71 opt.on('-i', '--info', 'Display detailed information about the image') do |t|
72         worker = Rex::PeScan::Analyze::Information
73 end
74
75 opt.on('-R', '--ripper [directory]', 'Rip all module resources to disk ') do |t|
76         worker = Rex::PeScan::Analyze::Ripper
77         param['dir'] = t
78 end
79
80 opt.on('--context-map [directory]', 'Generate context-map files') do |t|
81         worker = Rex::PeScan::Analyze::ContextMapDumper
82         param['dir'] = t
83 end
84
85 opt.separator('')
86 opt.separator('Options:')
87
88 opt.on('-M', '--memdump', 'The targets are memdump.exe directories') do |t|
89         pe_klass = Rex::PeParsey::PeMemDump
90 end
91
92
93 opt.on('-A', '--after [bytes]', 'Number of bytes to show after match (-a/-b)') do |t|
94         param['after'] = opt2i(t)
95 end
96
97 opt.on('-B', '--before [bytes]', 'Number of bytes to show before match (-a/-b)') do |t|
98         param['before'] = opt2i(t)
99 end
100
101 opt.on('-D', '--disasm', 'Disassemble the bytes at this address') do |t|
102         param['disasm'] = true
103 end
104
105 opt.on('-I', '--image-base [address]', 'Specify an alternate ImageBase') do |t|
106         param['imagebase'] = opt2i(t)
107 end
108
109 opt.on_tail("-h", "--help", "Show this message") do
110         puts opt
111         exit
112 end
113
114 opt.parse!
115
116 if (! worker)
117         puts opt
118         exit(0)
119 end
120
121 ARGV.each do |file|
122        
123         param['file'] = file
124        
125         begin
126                 pe = pe_klass.new_from_file(file, true)
127         rescue Rex::PeParsey::FileHeaderError
128                 next if $!.message == "Couldn't find the PE magic!"
129                 raise $!
130         rescue Errno::ENOENT
131                 $stderr.puts("File does not exist: #{file}")
132                 next
133         end
134        
135         if (param['imagebase'])
136                 pe.image_base = param['imagebase'];
137         end
138
139         o = worker.new(pe)
140         o.scan(param)
141        
142         pe.close
143
144 end
Note: See TracBrowser for help on using the browser.