class Rex::Java::Serialization::Model::NewArray

This class provides a NewArray (Java Array) representation

Attributes

array_description[RW]

@!attribute array_description

@return [Java::Serialization::Model::ClassDesc] The description of the array
type[RW]

@!attribute type

@return [String] The type of the array values
values[RW]

@!attribute values

@return [Array] The contents of the java array

Public Class Methods

new(stream = nil) click to toggle source

@param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to

# File lib/rex/java/serialization/model/new_array.rb, line 22
def initialize(stream = nil)
  super(stream)
  self.array_description = nil
  self.type = ''
  self.values = []
end

Public Instance Methods

decode(io) click to toggle source

Deserializes a Rex::Java::Serialization::Model::NewArray

@param io [IO] the io to read from @return [self] if deserialization succeeds @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed

# File lib/rex/java/serialization/model/new_array.rb, line 34
def decode(io)
  self.array_description = ClassDesc.decode(io, stream)
  stream.add_reference(self) unless stream.nil?
  self.type = array_type

  values_length = decode_values_length(io)

  values_length.times do
    value = decode_value(io)
    self.values << value
  end

  self
end
encode() click to toggle source

Serializes the Rex::Java::Serialization::Model::NewArray

@return [String] if serialization succeeds @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed

# File lib/rex/java/serialization/model/new_array.rb, line 53
def encode
  unless array_description.kind_of?(ClassDesc)
    raise Rex::Java::Serialization::EncodeError, 'Failed to serialize NewArray'
  end

  encoded = ''
  encoded << array_description.encode

  encoded << [values.length].pack('N')

  values.each do |value|
    encoded << encode_value(value)
  end

  encoded
end
to_s() click to toggle source

Creates a print-friendly string representation

@return [String]

# File lib/rex/java/serialization/model/new_array.rb, line 73
def to_s
  str = "#{type}, "
  values_data = values.collect {|v| "#{v}"}
  str << "#{values_data}"
end

Private Instance Methods

array_type() click to toggle source

Extracts the NewArray data type

@return [String] @raise [Rex::Java::Serialization::DecodeError] if the NewArray description isn't valid

or type isn't supported
# File lib/rex/java/serialization/model/new_array.rb, line 100
def array_type
  if array_description.nil?
    raise Rex::Java::Serialization::DecodeError, 'Empty NewArray description'
  end

  unless array_description.kind_of?(ClassDesc)
    raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray description class'
  end

  desc = array_description.description

  if desc.class == Reference
    ref = desc.handle - BASE_WIRE_HANDLE
    desc = stream.references[ref]
  end

  unless desc.class_name.contents[0] == '[' # Array
    raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray description'
  end

  decoded_type = desc.class_name.contents[1]
  if PRIMITIVE_TYPE_CODES.keys.include?(decoded_type)
    return PRIMITIVE_TYPE_CODES[decoded_type]
  elsif decoded_type == 'L' # L : Object
    return desc.class_name.contents[2..desc.class_name.contents.index(';')] # Object class
  else
    raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray Type'
  end
end
decode_value(io) click to toggle source

Deserializes a NewArray value

@param io [IO] the io to read from @return [Fixnum, Float] if deserialization succeeds @raise [Rex::Java::Serialization::DecodeError] if deserialization fails

# File lib/rex/java/serialization/model/new_array.rb, line 135
def decode_value(io)
  value = nil

  case type
  when 'byte'
    value = io.read(1)
    raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value.nil?
    value = value.unpack('c')[0]
  when 'char'
    value = io.read(2)
    unless value && value.length == 2
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('s>')[0]
  when 'double'
    value = io.read(8)
    unless value && value.length == 8
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('G')[0]
  when 'float'
    value = io.read(4)
    unless value && value.length == 4
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('g')[0]
  when 'int'
    value = io.read(4)
    unless value && value.length == 4
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('l>')[0]
  when 'long'
    value = io.read(8)
    unless value && value.length == 8
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('q>')[0]
  when 'short'
    value = io.read(2)
    unless value && value.length == 2
      raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
    end
    value = value.unpack('s>')[0]
  when 'boolean'
    value = io.read(1)
    raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value.nil?
    value = value.unpack('c')[0]
  else # object
    value = decode_content(io, stream)
  end

  value
end
decode_values_length(io) click to toggle source

Deserializes the NewArray length

@param io [IO] the io to read from @return [Integer] if deserialization succeeds @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed

# File lib/rex/java/serialization/model/new_array.rb, line 86
def decode_values_length(io)
  values_length = io.read(4)
  if values_length.nil? || values_length.length != 4
    raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize NewArray'
  end

  values_length.unpack('N')[0]
end
encode_value(value) click to toggle source

Serializes an NewArray value

@param value [<Fixnum, Float>] the value to serialize @return [String] the serialized value @raise [Rex::Java::Serialization::EncodeError] if serialization fails

# File lib/rex/java/serialization/model/new_array.rb, line 195
def encode_value(value)
  res = ''

  case type
  when 'byte'
    res = [value].pack('c')
  when 'char'
    res = [value].pack('s>')
  when 'double'
    res = [value].pack('G')
  when 'float'
    res = [value].pack('g')
  when 'int'
    res = [value].pack('l>')
  when 'long'
    res = [value].pack('q>')
  when 'short'
    res = [value].pack('s>')
  when 'boolean'
    res = [value].pack('c')
  when Element
    res = value.encode
  else # object
    res = encode_content(value)
  end

  res
end