Refactor contents serialization

bug/bundler_fix
jvazquez-r7 2014-12-04 18:28:25 -06:00
parent 8c11e6047b
commit 4b8bdad44b
11 changed files with 147 additions and 124 deletions

View File

@ -1,15 +1,17 @@
require 'rex/java/serialization/model/element'
require 'rex/java/serialization/model/end_block_data'
require 'rex/java/serialization/model/null_reference'
require 'rex/java/serialization/model/reset'
require 'rex/java/serialization/model/utf'
require 'rex/java/serialization/model/long_utf'
require 'rex/java/serialization/model/block_data'
require 'rex/java/serialization/model/block_data_long'
require 'rex/java/serialization/model/end_block_data'
require 'rex/java/serialization/model/field'
require 'rex/java/serialization/model/new_array'
require 'rex/java/serialization/model/new_enum'
require 'rex/java/serialization/model/contents'
require 'rex/java/serialization/model/annotation'
require 'rex/java/serialization/model/class_desc'
require 'rex/java/serialization/model/new_class_desc'
require 'rex/java/serialization/model/new_array'
require 'rex/java/serialization/model/new_enum'
require 'rex/java/serialization/model/new_object'
require 'rex/java/serialization/model/stream'

View File

@ -7,6 +7,7 @@ module Rex
class Annotation < Element
include Rex::Java::Serialization
include Rex::Java::Serialization::Model::Contents
# @!attribute contents
# @return [Array] The annotation contents
@ -23,25 +24,9 @@ module Rex
# @raise [RuntimeError] if deserialization doesn't succeed
def decode(io)
loop do
opcode = io.read(1)
if opcode.nil?
raise ::RuntimeError, 'Failed to unserialize Annotation'
end
opcode = opcode.unpack('C')[0]
case opcode
when TC_BLOCKDATA
block = BlockData.decode(io)
self.contents << block
when TC_BLOCKDATALONG
block = BlockDataLong.decode(io)
self.contents << block
when TC_ENDBLOCKDATA
return self
else
#TODO: unsupported
raise ::RuntimeError, 'Unsupported content opcode'
end
content = decode_content(io)
self.contents << content
return self if content.class == Rex::Java::Serialization::Model::EndBlockData
end
self
@ -52,23 +37,14 @@ module Rex
# @return [String] if serialization suceeds
# @raise [RuntimeError] if serialization doesn't succeed
def encode
raise ::RuntimeError, 'Failed to serialize Annotation with empty contents' if contents.empty?
encoded = ''
contents.each do |content|
case content
when Rex::Java::Serialization::Model::BlockData
encoded << [TC_BLOCKDATA].pack('C')
when Rex::Java::Serialization::Model::BlockDataLong
encoded << [TC_BLOCKDATALONG].pack('C')
else
raise ::RuntimeError, 'Unsupported content'
end
encoded_content = content.encode
encoded << encoded_content
encoded << encode_content(content)
end
encoded << [TC_ENDBLOCKDATA].pack('C')
encoded
end

View File

