ronin-support 0.1.0.pre1
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.
- data/.document +4 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +504 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +23 -0
- data/README.md +98 -0
- data/Rakefile +29 -0
- data/gemspec.yml +20 -0
- data/lib/ronin/extensions.rb +28 -0
- data/lib/ronin/extensions/file.rb +63 -0
- data/lib/ronin/extensions/ip_addr.rb +220 -0
- data/lib/ronin/extensions/kernel.rb +45 -0
- data/lib/ronin/extensions/meta.rb +22 -0
- data/lib/ronin/extensions/meta/object.rb +24 -0
- data/lib/ronin/extensions/string.rb +200 -0
- data/lib/ronin/formatting.rb +26 -0
- data/lib/ronin/formatting/binary.rb +22 -0
- data/lib/ronin/formatting/digest.rb +22 -0
- data/lib/ronin/formatting/extensions.rb +25 -0
- data/lib/ronin/formatting/extensions/binary.rb +24 -0
- data/lib/ronin/formatting/extensions/binary/file.rb +35 -0
- data/lib/ronin/formatting/extensions/binary/integer.rb +147 -0
- data/lib/ronin/formatting/extensions/binary/string.rb +363 -0
- data/lib/ronin/formatting/extensions/digest.rb +23 -0
- data/lib/ronin/formatting/extensions/digest/file.rb +117 -0
- data/lib/ronin/formatting/extensions/digest/string.rb +80 -0
- data/lib/ronin/formatting/extensions/http.rb +23 -0
- data/lib/ronin/formatting/extensions/http/integer.rb +57 -0
- data/lib/ronin/formatting/extensions/http/string.rb +102 -0
- data/lib/ronin/formatting/extensions/text.rb +23 -0
- data/lib/ronin/formatting/extensions/text/array.rb +125 -0
- data/lib/ronin/formatting/extensions/text/string.rb +206 -0
- data/lib/ronin/formatting/http.rb +22 -0
- data/lib/ronin/formatting/text.rb +22 -0
- data/lib/ronin/network.rb +29 -0
- data/lib/ronin/network/esmtp.rb +22 -0
- data/lib/ronin/network/extensions.rb +29 -0
- data/lib/ronin/network/extensions/esmtp.rb +22 -0
- data/lib/ronin/network/extensions/esmtp/net.rb +100 -0
- data/lib/ronin/network/extensions/http.rb +22 -0
- data/lib/ronin/network/extensions/http/net.rb +661 -0
- data/lib/ronin/network/extensions/imap.rb +22 -0
- data/lib/ronin/network/extensions/imap/net.rb +124 -0
- data/lib/ronin/network/extensions/pop3.rb +22 -0
- data/lib/ronin/network/extensions/pop3/net.rb +92 -0
- data/lib/ronin/network/extensions/smtp.rb +22 -0
- data/lib/ronin/network/extensions/smtp/net.rb +110 -0
- data/lib/ronin/network/extensions/ssl.rb +22 -0
- data/lib/ronin/network/extensions/ssl/net.rb +147 -0
- data/lib/ronin/network/extensions/tcp.rb +22 -0
- data/lib/ronin/network/extensions/tcp/net.rb +304 -0
- data/lib/ronin/network/extensions/telnet.rb +22 -0
- data/lib/ronin/network/extensions/telnet/net.rb +156 -0
- data/lib/ronin/network/extensions/udp.rb +22 -0
- data/lib/ronin/network/extensions/udp/net.rb +226 -0
- data/lib/ronin/network/http.rb +24 -0
- data/lib/ronin/network/http/exceptions.rb +22 -0
- data/lib/ronin/network/http/exceptions/unknown_request.rb +29 -0
- data/lib/ronin/network/http/http.rb +290 -0
- data/lib/ronin/network/http/proxy.rb +307 -0
- data/lib/ronin/network/imap.rb +49 -0
- data/lib/ronin/network/network.rb +41 -0
- data/lib/ronin/network/pop3.rb +49 -0
- data/lib/ronin/network/smtp.rb +24 -0
- data/lib/ronin/network/smtp/email.rb +143 -0
- data/lib/ronin/network/smtp/smtp.rb +68 -0
- data/lib/ronin/network/ssl.rb +47 -0
- data/lib/ronin/network/tcp.rb +22 -0
- data/lib/ronin/network/telnet.rb +109 -0
- data/lib/ronin/network/udp.rb +22 -0
- data/lib/ronin/path.rb +132 -0
- data/lib/ronin/support.rb +28 -0
- data/lib/ronin/support/inflector.rb +40 -0
- data/lib/ronin/support/version.rb +27 -0
- data/lib/ronin/templates.rb +23 -0
- data/lib/ronin/templates/erb.rb +75 -0
- data/lib/ronin/templates/template.rb +161 -0
- data/ronin-support.gemspec +10 -0
- data/spec/extensions/file_spec.rb +24 -0
- data/spec/extensions/ip_addr_spec.rb +171 -0
- data/spec/extensions/kernel_spec.rb +30 -0
- data/spec/extensions/string_spec.rb +177 -0
- data/spec/formatting/binary/helpers/hexdumps.rb +16 -0
- data/spec/formatting/binary/helpers/hexdumps/ascii.bin +0 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_decimal_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_hex_bytes.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_hex_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_octal_bytes.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_octal_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/hexdump_repeated.txt +6 -0
- data/spec/formatting/binary/helpers/hexdumps/od_decimal_bytes.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_decimal_ints.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_decimal_quads.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_decimal_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_hex_bytes.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_hex_ints.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_hex_quads.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_hex_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_octal_bytes.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_octal_ints.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_octal_quads.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_octal_shorts.txt +17 -0
- data/spec/formatting/binary/helpers/hexdumps/od_repeated.txt +6 -0
- data/spec/formatting/binary/helpers/hexdumps/repeated.bin +1 -0
- data/spec/formatting/binary/integer_spec.rb +140 -0
- data/spec/formatting/binary/string_spec.rb +306 -0
- data/spec/formatting/digest/string_spec.rb +82 -0
- data/spec/formatting/http/integer_spec.rb +42 -0
- data/spec/formatting/http/string_spec.rb +76 -0
- data/spec/formatting/text/array_spec.rb +105 -0
- data/spec/formatting/text/string_spec.rb +180 -0
- data/spec/network/http/http_spec.rb +280 -0
- data/spec/network/http/proxy_spec.rb +150 -0
- data/spec/network/network_spec.rb +8 -0
- data/spec/network/ssl_spec.rb +14 -0
- data/spec/path_spec.rb +84 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support_spec.rb +8 -0
- data/spec/templates/classes/example_erb.rb +11 -0
- data/spec/templates/classes/example_template.rb +35 -0
- data/spec/templates/erb_spec.rb +21 -0
- data/spec/templates/helpers/data.rb +9 -0
- data/spec/templates/helpers/data/includes/_relative.erb +1 -0
- data/spec/templates/helpers/data/templates/example.erb +1 -0
- data/spec/templates/template_spec.rb +54 -0
- metadata +286 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Ronin - A Ruby platform for exploit development and security research.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006-2010 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
5
|
+
#
|
|
6
|
+
# This library is free software; you can redistribute it and/or
|
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
8
|
+
# License as published by the Free Software Foundation; either
|
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
# Lesser General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
# License along with this library; if not, write to the Free Software
|
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
19
|
+
# Boston, MA 02110-1301 USA
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
class Integer
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Extracts a sequence of bytes which represent the Integer.
|
|
26
|
+
#
|
|
27
|
+
# @param [Integer] address_length
|
|
28
|
+
# The number of bytes to decode from the Integer.
|
|
29
|
+
#
|
|
30
|
+
# @param [Symbol, String] endian
|
|
31
|
+
# The endianness to use while decoding the bytes of the Integer.
|
|
32
|
+
# May be either `:big`, `:little` or `:net`.
|
|
33
|
+
#
|
|
34
|
+
# @return [Array]
|
|
35
|
+
# The bytes decoded from the Integer.
|
|
36
|
+
#
|
|
37
|
+
# @raise [ArgumentError]
|
|
38
|
+
# The given `endian` is not `:little`, `"little"`, `:net`, `"net"`,
|
|
39
|
+
# `:big` or `"big"`.
|
|
40
|
+
#
|
|
41
|
+
# @example
|
|
42
|
+
# 0xff41.bytes(2)
|
|
43
|
+
# # => [65, 255]
|
|
44
|
+
#
|
|
45
|
+
# @example
|
|
46
|
+
# 0xff41.bytes(4, :big)
|
|
47
|
+
# # => [0, 0, 255, 65]
|
|
48
|
+
#
|
|
49
|
+
def bytes(address_length,endian=:little)
|
|
50
|
+
endian = endian.to_sym
|
|
51
|
+
buffer = []
|
|
52
|
+
|
|
53
|
+
case endian
|
|
54
|
+
when :little, :net
|
|
55
|
+
mask = 0xff
|
|
56
|
+
|
|
57
|
+
address_length.times do |i|
|
|
58
|
+
buffer << ((self & mask) >> (i*8))
|
|
59
|
+
mask <<= 8
|
|
60
|
+
end
|
|
61
|
+
when :big
|
|
62
|
+
mask = (0xff << ((address_length-1)*8))
|
|
63
|
+
|
|
64
|
+
address_length.times do |i|
|
|
65
|
+
buffer << ((self & mask) >> ((address_length-i-1)*8))
|
|
66
|
+
mask >>= 8
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
raise(ArgumentError,"invalid endian #{endian}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
return buffer
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#
|
|
76
|
+
# Packs the Integer into a String, for a specific architecture and
|
|
77
|
+
# address-length.
|
|
78
|
+
#
|
|
79
|
+
# @param [Ronin::Arch, #endian, #address_length, String] arch
|
|
80
|
+
# The architecture to pack the Integer for.
|
|
81
|
+
#
|
|
82
|
+
# @param [Integer] address_length
|
|
83
|
+
# The number of bytes to pack.
|
|
84
|
+
#
|
|
85
|
+
# @return [String]
|
|
86
|
+
# The packed Integer.
|
|
87
|
+
#
|
|
88
|
+
# @raise [ArgumentError]
|
|
89
|
+
# The given `arch` does not respond to the `endian` or
|
|
90
|
+
# `address_length` methods.
|
|
91
|
+
#
|
|
92
|
+
# @example using archs other than `Ronin::Arch`.
|
|
93
|
+
# arch = OpenStruct.new(:endian => :little, :address_length => 4)
|
|
94
|
+
#
|
|
95
|
+
# 0x41.pack(arch)
|
|
96
|
+
# # => "A\0\0\0"
|
|
97
|
+
#
|
|
98
|
+
# @example using a `Ronin::Arch` arch.
|
|
99
|
+
# 0x41.pack(Arch.i686)
|
|
100
|
+
# # => "A\0\0\0"
|
|
101
|
+
#
|
|
102
|
+
# @example specifying a custom address-length.
|
|
103
|
+
# 0x41.pack(Arch.ppc,2)
|
|
104
|
+
# # => "\0A"
|
|
105
|
+
#
|
|
106
|
+
# @example using a `Array#pack` template String for the arch.
|
|
107
|
+
# 0x41.pack('L')
|
|
108
|
+
# # => "A\0\0\0"
|
|
109
|
+
#
|
|
110
|
+
# @see http://ruby-doc.org/core/classes/Array.html#M002222
|
|
111
|
+
#
|
|
112
|
+
def pack(arch,address_length=nil)
|
|
113
|
+
if arch.kind_of?(String)
|
|
114
|
+
return [self].pack(arch)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
unless arch.respond_to?(:address_length)
|
|
118
|
+
raise(ArgumentError,"first argument to Ineger#pack must respond to address_length")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
unless arch.respond_to?(:endian)
|
|
122
|
+
raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
address_length ||= arch.address_length
|
|
126
|
+
|
|
127
|
+
integer_bytes = bytes(address_length,arch.endian)
|
|
128
|
+
integer_bytes.map! { |b| b.chr }
|
|
129
|
+
|
|
130
|
+
return integer_bytes.join
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# @return [String]
|
|
135
|
+
# The hex escaped version of the Integer.
|
|
136
|
+
#
|
|
137
|
+
# @example
|
|
138
|
+
# 42.hex_escape
|
|
139
|
+
# # => "\\x2a"
|
|
140
|
+
#
|
|
141
|
+
def hex_escape
|
|
142
|
+
"\\x%.2x" % self
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
alias char chr
|
|
146
|
+
|
|
147
|
+
end
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Ronin - A Ruby platform for exploit development and security research.
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2006-2010 Hal Brodigan (postmodern.mod3 at gmail.com)
|
|
5
|
+
#
|
|
6
|
+
# This library is free software; you can redistribute it and/or
|
|
7
|
+
# modify it under the terms of the GNU Lesser General Public
|
|
8
|
+
# License as published by the Free Software Foundation; either
|
|
9
|
+
# version 2.1 of the License, or (at your option) any later version.
|
|
10
|
+
#
|
|
11
|
+
# This library is distributed in the hope that it will be useful,
|
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
# Lesser General Public License for more details.
|
|
15
|
+
#
|
|
16
|
+
# You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
# License along with this library; if not, write to the Free Software
|
|
18
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
19
|
+
# Boston, MA 02110-1301 USA
|
|
20
|
+
#
|
|
21
|
+
|
|
22
|
+
require 'ronin/formatting/extensions/binary/integer'
|
|
23
|
+
require 'ronin/formatting/extensions/text'
|
|
24
|
+
|
|
25
|
+
require 'base64'
|
|
26
|
+
require 'enumerator'
|
|
27
|
+
|
|
28
|
+
begin
|
|
29
|
+
require 'zlib'
|
|
30
|
+
rescue Gem::LoadError => e
|
|
31
|
+
raise(e)
|
|
32
|
+
rescue ::LoadError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class String
|
|
36
|
+
|
|
37
|
+
#
|
|
38
|
+
# Packs an Integer from a String, which was originally packed for
|
|
39
|
+
# a specific architecture and address-length.
|
|
40
|
+
#
|
|
41
|
+
# @param [Ronin::Arch, #endian, #address_length, String] arch
|
|
42
|
+
# The architecture that the Integer was originally packed with.
|
|
43
|
+
#
|
|
44
|
+
# @param [Integer] address_length
|
|
45
|
+
# The number of bytes to depack.
|
|
46
|
+
#
|
|
47
|
+
# @return [Integer]
|
|
48
|
+
# The depacked Integer.
|
|
49
|
+
#
|
|
50
|
+
# @raise [ArgumentError]
|
|
51
|
+
# The given `arch` does not respond to the `endian` or
|
|
52
|
+
# `address_length` methods.
|
|
53
|
+
#
|
|
54
|
+
# @example using archs other than `Ronin::Arch`.
|
|
55
|
+
# arch = OpenStruct.new(:endian => :little, :address_length => 4)
|
|
56
|
+
#
|
|
57
|
+
# "A\0\0\0".depack(arch)
|
|
58
|
+
# # => 65
|
|
59
|
+
#
|
|
60
|
+
# @example using a `Ronin::Arch` arch.
|
|
61
|
+
# "A\0\0\0".depack(Arch.i386)
|
|
62
|
+
# # => 65
|
|
63
|
+
#
|
|
64
|
+
# @example specifying a custom address-length.
|
|
65
|
+
# "A\0".depack(Arch.ppc,2)
|
|
66
|
+
# # => 65
|
|
67
|
+
#
|
|
68
|
+
# @example using a `String#unpack` template String as the arch.
|
|
69
|
+
# "A\0\0\0".depack('L')
|
|
70
|
+
# # => 65
|
|
71
|
+
#
|
|
72
|
+
# @see http://ruby-doc.org/core/classes/String.html#M000760
|
|
73
|
+
#
|
|
74
|
+
def depack(arch,address_length=nil)
|
|
75
|
+
if arch.kind_of?(String)
|
|
76
|
+
return self.unpack(arch)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
unless arch.respond_to?(:address_length)
|
|
80
|
+
raise(ArgumentError,"first argument to Ineger#pack must respond to address_length")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
unless arch.respond_to?(:endian)
|
|
84
|
+
raise(ArgumentError,"first argument to Ineger#pack must respond to endian")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
address_length ||= arch.address_length
|
|
88
|
+
|
|
89
|
+
integer = 0x0
|
|
90
|
+
byte_index = 0
|
|
91
|
+
|
|
92
|
+
case arch.endian
|
|
93
|
+
when :little, 'little'
|
|
94
|
+
mask = lambda { |b| b << (byte_index * 8) }
|
|
95
|
+
when :big, 'big'
|
|
96
|
+
mask = lambda { |b|
|
|
97
|
+
b << ((address_length - byte_index - 1) * 8)
|
|
98
|
+
}
|
|
99
|
+
else
|
|
100
|
+
raise(ArgumentError,"invalid endian #{arch.endian.inspect}")
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
self.each_byte do |b|
|
|
104
|
+
break if byte_index >= address_length
|
|
105
|
+
|
|
106
|
+
integer |= mask.call(b)
|
|
107
|
+
byte_index += 1
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
return integer
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# @return [String]
|
|
115
|
+
# The hex escaped version of the String.
|
|
116
|
+
#
|
|
117
|
+
# @example
|
|
118
|
+
# "hello".hex_escape
|
|
119
|
+
# # => "\\x68\\x65\\x6c\\x6c\\x6f"
|
|
120
|
+
#
|
|
121
|
+
# @see String#format_bytes
|
|
122
|
+
#
|
|
123
|
+
def hex_escape(options={})
|
|
124
|
+
format_bytes(options) { |b| b.hex_escape }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
#
|
|
128
|
+
# @return [String]
|
|
129
|
+
# The unescaped version of the hex escaped String.
|
|
130
|
+
#
|
|
131
|
+
# @example
|
|
132
|
+
# "\\x68\\x65\\x6c\\x6c\\x6f".hex_unescape
|
|
133
|
+
# # => "hello"
|
|
134
|
+
#
|
|
135
|
+
def hex_unescape
|
|
136
|
+
buffer = ''
|
|
137
|
+
hex_index = 0
|
|
138
|
+
hex_length = length
|
|
139
|
+
|
|
140
|
+
while (hex_index < hex_length)
|
|
141
|
+
hex_substring = self[hex_index..-1]
|
|
142
|
+
|
|
143
|
+
if hex_substring =~ /^\\[0-7]{3}/
|
|
144
|
+
buffer << hex_substring[0..3].to_i(8)
|
|
145
|
+
hex_index += 3
|
|
146
|
+
elsif hex_substring =~ /^\\x[0-9a-fA-F]{1,2}/
|
|
147
|
+
hex_substring[2..-1].scan(/^[0-9a-fA-F]{1,2}/) do |hex_byte|
|
|
148
|
+
buffer << hex_byte.to_i(16)
|
|
149
|
+
hex_index += (2 + hex_byte.length)
|
|
150
|
+
end
|
|
151
|
+
elsif hex_substring =~ /^\\./
|
|
152
|
+
escaped_char = hex_substring[1..1]
|
|
153
|
+
|
|
154
|
+
buffer << case escaped_char
|
|
155
|
+
when '0'
|
|
156
|
+
"\0"
|
|
157
|
+
when 'a'
|
|
158
|
+
"\a"
|
|
159
|
+
when 'b'
|
|
160
|
+
"\b"
|
|
161
|
+
when 't'
|
|
162
|
+
"\t"
|
|
163
|
+
when 'n'
|
|
164
|
+
"\n"
|
|
165
|
+
when 'v'
|
|
166
|
+
"\v"
|
|
167
|
+
when 'f'
|
|
168
|
+
"\f"
|
|
169
|
+
when 'r'
|
|
170
|
+
"\r"
|
|
171
|
+
else
|
|
172
|
+
escaped_char
|
|
173
|
+
end
|
|
174
|
+
hex_index += 2
|
|
175
|
+
else
|
|
176
|
+
buffer << hex_substring[0]
|
|
177
|
+
hex_index += 1
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
return buffer
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
#
|
|
185
|
+
# XOR encodes the String.
|
|
186
|
+
#
|
|
187
|
+
# @param [Enumerable, Integer] key
|
|
188
|
+
# The byte to XOR against each byte in the String.
|
|
189
|
+
#
|
|
190
|
+
# @return [String]
|
|
191
|
+
# The XOR encoded String.
|
|
192
|
+
#
|
|
193
|
+
# @example
|
|
194
|
+
# "hello".xor(0x41)
|
|
195
|
+
# # => ")$--."
|
|
196
|
+
#
|
|
197
|
+
# @example
|
|
198
|
+
# "hello again".xor([0x55, 0x41, 0xe1])
|
|
199
|
+
# # => "=$\x8d9.\xc14&\x80</"
|
|
200
|
+
#
|
|
201
|
+
def xor(key)
|
|
202
|
+
key = if key.kind_of?(Integer)
|
|
203
|
+
[key]
|
|
204
|
+
elsif key.kind_of?(String)
|
|
205
|
+
key.bytes
|
|
206
|
+
else
|
|
207
|
+
key
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
key = key.cycle
|
|
211
|
+
result = ''
|
|
212
|
+
|
|
213
|
+
self.bytes.inject('') { |result,b| result << (b ^ key.next).chr }
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
#
|
|
219
|
+
# Base64 encodes a string.
|
|
220
|
+
#
|
|
221
|
+
# @return [String]
|
|
222
|
+
# The base64 encoded form of the string.
|
|
223
|
+
#
|
|
224
|
+
def base64_encode
|
|
225
|
+
Base64.encode64(self)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
#
|
|
229
|
+
# Base64 decodes a string.
|
|
230
|
+
#
|
|
231
|
+
# @return [String]
|
|
232
|
+
# The base64 decoded form of the string.
|
|
233
|
+
#
|
|
234
|
+
def base64_decode
|
|
235
|
+
Base64.decode64(self)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
#
|
|
239
|
+
# Zlib inflate a string.
|
|
240
|
+
#
|
|
241
|
+
# @return [String]
|
|
242
|
+
# The zlib inflated form of the string.
|
|
243
|
+
#
|
|
244
|
+
def zlib_inflate
|
|
245
|
+
Zlib::Inflate.inflate(self)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
#
|
|
249
|
+
# Zlib deflate a string.
|
|
250
|
+
#
|
|
251
|
+
# @return [String]
|
|
252
|
+
# The zlib deflated form of the string.
|
|
253
|
+
#
|
|
254
|
+
def zlib_deflate
|
|
255
|
+
Zlib::Deflate.deflate(self)
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
#
|
|
259
|
+
# Converts a multitude of hexdump formats back into raw-data.
|
|
260
|
+
#
|
|
261
|
+
# @param [Hash] options
|
|
262
|
+
# Additional options.
|
|
263
|
+
#
|
|
264
|
+
# @option options [Symbol] :format
|
|
265
|
+
# The expected format of the hexdump. Must be either `:od` or
|
|
266
|
+
# `:hexdump`.
|
|
267
|
+
#
|
|
268
|
+
# @option options [Symbol] :encoding
|
|
269
|
+
# Denotes the encoding used for the bytes within the hexdump.
|
|
270
|
+
# Must be one of the following: `:binary`, `:octal`, `:octal_bytes`
|
|
271
|
+
# `:octal_shorts`, `:octal_ints`, :octal_quads`, `:decimal`,
|
|
272
|
+
# `:decimal_bytes`, `:decimal_shorts`, `:decimal_ints`,
|
|
273
|
+
# `:decimal_quads`, `:hex`, `:hex_bytes`, `:hex_shorts`, `:hex_ints` or
|
|
274
|
+
# `:hex_quads`.
|
|
275
|
+
#
|
|
276
|
+
# @option options [Integer] :segment (16)
|
|
277
|
+
# The length in bytes of each segment in the hexdump.
|
|
278
|
+
#
|
|
279
|
+
# @return [String] The raw-data from the hexdump.
|
|
280
|
+
#
|
|
281
|
+
def unhexdump(options={})
|
|
282
|
+
case (format = options[:format])
|
|
283
|
+
when :od
|
|
284
|
+
address_base = base = 8
|
|
285
|
+
word_size = 2
|
|
286
|
+
when :hexdump
|
|
287
|
+
address_base = base = 16
|
|
288
|
+
word_size = 2
|
|
289
|
+
else
|
|
290
|
+
address_base = base = 16
|
|
291
|
+
word_size = 1
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
case options[:encoding]
|
|
295
|
+
when :binary
|
|
296
|
+
base = 2
|
|
297
|
+
when :octal, :octal_bytes, :octal_shorts, :octal_ints, :octal_quads
|
|
298
|
+
base = 8
|
|
299
|
+
when :decimal, :decimal_bytes, :decimal_shorts, :decimal_ints, :decimal_quads
|
|
300
|
+
base = 10
|
|
301
|
+
when :hex, :hex_bytes, :hex_shorts, :hex_ints, :hex_quads
|
|
302
|
+
base = 16
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
case options[:encoding]
|
|
306
|
+
when :binary, :octal_bytes, :decimal_bytes, :hex_bytes
|
|
307
|
+
word_size = 1
|
|
308
|
+
when :octal_shorts, :decimal_shorts, :hex_shorts
|
|
309
|
+
word_size = 2
|
|
310
|
+
when :octal_ints, :decimal_ints, :hex_ints
|
|
311
|
+
word_size = 4
|
|
312
|
+
when :octal_quads, :decimal_quads, :hex_quads
|
|
313
|
+
word_size = 8
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
current_addr = last_addr = first_addr = nil
|
|
317
|
+
repeated = false
|
|
318
|
+
|
|
319
|
+
segment_length = (options[:segment] || 16)
|
|
320
|
+
segment = []
|
|
321
|
+
buffer = []
|
|
322
|
+
|
|
323
|
+
each_line do |line|
|
|
324
|
+
if format == :hexdump
|
|
325
|
+
line = line.gsub(/\s+\|.+\|\s*$/,'')
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
words = line.split
|
|
329
|
+
|
|
330
|
+
if words.first == '*'
|
|
331
|
+
repeated = true
|
|
332
|
+
elsif words.length > 0
|
|
333
|
+
current_addr = words.shift.to_i(address_base)
|
|
334
|
+
first_addr ||= current_addr
|
|
335
|
+
|
|
336
|
+
if repeated
|
|
337
|
+
(((current_addr - last_addr) / segment.length) - 1).times do
|
|
338
|
+
buffer += segment
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
repeated = false
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
segment.clear
|
|
345
|
+
|
|
346
|
+
words.each do |word|
|
|
347
|
+
if (base != 10 && word =~ /^(\\[0abtnvfr\\]|.)$/)
|
|
348
|
+
word.hex_unescape.each_byte { |b| segment << b }
|
|
349
|
+
else
|
|
350
|
+
segment += word.to_i(base).bytes(word_size)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
segment = segment[0...segment_length]
|
|
355
|
+
buffer += segment
|
|
356
|
+
last_addr = current_addr
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
return buffer[0...(last_addr - first_addr)]
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
end
|