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,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