rex-java 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,79 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a NewEnum (Java Enum) representation
8
+ class NewEnum < Element
9
+
10
+ include Rex::Java::Serialization::Model::Contents
11
+
12
+ # @!attribute enum_description
13
+ # @return [Rex::Java::Serialization::Model::ClassDescription] The description of the enum
14
+ attr_accessor :enum_description
15
+ # @!attribute constant_name
16
+ # @return [Rex::Java::Serialization::Model::Utf] The constant value in the Java Enum
17
+ attr_accessor :constant_name
18
+
19
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
20
+ def initialize(stream = nil)
21
+ super(stream)
22
+ self.enum_description = nil
23
+ self.constant_name = nil
24
+ end
25
+
26
+ # Deserializes a Rex::Java::Serialization::Model::NewEnum
27
+ #
28
+ # @param io [IO] the io to read from
29
+ # @return [self] if deserialization succeeds
30
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
31
+ def decode(io)
32
+ self.enum_description = ClassDesc.decode(io, stream)
33
+ stream.add_reference(self) unless stream.nil?
34
+ self.constant_name = decode_constant_name(io)
35
+
36
+ self
37
+ end
38
+
39
+ # Serializes the Rex::Java::Serialization::Model::NewEnum
40
+ #
41
+ # @return [String] if serialization succeeds
42
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
43
+ def encode
44
+ unless enum_description.kind_of?(ClassDesc) &&
45
+ constant_name.kind_of?(Utf)
46
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize EnumDescription'
47
+ end
48
+
49
+ encoded = ''
50
+ encoded << enum_description.encode
51
+ encoded << encode_content(constant_name)
52
+ encoded
53
+ end
54
+
55
+ # Creates a print-friendly string representation
56
+ #
57
+ # @return [String]
58
+ def to_s
59
+ constant_name.to_s
60
+ end
61
+
62
+ private
63
+
64
+ # Deserializes the NewEnum constant name
65
+ #
66
+ # @param io [IO] the io to read from
67
+ # @return [Rex::Java::Serialization::Model::Utf] if deserialization succeeds
68
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succed
69
+ def decode_constant_name(io)
70
+ content = decode_content(io, stream)
71
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize NewEnum' unless content.kind_of?(Rex::Java::Serialization::Model::Utf)
72
+
73
+ content
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,235 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a NewObject (Java Object) representation
8
+ class NewObject < Element
9
+
10
+ include Rex::Java::Serialization::Model::Contents
11
+
12
+ # @!attribute class_desc
13
+ # @return [Rex::Java::Serialization::Model::ClassDesc] The description of the object
14
+ attr_accessor :class_desc
15
+ # @!attribute class_data
16
+ # @return [Array] The data of the object
17
+ attr_accessor :class_data
18
+
19
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
20
+ def initialize(stream = nil)
21
+ super(stream)
22
+ self.class_desc = nil
23
+ self.class_data = []
24
+ end
25
+
26
+ # Deserializes a Rex::Java::Serialization::Model::NewObject
27
+ #
28
+ # @param io [IO] the io to read from
29
+ # @return [self] if deserialization succeeds
30
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
31
+ def decode(io)
32
+ self.class_desc = ClassDesc.decode(io, stream)
33
+ stream.add_reference(self) unless stream.nil?
34
+
35
+ case class_desc.description
36
+ when NewClassDesc
37
+ self.class_data = decode_class_data(io, class_desc.description)
38
+ when Reference
39
+ ref = class_desc.description.handle - BASE_WIRE_HANDLE
40
+ self.class_data = decode_class_data(io, stream.references[ref])
41
+ end
42
+
43
+ self
44
+ end
45
+
46
+ # Serializes the Rex::Java::Serialization::Model::NewObject
47
+ #
48
+ # @return [String] if serialization succeeds
49
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
50
+ def encode
51
+ unless class_desc.kind_of?(ClassDesc)
52
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize NewObject'
53
+ end
54
+
55
+ encoded = ''
56
+ encoded << class_desc.encode
57
+
58
+ class_data.each do |value|
59
+ if value.kind_of?(Array)
60
+ encoded << encode_value(value)
61
+ else
62
+ encoded << encode_content(value)
63
+ end
64
+ end
65
+
66
+ encoded
67
+ end
68
+
69
+ # Creates a print-friendly string representation
70
+ #
71
+ # @return [String]
72
+ def to_s
73
+ str = ''
74
+
75
+ case class_desc.description
76
+ when NewClassDesc
77
+ str << class_desc.description.class_name.to_s
78
+ when ProxyClassDesc
79
+ str << class_desc.description.interfaces.collect { |iface| iface.contents }.join(',')
80
+ when Reference
81
+ str << (class_desc.description.handle - BASE_WIRE_HANDLE).to_s(16)
82
+ end
83
+
84
+ str << ' => { '
85
+ data_str = class_data.collect { |data| data.to_s }
86
+ str << data_str.join(', ')
87
+ str << ' }'
88
+
89
+ str
90
+ end
91
+
92
+ private
93
+
94
+ # Deserializes the class_data for a class_desc and its super classes
95
+ #
96
+ # @param io [IO] the io to read from
97
+ # @param my_class_desc [Rex::Java::Serialization::Model::NewClassDesc] the class description whose data is being extracted
98
+ # @return [Array] class_data values if deserialization succeeds
99
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
100
+ def decode_class_data(io, my_class_desc)
101
+ values = []
102
+
103
+ unless my_class_desc.super_class.description.class == NullReference
104
+ if my_class_desc.super_class.description.class == Reference
105
+ ref = my_class_desc.super_class.description.handle - BASE_WIRE_HANDLE
106
+ values += decode_class_data(io, stream.references[ref])
107
+ else
108
+ values += decode_class_data(io, my_class_desc.super_class.description)
109
+ end
110
+ end
111
+
112
+ values += decode_class_fields(io, my_class_desc)
113
+
114
+ values
115
+ end
116
+
117
+ # Deserializes the fields data for a class_desc
118
+ #
119
+ # @param io [IO] the io to read from
120
+ # @param my_class_desc [Rex::Java::Serialization::Model::NewClassDesc] the class description whose data is being extracted
121
+ # @return [Array] class_data values if deserialization succeeds
122
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
123
+ def decode_class_fields(io, my_class_desc)
124
+ values = []
125
+
126
+ my_class_desc.fields.each do |field|
127
+ if field.is_primitive?
128
+ values << decode_value(io, field.type)
129
+ else
130
+ content = decode_content(io, stream)
131
+ values << content
132
+ end
133
+ end
134
+
135
+ values
136
+ end
137
+
138
+ # Deserializes a class_data value
139
+ #
140
+ # @param io [IO] the io to read from
141
+ # @param type [String] the type of the value to deserialize
142
+ # @return [Array(String, <Fixnum, Float>)] type and value if deserialization succeeds
143
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization fails
144
+ def decode_value(io, type)
145
+ value = []
146
+
147
+ case type
148
+ when 'byte'
149
+ value_raw = io.read(1)
150
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value_raw.nil?
151
+ value.push('byte', value_raw.unpack('c')[0])
152
+ when 'char'
153
+ value_raw = io.read(2)
154
+ unless value_raw && value_raw.length == 2
155
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
156
+ end
157
+ value.push('char', value_raw.unpack('s>')[0])
158
+ when 'double'
159
+ value_raw = io.read(8)
160
+ unless value_raw && value_raw.length == 8
161
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
162
+ end
163
+ value.push('double', value = value_raw.unpack('G')[0])
164
+ when 'float'
165
+ value_raw = io.read(4)
166
+ unless value_raw && value_raw.length == 4
167
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
168
+ end
169
+ value.push('float', value_raw.unpack('g')[0])
170
+ when 'int'
171
+ value_raw = io.read(4)
172
+ unless value_raw && value_raw.length == 4
173
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
174
+ end
175
+ value.push('int', value_raw.unpack('l>')[0])
176
+ when 'long'
177
+ value_raw = io.read(8)
178
+ unless value_raw && value_raw.length == 8
179
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
180
+ end
181
+ value.push('long', value_raw.unpack('q>')[0])
182
+ when 'short'
183
+ value_raw = io.read(2)
184
+ unless value_raw && value_raw.length == 2
185
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
186
+ end
187
+ value.push('short', value_raw.unpack('s>')[0])
188
+ when 'boolean'
189
+ value_raw = io.read(1)
190
+ raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value_raw.nil?
191
+ value.push('boolean', value_raw.unpack('c')[0])
192
+ else
193
+ raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray type'
194
+ end
195
+
196
+ value
197
+ end
198
+
199
+ # Serializes an class_data value
200
+ #
201
+ # @param value [Array] the type and value to serialize
202
+ # @return [String] the serialized value
203
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization fails
204
+ def encode_value(value)
205
+ res = ''
206
+
207
+ case value[0]
208
+ when 'byte'
209
+ res = [value[1]].pack('c')
210
+ when 'char'
211
+ res = [value[1]].pack('s>')
212
+ when 'double'
213
+ res = [value[1]].pack('G')
214
+ when 'float'
215
+ res = [value[1]].pack('g')
216
+ when 'int'
217
+ res = [value[1]].pack('l>')
218
+ when 'long'
219
+ res = [value[1]].pack('q>')
220
+ when 'short'
221
+ res = [value[1]].pack('s>')
222
+ when 'boolean'
223
+ res = [value[1]].pack('c')
224
+ else
225
+ raise Rex::Java::Serialization::EncodeError, 'Unsupported NewArray type'
226
+ end
227
+
228
+ res
229
+ end
230
+
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -0,0 +1,12 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ class NullReference < Element
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,109 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a ProxyClassDesc representation
8
+ class ProxyClassDesc < Element
9
+
10
+ include Rex::Java::Serialization
11
+
12
+ # @!attribute interfaces
13
+ # @return [Array] An array of interface names
14
+ attr_accessor :interfaces
15
+ # @!attribute class_annotation
16
+ # @return [Rex::Java::Serialization::Model::Annotation] The java class annotations
17
+ attr_accessor :class_annotation
18
+ # @!attribute super_class
19
+ # @return [Rex::Java::Serialization::Model::ClassDesc] The java class superclass description
20
+ attr_accessor :super_class
21
+
22
+ # @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
23
+ def initialize(stream = nil)
24
+ super(stream)
25
+ self.interfaces = []
26
+ self.class_annotation = nil
27
+ self.super_class = nil
28
+ end
29
+
30
+ # Deserializes a Rex::Java::Serialization::Model::ProxyClassDesc
31
+ #
32
+ # @param io [IO] the io to read from
33
+ # @return [self] if deserialization succeeds
34
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
35
+ def decode(io)
36
+ stream.add_reference(self) unless stream.nil?
37
+
38
+ interfaces_length = decode_interfaces_length(io)
39
+ interfaces_length.times do
40
+ interface = Utf.decode(io, stream)
41
+ self.interfaces << interface
42
+ end
43
+ self.class_annotation = Annotation.decode(io, stream)
44
+ self.super_class = ClassDesc.decode(io, stream)
45
+
46
+ self
47
+ end
48
+
49
+ # Serializes the Rex::Java::Serialization::Model::ProxyClassDesc
50
+ #
51
+ # @return [String] if serialization succeeds
52
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
53
+ def encode
54
+ unless class_annotation.class == Rex::Java::Serialization::Model::Annotation ||
55
+ super_class.class == Rex::Java::Serialization::Model::ClassDesc
56
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize ProxyClassDesc'
57
+ end
58
+ encoded = ''
59
+ encoded << [interfaces.length].pack('N')
60
+ interfaces.each do |interface|
61
+ encoded << interface.encode
62
+ end
63
+ encoded << class_annotation.encode
64
+ encoded << super_class.encode
65
+
66
+ encoded
67
+ end
68
+
69
+ # Creates a print-friendly string representation
70
+ #
71
+ # @return [String]
72
+ def to_s
73
+ str = '[ '
74
+ interfaces_str = []
75
+ interfaces.each do |interface|
76
+ interfaces_str << interface.to_s
77
+ end
78
+ str << "#{interfaces_str.join(', ')} ]"
79
+
80
+ case super_class.description
81
+ when NewClassDesc
82
+ str << ", @super_class: #{super_class.description.class_name.to_s}"
83
+ when Reference
84
+ str << ", @super_class: #{super_class.description.to_s}"
85
+ end
86
+
87
+ str
88
+ end
89
+
90
+ private
91
+
92
+ # Deserializes the number of interface names
93
+ #
94
+ # @param io [IO] the io to read from
95
+ # @return [Fixnum] if deserialization is possible
96
+ # @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
97
+ def decode_interfaces_length(io)
98
+ fields_length = io.read(4)
99
+ if fields_length.nil? || fields_length.length != 4
100
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ProxyClassDesc'
101
+ end
102
+
103
+ fields_length.unpack('N')[0]
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,61 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Java
5
+ module Serialization
6
+ module Model
7
+ # This class provides a Java Reference representation.
8
+ class Reference < Element
9
+
10
+ # @!attribute contents
11
+ # @return [Fixnum] The stream handle being referenced
12
+ attr_accessor :handle
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.handle = 0
18
+ end
19
+
20
+ # Deserializes a Rex::Java::Serialization::Model::Reference
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
+ handle_raw = io.read(4)
27
+ unless handle_raw && handle_raw.length == 4
28
+ raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize Reference'
29
+ end
30
+
31
+ self.handle = handle_raw.unpack('N')[0]
32
+
33
+ self
34
+ end
35
+
36
+ # Serializes the Rex::Java::Serialization::Model::Reference
37
+ #
38
+ # @return [String] if serialization succeeds
39
+ # @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
40
+ def encode
41
+ if handle < BASE_WIRE_HANDLE
42
+ raise Rex::Java::Serialization::EncodeError, 'Failed to serialize Reference'
43
+ end
44
+
45
+ encoded = ''
46
+ encoded << [handle].pack('N')
47
+
48
+ encoded
49
+ end
50
+
51
+ # Creates a print-friendly string representation
52
+ #
53
+ # @return [String]
54
+ def to_s
55
+ "0x#{handle.to_s(16)}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end