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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +52 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/rex/java.rb +10 -0
- data/lib/rex/java/serialization.rb +57 -0
- data/lib/rex/java/serialization/builder.rb +94 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +33 -0
- data/lib/rex/java/serialization/model/annotation.rb +69 -0
- data/lib/rex/java/serialization/model/block_data.rb +70 -0
- data/lib/rex/java/serialization/model/block_data_long.rb +72 -0
- data/lib/rex/java/serialization/model/class_desc.rb +64 -0
- data/lib/rex/java/serialization/model/contents.rb +163 -0
- data/lib/rex/java/serialization/model/element.rb +44 -0
- data/lib/rex/java/serialization/model/end_block_data.rb +12 -0
- data/lib/rex/java/serialization/model/field.rb +173 -0
- data/lib/rex/java/serialization/model/long_utf.rb +48 -0
- data/lib/rex/java/serialization/model/new_array.rb +229 -0
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +154 -0
- data/lib/rex/java/serialization/model/new_enum.rb +79 -0
- data/lib/rex/java/serialization/model/new_object.rb +235 -0
- data/lib/rex/java/serialization/model/null_reference.rb +12 -0
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +61 -0
- data/lib/rex/java/serialization/model/reset.rb +12 -0
- data/lib/rex/java/serialization/model/stream.rb +123 -0
- data/lib/rex/java/serialization/model/utf.rb +69 -0
- data/lib/rex/java/version.rb +5 -0
- data/rex-java.gemspec +24 -0
- metadata +199 -0
- metadata.gz.sig +1 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Java
|
5
|
+
module Serialization
|
6
|
+
module Model
|
7
|
+
# This class provides a Long Utf string representation
|
8
|
+
class LongUtf < Utf
|
9
|
+
|
10
|
+
# Deserializes a Rex::Java::Serialization::Model::LongUtf
|
11
|
+
#
|
12
|
+
# @param io [IO] the io to read from
|
13
|
+
# @return [self] if deserialization succeeds
|
14
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
15
|
+
def decode(io)
|
16
|
+
raw_length = io.read(8)
|
17
|
+
if raw_length.nil? || raw_length.length != 8
|
18
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize LongUtf'
|
19
|
+
end
|
20
|
+
self.length = raw_length.unpack('Q>')[0]
|
21
|
+
|
22
|
+
if length == 0
|
23
|
+
self.contents = ''
|
24
|
+
else
|
25
|
+
self.contents = io.read(length)
|
26
|
+
if contents.nil? || contents.length != length
|
27
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize LongUtf'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Serializes the Rex::Java::Serialization::Model::LongUtf
|
35
|
+
#
|
36
|
+
# @return [String]
|
37
|
+
def encode
|
38
|
+
encoded = [length].pack('Q>')
|
39
|
+
encoded << contents
|
40
|
+
|
41
|
+
encoded
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,229 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Java
|
5
|
+
module Serialization
|
6
|
+
module Model
|
7
|
+
# This class provides a NewArray (Java Array) representation
|
8
|
+
class NewArray < Element
|
9
|
+
|
10
|
+
include Rex::Java::Serialization::Model::Contents
|
11
|
+
|
12
|
+
# @!attribute array_description
|
13
|
+
# @return [Java::Serialization::Model::ClassDesc] The description of the array
|
14
|
+
attr_accessor :array_description
|
15
|
+
# @!attribute type
|
16
|
+
# @return [String] The type of the array values
|
17
|
+
attr_accessor :type
|
18
|
+
# @!attribute values
|
19
|
+
# @return [Array] The contents of the java array
|
20
|
+
attr_accessor :values
|
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.array_description = nil
|
26
|
+
self.type = ''
|
27
|
+
self.values = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# Deserializes a Rex::Java::Serialization::Model::NewArray
|
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
|
+
self.array_description = ClassDesc.decode(io, stream)
|
37
|
+
stream.add_reference(self) unless stream.nil?
|
38
|
+
self.type = array_type
|
39
|
+
|
40
|
+
values_length = decode_values_length(io)
|
41
|
+
|
42
|
+
values_length.times do
|
43
|
+
value = decode_value(io)
|
44
|
+
self.values << value
|
45
|
+
end
|
46
|
+
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# Serializes the Rex::Java::Serialization::Model::NewArray
|
51
|
+
#
|
52
|
+
# @return [String] if serialization succeeds
|
53
|
+
# @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
|
54
|
+
def encode
|
55
|
+
unless array_description.kind_of?(ClassDesc)
|
56
|
+
raise Rex::Java::Serialization::EncodeError, 'Failed to serialize NewArray'
|
57
|
+
end
|
58
|
+
|
59
|
+
encoded = ''
|
60
|
+
encoded << array_description.encode
|
61
|
+
|
62
|
+
encoded << [values.length].pack('N')
|
63
|
+
|
64
|
+
values.each do |value|
|
65
|
+
encoded << encode_value(value)
|
66
|
+
end
|
67
|
+
|
68
|
+
encoded
|
69
|
+
end
|
70
|
+
|
71
|
+
# Creates a print-friendly string representation
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
def to_s
|
75
|
+
str = "#{type}, "
|
76
|
+
values_data = values.collect {|v| "#{v}"}
|
77
|
+
str << "#{values_data}"
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Deserializes the NewArray length
|
83
|
+
#
|
84
|
+
# @param io [IO] the io to read from
|
85
|
+
# @return [Integer] if deserialization succeeds
|
86
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
87
|
+
def decode_values_length(io)
|
88
|
+
values_length = io.read(4)
|
89
|
+
if values_length.nil? || values_length.length != 4
|
90
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize NewArray'
|
91
|
+
end
|
92
|
+
|
93
|
+
values_length.unpack('N')[0]
|
94
|
+
end
|
95
|
+
|
96
|
+
# Extracts the NewArray data type
|
97
|
+
#
|
98
|
+
# @return [String]
|
99
|
+
# @raise [Rex::Java::Serialization::DecodeError] if the NewArray description isn't valid
|
100
|
+
# or type isn't supported
|
101
|
+
def array_type
|
102
|
+
if array_description.nil?
|
103
|
+
raise Rex::Java::Serialization::DecodeError, 'Empty NewArray description'
|
104
|
+
end
|
105
|
+
|
106
|
+
unless array_description.kind_of?(ClassDesc)
|
107
|
+
raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray description class'
|
108
|
+
end
|
109
|
+
|
110
|
+
desc = array_description.description
|
111
|
+
|
112
|
+
if desc.class == Reference
|
113
|
+
ref = desc.handle - BASE_WIRE_HANDLE
|
114
|
+
desc = stream.references[ref]
|
115
|
+
end
|
116
|
+
|
117
|
+
unless desc.class_name.contents[0] == '[' # Array
|
118
|
+
raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray description'
|
119
|
+
end
|
120
|
+
|
121
|
+
decoded_type = desc.class_name.contents[1]
|
122
|
+
if PRIMITIVE_TYPE_CODES.keys.include?(decoded_type)
|
123
|
+
return PRIMITIVE_TYPE_CODES[decoded_type]
|
124
|
+
elsif decoded_type == 'L' # L : Object
|
125
|
+
return desc.class_name.contents[2..desc.class_name.contents.index(';')] # Object class
|
126
|
+
else
|
127
|
+
raise Rex::Java::Serialization::DecodeError, 'Unsupported NewArray Type'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Deserializes a NewArray value
|
132
|
+
#
|
133
|
+
# @param io [IO] the io to read from
|
134
|
+
# @return [Fixnum, Float] if deserialization succeeds
|
135
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization fails
|
136
|
+
def decode_value(io)
|
137
|
+
value = nil
|
138
|
+
|
139
|
+
case type
|
140
|
+
when 'byte'
|
141
|
+
value = io.read(1)
|
142
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value.nil?
|
143
|
+
value = value.unpack('c')[0]
|
144
|
+
when 'char'
|
145
|
+
value = io.read(2)
|
146
|
+
unless value && value.length == 2
|
147
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
148
|
+
end
|
149
|
+
value = value.unpack('s>')[0]
|
150
|
+
when 'double'
|
151
|
+
value = io.read(8)
|
152
|
+
unless value && value.length == 8
|
153
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
154
|
+
end
|
155
|
+
value = value.unpack('G')[0]
|
156
|
+
when 'float'
|
157
|
+
value = io.read(4)
|
158
|
+
unless value && value.length == 4
|
159
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
160
|
+
end
|
161
|
+
value = value.unpack('g')[0]
|
162
|
+
when 'int'
|
163
|
+
value = io.read(4)
|
164
|
+
unless value && value.length == 4
|
165
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
166
|
+
end
|
167
|
+
value = value.unpack('l>')[0]
|
168
|
+
when 'long'
|
169
|
+
value = io.read(8)
|
170
|
+
unless value && value.length == 8
|
171
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
172
|
+
end
|
173
|
+
value = value.unpack('q>')[0]
|
174
|
+
when 'short'
|
175
|
+
value = io.read(2)
|
176
|
+
unless value && value.length == 2
|
177
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value'
|
178
|
+
end
|
179
|
+
value = value.unpack('s>')[0]
|
180
|
+
when 'boolean'
|
181
|
+
value = io.read(1)
|
182
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to deserialize NewArray value' if value.nil?
|
183
|
+
value = value.unpack('c')[0]
|
184
|
+
else # object
|
185
|
+
value = decode_content(io, stream)
|
186
|
+
end
|
187
|
+
|
188
|
+
value
|
189
|
+
end
|
190
|
+
|
191
|
+
# Serializes an NewArray value
|
192
|
+
#
|
193
|
+
# @param value [<Fixnum, Float>] the value to serialize
|
194
|
+
# @return [String] the serialized value
|
195
|
+
# @raise [Rex::Java::Serialization::EncodeError] if serialization fails
|
196
|
+
def encode_value(value)
|
197
|
+
res = ''
|
198
|
+
|
199
|
+
case type
|
200
|
+
when 'byte'
|
201
|
+
res = [value].pack('c')
|
202
|
+
when 'char'
|
203
|
+
res = [value].pack('s>')
|
204
|
+
when 'double'
|
205
|
+
res = [value].pack('G')
|
206
|
+
when 'float'
|
207
|
+
res = [value].pack('g')
|
208
|
+
when 'int'
|
209
|
+
res = [value].pack('l>')
|
210
|
+
when 'long'
|
211
|
+
res = [value].pack('q>')
|
212
|
+
when 'short'
|
213
|
+
res = [value].pack('s>')
|
214
|
+
when 'boolean'
|
215
|
+
res = [value].pack('c')
|
216
|
+
when Element
|
217
|
+
res = value.encode
|
218
|
+
else # object
|
219
|
+
res = encode_content(value)
|
220
|
+
end
|
221
|
+
|
222
|
+
res
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Java
|
5
|
+
module Serialization
|
6
|
+
module Model
|
7
|
+
# This class provides a NewArray (Java Array) representation
|
8
|
+
class NewClass < Element
|
9
|
+
|
10
|
+
include Rex::Java::Serialization::Model::Contents
|
11
|
+
|
12
|
+
# @!attribute array_description
|
13
|
+
# @return [Java::Serialization::Model::ClassDesc] The description of the class
|
14
|
+
attr_accessor :class_description
|
15
|
+
|
16
|
+
# @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
|
17
|
+
def initialize(stream = nil)
|
18
|
+
super(stream)
|
19
|
+
self.class_description = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
# Deserializes a Rex::Java::Serialization::Model::NewClass
|
23
|
+
#
|
24
|
+
# @param io [IO] the io to read from
|
25
|
+
# @return [self] if deserialization succeeds
|
26
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
27
|
+
def decode(io)
|
28
|
+
self.class_description = ClassDesc.decode(io, stream)
|
29
|
+
stream.add_reference(self) unless stream.nil?
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
# Serializes the Rex::Java::Serialization::Model::NewClass
|
35
|
+
#
|
36
|
+
# @return [String] if serialization succeeds
|
37
|
+
# @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
|
38
|
+
def encode
|
39
|
+
unless class_description.kind_of?(ClassDesc)
|
40
|
+
raise Rex::Java::Serialization::EncodeError, 'Failed to serialize NewClass'
|
41
|
+
end
|
42
|
+
|
43
|
+
encoded = ''
|
44
|
+
encoded << class_description.encode
|
45
|
+
end
|
46
|
+
|
47
|
+
# Creates a print-friendly string representation
|
48
|
+
#
|
49
|
+
# @return [String]
|
50
|
+
def to_s
|
51
|
+
print_content(class_description)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Java
|
5
|
+
module Serialization
|
6
|
+
module Model
|
7
|
+
# This class provides a newClassDesc representation
|
8
|
+
class NewClassDesc < Element
|
9
|
+
|
10
|
+
include Rex::Java::Serialization
|
11
|
+
|
12
|
+
# @!attribute class_name
|
13
|
+
# @return [Rex::Java::Serialization::Model::Utf] The name of the class
|
14
|
+
attr_accessor :class_name
|
15
|
+
# @!attribute serial_version
|
16
|
+
# @return [Fixnum] The java class serial version
|
17
|
+
attr_accessor :serial_version
|
18
|
+
# @!attribute flags
|
19
|
+
# @return [Fixnum] The java class flags
|
20
|
+
attr_accessor :flags
|
21
|
+
# @!attribute fields
|
22
|
+
# @return [Array] The java class fields
|
23
|
+
attr_accessor :fields
|
24
|
+
# @!attribute class_annotation
|
25
|
+
# @return [Rex::Java::Serialization::Model::Annotation] The java class annotations
|
26
|
+
attr_accessor :class_annotation
|
27
|
+
# @!attribute super_class
|
28
|
+
# @return [Rex::Java::Serialization::Model::ClassDesc] The java class superclass description
|
29
|
+
attr_accessor :super_class
|
30
|
+
|
31
|
+
# @param stream [Rex::Java::Serialization::Model::Stream] the stream where it belongs to
|
32
|
+
def initialize(stream = nil)
|
33
|
+
super(stream)
|
34
|
+
self.class_name = nil
|
35
|
+
self.serial_version = 0
|
36
|
+
self.flags = 0
|
37
|
+
self.fields = []
|
38
|
+
self.class_annotation = nil
|
39
|
+
self.super_class = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Deserializes a Rex::Java::Serialization::Model::NewClassDesc
|
43
|
+
#
|
44
|
+
# @param io [IO] the io to read from
|
45
|
+
# @return [self] if deserialization succeeds
|
46
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
47
|
+
def decode(io)
|
48
|
+
self.class_name = Utf.decode(io, stream)
|
49
|
+
self.serial_version = decode_serial_version(io)
|
50
|
+
stream.add_reference(self) unless stream.nil?
|
51
|
+
self.flags = decode_flags(io)
|
52
|
+
fields_length = decode_fields_length(io)
|
53
|
+
fields_length.times do
|
54
|
+
field = Field.decode(io, stream)
|
55
|
+
self.fields << field
|
56
|
+
end
|
57
|
+
|
58
|
+
self.class_annotation = Annotation.decode(io, stream)
|
59
|
+
self.super_class = ClassDesc.decode(io, stream)
|
60
|
+
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Serializes the Rex::Java::Serialization::Model::ClassDescription
|
65
|
+
#
|
66
|
+
# @return [String] if serialization succeeds
|
67
|
+
# @raise [Rex::Java::Serialization::EncodeError] if serialization doesn't succeed
|
68
|
+
def encode
|
69
|
+
unless class_name.class == Rex::Java::Serialization::Model::Utf ||
|
70
|
+
class_annotation.class == Rex::Java::Serialization::Model::Annotation ||
|
71
|
+
super_class.class == Rex::Java::Serialization::Model::ClassDesc
|
72
|
+
raise Rex::Java::Serialization::EncodeError, 'Filed to serialize NewClassDesc'
|
73
|
+
end
|
74
|
+
encoded = ''
|
75
|
+
encoded << class_name.encode
|
76
|
+
encoded << [serial_version].pack('q>')
|
77
|
+
encoded << [flags].pack('C')
|
78
|
+
encoded << [fields.length].pack('n')
|
79
|
+
fields.each do |field|
|
80
|
+
encoded << field.encode
|
81
|
+
end
|
82
|
+
encoded << class_annotation.encode
|
83
|
+
encoded << super_class.encode
|
84
|
+
|
85
|
+
encoded
|
86
|
+
end
|
87
|
+
|
88
|
+
# Creates a print-friendly string representation
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
def to_s
|
92
|
+
str = "#{class_name}, [ "
|
93
|
+
fields_str = []
|
94
|
+
fields.each do |field|
|
95
|
+
fields_str << field.to_s
|
96
|
+
end
|
97
|
+
str << "#{fields_str.join(', ')} ]"
|
98
|
+
|
99
|
+
case super_class.description
|
100
|
+
when NewClassDesc
|
101
|
+
str << ", @super_class: #{super_class.description.class_name.to_s}"
|
102
|
+
when Reference
|
103
|
+
str << ", @super_class: #{super_class.description.to_s}"
|
104
|
+
end
|
105
|
+
|
106
|
+
str
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Deserializes a class serial version
|
112
|
+
#
|
113
|
+
# @param io [IO] the io to read from
|
114
|
+
# @return [Integer] if deserialization succeeds
|
115
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
116
|
+
def decode_serial_version(io)
|
117
|
+
raw_serial = io.read(8)
|
118
|
+
if raw_serial.nil? || raw_serial.length != 8
|
119
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription'
|
120
|
+
end
|
121
|
+
|
122
|
+
raw_serial.unpack('Q>')[0]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Deserializes a class flags
|
126
|
+
#
|
127
|
+
# @param io [IO] the io to read from
|
128
|
+
# @return [Integer] if deserialization is possible
|
129
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
130
|
+
def decode_flags(io)
|
131
|
+
raw_flags = io.read(1)
|
132
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription' if raw_flags.nil?
|
133
|
+
|
134
|
+
raw_flags.unpack('C')[0]
|
135
|
+
end
|
136
|
+
|
137
|
+
# Deserializes a class fields length
|
138
|
+
#
|
139
|
+
# @param io [IO] the io to read from
|
140
|
+
# @return [Integer] if deserialization is possible
|
141
|
+
# @raise [Rex::Java::Serialization::DecodeError] if deserialization doesn't succeed
|
142
|
+
def decode_fields_length(io)
|
143
|
+
fields_length = io.read(2)
|
144
|
+
if fields_length.nil? || fields_length.length != 2
|
145
|
+
raise Rex::Java::Serialization::DecodeError, 'Failed to unserialize ClassDescription'
|
146
|
+
end
|
147
|
+
|
148
|
+
fields_length.unpack('n')[0]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|