ronin-support 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/.document +4 -0
  2. data/.rspec +1 -0
  3. data/.yardopts +1 -0
  4. data/COPYING.txt +504 -0
  5. data/ChangeLog.md +4 -0
  6. data/Gemfile +23 -0
  7. data/README.md +98 -0
  8. data/Rakefile +29 -0
  9. data/gemspec.yml +20 -0
  10. data/lib/ronin/extensions.rb +28 -0
  11. data/lib/ronin/extensions/file.rb +63 -0
  12. data/lib/ronin/extensions/ip_addr.rb +220 -0
  13. data/lib/ronin/extensions/kernel.rb +45 -0
  14. data/lib/ronin/extensions/meta.rb +22 -0
  15. data/lib/ronin/extensions/meta/object.rb +24 -0
  16. data/lib/ronin/extensions/string.rb +200 -0
  17. data/lib/ronin/formatting.rb +26 -0
  18. data/lib/ronin/formatting/binary.rb +22 -0
  19. data/lib/ronin/formatting/digest.rb +22 -0
  20. data/lib/ronin/formatting/extensions.rb +25 -0
  21. data/lib/ronin/formatting/extensions/binary.rb +24 -0
  22. data/lib/ronin/formatting/extensions/binary/file.rb +35 -0
  23. data/lib/ronin/formatting/extensions/binary/integer.rb +147 -0
  24. data/lib/ronin/formatting/extensions/binary/string.rb +363 -0
  25. data/lib/ronin/formatting/extensions/digest.rb +23 -0
  26. data/lib/ronin/formatting/extensions/digest/file.rb +117 -0
  27. data/lib/ronin/formatting/extensions/digest/string.rb +80 -0
  28. data/lib/ronin/formatting/extensions/http.rb +23 -0
  29. data/lib/ronin/formatting/extensions/http/integer.rb +57 -0
  30. data/lib/ronin/formatting/extensions/http/string.rb +102 -0
  31. data/lib/ronin/formatting/extensions/text.rb +23 -0
  32. data/lib/ronin/formatting/extensions/text/array.rb +125 -0
  33. data/lib/ronin/formatting/extensions/text/string.rb +206 -0
  34. data/lib/ronin/formatting/http.rb +22 -0
  35. data/lib/ronin/formatting/text.rb +22 -0
  36. data/lib/ronin/network.rb +29 -0
  37. data/lib/ronin/network/esmtp.rb +22 -0
  38. data/lib/ronin/network/extensions.rb +29 -0
  39. data/lib/ronin/network/extensions/esmtp.rb +22 -0
  40. data/lib/ronin/network/extensions/esmtp/net.rb +100 -0
  41. data/lib/ronin/network/extensions/http.rb +22 -0
  42. data/lib/ronin/network/extensions/http/net.rb +661 -0
  43. data/lib/ronin/network/extensions/imap.rb +22 -0
  44. data/lib/ronin/network/extensions/imap/net.rb +124 -0
  45. data/lib/ronin/network/extensions/pop3.rb +22 -0
  46. data/lib/ronin/network/extensions/pop3/net.rb +92 -0
  47. data/lib/ronin/network/extensions/smtp.rb +22 -0
  48. data/lib/ronin/network/extensions/smtp/net.rb +110 -0
  49. data/lib/ronin/network/extensions/ssl.rb +22 -0
  50. data/lib/ronin/network/extensions/ssl/net.rb +147 -0
  51. data/lib/ronin/network/extensions/tcp.rb +22 -0
  52. data/lib/ronin/network/extensions/tcp/net.rb +304 -0
  53. data/lib/ronin/network/extensions/telnet.rb +22 -0
  54. data/lib/ronin/network/extensions/telnet/net.rb +156 -0
  55. data/lib/ronin/network/extensions/udp.rb +22 -0
  56. data/lib/ronin/network/extensions/udp/net.rb +226 -0
  57. data/lib/ronin/network/http.rb +24 -0
  58. data/lib/ronin/network/http/exceptions.rb +22 -0
  59. data/lib/ronin/network/http/exceptions/unknown_request.rb +29 -0
  60. data/lib/ronin/network/http/http.rb +290 -0
  61. data/lib/ronin/network/http/proxy.rb +307 -0
  62. data/lib/ronin/network/imap.rb +49 -0
  63. data/lib/ronin/network/network.rb +41 -0
  64. data/lib/ronin/network/pop3.rb +49 -0
  65. data/lib/ronin/network/smtp.rb +24 -0
  66. data/lib/ronin/network/smtp/email.rb +143 -0
  67. data/lib/ronin/network/smtp/smtp.rb +68 -0
  68. data/lib/ronin/network/ssl.rb +47 -0
  69. data/lib/ronin/network/tcp.rb +22 -0
  70. data/lib/ronin/network/telnet.rb +109 -0
  71. data/lib/ronin/network/udp.rb +22 -0
  72. data/lib/ronin/path.rb +132 -0
  73. data/lib/ronin/support.rb +28 -0
  74. data/lib/ronin/support/inflector.rb +40 -0
  75. data/lib/ronin/support/version.rb +27 -0
  76. data/lib/ronin/templates.rb +23 -0
  77. data/lib/ronin/templates/erb.rb +75 -0
  78. data/lib/ronin/templates/template.rb +161 -0
  79. data/ronin-support.gemspec +10 -0
  80. data/spec/extensions/file_spec.rb +24 -0
  81. data/spec/extensions/ip_addr_spec.rb +171 -0
  82. data/spec/extensions/kernel_spec.rb +30 -0
  83. data/spec/extensions/string_spec.rb +177 -0
  84. data/spec/formatting/binary/helpers/hexdumps.rb +16 -0
  85. data/spec/formatting/binary/helpers/hexdumps/ascii.bin +0 -0
  86. data/spec/formatting/binary/helpers/hexdumps/hexdump_decimal_shorts.txt +17 -0
  87. data/spec/formatting/binary/helpers/hexdumps/hexdump_hex_bytes.txt +17 -0
  88. data/spec/formatting/binary/helpers/hexdumps/hexdump_hex_shorts.txt +17 -0
  89. data/spec/formatting/binary/helpers/hexdumps/hexdump_octal_bytes.txt +17 -0
  90. data/spec/formatting/binary/helpers/hexdumps/hexdump_octal_shorts.txt +17 -0
  91. data/spec/formatting/binary/helpers/hexdumps/hexdump_repeated.txt +6 -0
  92. data/spec/formatting/binary/helpers/hexdumps/od_decimal_bytes.txt +17 -0
  93. data/spec/formatting/binary/helpers/hexdumps/od_decimal_ints.txt +17 -0
  94. data/spec/formatting/binary/helpers/hexdumps/od_decimal_quads.txt +17 -0
  95. data/spec/formatting/binary/helpers/hexdumps/od_decimal_shorts.txt +17 -0
  96. data/spec/formatting/binary/helpers/hexdumps/od_hex_bytes.txt +17 -0
  97. data/spec/formatting/binary/helpers/hexdumps/od_hex_ints.txt +17 -0
  98. data/spec/formatting/binary/helpers/hexdumps/od_hex_quads.txt +17 -0
  99. data/spec/formatting/binary/helpers/hexdumps/od_hex_shorts.txt +17 -0
  100. data/spec/formatting/binary/helpers/hexdumps/od_octal_bytes.txt +17 -0
  101. data/spec/formatting/binary/helpers/hexdumps/od_octal_ints.txt +17 -0
  102. data/spec/formatting/binary/helpers/hexdumps/od_octal_quads.txt +17 -0
  103. data/spec/formatting/binary/helpers/hexdumps/od_octal_shorts.txt +17 -0
  104. data/spec/formatting/binary/helpers/hexdumps/od_repeated.txt +6 -0
  105. data/spec/formatting/binary/helpers/hexdumps/repeated.bin +1 -0
  106. data/spec/formatting/binary/integer_spec.rb +140 -0
  107. data/spec/formatting/binary/string_spec.rb +306 -0
  108. data/spec/formatting/digest/string_spec.rb +82 -0
  109. data/spec/formatting/http/integer_spec.rb +42 -0
  110. data/spec/formatting/http/string_spec.rb +76 -0
  111. data/spec/formatting/text/array_spec.rb +105 -0
  112. data/spec/formatting/text/string_spec.rb +180 -0
  113. data/spec/network/http/http_spec.rb +280 -0
  114. data/spec/network/http/proxy_spec.rb +150 -0
  115. data/spec/network/network_spec.rb +8 -0
  116. data/spec/network/ssl_spec.rb +14 -0
  117. data/spec/path_spec.rb +84 -0
  118. data/spec/spec_helper.rb +4 -0
  119. data/spec/support_spec.rb +8 -0
  120. data/spec/templates/classes/example_erb.rb +11 -0
  121. data/spec/templates/classes/example_template.rb +35 -0
  122. data/spec/templates/erb_spec.rb +21 -0
  123. data/spec/templates/helpers/data.rb +9 -0
  124. data/spec/templates/helpers/data/includes/_relative.erb +1 -0
  125. data/spec/templates/helpers/data/templates/example.erb +1 -0
  126. data/spec/templates/template_spec.rb +54 -0
  127. 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