Metasploit mailing list archives

[PATCH] speedup


From: john-metasploit at ofjj.net (Yoann Guillot)
Date: Thu, 25 Jun 2009 19:42:56 +0200

Hi

This is a patch that speeds up Msf::Simple::Framework.create by a factor 2 on
my machine. I'm not quite sure this is 100% correct, but it seem to be, as far
as I understand the framework.

The _intersect_expand method is particularly weird, but I think i preserved the
semantics.
Also PlatformList#& had a strange behavior in the beginning (with the 'all?' tests),
I think my version is correct (anyway there don't seem to be a module whose
PlatformList#all? is true).

-- 
Yoann Guillot



diff -r b71036428911 lib/msf/core/module/platform.rb
--- a/lib/msf/core/module/platform.rb   Wed Jun 24 22:02:29 2009 +0200
+++ b/lib/msf/core/module/platform.rb   Thu Jun 25 19:15:41 2009 +0200
@@ -67,13 +67,13 @@
        # Finds all inherited children from a given module.
        # 
        def self.find_children
-               constants.map { |c| 
-                       const_get(c) 
-               }.delete_if { |m| 
-                       !m.kind_of?(Class) || ! (m < self) 
-               }.sort { |a, b|
-                       a::Rank <=> b::Rank
-               }
+               @subclasses ||= []
+               @subclasses.sort_by { |a| a::Rank }
+       end
+
+       def self.inherited(subclass)
+               @subclasses ||= []
+               @subclasses << subclass
        end
 
        #
@@ -431,4 +431,4 @@
                Rank = 100
                Alias = "php"
        end     
-end
\ No newline at end of file
+end
diff -r b71036428911 lib/msf/core/module/platform_list.rb
--- a/lib/msf/core/module/platform_list.rb      Wed Jun 24 22:02:29 2009 +0200
+++ b/lib/msf/core/module/platform_list.rb      Thu Jun 25 19:15:41 2009 +0200
@@ -83,10 +83,7 @@
        # Symbolic check to see if this platform list represents 'all' platforms.
        #
        def all?
-               names.each do |name|
-                       return true if name == ''
-               end
-               return false
+               names.include? ''
        end
 
        #
@@ -119,39 +116,30 @@
        # used for say, building a payload from a stage and stager
        #
        def &(plist)
+               # If either list has all in it, return the other one
+               if plist.all?
+                       return self
+               elsif self.all?
+                       return plist
+               end
+
                list1 = plist.platforms
                list2 = platforms
-               total = [ ]
-
-               # If either list has all in it, just merge the two
-               if (plist.all? or all?)
-                       return list1.dup.concat(list2)
-               end
-
-               #
-               # um, yeah, expand the lowest depth (like highest superset)
-               # each time and then do another intersection, keep doing
-               # this until no one has any children anymore...
-               #
+               total = []
 
                loop do
                        # find any intersections
                        inter = list1 & list2
                        # remove them from the two sides
-                       list1 = list1 - inter
-                       list2 = list2 - inter
+                       list1 -= inter
+                       list2 -= inter
                        # add them to the total
                        total += inter
 
-                       if list1.empty? || list2.empty?
-                               break
-                       end
+                       break if list1.empty? || list2.empty?
 
-                       begin
-                               list1, list2 = _intersect_expand(list1, list2)
-                       rescue ::RuntimeError
-                               break
-                       end
+                       # try to expand to subclasses to refine the match
+                       break if ! _intersect_expand(list1, list2)
                end
 
                return Msf::Module::PlatformList.new(*total)
@@ -165,21 +153,28 @@
        # been intersected with each other..
        #
        def _intersect_expand(list1, list2)
-               (list1 + list2).sort { |a, b|
-                 a.name.split('::').length <=> b.name.split('::').length }.
-                 each { |m|
-                       children = m.find_children
-                       if !children.empty?
-                               if list1.include?(m)
-                                       return [ list1 - [ m ] + children, list2 ]
-                               else
-                                       return [ list1, list2 - [ m ] + children ]
-                               end
-                       end
+               # abort if no shared prefix is found between l1 and l2
+               # shortcircuits [Windows] & [Linux] without going
+               #  through XP => SP2 => DE
+               ln1 = list1.map { |c| c.name }
+               ln2 = list2.map { |c| c.name }
+               return if not ln1.find { |n1|
+                       ln2.find { |n2| n1[0, n2.length] == n2[0, n1.length] }
                }
 
-               # XXX what's a better exception to throw here?
-               raise RuntimeError, "No more expansion possible", caller
+               (list1 + list2).sort { |a, b|
+                       # find the superest class in both lists
+                       a.name.count(':') <=> b.name.count(':')
+               }.find { |m|
+                       # which has children
+                       children = m.find_children
+                       next if children.empty?
+                       # replace this class in its list by its children
+                       l = list1.include?(m) ? list1 : list2
+                       l.delete m
+                       l.concat children
+                       true
+               }
        end
 
end


Current thread: