ronin-support 0.4.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +11 -0
  3. data/.github/workflows/ruby.yml +28 -0
  4. data/.ruby-version +1 -0
  5. data/.yardopts +1 -1
  6. data/ChangeLog.md +121 -33
  7. data/Gemfile +17 -18
  8. data/README.md +57 -33
  9. data/Rakefile +10 -3
  10. data/gemspec.yml +16 -7
  11. data/lib/ronin/binary.rb +21 -0
  12. data/lib/ronin/binary/hexdump.rb +20 -0
  13. data/lib/ronin/binary/hexdump/parser.rb +403 -0
  14. data/lib/ronin/binary/struct.rb +567 -0
  15. data/lib/ronin/binary/template.rb +454 -0
  16. data/lib/ronin/extensions.rb +5 -5
  17. data/lib/ronin/extensions/enumerable.rb +5 -5
  18. data/lib/ronin/extensions/file.rb +39 -33
  19. data/lib/ronin/extensions/ip_addr.rb +29 -31
  20. data/lib/ronin/extensions/kernel.rb +5 -5
  21. data/lib/ronin/extensions/meta.rb +5 -5
  22. data/lib/ronin/extensions/regexp.rb +50 -5
  23. data/lib/ronin/extensions/resolv.rb +7 -9
  24. data/lib/ronin/extensions/string.rb +10 -10
  25. data/lib/ronin/formatting.rb +5 -5
  26. data/lib/ronin/formatting/binary.rb +5 -5
  27. data/lib/ronin/formatting/digest.rb +5 -5
  28. data/lib/ronin/formatting/extensions.rb +5 -5
  29. data/lib/ronin/formatting/extensions/binary.rb +7 -5
  30. data/lib/ronin/formatting/extensions/binary/array.rb +61 -0
  31. data/lib/ronin/formatting/extensions/binary/base64.rb +106 -0
  32. data/lib/ronin/formatting/extensions/binary/file.rb +44 -11
  33. data/lib/ronin/formatting/extensions/binary/float.rb +65 -0
  34. data/lib/ronin/formatting/extensions/binary/integer.rb +66 -50
  35. data/lib/ronin/formatting/extensions/binary/string.rb +81 -205
  36. data/lib/ronin/formatting/extensions/digest.rb +5 -5
  37. data/lib/ronin/formatting/extensions/digest/file.rb +5 -5
  38. data/lib/ronin/formatting/extensions/digest/string.rb +5 -5
  39. data/lib/ronin/formatting/extensions/html.rb +5 -5
  40. data/lib/ronin/formatting/extensions/html/integer.rb +9 -13
  41. data/lib/ronin/formatting/extensions/html/string.rb +31 -39
  42. data/lib/ronin/formatting/extensions/http.rb +5 -5
  43. data/lib/ronin/formatting/extensions/http/integer.rb +6 -6
  44. data/lib/ronin/formatting/extensions/http/string.rb +7 -7
  45. data/lib/ronin/formatting/extensions/sql.rb +5 -5
  46. data/lib/ronin/formatting/extensions/sql/string.rb +22 -24
  47. data/lib/ronin/formatting/extensions/text.rb +5 -5
  48. data/lib/ronin/formatting/extensions/text/array.rb +13 -11
  49. data/lib/ronin/formatting/extensions/text/string.rb +70 -13
  50. data/lib/ronin/formatting/html.rb +5 -5
  51. data/lib/ronin/formatting/http.rb +5 -5
  52. data/lib/ronin/formatting/sql.rb +5 -5
  53. data/lib/ronin/formatting/text.rb +5 -5
  54. data/lib/ronin/fuzzing.rb +5 -5
  55. data/lib/ronin/fuzzing/extensions.rb +5 -5
  56. data/lib/ronin/fuzzing/extensions/string.rb +42 -213
  57. data/lib/ronin/fuzzing/fuzzer.rb +110 -0
  58. data/lib/ronin/fuzzing/fuzzing.rb +33 -26
  59. data/lib/ronin/fuzzing/mutator.rb +161 -0
  60. data/lib/ronin/fuzzing/repeater.rb +81 -0
  61. data/lib/ronin/fuzzing/template.rb +133 -0
  62. data/lib/ronin/mixin.rb +2 -2
  63. data/lib/ronin/network.rb +7 -5
  64. data/lib/ronin/network/dns.rb +64 -24
  65. data/lib/ronin/network/esmtp.rb +5 -5
  66. data/lib/ronin/network/extensions.rb +5 -5
  67. data/lib/ronin/network/extensions/dns.rb +5 -5
  68. data/lib/ronin/network/extensions/dns/net.rb +5 -5
  69. data/lib/ronin/network/extensions/esmtp.rb +5 -5
  70. data/lib/ronin/network/extensions/esmtp/net.rb +5 -5
  71. data/lib/ronin/network/extensions/http.rb +5 -5
  72. data/lib/ronin/network/extensions/http/net.rb +5 -5
  73. data/lib/ronin/network/extensions/http/uri/http.rb +5 -5
  74. data/lib/ronin/network/extensions/imap.rb +5 -5
  75. data/lib/ronin/network/extensions/imap/net.rb +5 -5
  76. data/lib/ronin/network/extensions/pop3.rb +5 -5
  77. data/lib/ronin/network/extensions/pop3/net.rb +5 -5
  78. data/lib/ronin/network/extensions/smtp.rb +5 -5
  79. data/lib/ronin/network/extensions/smtp/net.rb +5 -5
  80. data/lib/ronin/network/extensions/ssl.rb +5 -5
  81. data/lib/ronin/network/extensions/ssl/net.rb +5 -5
  82. data/lib/ronin/network/extensions/tcp.rb +5 -5
  83. data/lib/ronin/network/extensions/tcp/net.rb +5 -5
  84. data/lib/ronin/network/extensions/telnet.rb +5 -5
  85. data/lib/ronin/network/extensions/telnet/net.rb +5 -5
  86. data/lib/ronin/network/extensions/udp.rb +5 -5
  87. data/lib/ronin/network/extensions/udp/net.rb +5 -5
  88. data/lib/ronin/network/ftp.rb +149 -0
  89. data/lib/ronin/network/http.rb +5 -5
  90. data/lib/ronin/network/http/exceptions.rb +5 -5
  91. data/lib/ronin/network/http/exceptions/unknown_request.rb +5 -5
  92. data/lib/ronin/network/http/http.rb +65 -70
  93. data/lib/ronin/network/http/proxy.rb +5 -5
  94. data/lib/ronin/network/imap.rb +16 -15
  95. data/lib/ronin/network/mixins.rb +6 -5
  96. data/lib/ronin/network/mixins/dns.rb +5 -5
  97. data/lib/ronin/network/mixins/esmtp.rb +5 -5
  98. data/lib/ronin/network/mixins/ftp.rb +155 -0
  99. data/lib/ronin/network/mixins/http.rb +58 -587
  100. data/lib/ronin/network/mixins/imap.rb +5 -5
  101. data/lib/ronin/network/mixins/mixin.rb +5 -5
  102. data/lib/ronin/network/mixins/pop3.rb +5 -5
  103. data/lib/ronin/network/mixins/smtp.rb +5 -5
  104. data/lib/ronin/network/mixins/ssl.rb +5 -5
  105. data/lib/ronin/network/mixins/tcp.rb +43 -10
  106. data/lib/ronin/network/mixins/telnet.rb +5 -5
  107. data/lib/ronin/network/mixins/udp.rb +126 -6
  108. data/lib/ronin/network/mixins/unix.rb +279 -0
  109. data/lib/ronin/network/network.rb +5 -5
  110. data/lib/ronin/network/pop3.rb +10 -10
  111. data/lib/ronin/network/proxy.rb +578 -0
  112. data/lib/ronin/network/smtp.rb +5 -5
  113. data/lib/ronin/network/smtp/email.rb +6 -6
  114. data/lib/ronin/network/smtp/smtp.rb +12 -13
  115. data/lib/ronin/network/ssl.rb +16 -17
  116. data/lib/ronin/network/tcp.rb +7 -310
  117. data/lib/ronin/network/tcp/proxy.rb +417 -0
  118. data/lib/ronin/network/tcp/tcp.rb +452 -0
  119. data/lib/ronin/network/telnet.rb +34 -28
  120. data/lib/ronin/network/udp.rb +7 -271
  121. data/lib/ronin/network/udp/proxy.rb +191 -0
  122. data/lib/ronin/network/udp/udp.rb +452 -0
  123. data/lib/ronin/network/unix.rb +286 -0
  124. data/lib/ronin/path.rb +35 -39
  125. data/lib/ronin/spec/ui/output.rb +6 -12
  126. data/lib/ronin/support.rb +6 -5
  127. data/lib/ronin/support/inflector.rb +8 -12
  128. data/lib/ronin/support/support.rb +7 -5
  129. data/lib/ronin/support/version.rb +6 -6
  130. data/lib/ronin/templates.rb +5 -5
  131. data/lib/ronin/templates/erb.rb +5 -5
  132. data/lib/ronin/templates/template.rb +5 -5
  133. data/lib/ronin/ui/output.rb +5 -5
  134. data/lib/ronin/ui/output/helpers.rb +42 -28
  135. data/lib/ronin/ui/output/output.rb +17 -21
  136. data/lib/ronin/ui/output/terminal.rb +5 -5
  137. data/lib/ronin/ui/output/terminal/color.rb +15 -9
  138. data/lib/ronin/ui/output/terminal/raw.rb +5 -5
  139. data/lib/ronin/ui/shell.rb +8 -11
  140. data/lib/ronin/wordlist.rb +110 -30
  141. data/ronin-support.gemspec +39 -109
  142. data/spec/binary/hexdump/helpers/hexdumps.rb +13 -0
  143. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/ascii.bin +0 -0
  144. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_decimal_shorts.txt +0 -0
  145. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_bytes.txt +0 -0
  146. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_hex_shorts.txt +0 -0
  147. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_bytes.txt +0 -0
  148. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_octal_shorts.txt +0 -0
  149. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/hexdump_repeated.txt +0 -0
  150. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_bytes.txt +0 -0
  151. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_ints.txt +0 -0
  152. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_quads.txt +0 -0
  153. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_decimal_shorts.txt +0 -0
  154. data/spec/binary/hexdump/helpers/hexdumps/od_doubles.txt +17 -0
  155. data/spec/binary/hexdump/helpers/hexdumps/od_floats.txt +17 -0
  156. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_bytes.txt +0 -0
  157. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_ints.txt +0 -0
  158. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_quads.txt +0 -0
  159. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_hex_shorts.txt +0 -0
  160. data/spec/binary/hexdump/helpers/hexdumps/od_named_chars.txt +17 -0
  161. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_bytes.txt +0 -0
  162. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_ints.txt +0 -0
  163. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_quads.txt +0 -0
  164. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_octal_shorts.txt +0 -0
  165. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/od_repeated.txt +0 -0
  166. data/spec/{formatting/binary → binary/hexdump}/helpers/hexdumps/repeated.bin +0 -0
  167. data/spec/binary/hexdump/parser_spec.rb +302 -0
  168. data/spec/binary/struct_spec.rb +496 -0
  169. data/spec/binary/template_spec.rb +416 -0
  170. data/spec/extensions/enumerable_spec.rb +4 -4
  171. data/spec/extensions/file_spec.rb +12 -14
  172. data/spec/extensions/ip_addr_spec.rb +76 -50
  173. data/spec/extensions/kernel_spec.rb +7 -7
  174. data/spec/extensions/regexp_spec.rb +119 -59
  175. data/spec/extensions/resolv_spec.rb +2 -2
  176. data/spec/extensions/string_spec.rb +31 -30
  177. data/spec/formatting/binary/array_spec.rb +26 -0
  178. data/spec/formatting/binary/base64_spec.rb +50 -0
  179. data/spec/formatting/binary/float_spec.rb +36 -0
  180. data/spec/formatting/binary/integer_spec.rb +76 -50
  181. data/spec/formatting/binary/string_spec.rb +91 -198
  182. data/spec/formatting/digest/string_spec.rb +5 -5
  183. data/spec/formatting/html/integer_spec.rb +6 -6
  184. data/spec/formatting/html/string_spec.rb +10 -10
  185. data/spec/formatting/http/integer_spec.rb +3 -3
  186. data/spec/formatting/http/string_spec.rb +5 -5
  187. data/spec/formatting/sql/string_spec.rb +21 -19
  188. data/spec/formatting/text/array_spec.rb +15 -15
  189. data/spec/formatting/text/string_spec.rb +58 -28
  190. data/spec/fuzzing/extensions/string_spec.rb +87 -0
  191. data/spec/fuzzing/fuzzer_spec.rb +109 -0
  192. data/spec/fuzzing/fuzzing_spec.rb +24 -0
  193. data/spec/fuzzing/mutator_spec.rb +112 -0
  194. data/spec/fuzzing/repeater_spec.rb +57 -0
  195. data/spec/fuzzing/template_spec.rb +54 -0
  196. data/spec/mixin_spec.rb +10 -12
  197. data/spec/network/dns_spec.rb +89 -23
  198. data/spec/network/ftp_spec.rb +81 -0
  199. data/spec/network/http/http_spec.rb +237 -144
  200. data/spec/network/http/proxy_spec.rb +37 -37
  201. data/spec/network/network_spec.rb +2 -2
  202. data/spec/network/proxy_spec.rb +121 -0
  203. data/spec/network/shared/unix_server.rb +31 -0
  204. data/spec/network/smtp/email_spec.rb +14 -14
  205. data/spec/network/ssl_spec.rb +53 -3
  206. data/spec/network/tcp/proxy_spec.rb +118 -0
  207. data/spec/network/tcp/tcp_spec.rb +316 -0
  208. data/spec/network/telnet_spec.rb +67 -0
  209. data/spec/network/udp/udp_spec.rb +298 -0
  210. data/spec/network/unix_spec.rb +182 -0
  211. data/spec/path_spec.rb +43 -18
  212. data/spec/spec_helper.rb +2 -3
  213. data/spec/support/inflector_spec.rb +4 -4
  214. data/spec/support_spec.rb +1 -1
  215. data/spec/templates/erb_spec.rb +3 -3
  216. data/spec/templates/template_spec.rb +10 -10
  217. data/spec/ui/shell_spec.rb +15 -15
  218. data/spec/wordlist_spec.rb +80 -19
  219. metadata +176 -121
  220. data/.gemtest +0 -0
  221. data/spec/formatting/binary/helpers/hexdumps.rb +0 -16
  222. data/spec/fuzzing/string_spec.rb +0 -158
  223. data/spec/network/tcp_spec.rb +0 -247
  224. data/spec/network/udp_spec.rb +0 -248
