Skip to content

Commit 8e16a50

Browse files
committed
Adds reloading for stagers/stages/adapters
1 parent e351da4 commit 8e16a50

File tree

1 file changed

+38
-30
lines changed

1 file changed

+38
-30
lines changed

lib/msf/core/module_manager/reloading.rb

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# -*- coding: binary -*-
2+
23
# Concerns reloading modules
34

45
module Msf::ModuleManager::Reloading
@@ -14,29 +15,41 @@ def reload_module(mod)
1415
metasploit_class = mod
1516
end
1617

17-
if aliased_as = self.inv_aliases[metasploit_class.fullname]
18+
if aliased_as = inv_aliases[metasploit_class.fullname]
1819
aliased_as.each do |a|
19-
self.aliases.delete a
20+
aliases.delete a
2021
end
21-
self.inv_aliases.delete metasploit_class.fullname
22+
inv_aliases.delete metasploit_class.fullname
2223
end
2324

2425
if mod.payload?
2526
return reload_payload_module(mod)
2627
end
27-
28+
29+
if aliased_as = inv_aliases[metasploit_class.fullname]
30+
aliased_as.each do |a|
31+
aliases.delete a
32+
end
33+
inv_aliases.delete metasploit_class.fullname
34+
end
35+
2836
namespace_module = metasploit_class.module_parent
29-
37+
3038
# Check if the namespace module has a loader
3139
unless namespace_module.respond_to?(:loader)
32-
elog("Module does not have loader")
40+
elog('Module does not have loader')
3341
return mod
3442
end
3543

3644
loader = namespace_module.loader
3745
loader.reload_module(mod)
3846
end
39-
# 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.
47+
48+
def manual_reload(parent_path, type, ref_name)
49+
loaders.each { |loader| loader.load_module(parent_path, type, ref_name, { force: true }) }
50+
end
51+
52+
# 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.
4053
# @param [Msf::Module, Class] mod either an instance of a module or a module class
4154
# @return (see Msf::Modules::Loader::Base#reload_module)
4255
def reload_payload_module(mod)
@@ -46,44 +59,39 @@ def reload_payload_module(mod)
4659
else
4760
metasploit_class = mod
4861
original_instance = nil
49-
end
50-
if (module_set = self.module_set_by_type.fetch(metasploit_class.type, nil))
62+
end
63+
if (module_set = module_set_by_type.fetch(metasploit_class.type, nil))
5164
module_set.delete(metasploit_class.refname)
5265
end
53-
54-
module_info = self.module_info_by_path[metasploit_class.file_path]
66+
module_info = module_info_by_path[metasploit_class.file_path]
5567
unless module_info && (parent_path = module_info[:parent_path])
56-
elog("Failed to get parent_path from module object")
68+
elog('Failed to get parent_path from module object')
5769
return mod
5870
end
5971

60-
case original_instance&.payload_type
61-
when Msf::Payload::Type::Single
62-
prepend_path = 'singles'
63-
when Msf::Payload::Type::Stager
64-
prepend_path = 'stagers'
65-
when Msf::Payload::Type::Stage
66-
prepend_path = 'stages'
67-
when Msf::Payload::Type::Adapter
68-
prepend_path = 'adapters'
69-
end
72+
# reload adapters if any
73+
manual_reload(parent_path, module_info[:type], File.join('adapters', mod.adapter_refname)) if mod.adapter_refname
74+
75+
# reload stagers if any
76+
manual_reload(parent_path, module_info[:type], File.join('stagers', mod.stager_refname)) if mod.stager_refname
7077

71-
full_reference_name = File.join(prepend_path, module_info[:reference_name])
72-
self.loaders.each { |loader| loader.load_module(parent_path,module_info[:type], full_reference_name, {:force => true}) }
78+
# reload stages if any
79+
manual_reload(parent_path, module_info[:type], File.join('stages', mod.stage_refname)) if mod.stage_refname
7380

81+
# reload single if any
82+
manual_reload(parent_path, module_info[:type], File.join('singles', module_info[:reference_name])) if original_instance.payload_type == Msf::Payload::Type::Single
7483

7584
# Get reloaded module
7685
new_instance = framework.modules.create(metasploit_class.fullname)
7786

7887
if new_instance.blank?
79-
elog("Failed create new instance")
88+
elog('Failed create new instance')
8089
return mod
8190
end
8291

83-
# Restore the datastore
92+
# Restore the datastore
8493
new_instance.datastore.merge!(original_instance.datastore)
8594

86-
8795
# Return the new instance, which the framework will make the active module.
8896
return new_instance
8997
rescue StandardError => e
@@ -95,12 +103,12 @@ def reload_payload_module(mod)
95103
#
96104
# @return (see Msf::ModuleManager::Loading#load_modules)
97105
def reload_modules
98-
self.enablement_by_type.each_key do |type|
106+
enablement_by_type.each_key do |type|
99107
module_set_by_type[type].clear
100108
init_module_set(type)
101109
end
102-
self.aliases.clear
103-
self.inv_aliases.clear
110+
aliases.clear
111+
inv_aliases.clear
104112

105113
# default the count to zero the first time a type is accessed
106114
count_by_type = Hash.new(0)

0 commit comments

Comments
 (0)