@ -0,0 +1,101 @@
module Rex
module Java
module Serialization
module Model
module Contents
include Rex::Java::Serialization
# Deserializes a content
#
# @param io [IO] the io to read from
# @return [Rex::Java::Serialization::Model::Element] if deserialization succeeds
# @raise [RuntimeError] if deserialization doesn't succeed or unsupported content
def decode_content(io)
opcode = io.read(1)
raise ::RuntimeError, 'Failed to unserialize content' if opcode.nil?
opcode = opcode.unpack('C')[0]
content = nil
case opcode
when TC_BLOCKDATA
content = BlockData.decode(io)
when TC_BLOCKDATALONG
content = BlockDataLong.decode(io)
when TC_ENDBLOCKDATA
content = EndBlockData.decode(io)
when TC_OBJECT
content = NewObject.decode(io)
when TC_CLASS
content = ClassDesc.decode(io)
when TC_ARRAY
content = NewArray.decode(io)
when TC_STRING
content = Utf.decode(io)
when TC_LONGSTRING
content = LongUtf.decode(io)
when TC_ENUM
content = NewEnum.decode(io)
when TC_CLASSDESC
content = NewClassDesc.decode(io)
when TC_PROXYCLASSDESC
raise ::RuntimeError, 'Failed to unserialize unsupported TC_PROXYCLASSDESC content'
when TC_REFERENCE
raise ::RuntimeError, 'Failed to unserialize unsupported TC_REFERENCE content'
when TC_NULL
content = NullReference.decode(io)
when TC_EXCEPTION
raise ::RuntimeError, 'Failed to unserialize unsupported TC_EXCEPTION content'
when TC_RESET
content = Reset.decode(io)
else
raise ::RuntimeError, 'Failed to unserialize content'
end
content
end
# Serializes a content
#
# @param content [Rex::Java::Serialization::Model::Element] the content to serialize
# @return [String] if serialization succeeds
# @raise [RuntimeError] if serialization doesn't succeed
def encode_content(content)
encoded = ''
case content
when Rex::Java::Serialization::Model::BlockData
encoded << [TC_BLOCKDATA].pack('C')
when Rex::Java::Serialization::Model::BlockDataLong
encoded << [TC_BLOCKDATALONG].pack('C')
when Rex::Java::Serialization::Model::EndBlockData
encoded << [TC_ENDBLOCKDATA].pack('C')
when Rex::Java::Serialization::Model::NewObject
encoded << [TC_OBJECT].pack('C')
when Rex::Java::Serialization::Model::ClassDesc
encoded << [TC_CLASS].pack('C')
when Rex::Java::Serialization::Model::NewArray
encoded << [TC_ARRAY].pack('C')
when Rex::Java::Serialization::Model::Utf
encoded << [TC_STRING].pack('C')
when Rex::Java::Serialization::Model::LongUtf
encoded << [TC_LONGSTRING].pack('C')
when Rex::Java::Serialization::Model::NewEnum
encoded << [TC_ENUM].pack('C')
when Rex::Java::Serialization::Model::NewClassDesc
encoded << [TC_CLASSDESC].pack('C')
when Rex::Java::Serialization::Model::NullReference
encoded << [TC_NULL].pack('C')
when Rex::Java::Serialization::Model::Reset
encoded << [TC_RESET].pack('C')
else
raise ::RuntimeError, 'Failed to serialize content'
end
encoded << content.encode
encoded
end
end
end
end
end
end

View File

