diff --git a/lib/rex/java/serialization/model/class_desc.rb b/lib/rex/java/serialization/model/class_desc.rb index 8fdf9744a8..750e2d408f 100644 --- a/lib/rex/java/serialization/model/class_desc.rb +++ b/lib/rex/java/serialization/model/class_desc.rb @@ -28,7 +28,6 @@ module Rex end self.description = content - stream.add_reference(self) unless stream.nil? self end diff --git a/lib/rex/java/serialization/model/contents.rb b/lib/rex/java/serialization/model/contents.rb index 752d1f01a1..d20a512bdc 100644 --- a/lib/rex/java/serialization/model/contents.rb +++ b/lib/rex/java/serialization/model/contents.rb @@ -31,8 +31,10 @@ module Rex content = NewArray.decode(io, stream) when TC_STRING content = Utf.decode(io, stream) + stream.add_reference(content) unless stream.nil? when TC_LONGSTRING content = LongUtf.decode(io, stream) + stream.add_reference(content) unless stream.nil? when TC_ENUM content = NewEnum.decode(io, stream) when TC_CLASSDESC diff --git a/lib/rex/java/serialization/model/long_utf.rb b/lib/rex/java/serialization/model/long_utf.rb index 591c60e216..fa1296c9dc 100644 --- a/lib/rex/java/serialization/model/long_utf.rb +++ b/lib/rex/java/serialization/model/long_utf.rb @@ -11,7 +11,6 @@ module Rex # @return [self] if deserialization succeeds # @return [nil] if deserialization doesn't succeed def decode(io) - stream.add_reference(self) unless stream.nil? raw_length = io.read(8) if raw_length.nil? || raw_length.length != 8 raise ::RuntimeError, 'Failed to unserialize LongUtf' diff --git a/lib/rex/java/serialization/model/new_class_desc.rb b/lib/rex/java/serialization/model/new_class_desc.rb index c5dd7316ec..e0cdb15a0a 100644 --- a/lib/rex/java/serialization/model/new_class_desc.rb +++ b/lib/rex/java/serialization/model/new_class_desc.rb @@ -44,6 +44,7 @@ module Rex def decode(io) self.class_name = Utf.decode(io, stream) self.serial_version = decode_serial_version(io) + stream.add_reference(self) unless stream.nil? self.flags = decode_flags(io) fields_length = decode_fields_length(io) fields_length.times do diff --git a/lib/rex/java/serialization/model/new_object.rb b/lib/rex/java/serialization/model/new_object.rb index bb66f3bd3e..a8615ea7a2 100644 --- a/lib/rex/java/serialization/model/new_object.rb +++ b/lib/rex/java/serialization/model/new_object.rb @@ -28,8 +28,12 @@ module Rex def decode(io) self.class_desc = ClassDesc.decode(io, stream) stream.add_reference(self) unless stream.nil? + if class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc - self.class_data = decode_class_data(io, class_desc) + self.class_data = decode_class_data(io, class_desc.description) + elsif class_desc.description.class == Rex::Java::Serialization::Model::Reference + ref = class_desc.description.handler - BASE_WIRE_HANDLE + self.class_data = decode_class_data(io, stream.references[ref]) end self @@ -59,14 +63,14 @@ module Rex # Deserializes the class_data for a class_desc and its super classes # # @param io [IO] the io to read from - # @param my_class_desc [Rex::Java::Serialization::Model::ClassDesc] the class_desc whose data is being extracted + # @param my_class_desc [Rex::Java::Serialization::Model::NewClassDesc] the class description whose data is being extracted # @return [Array] class_data values if deserialization succeeds # @raise [RuntimeError] if deserialization doesn't succeed def decode_class_data(io, my_class_desc) values = [] - unless my_class_desc.description.super_class.description.class == Rex::Java::Serialization::Model::NullReference - values += decode_class_data(io, my_class_desc.description.super_class) + unless my_class_desc.super_class.description.class == Rex::Java::Serialization::Model::NullReference + values += decode_class_data(io, my_class_desc.super_class.description) end values += decode_class_fields(io, my_class_desc) @@ -77,13 +81,13 @@ module Rex # Deserializes the fields data for a class_desc # # @param io [IO] the io to read from - # @param my_class_desc [Rex::Java::Serialization::Model::ClassDesc] the class_desc whose data is being extracted + # @param my_class_desc [Rex::Java::Serialization::Model::NewClassDesc] the class description whose data is being extracted # @return [Array] class_data values if deserialization succeeds # @raise [RuntimeError] if deserialization doesn't succeed def decode_class_fields(io, my_class_desc) values = [] - my_class_desc.description.fields.each do |field| + my_class_desc.fields.each do |field| if field.is_primitive? values << decode_value(io, field.type) else diff --git a/lib/rex/java/serialization/model/reference.rb b/lib/rex/java/serialization/model/reference.rb index 42bc3f13d5..a6e189fc80 100644 --- a/lib/rex/java/serialization/model/reference.rb +++ b/lib/rex/java/serialization/model/reference.rb @@ -17,7 +17,9 @@ module Rex raise ::RuntimeError, 'Failed to unserialize Reference' end - handler_raw.unpack('N')[0] + self.handler = handler_raw.unpack('N')[0] + + self end end end diff --git a/lib/rex/java/serialization/model/utf.rb b/lib/rex/java/serialization/model/utf.rb index 11170bf762..2d428211fe 100644 --- a/lib/rex/java/serialization/model/utf.rb +++ b/lib/rex/java/serialization/model/utf.rb @@ -25,7 +25,6 @@ module Rex # @return [self] if deserialization succeeds # @raise [RuntimeError] if deserialization doesn't succeed def decode(io) - stream.add_reference(self) unless stream.nil? raw_length = io.read(2) if raw_length.nil? || raw_length.length != 2 raise ::RuntimeError, 'Failed to unserialize Utf'