1
1
# -*- coding: binary -*-
2
-
3
2
# Concerns reloading modules
3
+ require 'pry'
4
+ require 'pry-byebug'
4
5
module Msf ::ModuleManager ::Reloading
5
6
# Reloads the module specified in mod. This can either be an instance of a module or a module class.
6
7
#
7
8
# @param [Msf::Module, Class] mod either an instance of a module or a module class
8
9
# @return (see Msf::Modules::Loader::Base#reload_module)
9
10
def reload_module ( mod )
10
11
# if it's an instance, then get its class
12
+ binding . pry
11
13
if mod . is_a? Msf ::Module
12
14
metasploit_class = mod . class
13
- original_instance = mod
14
15
else
15
16
metasploit_class = mod
16
- original_instance = nil
17
17
end
18
18
19
- # Handle aliases cleanup
20
- if ( aliased_as = inv_aliases [ metasploit_class . fullname ] )
19
+ if aliased_as = self . inv_aliases [ metasploit_class . fullname ]
21
20
aliased_as . each do |a |
22
- aliases . delete a
21
+ self . aliases . delete a
23
22
end
24
- inv_aliases . delete metasploit_class . fullname
23
+ self . inv_aliases . delete metasploit_class . fullname
25
24
end
26
25
27
- # Special handling for payload modules
28
- if mod &.payload?
29
- return reload_payload_module ( metasploit_class , original_instance )
26
+ if mod . payload?
27
+ return reload_payload_module ( mod )
30
28
end
31
-
32
- # Standard module reloading for non-payloads
29
+
33
30
namespace_module = metasploit_class . module_parent
34
-
31
+
35
32
# Check if the namespace module has a loader
36
33
unless namespace_module . respond_to? ( :loader )
37
- raise "Module #{ metasploit_class . fullname } namespace does not have a loader"
34
+ elog ( "Module does not have loader" )
35
+ return mod
38
36
end
39
37
40
38
loader = namespace_module . loader
41
39
loader . reload_module ( mod )
42
40
end
41
+ # Reload payload module, separately from other categories. This is due to complexity of payload module and due to the fact they don't follow class structure as rest of the modules.
42
+ # @param [Msf::Module, Class] mod either an instance of a module or a module class
43
+ # @return (see Msf::Modules::Loader::Base#reload_module)
44
+ def reload_payload_module ( mod )
45
+ if mod . is_a? Msf ::Module
46
+ metasploit_class = mod . class
47
+ original_instance = mod
48
+ else
49
+ metasploit_class = mod
50
+ original_instance = nil
51
+ end
52
+ binding . pry
43
53
44
- private
45
-
46
- # Reloads a payload module. This must be done by reloading the entire parent
47
- # directory to ensure the framework's complex payload "stitching" process
48
- # (combining stages, stagers, and mixins) is correctly executed. This is slower
49
- # but guarantees a fully-functional reloaded module.
50
- def reload_payload_module ( metasploit_class , original_instance = nil )
51
- # Step 1: Get all necessary identifiers from the original module class.
52
- fullname = metasploit_class . fullname
53
- refname = metasploit_class . refname
54
- type = metasploit_class . type
55
- file_path = metasploit_class . file_path
56
-
57
- # Get a reference to the original datastore now, but do not copy it yet.
58
- original_datastore = original_instance &.datastore
59
-
60
- # Step 2: Manually purge the old module from the framework's caches.
61
- if ( module_set = module_set_by_type . fetch ( type , nil ) )
62
- module_set . delete ( refname )
63
- end
64
- if ( aliases_for_fullname = inv_aliases [ fullname ] )
65
- aliases_for_fullname . each { |a | aliases . delete ( a ) }
66
- inv_aliases . delete ( fullname )
54
+ if ( module_set = self . module_set_by_type . fetch ( metasploit_class . type , nil ) )
55
+ module_set . delete ( metasploit_class . refname )
67
56
end
68
57
69
- # Step 3: Get the module's parent directory path.
70
- module_info = module_info_by_path [ file_path ]
58
+ module_info = self . module_info_by_path [ metasploit_class . file_path ]
71
59
unless module_info && ( parent_path = module_info [ :parent_path ] )
72
- raise Msf ::LoadError , "Could not find cached module information for path: #{ file_path } "
60
+ elog ( "Failed to get parent_path from module object" )
61
+ return mod
62
+ end
63
+
64
+ case original_instance &.payload_type
65
+ when Msf ::Payload ::Type ::Single
66
+ prepend_path = 'singles'
67
+ when Msf ::Payload ::Type ::Stager
68
+ prepend_path = 'stagers'
69
+ when Msf ::Payload ::Type ::Stage
70
+ prepend_path = 'stages'
71
+ when Msf ::Payload ::Type ::Adapter
72
+ prepend_path = 'adapters'
73
73
end
74
74
75
- # Step 4: Use the core framework loader to reload the entire parent directory.
76
- # This is the only way to reliably trigger the payload stitching logic.
77
- load_modules ( parent_path , force : true )
75
+ full_reference_name = File . join ( prepend_path , module_info [ :reference_name ] )
76
+ self . loaders . each { | loader | loader . load_module ( parent_path , module_info [ :type ] , full_reference_name , { :force => true } ) }
77
+
78
78
79
- # Step 5: Now that the framework has completed its full reload process,
80
- # use the public API to get a new instance of our reloaded module.
81
- new_instance = framework . modules . create ( fullname )
79
+ # Get reloaded module
80
+ new_instance = framework . modules . create ( metasploit_class . fullname )
82
81
83
82
if new_instance . blank?
84
- raise Msf ::LoadError , "Failed to create a new instance of #{ fullname } after reloading. The module file may be broken."
83
+ elog ( "Failed create new instance" )
84
+ return mod
85
85
end
86
86
87
- # Step 6: Restore the datastore to the new, fully-functional instance.
88
- # Now we perform the copy, which is a method on the new datastore's merge function.
89
- if original_datastore
90
- new_instance . datastore . merge! ( original_datastore )
91
- end
87
+ # Restore the datastore
88
+ new_instance . datastore . merge! ( original_instance . datastore )
89
+
92
90
93
91
# Return the new instance, which the framework will make the active module.
94
92
return new_instance
95
93
rescue StandardError => e
96
- elog ( "Failed to reload payload #{ fullname } " , error : e )
97
- raise Msf :: LoadError , e . message
94
+ elog ( "Failed to reload payload #{ fullname } : #{ e . message } " )
95
+ return mod
98
96
end
99
97
100
- public
101
-
102
98
# Reloads modules from all module paths
103
99
#
104
100
# @return (see Msf::ModuleManager::Loading#load_modules)
105
101
def reload_modules
106
- enablement_by_type . each_key do |type |
102
+ self . enablement_by_type . each_key do |type |
107
103
module_set_by_type [ type ] . clear
108
104
init_module_set ( type )
109
105
end
110
-
111
- aliases . clear
112
- inv_aliases . clear
106
+ self . aliases . clear
107
+ self . inv_aliases . clear
113
108
114
109
# default the count to zero the first time a type is accessed
115
110
count_by_type = Hash . new ( 0 )
116
111
112
+ framework . init_module_paths unless framework . module_paths_inited
113
+
117
114
module_paths . each do |path |
118
115
path_count_by_type = load_modules ( path , force : true )
119
116
@@ -124,6 +121,7 @@ def reload_modules
124
121
end
125
122
126
123
refresh_cache_from_module_files
124
+
127
125
count_by_type
128
126
end
129
127
end
0 commit comments