@ -6,6 +6,7 @@ module Rex
class Stream < Element
include Rex::Java::Serialization
include Rex::Java::Serialization::Model::Contents
# @!attribute magic
# @return [Fixnum] The stream signature
@ -81,92 +82,6 @@ module Rex
STREAM_VERSION
end
# Deserializes a content
#
# @param io [IO] the io to read from
# @return [Rex::Java::Serialization::Model::Element] if deserialization succeeds
# @raise [RuntimeError] if deserialization doesn't succeed or unsupported content
def decode_content(io)
opcode = io.read(1)
raise ::RuntimeError, 'Failed to unserialize content' if opcode.nil?
opcode = opcode.unpack('C')[0]
content = nil
case opcode
when TC_BLOCKDATA
content = BlockData.decode(io)
when TC_BLOCKDATALONG
content = BlockDataLong.decode(io)
when TC_OBJECT
content = NewObject.decode(io)
when TC_CLASS
content = ClassDesc.decode(io)
when TC_ARRAY
content = NewArray.decode(io)
when TC_STRING
content = Utf.decode(io)
when TC_LONGSTRING
content = LongUtf.decode(io)
when TC_ENUM
content = NewEnum.decode(io)
when TC_CLASSDESC
content = NewClassDesc.decode(io)
when TC_PROXYCLASSDESC
raise ::RuntimeError, 'Failed to unserialize unsupported TC_PROXYCLASSDESC content'
when TC_REFERENCE
raise ::RuntimeError, 'Failed to unserialize unsupported TC_REFERENCE content'
when TC_NULL
content = NullReference.decode(io)
when TC_EXCEPTION
raise ::RuntimeError, 'Failed to unserialize unsupported TC_EXCEPTION content'
when TC_RESET
content = Reset.decode(io)
else
raise ::RuntimeError, 'Failed to unserialize content'
end
content
end
# Serializes a content
#
# @param content [Rex::Java::Serialization::Model::Element] the content to serialize
# @return [String] if serialization succeeds
# @raise [RuntimeError] if serialization doesn't succeed
def encode_content(content)
encoded = ''
case content
when Rex::Java::Serialization::Model::BlockData
encoded << [TC_BLOCKDATA].pack('C')
when Rex::Java::Serialization::Model::BlockDataLong
encoded << [TC_BLOCKDATALONG].pack('C')
when Rex::Java::Serialization::Model::NewObject
encoded << [TC_OBJECT].pack('C')
when Rex::Java::Serialization::Model::ClassDesc
encoded << [TC_CLASS].pack('C')
when Rex::Java::Serialization::Model::NewArray
encoded << [TC_ARRAY].pack('C')
when Rex::Java::Serialization::Model::Utf
encoded << [TC_STRING].pack('C')
when Rex::Java::Serialization::Model::LongUtf
encoded << [TC_LONGSTRING].pack('C')
when Rex::Java::Serialization::Model::NewEnum
encoded << [TC_ENUM].pack('C')
when Rex::Java::Serialization::Model::NewClassDesc
encoded << [TC_CLASSDESC].pack('C')
when Rex::Java::Serialization::Model::NullReference
encoded << [TC_NULL].pack('C')
when Rex::Java::Serialization::Model::Reset
encoded << [TC_RESET].pack('C')
else
raise ::RuntimeError, 'Failed to serialize content'
end
encoded << content.encode
encoded
end
end
end
end

View File

@ -25,6 +25,7 @@ describe Rex::Java::Serialization::Model::Annotation do
context "when empty contents" do
it do
annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
expect(annotation.encode).to eq(empty_contents)
end
end
@ -33,6 +34,7 @@ describe Rex::Java::Serialization::Model::Annotation do
it do
annotation.contents << Rex::Java::Serialization::Model::BlockData.new("\x01\x02\x03\x04\x05")
annotation.contents << Rex::Java::Serialization::Model::BlockDataLong.new("\x01\x02\x03\x04\x05")
annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
expect(annotation.encode).to eq(contents)
end
end
@ -46,9 +48,14 @@ describe Rex::Java::Serialization::Model::Annotation do
expect(annotation.decode(empty_contents_io)).to be_a(Rex::Java::Serialization::Model::Annotation)
end
it "keeps contents" do
it "unserializes one content" do
annotation.decode(empty_contents_io)
expect(annotation.contents).to be_empty
expect(annotation.contents.length).to eq(1)
end
it "unserializes one EndBlockData content" do
annotation.decode(empty_contents_io)
expect(annotation.contents[0]).to be_a(Rex::Java::Serialization::Model::EndBlockData)
end
end
@ -59,7 +66,7 @@ describe Rex::Java::Serialization::Model::Annotation do
it "deserializes contents" do
annotation.decode(contents_io)
expect(annotation.contents.length).to eq(2)
expect(annotation.contents.length).to eq(3)
end
it "deserializes block data contents" do
@ -71,6 +78,11 @@ describe Rex::Java::Serialization::Model::Annotation do
annotation.decode(contents_io)
expect(annotation.contents[1]).to be_a_kind_of(Rex::Java::Serialization::Model::BlockDataLong)
end
it "deserializes end block data" do
annotation.decode(contents_io)
expect(annotation.contents[2]).to be_a_kind_of(Rex::Java::Serialization::Model::EndBlockData)
end
end
end

View File

