Files
metasploit-gs/lib/rex/java/serialization/model/new_class_desc.rb
T

155 lines
5.6 KiB
Ruby
Raw Normal View History

2014-12-10 09:52:23 -06:00
# -*- coding: binary -*-
module Rex
module Java
module Serialization
module Model
# This class provides a newClassDesc representation
class NewClassDesc < Element
include Rex::Java::Serialization
# @!attribute class_name
2014-12-09 19:37:42 -06:00
# @return [Rex::Java::Serialization::Model::Utf] The name of the class
attr_accessor :class_name
# @!attribute serial_version
# @return [Fixnum] The java class serial version
attr_accessor :serial_version
# @!attribute flags
# @return [Fixnum] The java class flags
attr_accessor :flags
# @!attribute fields
# @return [Array] The java class fields
attr_accessor :fields
# @!attribute class_annotation
2014-12-09 19:37:42 -06:00
# @return [Rex::Java::Serialization::Model::Annotation] The java class annotations
attr_accessor :class_annotation
# @!attribute super_class
2014-12-09 19:37:42 -06:00
# @return [Rex::Java::Serialization::Model::ClassDesc] The java class superclass description
attr_accessor :super_class
2014-12-05 20:11:45 -06:00
# @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
2014-12-05 16:52:59 -06:00
def initialize(stream = nil)
super(stream)
self.class_name = nil
self.serial_version = 0
self.flags = 0
self.fields = []
self.class_annotation = nil
self.super_class = nil
end
# Deserializes a Rex::Java::Serialization::Model::NewClassDesc
#
# @param io [IO] the io to read from
# @return [self] if deserialization succeeds
2015-04-05 18:43:03 -05:00
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
def decode(io)
2014-12-05 17:14:37 -06:00
self.class_name = Utf.decode(io, stream)
self.serial_version = decode_serial_version(io)
2014-12-05 19:12:05 -06:00
stream.add_reference(self) unless stream.nil?
self.flags = decode_flags(io)
fields_length = decode_fields_length(io)
fields_length.times do
2014-12-05 17:14:37 -06:00
field = Field.decode(io, stream)
self.fields << field
end
2014-12-05 17:14:37 -06:00
self.class_annotation = Annotation.decode(io, stream)
self.super_class = ClassDesc.decode(io, stream)
self
end
2014-12-09 19:37:42 -06:00
# Serializes the Rex::Java::Serialization::Model::ClassDescription
#
# @return [String] if serialization succeeds
2015-04-05 18:43:03 -05:00
# @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
def encode
2015-01-07 12:05:44 -06:00
unless class_name.class == Rex::Java::Serialization::Model::Utf ||
class_annotation.class == Rex::Java::Serialization::Model::Annotation ||
2014-12-09 19:37:42 -06:00
super_class.class == Rex::Java::Serialization::Model::ClassDesc
2015-04-05 18:43:03 -05:00
raise Rex::Java::Serialization::EncodeError, 'Filed to serialize NewClassDesc'
2014-12-03 15:06:28 -06:00
end
encoded = ''
encoded << class_name.encode
2015-04-05 16:23:39 -05:00
encoded << [serial_version].pack('q>')
encoded << [flags].pack('C')
encoded << [fields.length].pack('n')
fields.each do |field|
encoded << field.encode
end
encoded << class_annotation.encode
encoded << super_class.encode
encoded
end
2014-12-07 17:52:09 -06:00
# Creates a print-friendly string representation
#
# @return [String]
def to_s
str = "#{class_name}, [ "
fields_str = []
fields.each do |field|
fields_str << field.to_s
end
str << "#{fields_str.join(', ')} ]"
case super_class.description
when NewClassDesc
str << ", @super_class: #{super_class.description.class_name.to_s}"
when Reference
str << ", @super_class: #{super_class.description.to_s}"
end
str
end
private
2014-12-03 14:59:38 -06:00
# Deserializes a class serial version
#
# @param io [IO] the io to read from
2014-12-03 14:59:38 -06:00
# @return [Integer] if deserialization succeeds
2015-04-05 18:43:03 -05:00
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
def decode_serial_version(io)
raw_serial = io.read(8)
if raw_serial.nil? || raw_serial.length != 8
2015-04-05 18:43:03 -05:00
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription'
end
raw_serial.unpack('Q>')[0]
end
2014-12-03 14:59:38 -06:00
# Deserializes a class flags
#
# @param io [IO] the io to read from
# @return [Integer] if deserialization is possible
2015-04-05 18:43:03 -05:00
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
def decode_flags(io)
raw_flags = io.read(1)
2015-04-05 18:43:03 -05:00
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription' if raw_flags.nil?
raw_flags.unpack('C')[0]
end
2014-12-03 14:59:38 -06:00
# Deserializes a class fields length
#
# @param io [IO] the io to read from
# @return [Integer] if deserialization is possible
2015-04-05 18:43:03 -05:00
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
def decode_fields_length(io)
fields_length = io.read(2)
if fields_length.nil? || fields_length.length != 2
2015-04-05 18:43:03 -05:00
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription'
end
fields_length.unpack('n')[0]
end
end
end
end
end
end