data/gemspec.yml CHANGED
@@ -1,18 +1,27 @@
1
1
  name: ronin-support
2
- summary: A support library for Ronin.
3
- description:
4
- Ronin Support is a support library for Ronin. Ronin Support contains many
2
+ summary: A support library for ronin-rb.
3
+ description: |
4
+ ronin-support is a support library for ronin-rb. ronin-support contains many
5
5
  of the convenience methods used by Ronin and additional libraries.
6
6
 
7
- license: LGPL-3
7
+ It's like activesupport, but for hacking!
8
+
9
+ license: LGPL-3.0
8
10
  authors: Postmodern
9
11
  email: postmodern.mod3@gmail.com
10
- homepage: http://github.com/ronin-ruby/ronin-support
12
+ homepage: https://ronin-rb.dev
11
13
  has_yard: true
12
14
 
15
+ metadata:
16
+ documentation_uri: https://ronin-rb.dev/docs/ronin-support/frames
17
+ source_code_uri: https://github.com/ronin-rb/ronin-support
18
+ bug_tracker_uri: https://github.com/ronin-rb/ronin-support/issues
19
+ changelog_uri: https://github.com/ronin-rb/ronin-support/blob/master/ChangeLog.md
20
+
13
21
  required_ruby_version: ">= 1.8.7"
