forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextension_mapper.rb
106 lines (88 loc) · 2.9 KB
/
extension_mapper.rb
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
# -*- coding: binary -*-
module Rex
module Post
module Meterpreter
class ExtensionMapper
@@klasses = {}
# Get the names of all of the extensions.
#
# @return [Array<String>] An array of all of the extension names.
def self.get_extension_names
base = ::File.join(File.dirname(__dir__), 'meterpreter/extensions')
::Dir.entries(base).select do |e|
::File.directory?(::File.join(base, e)) && !['.', '..'].include?(e)
end
end
# Get the numeric ID for the specified extension name.
#
# @param [String] name The name of the extension to retrieve the ID for. This
# parameter is case insensitive.
# @return [Integer, nil] The extension ID or nil if the name does not exist.
def self.get_extension_id(name)
begin
k = self.get_extension_klass(name)
rescue RuntimeError
return nil
end
k.extension_id
end
# Get the string extension name for the specified extension ID.
#
# @param [Integer] id The ID of the extension to retrieve the name for.
# @return [String, nil] The extension name or nil if the ID does not exist.
def self.get_extension_name(id)
id = id - (id % COMMAND_ID_RANGE)
self.get_extension_names.find do |name|
begin
klass = self.get_extension_klass(name)
rescue RuntimeError
next
end
klass.extension_id == id
end
end
# Get the module for the specified extension name.
#
# @param [String] name The name of the extension to retrieve the module for.
# This parameter is case insensitive.
# @raise [RuntimeError] A RuntimeError is raised if the specified module can
# not be loaded.
# @return [Module] The extension module.
def self.get_extension_module(name)
name.downcase!
begin
require("rex/post/meterpreter/extensions/#{name}/#{name}")
rescue LoadError
# the extension doesn't exist on disk
raise RuntimeError, "Unable to load extension '#{name}' - module does not exist."
end
s = Rex::Post::Meterpreter::Extensions.constants.find { |c| name == c.to_s.downcase }
Rex::Post::Meterpreter::Extensions.const_get(s)
end
# Get the class for the specified extension name.
#
# @param [String] name The name of the extension to retrieve the class for.
# This parameter is case insensitive.
# @raise [RuntimeError] A RuntimeError is raised if the specified module can
# not be loaded.
# @return [Class] The extension class.
def self.get_extension_klass(name)
name.downcase!
unless @@klasses[name]
mod = self.get_extension_module(name)
@@klasses[name] = mod.const_get(mod.name.split('::').last)
end
@@klasses[name]
end
def self.get_extension_klasses
self.get_extension_names.map { |name| self.get_extension_module(name) }
end
def self.dump_extensions
self.get_extension_names.each { |n|
STDERR.puts("EXTENSION_ID_#{n.upcase} = #{self.get_extension_id(n)}\n")
}
end
end
end
end
end