Utility for working with pointers. Test coverage is incomplete

This commit is contained in:
chao-mu 2012-01-04 19:30:30 -05:00
parent b9b5b1e66f
commit 3d7d5d5f3d
2 changed files with 188 additions and 0 deletions

View File

@ -0,0 +1,108 @@
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
module Railgun
module Type
module PointerUtil
X86_64 = :x86_64
X86_32 = :x86_32
ARCH_POINTER_SIZE = {
X86_64 => 8,
X86_32 => 4
}.freeze
# Returns the pointer size for this architecture. Should accept client or platform or arch
def self.pointer_size(platform)
ARCH_POINTER_SIZE[platform]
end
def self.pack_pointer(pointer, platform)
# TODO: Ensure the correct size
unless pointer.kind_of?(Fixnum)
return nil
end
case platform
when X86_64
# XXX: Only works if attacker and victim are like-endianed
[pointer].pack('Q')
when X86_32
[pointer].pack('V')
else
raise "platform symbol #{platform.to_s} not supported"
end
end
# Given a packed pointer, unpack it according to architecture
def self.unpack_pointer(packed_pointer, platform)
case platform
when X86_64
# XXX: Only works if attacker and victim are like-endianed
packed_pointer.unpack('Q').first
when X86_32
packed_pointer.unpack('V').first
else
raise "platform symbol #{platform.to_s} not supported"
end
end
def self.null_pointer(pointer, platform)
pack_pointer(0, platform)
end
###
# Summary: Returns true if pointer will be considered a 'null' pointer
#
# If given nil, returns true
# If given 0, returns true
# If given a string, if 0 after unpacking, returns true
# false otherwise
##
def self.is_null_pointer?(pointer, platform)
if pointer.kind_of?(String)
pointer = unpack_pointer(pointer, platform)
end
return pointer.nil? || pointer == 0
end
def self.is_unpacked_pointer?(pointer, platform)
# TODO also check that the integer size is appropriate for the platform
unless pointer.kind_of?(Fixnum) and pointer > 0 # and pointer <
return false
end
packed_pointer = pack_pointer(pointer, platform)
if !packed_pointer.nil? and packed_pointer.length == pointer_size(platform)
return true
end
return false
end
# Returns true if the data type is a pointer, false otherwise
def self.is_pointer_type?(type)
if type == :pointer
return true
end
if type.kind_of?(String) && type =~ /^P/
return true
end
return false
end
end # PointerUtil
end # Type
end # Railgun
end # Stdapi
end # Extensions
end # Meterpreter
end # Post
end # Rex

View File

@ -0,0 +1,80 @@
#!/usr/bin/env ruby
$:.unshift(File.join(File.dirname(__FILE__), '..', '..','..','..','..','..', '..', '..', 'lib'))
require 'rex/post/meterpreter/extensions/stdapi/railgun/type/pointer_util'
require 'rex/post/meterpreter/extensions/stdapi/railgun/mock_magic'
require 'test/unit'
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
module Railgun
module Type
class PointerUtil::UnitTest < Test::Unit::TestCase
include Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::MockMagic
# memread value of win x86 pointer mapped to target unpack value
X86_32_POINTERS = {
"8D\x15\x00" => 1393720,
"\x1C\x84\x15\x00" => 1410076,
"\x0E\x84\x15\x00" => 1410062,
"\x02\x84\x15\x00" => 1410050,
"\xE6\x83\x15\x00" => 1410022,
"\xC4\x83\x15\x00" => 1409988,
"\x00\x00\x00\x00" => 0,
}
X86_64_POINTERS = {
"\x10^ \x00\x00\x00\x00\x00" => 2121232,
"\xCA\x9D \x00\x00\x00\x00\x00" => 2137546,
"\xC8\x9D \x00\x00\x00\x00\x00" => 2137544,
"Z\x9D \x00\x00\x00\x00\x00" => 2137434,
"X\x9D \x00\x00\x00\x00\x00" => 2137432,
"\x00\x00\x00\x00\x00\x00\x00\x00" => 0,
}
X86_64_NULL_POINTER = "\x00\x00\x00\x00\x00\x00\x00\x00"
X86_32_NULL_POINTER = "\x00\x00\x00\x00"
X86_64 = :x86_64
X86_32 = :x86_32
def test_unpack_pointer
X86_64_POINTERS.each_pair do |packed, unpacked|
assert_equal(unpacked, PointerUtil.unpack_pointer(packed, X86_64),
"unpack_pointer should unpack 64-bit pointers")
end
X86_32_POINTERS.each_pair do |packed, unpacked|
assert_equal(unpacked, PointerUtil.unpack_pointer(packed, X86_32),
"unpack_pointer should unpack 32-bit pointers")
end
end
def test_is_null_pointer
[X86_32, X86_64].each do |platform|
assert(PointerUtil.is_null_pointer?(nil, platform), 'nil should be a null pointer')
assert(PointerUtil.is_null_pointer?(0, platform), 'numeric 0 should be a null pointer')
end
assert_equal(true, PointerUtil.is_null_pointer?(X86_32_NULL_POINTER, X86_32),
'is_null_pointer? should return true for packed 32-bit null pointers')
assert_equal(true, PointerUtil.is_null_pointer?(X86_64_NULL_POINTER, X86_64),
'is_null_pointer? should return true for packed 64-bit null pointers')
end
def test_pointer_size
end
end
end
end
end
end
end
end
end