14
22
 
15
23
  dependencies:
24
+ net-telnet: ~> 0.1
16
25
  chars: ~> 0.2
17
26
  hexdump: ~> 0.1
18
27
  combinatorics: ~> 0.4
@@ -21,6 +30,6 @@ dependencies:
21
30
  parameters: ~> 0.4
22
31
 
23
32
  development_dependencies:
24
- bundler: ~> 1.0
25
- yard: ~> 0.7
33
+ bundler: ~> 2.0
34
+ yard: ~> 0.9
26
35
  yard-parameters: ~> 0.1
@@ -0,0 +1,21 @@
1
+ #
2
+ # Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of ronin-support.
5
+ #
6
+ # ronin-support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ronin-support 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
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ronin-support. If not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'ronin/binary/template'
21
+ require 'ronin/binary/struct'
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of ronin-support.
5
+ #
6
+ # ronin-support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ronin-support 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
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ronin-support. If not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'ronin/binary/hexdump/parser'
@@ -0,0 +1,403 @@
1
+ #
2
+ # Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
3
+ #
4
+ # This file is part of ronin-support.
5
+ #
6
+ # ronin-support is free software: you can redistribute it and/or modify
7
+ # it under the terms of the GNU Lesser General Public License as published
8
+ # by the Free Software Foundation, either version 3 of the License, or
9
+ # (at your option) any later version.
10
+ #
11
+ # ronin-support 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
14
+ # GNU Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public License
17
+ # along with ronin-support. If not, see <https://www.gnu.org/licenses/>.
18
+ #
19
+
20
+ require 'chars'
21
+
22
+ module Ronin
23
+ module Binary
24
+ module Hexdump
25
+ #
26
+ # @since 0.5.0
27
+ #
28
+ # @api semipublic
29
+ #
30
+ class Parser
31
+
32
+ # Bases for various encodings
33
+ BASES = {
34
+ :binary => 2,
35
+ :octal => 8,
36
+ :octal_bytes => 8,
37
+ :octal_shorts => 8,
38
+ :octal_ints => 8,
39
+ :octal_quads => 8,
40
+ :decimal => 10,
41
+ :decimal_bytes => 10,
42
+ :decimal_shorts => 10,
43
+ :decimal_ints => 10,
44
+ :decimal_quads => 10,
45
+ :hex => 16,
46
+ :hex_bytes => 16,
47
+ :hex_shorts => 16,
48
+ :hex_ints => 16,
49
+ :hex_quads => 16,
50
+ :named_chars => 16,
51
+ :floats => 10,
52
+ :doubles => 10
53
+ }
54
+
55
+ # Word-sizes for various encodings
56
+ WORD_SIZES = {
57
+ :binary => 1,
58
+ :octal_bytes => 1,
59
+ :decimal_bytes => 1,
60
+ :hex_bytes => 1,
61
+ :hex_chars => 1,
62
+ :named_chars => 1,
63
+ :octal_shorts => 2,
64
+ :decimal_shorts => 2,
65
+ :hex_shorts => 2,
66
+ :octal_ints => 4,
67
+ :decimal_ints => 4,
68
+ :hex_ints => 4,
69
+ :octal_quads => 8,
70
+ :decimal_quads => 8,
71
+ :hex_quads => 8,
72
+ :floats => 4,
73
+ :doubles => 8
74
+ }
75
+
76
+ # The format to parse (`:hexdump` / `:od`)
77
+ attr_reader :format
78
+
79
+ # The encoding of the hexdump data
80
+ attr_reader :encoding
81
+
82
+ # The type of data to parse (`:integer` / `:float`)
83
+ attr_reader :type
84
+
85
+ # The endianness of data to parse (`:little`, `:big`, `:network`)
86
+ attr_reader :endian
87
+
88
+ # The size of words to parse
89
+ attr_reader :word_size
90
+
91
+ # The base of all addresses to parse
92
+ attr_reader :address_base
93
+
94
+ # The base of all words to parse
95
+ attr_reader :base
96
+
97
+ #
98
+ # Initializes the hexdump parser.
99
+ #
100
+ # @param [Hash] options
101
+ # Additional options.
102
+ #
103
+ # @option options [Symbol] :format
104
+ # The expected format of the hexdump. Must be either `:od` or
105
+ # `:hexdump`.
106
+ #
107
+ # @option options [Symbol] :encoding
108
+ # Denotes the encoding used for the bytes within the hexdump.
109
+ # Must be one of the following:
110
+ #
111
+ # * `:binary`
112
+ # * `:octal`
113
+ # * `:octal_bytes`
114
+ # * `:octal_shorts`
115
+ # * `:octal_ints`
116
+ # * `:octal_quads` (Ruby 1.9 only)
117
+ # * `:decimal`
118
+ # * `:decimal_bytes`
119
+ # * `:decimal_shorts`
120
+ # * `:decimal_ints`
121
+ # * `:decimal_quads` (Ruby 1.9 only)
122
+ # * `:hex`
123
+ # * `:hex_chars`
124
+ # * `:hex_bytes`
125
+ # * `:hex_shorts`
126
+ # * `:hex_ints`
127
+ # * `:hex_quads` (Ruby 1.9 only)
128
+ # * `:named_chars`
129
+ # * `:floats`
130
+ # * `:doubles`
131
+ #
132
+ # @option options [:little, :big, :network] :endian (:little)
133
+ # The endianness of the words.
134
+ #
135
+ def initialize(options={})
136
+ @format = options[:format]
137
+ @encoding = options[:encoding]
138
+
139
+ @type = case @encoding
140
+ when :floats, :doubles then :float
141
+ else :integer
142
+ end
143
+ @endian = options.fetch(:endian,:little)
144
+
145
+ case @format
146
+ when :od
147
+ @address_base = 8
148
+ @base = 8
149
+ @word_size = 2
150
+ when :hexdump
151
+ @address_base = 16
152
+ @base = 16
153
+ @word_size = 2
154
+ else
155
+ @address_base = 16
156
+ @base = 16
157
+ @word_size = 1
158
+ end
159
+
160
+ if @encoding
161
+ @base = BASES.fetch(options[:encoding])
162
+ @word_size = WORD_SIZES.fetch(options[:encoding])
163
+ end
164
+
165
+ @chars = case @encoding
166
+ when :hex_chars then CHARS.merge(ESCAPED_CHARS)
167
+ when :named_chars then CHARS.merge(NAMED_CHARS)
168
+ end
169
+ end
170
+
171
+ #
172
+ # Parses a hexdump.
173
+ #
174
+ # @param [#each_line] hexdump
175
+ # The hexdump output.
176
+ #
177
+ # @return [String]
178
+ # The raw-data from the hexdump.
179
+ #
180
+ def parse(hexdump)
181
+ current_addr = last_addr = first_addr = nil
182
+ repeated = false
183
+
184
+ segment = ''
185
+ buffer = ''
186
+
187
+ hexdump.each_line do |line|
188
+ if @format == :hexdump
189
+ line = line.gsub(/\s+\|.+\|\s*$/,'')
190
+ end
191
+
192
+ words = line.split
193
+
194
+ if words.first == '*'
195
+ repeated = true
196
+ elsif words.length > 0
197
+ current_addr = parse_address(words.shift)
198
+ first_addr ||= current_addr
199
+
200
+ if repeated
201
+ (((current_addr - last_addr) / segment.length) - 1).times do
202
+ buffer << segment
203
+ end
204
+
205
+ repeated = false
206
+ end
207
+
208
+ segment = pack(words.map { |word| parse_word(word) })
209
+
210
+ buffer << segment
211
+ last_addr = current_addr
212
+ end
213
+ end
214
+
215
+ return buffer[0,last_addr - first_addr]
216
+ end
217
+
218
+ protected
219
+
220
+ # Visible characters
221
+ CHARS = Hash[Chars::VISIBLE.chars.sort.zip(Chars::VISIBLE.bytes.sort)]
222
+
223
+ # Escaped characters
224
+ ESCAPED_CHARS = {
225
+ '\0' => 0x00,
226
+ '\a' => 0x07,
227
+ '\b' => 0x08,
228
+ '\t' => 0x09,
229
+ '\n' => 0x0a,
230
+ '\v' => 0x0b,
231
+ '\f' => 0x0c,
232
+ '\r' => 0x0d
233
+ }
234
+
235
+ # od named characters
236
+ NAMED_CHARS = {
237
+ 'nul' => 0x00,
238
+ 'soh' => 0x01,
239
+ 'stx' => 0x02,
240
+ 'etx' => 0x03,
241
+ 'eot' => 0x04,
242
+ 'enq' => 0x05,
243
+ 'ack' => 0x06,
244
+ 'bel' => 0x07,
245
+ 'bs' => 0x08,
246
+ 'ht' => 0x09,
247
+ 'lf' => 0x0a,
248
+ 'nl' => 0x0a,
249
+ 'vt' => 0x0b,
250
+ 'ff' => 0x0c,
251
+ 'cr' => 0x0d,
252
+ 'so' => 0x0e,
253
+ 'si' => 0x0f,
254
+ 'dle' => 0x10,
255
+ 'dc1' => 0x11,
256
+ 'dc2' => 0x12,
257
+ 'dc3' => 0x13,
258
+ 'dc4' => 0x14,
259
+ 'nak' => 0x15,
260
+ 'syn' => 0x16,
261
+ 'etb' => 0x17,
262
+ 'can' => 0x18,
263
+ 'em' => 0x19,
264
+ 'sub' => 0x1a,
265
+ 'esc' => 0x1b,
266
+ 'fs' => 0x1c,
267
+ 'gs' => 0x1d,
268
+ 'rs' => 0x1e,
269
+ 'us' => 0x1f,
270
+ 'sp' => 0x20,
271
+ 'del' => 0x7f
272
+ }
273
+
274
+ # `Array#pack` codes for various types/endianness/word-sizes
275
+ FORMATS = {
276
+ :integer => {
277
+ :little => {
278
+ 1 => 'C',
279
+ 2 => (RUBY_VERSION > '1.9.' ? 'S<' : 'v'),
280
+ 4 => (RUBY_VERSION > '1.9.' ? 'L<' : 'V'),
281
+ 8 => 'Q<' # Ruby 1.9 only
282
+ },
283
+
284
+ :big => {
285
+ 1 => 'C',
286
+ 2 => (RUBY_VERSION > '1.9.' ? 'S>' : 'n'),
287
+ 4 => (RUBY_VERSION > '1.9.' ? 'L>' : 'N'),
288
+ 8 => 'Q>' # Ruby 1.9 only
289
+ }
290
+ },
291
+
292
+ :float => {
293
+ :little => {
294
+ 4 => 'e',
295
+ 8 => 'E'
296
+ },
297
+
298
+ :big => {
299
+ 4 => 'g',
300
+ 8 => 'G'
301
+ }
302
+ }
303
+ }
304
+
305
+ # alias network endianness to big endian
306
+ FORMATS[:integer][:network] = FORMATS[:integer][:big]
307
+ FORMATS[:float][:network] = FORMATS[:float][:big]
308
+
309
+ #
310
+ # Parses an address.
311
+ #
312
+ # @param [String] address
313
+ # The text of the address.
314
+ #
315
+ # @return [Integer]
316
+ # The parsed address.
317
+ #
318
+ # @api private
319
+ #
320
+ def parse_address(address)
321
+ address.to_i(@address_base)
322
+ end
323
+
324
+ #
325
+ # Parses a character or hex-byte.
326
+ #
327
+ # @param [String] char
328
+ # The character to parse.
329
+ #
330
+ # @return [Integer]
331
+ # The parsed byte.
332
+ #
333
+ def parse_char(char)
334
+ @chars.fetch(char) do |hex_byte|
335
+ hex_byte.to_i(16)
336
+ end
337
+ end
338
+
339
+ #
340
+ # Parses an Integer.
341
+ #
342
+ # @param [String] int
343
+ # The text of the Integer.
344
+ #
345
+ # @return [Integer]
346
+ # The parsed word.
347
+ #
348
+ # @api private
349
+ #
350
+ def parse_int(int)
351
+ if @chars then parse_char(int)
352
+ else int.to_i(@base)
353
+ end
354
+ end
355
+
356
+ #
357
+ # Parses a float.
358
+ #
359
+ # @param [String] float
360
+ # The text of the float.
361
+ #
362
+ # @return [Float]
363
+ # The parsed float.
364
+ #
365
+ def parse_float(float)
366
+ float.to_f
367
+ end
368
+
369
+ #
370
+ # Parses a word within a segment.
371
+ #
372
+ # @param [String] word
373
+ # The word to parse.
374
+ #
375
+ # @return [Integer, Float]
376
+ # The value of the word.
377
+ #
378
+ def parse_word(word)
379
+ case @type
380
+ when :integer then parse_int(word)
381
+ when :float then parse_float(word)
382
+ end
383
+ end
384
+
385
+ #
386
+ # Packs a segment back into bytes.
387
+ #
388
+ # @param [Array<Integer, Float>] values
389
+ # A segment of words.
390
+ #
391
+ # @return [String]
392
+ # The packed segment.
393
+ #
394
+ # @api private
395
+ #
396
+ def pack(values)
397
+ values.pack(FORMATS[@type][@endian][@word_size] * values.length)
398
+ end
399
+
400
+ end
401
+ end
402
+ end
403
+ end