#!/usr/bin/env ruby # -*- coding: binary -*- $:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..','..','..','..','..', 'lib')) require 'rex/post/meterpreter/extensions/stdapi/railgun/railgun' require 'rex/post/meterpreter/extensions/stdapi/railgun/mock_magic' require 'test/unit' require 'benchmark' module Rex module Post module Meterpreter module Extensions module Stdapi module Railgun class Railgun::UnitTest < Test::Unit::TestCase # DLLs we know should be available at the time of this writing, # and DLLs that because of changes since then should be available STOCK_DLLS = [ 'kernel32', 'ntdll', 'user32', 'ws2_32', 'iphlpapi', 'advapi32', 'shell32', 'netapi32', 'crypt32', ] | Railgun::BUILTIN_DLLS include MockMagic def test_known_dll_names railgun = Railgun.new(make_mock_client()) dll_names = railgun.known_dll_names assert_equal(dll_names.length, dll_names.uniq.length, "known_dll_names should not have duplicates") STOCK_DLLS.each do |name| assert(dll_names.include?(name), "known_dll_names should include #{name}") end end # # TODO: # def test_multi # mock_function_descriptions.each do |func| # railgun = Railgun.new(make_mock_client(func[:platform])) # # functions = [ # [func[:dll_name], func[:name], func[:ruby_args]] # ] # # results = railgun.multi(functions) # end # end # def test_const railgun = Railgun.new(make_mock_client()) assert_equal(0, railgun.const('SUCCESS'), "const should look up constants like SUCCESS") end def test_add_dll railgun = Railgun.new(make_mock_client()) target_dll_name = 'discordia' target_windows_name = 'C:\look\behind\you' railgun.add_dll(target_dll_name, target_windows_name) actual_dll = railgun.get_dll(target_dll_name); assert_not_nil(actual_dll, "add_dll should make a DLL accessible via get_dll") assert_equal(actual_dll.dll_path, target_windows_name, "add_dll should set a dll path when specified") wrapper = railgun.send(target_dll_name.to_sym) assert_same(wrapper._dll, actual_dll, "railgun instance responds with dll wrapper of requested dll") end def test_method_missing railgun = Railgun.new(make_mock_client()) STOCK_DLLS.each do |dll_name| assert_nothing_raised do railgun.send(dll_name.to_sym) end end end def test_get_dll railgun = Railgun.new(make_mock_client()) STOCK_DLLS.each do |dll_name| dll = railgun.get_dll(dll_name) # We want to ensure autoloading is working assert(dll.instance_of?(DLL), "get_dll should be able to return a value for dll #{dll_name}") assert(dll.frozen?, "Stock DLLs loaded lazily in get_dll should be frozen") # adding a function should create a local unfrozen instance railgun.add_function(dll_name, '__lolz', 'VOID', []) unfrozen_dll = railgun.get_dll(dll_name) assert_not_same(dll, unfrozen_dll, "add_function should create a local unfrozen instance that get_dll can then access") assert(!unfrozen_dll.frozen?, "add_function should create a local unfrozen instance that get_dll can then access") railgun2 = Railgun.new(make_mock_client()) assert(!railgun2.get_dll(dll_name).functions.has_key?('__lolz'), "functions added to one instance of railgun should not be accessible to others") assert_not_same(!railgun2.get_dll(dll_name).functions, unfrozen_dll.functions, "function hash should have been duplicated during unfreeze") end end def test_add_function mock_function_descriptions.each do |func| railgun = Railgun.new(make_mock_client(func[:platform])) dll_name = func[:dll_name] function_name = func[:name] railgun.add_dll(dll_name) railgun.add_function(dll_name, function_name, func[:return_type], func[:params]) assert(railgun.get_dll(dll_name).functions.has_key?(function_name), "add_function should add a function to the DLL specified") end end end end end end end end end