rex-java 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +2 -0
  6. data/.travis.yml +5 -0
  7. data/CODE_OF_CONDUCT.md +52 -0
  8. data/Gemfile +4 -0
  9. data/README.md +36 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/lib/rex/java.rb +10 -0
  14. data/lib/rex/java/serialization.rb +57 -0
  15. data/lib/rex/java/serialization/builder.rb +94 -0
  16. data/lib/rex/java/serialization/decode_error.rb +11 -0
  17. data/lib/rex/java/serialization/encode_error.rb +11 -0
  18. data/lib/rex/java/serialization/model.rb +33 -0
  19. data/lib/rex/java/serialization/model/annotation.rb +69 -0
  20. data/lib/rex/java/serialization/model/block_data.rb +70 -0
  21. data/lib/rex/java/serialization/model/block_data_long.rb +72 -0
  22. data/lib/rex/java/serialization/model/class_desc.rb +64 -0
  23. data/lib/rex/java/serialization/model/contents.rb +163 -0
  24. data/lib/rex/java/serialization/model/element.rb +44 -0
  25. data/lib/rex/java/serialization/model/end_block_data.rb +12 -0
  26. data/lib/rex/java/serialization/model/field.rb +173 -0
  27. data/lib/rex/java/serialization/model/long_utf.rb +48 -0
  28. data/lib/rex/java/serialization/model/new_array.rb +229 -0
  29. data/lib/rex/java/serialization/model/new_class.rb +57 -0
  30. data/lib/rex/java/serialization/model/new_class_desc.rb +154 -0
  31. data/lib/rex/java/serialization/model/new_enum.rb +79 -0
  32. data/lib/rex/java/serialization/model/new_object.rb +235 -0
  33. data/lib/rex/java/serialization/model/null_reference.rb +12 -0
  34. data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
  35. data/lib/rex/java/serialization/model/reference.rb +61 -0
  36. data/lib/rex/java/serialization/model/reset.rb +12 -0
  37. data/lib/rex/java/serialization/model/stream.rb +123 -0
  38. data/lib/rex/java/serialization/model/utf.rb +69 -0
  39. data/lib/rex/java/version.rb +5 -0
  40. data/rex-java.gemspec +24 -0
  41. metadata +199 -0
  42. metadata.gz.sig +1 -0
