git-svn-id: file:///home/svn/incoming/trunk@2538 4d416f70-5f16-0410-b530-b9f4589650da
unstable
Spoon M 2005-05-31 00:36:22 +00:00
parent 77688d73b4
commit 7b494ee350
3 changed files with 89 additions and 3 deletions

View File

@ -28,9 +28,14 @@ class Msf::Module::Platform
return mod
end
def find_children
self.class.find_children
end
# this is useful a lot of places, and should go into some
# library somewhere, or something
def self._find_children(mod)
def self.find_children
mod = self
mod.constants.map { |n| mod.const_get(n) }.
delete_if { |v| ! v.kind_of?(Class) || ! (v < mod) }
end
@ -39,7 +44,7 @@ class Msf::Module::Platform
def self._find_short(base, name)
# get a list of possible base classes, and sort them by
# their relative ranks to each other
poss = _find_children(base).sort { |a, b| a::Rank <=> b::Rank }
poss = base.find_children.sort { |a, b| a::Rank <=> b::Rank }
if poss.empty?
raise ArgumentError, "No classes in #{base.to_s}!", caller

View File

@ -20,7 +20,7 @@ class Msf::Module::PlatformList
b = Msf::Module::Platform.find_platform(a.begin)
e = Msf::Module::Platform.find_platform(a.end)
children = Msf::Module::Platform._find_children(b.superclass)
children = b.superclass.find_children
r = (b::Rank .. e::Rank)
children.each { |c|
platforms << c if r.include?(c::Rank)
@ -37,6 +37,7 @@ class Msf::Module::PlatformList
end
# Do I support plist (do I support all of they support?)
# use for matching say, an exploit and a payload
def supports?(plist)
plist.platforms.each { |pl|
supported = false
@ -52,5 +53,72 @@ class Msf::Module::PlatformList
return true
end
#
# WARNING: I pulled this algorithm out of my ass, it's probably broken
#
# Ok, this was a bit weird, but I think it should work. We basically
# want to do a set intersection, but with like superset expansion or
# something or another. So I try to do that recursively, and the
# result should be a the valid platform intersection...
#
# used for say, building a payload from a stage and stager
#
def &(plist)
list1 = plist.platforms
list2 = platforms
total = [ ]
#
# 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...
#
loop do
# find any intersections
inter = list1 & list2
# remove them from the two sides
list1 = list1 - inter
list2 = list2 - inter
# add them to the total
total += inter
if list1.empty? || list2.empty?
break
end
begin
list1, list2 = _intersect_expand(list1, list2)
rescue RuntimeError
break
end
end
return Msf::Module::PlatformList.new(*total)
end
protected
#
# man this be ghetto. Expand the 'superest' set of the two lists.
# will only ever expand 1 set, excepts both sets to already have
# 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
}
# XXX what's a better exception to throw here?
raise RuntimeError, "No more expansion possible", caller
end
end

View File

@ -33,4 +33,17 @@ class Msf::Module::PlatformList::UnitTest < Test::Unit::TestCase
assert_equal( true, l1.supports?(l2) )
assert_equal( false, l2.supports?(l1) )
end
def test_intersect
l1 = Msf::Module::PlatformList.new('win')
l2 = Msf::Module::PlatformList.new('win xp sp0', 'win xp sp2')
assert_equal(
[ Msf::Module::Platform::Windows::X86::XP::SP0,
Msf::Module::Platform::Windows::X86::XP::SP2
], (l1 & l2).platforms
)
l1 = Msf::Module::PlatformList.new('win xp sp1')
assert_equal( [ ], (l1 & l2).platforms )
end
end