metasploit-framework/lib/rex/proto/rmi/model/call_data.rb

137 lines
4.0 KiB
Ruby

# -*- coding: binary -*-
module Rex
module Proto
module Rmi
module Model
# This class provides a representation of an RMI return value
class CallData < Element
# @!attribute object_number
# @return [Fixnum] Random to identify the object being called
attr_accessor :object_number
# @!attribute uid
# @return [Rex::Proto::Rmi::Model::UniqueIdentifier] unique identifier for the target to call
attr_accessor :uid
# @!attribute operation
# @return [Fixnum] On JDK 1.1 stub protocol the operation index in the interface. On JDK 1.2
# it is -1.
attr_accessor :operation
# @!attribute hash
# @return [Fixnum] On JDK 1.1 stub protocol the stub's interface hash. On JDK1.2 is a hash
# representing the method to call.
attr_accessor :hash
# @!attribute arguments
# @return [Array] the returned exception or value according to code
attr_accessor :arguments
# Encodes the Rex::Proto::Rmi::Model::CallData into an String.
#
# @return [String]
def encode
stream = Rex::Java::Serialization::Model::Stream.new
block_data = Rex::Java::Serialization::Model::BlockData.new(nil, encode_object_number + encode_uid + encode_operation + encode_hash)
stream.contents << block_data
stream.contents += arguments
stream.encode
end
# Decodes the Rex::Proto::Rmi::Model::CallData from the input.
#
# @param io [IO] the IO to read from
# @return [Rex::Proto::Rmi::Model::CallData]
def decode(io)
stream = Rex::Java::Serialization::Model::Stream.decode(io)
block_data = stream.contents[0]
block_data_io = StringIO.new(block_data.contents, 'rb')
self.object_number = decode_object_number(block_data_io)
self.uid = decode_uid(block_data_io)
self.operation = decode_operation(block_data_io)
self.hash = decode_hash(block_data_io)
self.arguments = []
stream.contents[1..stream.contents.length - 1].each do |content|
self.arguments << content
end
self
end
private
# Reads the object number from the IO
#
# @param io [IO] the IO to read from
# @return [Fixnum]
def decode_object_number(io)
object_number = read_long(io)
object_number
end
# Reads and deserializes the uid from the IO
#
# @param io [IO] the IO to read from
# @return [Rex::Proto::Rmi::Model::UniqueIdentifier]
def decode_uid(io)
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.decode(io)
uid
end
# Reads the operation from the IO
#
# @param io [IO] the IO to read from
# @return [Fixnum]
def decode_operation(io)
operation = read_int(io)
operation
end
# Reads the hash from the IO
#
# @param io [IO] the IO to read from
# @return [Fixnum]
def decode_hash(io)
hash = read_long(io)
hash
end
# Encodes the code field
#
# @return [String]
def encode_object_number
[object_number].pack('q>')
end
# Encodes the uid field
#
# @return [String]
def encode_uid
uid.encode
end
# Encodes the operation field
#
# @return [String]
def encode_operation
[operation].pack('l>')
end
# Encodes the hash field
#
# @return [String]
def encode_hash
[hash].pack('q>')
end
end
end
end
end
end