137 lines
4.0 KiB
Ruby
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 |