From ddc47955f22574e828294eaf1db1a830207f3ab1 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Wed, 24 Sep 2008 04:15:10 +0000 Subject: [PATCH] Simplified module loader, update to the platform module to be more compat with ruby 1.9 git-svn-id: file:///home/svn/framework3/trunk@5677 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/module/platform.rb | 17 +++++++++--- lib/msf/core/module_manager.rb | 47 ++++++++++++++++----------------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/lib/msf/core/module/platform.rb b/lib/msf/core/module/platform.rb index 2a45a5fc9a..f41747c40e 100644 --- a/lib/msf/core/module/platform.rb +++ b/lib/msf/core/module/platform.rb @@ -53,7 +53,7 @@ class Msf::Module::Platform str = str.gsub(' ', '').downcase # Start at the base platform module - mod = Msf::Module::Platform + mod = ::Msf::Module::Platform # Scan forward, trying to find the end module while str.length > 0 @@ -83,7 +83,7 @@ class Msf::Module::Platform def self.build_child_platform_abbrev(mod) # Flush out any non-class and non-inherited children children = mod.find_children - + # No children to speak of? return if (children.length == 0) @@ -130,11 +130,22 @@ class Msf::Module::Platform # the string). # def self.find_portion(mod, str) + # Check to see if we've built the abbreviated cache - if (mod.const_defined?('Abbrev') == false) + if (not ( + mod.const_defined?('Abbrev') and + mod.const_defined?('Names') and + mod.const_defined?('Ranks') + ) ) build_child_platform_abbrev(mod) end + if (not mod.const_defined?('Names')) + elog("Failed to instantiate the platform list for module #{mod}") + exit(0) + return nil + end + abbrev = mod.const_get('Abbrev') names = mod.const_get('Names') ranks = mod.const_get('Ranks') diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index 162659fa5b..0fc28b9bb5 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -501,6 +501,7 @@ class ModuleManager < ModuleSet @modcache['ModuleTypeCounts'].clear MODULE_TYPES.each { |type| + module_sets[type] ||= [] @modcache['ModuleTypeCounts'][type] = module_sets[type].length.to_s } end @@ -782,7 +783,7 @@ protected Rex::Find.find(path) { |file| # Skip non-ruby files - next if (file !~ /\.rb$/i) + next if (file !~ /\.rb$/) # Skip unit test files next if (file =~ /rb\.(ut|ts)\.rb$/) @@ -793,7 +794,6 @@ protected begin load_module_from_file(path, file, loaded, recalc, counts, demand) rescue NameError - # As of Jan-06-2007 this code isn't hit with the official module tree # If we get a name error, it's possible that this module depends @@ -838,9 +838,15 @@ protected } # Perform any required recalculations for the individual module types - # that actually had load changes + # that actually had load changes. Remove modules which generate + # exceptions during the recalculation phase. recalc.each_key { |key| - module_sets[key].recalculate + begin + module_sets[key].recalculate + rescue ::Exception => e + elog("Module #{key} threw exception #{e.class} #{e}: removing.") + module_sets.delete(key) + end } # Return per-module loaded counts @@ -895,7 +901,7 @@ protected # Get the module and grab the current number of constants old_constants = mod.constants - + # Load the file like it aint no thang begin if (!load(file)) @@ -918,7 +924,7 @@ protected elog("LoadError: #{$!}.") return false rescue ::Exception => e - elog("Failed to load module from #{file}: #{e.class} #{e}") + elog("Failed to load module from #{file}: #{e.class} #{e} #{e.backtrace}") self.module_failed[file] = e return false end @@ -1014,31 +1020,24 @@ protected # name. # def mod_from_name(name) - obj = Msf + + # The root namespace + obj = ::Msf + + # Build up a module container + name.split(File::SEPARATOR).each do |m| - name.split(File::SEPARATOR).each { |m| # Up-case the first letter and any prefixed by _ m.gsub!(/^[a-z]/) { |s| s.upcase } m.gsub!(/(_[a-z])/) { |s| s[1..1].upcase } - begin - new_obj = obj.const_get(m) - - # I can't really explain why this check is necessary. Perhaps - # someone cooloer than I can explain it. Here's the scenario. - # const_get is returning constants that are not accessible - # immediately from within the object passed. However, the - # documentation states that this is how it should operate. - # Perhaps I misread. - if obj.constants.grep(m).length == 0 - raise NameError - end - - obj = new_obj - rescue NameError + if(obj.const_defined?(m)) + obj = obj.const_get(m) + else + elog("Setting module constant #{obj}::#{m}") obj = obj.const_set(m, ::Module.new) end - } + end return obj end