diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb index ec58444edb04..f65b664445d8 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/library.rb @@ -228,7 +228,7 @@ def build_packet_and_layouts(packet, function, args, arch) # it's not a pointer (LPVOID is a pointer but is not backed by railgun memory, ala PBLOB) buffer = [0].pack(native) case param_desc[0] - when 'LPVOID', 'PULONG_PTR', 'ULONG_PTR' + when 'LPVOID', 'ULONG_PTR' num = param_to_number(args[param_idx]) buffer += [num].pack(native) when 'DWORD' @@ -273,8 +273,8 @@ def build_packet_and_layouts(packet, function, args, arch) [packet, layouts] end - def build_response(packet, function, layouts, arch) - case arch + def build_response(packet, function, layouts, client) + case client.native_arch when ARCH_X64 native = 'Q<' when ARCH_X86 @@ -301,7 +301,7 @@ def build_response(packet, function, layouts, arch) # process return value case function.return_type when 'LPVOID', 'ULONG_PTR' - if arch == ARCH_X64 + if client.native_arch == ARCH_X64 return_hash['return'] = rec_return_value else return_hash['return'] = rec_return_value & 0xffffffff @@ -317,9 +317,19 @@ def build_response(packet, function, layouts, arch) when 'VOID' return_hash['return'] = nil when 'PCHAR' - return_hash['return'] = rec_return_value == 0 ? nil : read_string(rec_return_value) + return_hash['return'] = rec_return_value == 0 ? nil : client.railgun.util.read_string(rec_return_value) + return_hash['&return'] = rec_return_value when 'PWCHAR' - return_hash['return'] = rec_return_value == 0 ? nil : read_wstring(rec_return_value) + return_hash['return'] = rec_return_value == 0 ? nil : client.railgun.util.read_wstring(rec_return_value) + return_hash['&return'] = rec_return_value + when 'PULONG_PTR' + if client.native_arch == ARCH_X64 + return_hash['return'] = rec_return_value == 0 ? nil : client.railgun.util.memread(rec_return_value, 8)&.unpack1('Q<') + return_hash['&return'] = rec_return_value + else + return_hash['return'] = rec_return_value == 0 ? nil : client.railgun.util.memread(rec_return_value, 4)&.unpack1('V') + return_hash['&return'] = rec_return_value + end else raise "unexpected return type: #{function.return_type}" end @@ -379,7 +389,7 @@ def process_function_call(function, args, client) response = client.send_request(request) - build_response(response, function, layouts, client.native_arch) + build_response(response, function, layouts, client) end # perform type conversions as necessary to reduce the datatypes to their primitives diff --git a/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb b/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb index 661154678d6f..d3d8d4e98dc6 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb @@ -90,7 +90,7 @@ def call(functions) lib_name, function, args = f library = @parent.get_library(lib_name) function = library.functions[function] unless function.instance_of? LibraryFunction - function_results << library.build_response(call_results.shift, function, call_layouts.shift, @client.native_arch) + function_results << library.build_response(call_results.shift, function, call_layouts.shift, @client) end function_results