@ -44,6 +44,7 @@ describe Rex::Java::Serialization::Model::ClassDesc do
super_class_desc_new.serial_version = 0x86ac951d0b94e08b
super_class_desc_new.flags = 2
super_class_desc_new.class_annotation = Rex::Java::Serialization::Model::Annotation.new
super_class_desc_new.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
super_class_desc_new.super_class = Rex::Java::Serialization::Model::ClassDesc.new
super_class_desc_new.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -59,6 +60,7 @@ describe Rex::Java::Serialization::Model::ClassDesc do
field.name = Rex::Java::Serialization::Model::Utf.new('value')
class_desc_new.fields << field
class_desc_new.class_annotation = Rex::Java::Serialization::Model::Annotation.new
class_desc_new.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
class_desc_new.super_class = super_class_desc
class_desc.description = class_desc_new

View File

@ -244,6 +244,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0x578f203914b85de2
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -261,6 +262,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0xacf317f8060854e0
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -278,6 +280,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0xb02666b0e25d84ac
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -295,6 +298,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0xef832e06e55db0fa
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -312,6 +316,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0x3ea68c14ab635a1e
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -329,6 +334,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0xb9c818922e00c42
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -346,6 +352,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0x4dba602676eab2a5
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -363,6 +370,7 @@ describe Rex::Java::Serialization::Model::NewArray do
new_class_desc.serial_version = 0x782004b512b17593
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new

View File

@ -88,7 +88,7 @@ describe Rex::Java::Serialization::Model::NewClassDesc do
it "deserializes class annotation contents" do
class_desc_new.decode(sample_io)
expect(class_desc_new.class_annotation.contents).to be_empty
expect(class_desc_new.class_annotation.contents[0]).to be_a(Rex::Java::Serialization::Model::EndBlockData)
end
it "deserializes super_class" do
@ -109,6 +109,7 @@ describe Rex::Java::Serialization::Model::NewClassDesc do
super_class_desc_new.serial_version = 0x86ac951d0b94e08b
super_class_desc_new.flags = 2
super_class_desc_new.class_annotation = Rex::Java::Serialization::Model::Annotation.new
super_class_desc_new.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
super_class_desc_new.super_class = Rex::Java::Serialization::Model::ClassDesc.new
super_class_desc_new.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -123,6 +124,7 @@ describe Rex::Java::Serialization::Model::NewClassDesc do
field.name = Rex::Java::Serialization::Model::Utf.new('value')
class_desc_new.fields << field
class_desc_new.class_annotation = Rex::Java::Serialization::Model::Annotation.new
class_desc_new.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
class_desc_new.super_class = super_class_desc
expect(class_desc_new.encode.unpack("C*")).to eq(sample.unpack("C*"))

View File

@ -52,12 +52,14 @@ describe Rex::Java::Serialization::Model::NewEnum do
new_class_desc.serial_version = 0
new_class_desc.flags = 18
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NewClassDesc.new
new_class_desc.super_class.description.class_name = Rex::Java::Serialization::Model::Utf.new('java.lang.Enum')
new_class_desc.super_class.description.serial_version = 0
new_class_desc.super_class.description.flags = 18
new_class_desc.super_class.description.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.super_class.description.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class.description.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description.super_class.description = Rex::Java::Serialization::Model::NullReference.new

View File

@ -58,6 +58,7 @@ describe Rex::Java::Serialization::Model::NewObject do
field.name = Rex::Java::Serialization::Model::Utf.new('SSN')
new_class_desc.fields << field
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new

View File

@ -84,6 +84,7 @@ describe Rex::Java::Serialization::Model::Stream do
field.name = Rex::Java::Serialization::Model::Utf.new('SSN')
new_class_desc.fields << field
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
@ -104,6 +105,7 @@ describe Rex::Java::Serialization::Model::Stream do
new_class_desc.serial_version = 0xb02666b0e25d84ac
new_class_desc.flags = 2
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
new_class_desc.class_annotation.contents << Rex::Java::Serialization::Model::EndBlockData.new
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new