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