@@ -0,0 +1,70 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a block data representation
8
+ class BlockData < Element
9
+
10
+ # @!attribute length
11
+ # @return [Integer] the length of the block
12
+ attr_accessor :length
13
+ # @!attribute contents
14
+ # @return [String] the contents of the block
15
+ attr_accessor :contents
16
+
17
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
18
+ # @param contents [String] the contents of the block
19
+ def initialize(stream = nil, contents = '')
20
+ super(stream)
21
+ self.contents = contents
22
+ self.length = contents.length
23
+ end
24
+
25
+ # Deserializes a Rex::Java::Serialization::Model::BlockData
26
+ #
27
+ # @param io [IO] the io to read from
28
+ # @return [self] if deserialization succeeds
29
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
30
+ def decode(io)
31
+ raw_length = io.read(1)
32
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize BlockData' if raw_length.nil?
33
+ self.length = raw_length.unpack('C')[0]
34
+
35
+ if length == 0
36
+ self.contents = ''
37
+ else
38
+ self.contents = io.read(length)
39
+ if contents.nil? || contents.length != length
40
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize BlockData'
41
+ end
42
+ end
43
+
44
+ self
45
+ end
46
+
47
+ # Creates a print-friendly string representation
48
+ #
49
+ # @return [String]
50
+ def to_s
51
+ contents_hex = []
52
+ contents.each_byte {|byte| contents_hex << "0x#{byte.to_s(16)}" }
53
+
54
+ "[ #{contents_hex.join(', ')} ]"
55
+ end
56
+
57
+ # Serializes the Rex::Java::Serialization::Model::BlockData
58
+ #
59
+ # @return [String]
60
+ def encode
61
+ encoded = [length].pack('C')
62
+ encoded << contents
63
+
64
+ encoded
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,72 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a block data (long) representation
8
+ class BlockDataLong < Element
9
+
10
+ # @!attribute length
11
+ # @return [Integer] the length of the block
12
+ attr_accessor :length
13
+ # @!attribute contents
14
+ # @return [String] the contents of the block
15
+ attr_accessor :contents
16
+
17
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
18
+ # @param contents [String] the contents of the block
19
+ def initialize(stream = nil, contents = '')
20
+ super(stream)
21
+ self.contents = contents
22
+ self.length = contents.length
23
+ end
24
+
25
+ # Deserializes a Rex::Java::Serialization::Model::BlockDataLong
26
+ #
27
+ # @param io [IO] the io to read from
28
+ # @return [self] if deserialization succeeds
29
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
30
+ def decode(io)
31
+ raw_length = io.read(4)
32
+ if raw_length.nil? || raw_length.length != 4
33
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize BlockDataLong'
34
+ end
35
+ self.length = raw_length.unpack('N')[0]
36
+
37
+ if length == 0
38
+ self.contents = ''
39
+ else
40
+ self.contents = io.read(length)
41
+ if contents.nil? || contents.length != length
42
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize BlockData'
43
+ end
44
+ end
45
+
46
+ self
47
+ end
48
+
49
+ # Serializes the Rex::Java::Serialization::Model::BlockDataLong
50
+ #
51
+ # @return [String]
52
+ def encode
53
+ encoded = [length].pack('N')
54
+ encoded << contents
55
+
56
+ encoded
57
+ end
58
+
59
+ # Creates a print-friendly string representation
60
+ #
61
+ # @return [String]
62
+ def to_s
63
+ contents_hex = []
64
+ contents.each_byte {|byte| contents_hex << "0x#{byte.to_s(16)}" }
65
+
66
+ "[ #{contents_hex.join(', ')} ]"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,64 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a Java classDesc representation
8
+ class ClassDesc < Element
9
+
10
+ include Rex::Java::Serialization::Model::Contents
11
+
12
+ attr_accessor :description
13
+
14
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
15
+ def initialize(stream = nil)
16
+ super(stream)
17
+ self.description = nil
18
+ end
19
+
20
+ # Deserializes a Rex::Java::Serialization::Model::ClassDesc
21
+ #
22
+ # @param io [IO] the io to read from
23
+ # @return [self] if deserialization succeeds
24
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
25
+ def decode(io)
26
+ content = decode_content(io, stream)
27
+ allowed_contents = [NullReference, NewClassDesc, Reference, ProxyClassDesc]
28
+
29
+ unless allowed_contents.include?(content.class)
30
+ raise Rex::Java::Serialization::DecodeError, 'ClassDesc unserialize failed'
31
+ end
32
+
33
+ self.description = content
34
+ self
35
+ end
36
+
37
+ # Serializes the Rex::Java::Serialization::Model::ClassDesc
38
+ #
39
+ # @return [String] if serialization succeeds
40
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
41
+ def encode
42
+ encoded = ''
43
+ allowed_contents = [NullReference, NewClassDesc, Reference, ProxyClassDesc]
44
+
45
+ unless allowed_contents.include?(description.class)
46
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize ClassDesc'
47
+ end
48
+
49
+ encoded << encode_content(description)
50
+
51
+ encoded
52
+ end
53
+
54
+ # Creates a print-friendly string representation
55
+ #
56
+ # @return [String]
57
+ def to_s
58
+ print_content(description)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,163 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ module Contents
8
+ include Rex::Java::Serialization
9
+
10
+ # Deserializes a content
11
+ #
12
+ # @param io [IO] the io to read from
13
+ # @return [Rex::Java::Serialization::Model::Element] if deserialization succeeds
14
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed or unsupported content
15
+ def decode_content(io, stream)
16
+ opcode = io.read(1)
17
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize content' if opcode.nil?
18
+ opcode = opcode.unpack('C')[0]
19
+ content = nil
20
+
21
+ case opcode
22
+ when TC_BLOCKDATA
23
+ content = BlockData.decode(io, stream)
24
+ when TC_BLOCKDATALONG
25
+ content = BlockDataLong.decode(io, stream)
26
+ when TC_ENDBLOCKDATA
27
+ content = EndBlockData.decode(io, stream)
28
+ when TC_OBJECT
29
+ content = NewObject.decode(io, stream)
30
+ when TC_CLASS
31
+ content = NewClass.decode(io, stream)
32
+ when TC_ARRAY
33
+ content = NewArray.decode(io, stream)
34
+ when TC_STRING
35
+ content = Utf.decode(io, stream)
36
+ stream.add_reference(content) unless stream.nil?
37
+ when TC_LONGSTRING
38
+ content = LongUtf.decode(io, stream)
39
+ stream.add_reference(content) unless stream.nil?
40
+ when TC_ENUM
41
+ content = NewEnum.decode(io, stream)
42
+ when TC_CLASSDESC
43
+ content = NewClassDesc.decode(io, stream)
44
+ when TC_PROXYCLASSDESC
45
+ content = ProxyClassDesc.decode(io, stream)
46
+ when TC_REFERENCE
47
+ content = Reference.decode(io, stream)
48
+ when TC_NULL
49
+ content = NullReference.decode(io, stream)
50
+ when TC_EXCEPTION
51
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize unsupported TC_EXCEPTION content'
52
+ when TC_RESET
53
+ content = Reset.decode(io, stream)
54
+ else
55
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize content'
56
+ end
57
+
58
+ content
59
+ end
60
+
61
+ # Serializes a content
62
+ #
63
+ # @param content [Rex::Java::Serialization::Model::Element] the content to serialize
64
+ # @return [String] if serialization succeeds
65
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
66
+ def encode_content(content)
67
+ encoded = ''
68
+
69
+ case content
70
+ when BlockData
71
+ encoded << [TC_BLOCKDATA].pack('C')
72
+ when BlockDataLong
73
+ encoded << [TC_BLOCKDATALONG].pack('C')
74
+ when EndBlockData
75
+ encoded << [TC_ENDBLOCKDATA].pack('C')
76
+ when NewObject
77
+ encoded << [TC_OBJECT].pack('C')
78
+ when NewClass
79
+ encoded << [TC_CLASS].pack('C')
80
+ when NewArray
81
+ encoded << [TC_ARRAY].pack('C')
82
+ when Utf
83
+ encoded << [TC_STRING].pack('C')
84
+ when LongUtf
85
+ encoded << [TC_LONGSTRING].pack('C')
86
+ when NewEnum
87
+ encoded << [TC_ENUM].pack('C')
88
+ when NewClassDesc
89
+ encoded << [TC_CLASSDESC].pack('C')
90
+ when ProxyClassDesc
91
+ encoded << [TC_PROXYCLASSDESC].pack('C')
92
+ when NullReference
93
+ encoded << [TC_NULL].pack('C')
94
+ when Reset
95
+ encoded << [TC_RESET].pack('C')
96
+ when Reference
97
+ encoded << [TC_REFERENCE].pack('C')
98
+ else
99
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize content'
100
+ end
101
+
102
+ encoded << content.encode
103
+ encoded
104
+ end
105
+
106
+ # Creates a print-friendly string representation
107
+ #
108
+ # @param content [Rex::Java::Serialization::Model::Element] the content to print
109
+ # @return [String]
110
+ # @raise [Rex::Java::Serialization::EncodeError] if the content is unknown
111
+ def print_content(content)
112
+ str = ''
113
+
114
+ case content
115
+ when BlockData
116
+ str << "#{print_class(content)} { #{content.to_s} }"
117
+ when BlockDataLong
118
+ str << "#{print_class(content)} { #{content.to_s} }"
119
+ when EndBlockData
120
+ str << "#{print_class(content)}"
121
+ when NewObject
122
+ str << "#{print_class(content)} { #{content.to_s} }"
123
+ when ClassDesc
124
+ str << "#{print_class(content)} { #{content.to_s} }"
125
+ when NewClass
126
+ str << "#{print_class(content)} { #{content.to_s} }"
127
+ when NewArray
128
+ str << "#{print_class(content)} { #{content.to_s} }"
129
+ when Utf
130
+ str << "#{print_class(content)} { #{content.to_s} }"
131
+ when LongUtf
132
+ str << "#{print_class(content)} { #{content.to_s} } "
133
+ when NewEnum
134
+ str << "#{print_class(content)} { #{content.to_s} }"
135
+ when NewClassDesc
136
+ str << "#{print_class(content)} { #{content.to_s} }"
137
+ when ProxyClassDesc
138
+ str << "#{print_class(content)} { #{content.to_s} }"
139
+ when NullReference
140
+ str << "#{print_class(content)}"
141
+ when Reset
142
+ str << "#{print_class(content)}"
143
+ when Reference
144
+ str << "#{print_class(content)} { #{content.to_s} }"
145
+ else
146
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize content'
147
+ end
148
+
149
+ str
150
+ end
151
+
152
+ # Creates a print-friendly string representation of the content class
153
+ #
154
+ # @param content [Rex::Java::Serialization::Model::Element] the content
155
+ # @return [String]
156
+ def print_class(content)
157
+ content.class.name.split('::').last
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,44 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ class Element
8
+
9
+ attr_accessor :stream
10
+
11
+ # Deserializes a Rex::Java::Serialization::Model::Element
12
+ #
13
+ # @param io [IO] the io to read from
14
+ # @return [Rex::Java::Serialization::Model::Element] if deserialization succeeds
15
+ # @return [nil] if deserialization doesn't succeed
16
+ def self.decode(io, stream = nil)
17
+ elem = self.new(stream)
18
+ elem.decode(io)
19
+ end
20
+
21
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
22
+ def initialize(stream = nil)
23
+ self.stream = stream
24
+ end
25
+
26
+ def decode(io)
27
+ self
28
+ end
29
+
30
+ def encode
31
+ ''
32
+ end
33
+
34
+ # Creates a print-friendly string representation
35
+ #
36
+ # @return [String]
37
+ def to_s
38
+ self.class.name.split('::').last
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,12 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ class EndBlockData < Element
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,173 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a field description representation (fieldDesc). It's used for
8
+ # both primitive descriptions (primitiveDesc) and object descriptions (objectDesc).
9
+ class Field < Element
10
+
11
+ include Rex::Java::Serialization::Model::Contents
12
+
13
+ # @!attribute type
14
+ # @return [String] The type of the field.
15
+ attr_accessor :type
16
+ # @!attribute name
17
+ # @return [Rex::Java::Serialization::Model::Utf] The name of the field.
18
+ attr_accessor :name
19
+ # @!attribute field_type
20
+ # @return [Rex::Java::Serialization::Model::Utf] The type of the field on object types.
21
+ attr_accessor :field_type
22
+
23
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
24
+ def initialize(stream = nil)
25
+ super(stream)
26
+ self.type = ''
27
+ self.name = nil
28
+ self.field_type = nil
29
+ end
30
+
31
+ # Deserializes a Rex::Java::Serialization::Model::Field
32
+ #
33
+ # @param io [IO] the io to read from
34
+ # @return [self] if deserialization succeeds
35
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
36
+ def decode(io)
37
+ code = io.read(1)
38
+
39
+ unless code && is_valid?(code)
40
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize Field'
41
+ end
42
+
43
+ self.type = TYPE_CODES[code]
44
+ self.name = Utf.decode(io, stream)
45
+
46
+ if is_object?
47
+ self.field_type = decode_field_type(io)
48
+ end
49
+
50
+ self
51
+ end
52
+
53
+ # Serializes the Rex::Java::Serialization::Model::Field
54
+ #
55
+ # @return [String] if serialization succeeds
56
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
57
+ def encode
58
+ unless name.kind_of?(Rex::Java::Serialization::Model::Utf)
59
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize Field'
60
+ end
61
+
62
+ unless is_type_valid?
63
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize Field'
64
+ end
65
+
66
+ encoded = ''
67
+ encoded << TYPE_CODES.key(type)
68
+ encoded << name.encode
69
+
70
+ if is_object?
71
+ encoded << encode_field_type
72
+ end
73
+
74
+ encoded
75
+ end
76
+
77
+ # Whether the field type is valid.
78
+ #
79
+ # @return [Boolean]
80
+ def is_type_valid?
81
+ if TYPE_CODES.values.include?(type)
82
+ return true
83
+ end
84
+
85
+ false
86
+ end
87
+
88
+ # Whether the field type is a primitive one.
89
+ #
90
+ # @return [Boolean]
91
+ def is_primitive?
92
+ if PRIMITIVE_TYPE_CODES.values.include?(type)
93
+ return true
94
+ end
95
+
96
+ false
97
+ end
98
+
99
+ # Whether the field type is an object one.
100
+ #
101
+ # @return [Boolean]
102
+ def is_object?
103
+ if OBJECT_TYPE_CODES.values.include?(type)
104
+ return true
105
+ end
106
+
107
+ false
108
+ end
109
+
110
+ # Creates a print-friendly string representation
111
+ #
112
+ # @return [String]
113
+ def to_s
114
+ str = "#{name} "
115
+ if is_primitive?
116
+ str << "(#{type})"
117
+ else
118
+ str << "(#{field_type})"
119
+ end
120
+
121
+ str
122
+ end
123
+
124
+ private
125
+
126
+ # Whether the type opcode is a valid one.
127
+ #
128
+ # @param code [String] A type opcode
129
+ # @return [Boolean]
130
+ def is_valid?(code)
131
+ if TYPE_CODES.keys.include?(code)
132
+ return true
133
+ end
134
+
135
+ false
136
+ end
137
+
138
+ # Serializes the `field_type` attribute.
139
+ #
140
+ # @return [String]
141
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization fails
142
+ def encode_field_type
143
+ allowed_contents = [Utf, Reference]
144
+
145
+ unless allowed_contents.include?(field_type.class)
146
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize Field'
147
+ end
148
+
149
+ encoded = encode_content(field_type)
150
+
151
+ encoded
152
+ end
153
+
154
+ # Deserializes the `field_type` value.
155
+ #
156
+ # @param io [IO] the io to read from
157
+ # @return [Java::Serialization::Model::Utf]
158
+ # @raise [Rex::Java::Serialization::DecodeError] if unserialization doesn't succeed
159
+ def decode_field_type(io)
160
+ allowed_contents = [Utf, Reference]
161
+ type = decode_content(io, stream)
162
+
163
+ unless allowed_contents.include?(type.class)
164
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize Field field_type'
165
+ end
166
+
167
+ type
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end