rex-java 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|