Parent

Class/Module Index [+]

Quicksearch

Rex::Post::Meterpreter::Extensions::Stdapi::Railgun::Railgun

The Railgun class to dynamically expose the Windows API.

Constants

BUILTIN_DLLS

Railgun::DLL's that have builtin definitions.

If you want to add additional DLL definitions to be preloaded create a definition class 'rex/post/meterpreter/extensions/stdapi/railgun/def/'. Naming is important and should follow convention. For example, if your dll's name was "my_dll" file name: def_my_dll.rb class name: Def_my_dll entry below: 'my_dll'

Attributes

client[RW]

Contains a reference to the client that corresponds to this instance of railgun

dlls[RW]

Returns a Hash containing DLLs added to this instance with add_dll as well as references to any frozen cached dlls added directly in get_dll and copies of any frozen dlls (added directly with add_function) that the user attempted to modify with add_function.

Keys are friendly DLL names and values are the corresponding DLL instance

Public Class Methods

builtin_dlls() click to toggle source
# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 107
def self.builtin_dlls
        BUILTIN_DLLS
end
new(client) click to toggle source
# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 102
def initialize(client)
        self.client = client
        self.dlls = {}
end

Public Instance Methods

add_dll(dll_name, windows_name=dll_name) click to toggle source

Adds a DLL to this Railgun.

The windows_name is the name used on the remote system and should be set appropriately if you want to include a path or the DLL name contains non-ruby-approved characters.

Raises an exception if a dll with the given name has already been defined.

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 211
def add_dll(dll_name, windows_name=dll_name)

        if dlls.has_key? dll_name
                raise "A DLL of name #{dll_name} has already been loaded."
        end

        dlls[dll_name] = DLL.new(windows_name, constant_manager)
end
add_function(dll_name, function_name, return_type, params, windows_name=nil) click to toggle source

Adds a function to an existing DLL definition.

If the DLL definition is frozen (ideally this should be the case for all cached dlls) an unfrozen copy is created and used henceforth for this instance.

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 181
def add_function(dll_name, function_name, return_type, params, windows_name=nil)

        unless known_dll_names.include?(dll_name)
                raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, "")}"
        end

        dll = get_dll(dll_name)

        # For backwards compatibility, we ensure the dll is thawed
        if dll.frozen?
                # Duplicate not only the dll, but its functions as well. Frozen status will be lost
                dll = Marshal.load(Marshal.dump(dll))

                # Update local dlls with the modifiable duplicate
                dlls[dll_name] = dll
        end

        dll.add_function(function_name, return_type, params, windows_name)
end
const(str) click to toggle source

Return a Windows constant matching str.

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 281
def const(str)
        return constant_manager.parse(str)
end
constant_manager() click to toggle source

Return this Railgun's WinConstManager instance, initially populated with constants defined in ApiConstants.

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 126
def constant_manager
        # Loads lazily
        return ApiConstants.manager
end
get_dll(dll_name) click to toggle source

Attempts to provide a DLL instance of the given name. Handles lazy loading and caching. Note that if a DLL of the given name does not exist, returns nil

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 230
def get_dll(dll_name)

        # If the DLL is not local, we now either load it from cache or load it lazily.
        # In either case, a reference to the dll is stored in the collection "dlls"
        # If the DLL can not be found/created, no actions are taken
        unless dlls.has_key? dll_name
                # We read and write to @@cached_dlls and rely on state consistency
                @@cache_semaphore.synchronize do
                        if @@cached_dlls.has_key? dll_name
                                dlls[dll_name] = @@cached_dlls[dll_name]
                        elsif BUILTIN_DLLS.include? dll_name
                                # I highly doubt this case will ever occur, but I am paranoid
                                if dll_name !~ /^\w+$/
                                        raise "DLL name #{dll_name} is bad. Correct Railgun::BUILTIN_DLLS"
                                end

                                require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_' << dll_name
                                dll = Def.const_get('Def_' << dll_name).create_dll.freeze

                                @@cached_dlls[dll_name] = dll
                                dlls[dll_name] = dll
                        end
                end

        end

        return dlls[dll_name]
end
known_dll_names() click to toggle source
# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 221
def known_dll_names
        return BUILTIN_DLLS | dlls.keys
end
memread(address, length) click to toggle source

Read data from a memory address on the host (useful for working with LPVOID parameters)

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 135
def memread(address, length)

        raise "Invalid parameters." if(not address or not length)

        request = Packet.create_request('stdapi_railgun_memread')

        request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address)
        request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length)

        response = client.send_request(request)
        if(response.result == 0)
                return response.get_tlv_value(TLV_TYPE_RAILGUN_MEM_DATA)
        end

        return nil
end
memwrite(address, data, length) click to toggle source

Write data to a memory address on the host (useful for working with LPVOID parameters)

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 156
def memwrite(address, data, length)

        raise "Invalid parameters." if(not address or not data or not length)

        request = Packet.create_request('stdapi_railgun_memwrite')

        request.add_tlv(TLV_TYPE_RAILGUN_MEM_ADDRESS, address)
        request.add_tlv(TLV_TYPE_RAILGUN_MEM_DATA, data)
        request.add_tlv(TLV_TYPE_RAILGUN_MEM_LENGTH, length)

        response = client.send_request(request)
        if(response.result == 0)
                return true
        end

        return false
end
method_missing(dll_symbol, *args) click to toggle source

Fake having members like user32 and kernel32. reason is that

...user32.MessageBoxW()

is prettier than

...dlls["user32"].functions["MessageBoxW"]()
# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 266
def method_missing(dll_symbol, *args)
        dll_name = dll_symbol.to_s

        unless known_dll_names.include? dll_name
                raise "DLL #{dll_name} not found. Known DLLs: #{PP.pp(known_dll_names, '')}"
        end

        dll = get_dll(dll_name)

        return DLLWrapper.new(dll, client)
end
multi(functions) click to toggle source

The multi-call shorthand (["kernel32", "ExitProcess", [0]])

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 288
def multi(functions)
        if @multicaller.nil?
                @multicaller = MultiCaller.new(client, self)
        end

        return @multicaller.call(functions)
end
util() click to toggle source

Return this Railgun's Util instance.

# File lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb, line 114
def util
        if @util.nil?
                @util = Util.new(self, client.platform)
        end

        return @util
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.