zsteg 0.1.1 → 0.2.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 68101c2a1131eef8343b68bc8176274d0d8d0a3e
4
- data.tar.gz: 090dabdfd430f5ef61dd2f70c84610842bdfffea
2
+ SHA256:
3
+ metadata.gz: 03b8c9494bd4dfb5953973438b62cd909abb1a0d6fc46363928e9a3773e1e47a
4
+ data.tar.gz: a46faa826bc3781860881b4c15d9e6c04fb86da6dedfd5df2487f62fa09fcbf1
5
5
  SHA512:
6
- metadata.gz: fa1a8dd3e81074ce70c3019d08f27d33a31b245b0f2ca12b7f28c2824a08fac1c0740b3bdcdcd86f83e38888267c6f0524a590b3dc1511ea62702468a308a76e
7
- data.tar.gz: c0f4e62456de78b373695f2cbd0f8ae4ea1e9c13f959a5554f0472eb7d35847c039331a5c5ea724fcbcfed1c80db09903f17c6428bb08bafd7ad0b224d8eb202
6
+ metadata.gz: 5f4243a62114c5098d56c59d273deaff5addf89b334377ba0d63032a6aee9759720ff3772805ae6a445179d3487a40b436024cc1c431f9a723e8de5140e2f683
7
+ data.tar.gz: 86eed1938f6c92812ab461f25b8647a25034e06b1b8c23b81187c253ef987de84d49a5e6d1521874fc480cf9cbe136559d921ab91ea8d2501383a13688dcb49d
data/Gemfile CHANGED
@@ -1,10 +1,10 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem 'zpng', ">= 0.2.3"
3
+ gem 'zpng', ">= 0.3.1"
4
4
  gem "iostruct"
5
5
 
6
6
  group :development do
7
- gem "rspec", ">= 2.8.0"
8
- gem "bundler", ">= 1.0.0"
9
- gem "jeweler", "~> 1.8.4"
7
+ gem "rspec", "~> 3.9.0"
8
+ gem "bundler", "~> 2.2.3"
9
+ gem "jeweler", "~> 2.3.9"
10
10
  end
data/Gemfile.lock CHANGED
@@ -1,68 +1,85 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- addressable (2.3.5)
5
- builder (3.2.2)
6
- diff-lcs (1.1.3)
7
- faraday (0.8.8)
8
- multipart-post (~> 1.2.0)
9
- git (1.2.6)
10
- github_api (0.10.1)
11
- addressable
12
- faraday (~> 0.8.1)
13
- hashie (>= 1.2)
14
- multi_json (~> 1.4)
15
- nokogiri (~> 1.5.2)
16
- oauth2
17
- hashie (2.0.5)
18
- highline (1.6.19)
19
- httpauth (0.2.0)
20
- iostruct (0.0.1)
21
- jeweler (1.8.7)
4
+ addressable (2.4.0)
5
+ builder (3.2.4)
6
+ descendants_tracker (0.0.4)
7
+ thread_safe (~> 0.3, >= 0.3.1)
8
+ diff-lcs (1.4.4)
9
+ faraday (0.9.2)
10
+ multipart-post (>= 1.2, < 3)
11
+ git (1.8.1)
12
+ rchardet (~> 1.8)
13
+ github_api (0.16.0)
14
+ addressable (~> 2.4.0)
15
+ descendants_tracker (~> 0.0.4)
16
+ faraday (~> 0.8, < 0.10)
17
+ hashie (>= 3.4)
18
+ mime-types (>= 1.16, < 3.0)
19
+ oauth2 (~> 1.0)
20
+ hashie (4.1.0)
21
+ highline (2.0.3)
22
+ iostruct (0.0.4)
23
+ jeweler (2.3.9)
22
24
  builder
23
- bundler (~> 1.0)
25
+ bundler
24
26
  git (>= 1.2.5)
25
- github_api (= 0.10.1)
27
+ github_api (~> 0.16.0)
26
28
  highline (>= 1.6.15)
27
- nokogiri (= 1.5.10)
29
+ nokogiri (>= 1.5.10)
30
+ psych
28
31
  rake
29
32
  rdoc
30
- json (1.8.0)
31
- jwt (0.1.8)
32
- multi_json (>= 1.5)
33
- multi_json (1.8.0)
34
- multi_xml (0.5.5)
35
- multipart-post (1.2.0)
36
- nokogiri (1.5.10)
37
- oauth2 (0.9.2)
38
- faraday (~> 0.8)
39
- httpauth (~> 0.2)
40
- jwt (~> 0.1.4)
41
- multi_json (~> 1.0)
33
+ semver2
34
+ jwt (2.2.2)
35
+ mime-types (2.99.3)
36
+ mini_portile2 (2.5.0)
37
+ multi_json (1.15.0)
38
+ multi_xml (0.6.0)
39
+ multipart-post (2.1.1)
40
+ nokogiri (1.11.1)
41
+ mini_portile2 (~> 2.5.0)
42
+ racc (~> 1.4)
43
+ oauth2 (1.4.4)
44
+ faraday (>= 0.8, < 2.0)
45
+ jwt (>= 1.0, < 3.0)
46
+ multi_json (~> 1.3)
42
47
  multi_xml (~> 0.5)
43
- rack (~> 1.2)
44
- rack (1.5.2)
45
- rainbow (1.1.4)
46
- rake (10.1.0)
47
- rdoc (4.0.1)
48
- json (~> 1.4)
49
- rspec (2.12.0)
50
- rspec-core (~> 2.12.0)
51
- rspec-expectations (~> 2.12.0)
52
- rspec-mocks (~> 2.12.0)
53
- rspec-core (2.12.2)
54
- rspec-expectations (2.12.1)
55
- diff-lcs (~> 1.1.3)
56
- rspec-mocks (2.12.1)
57
- zpng (0.2.3)
48
+ rack (>= 1.2, < 3)
49
+ psych (3.3.0)
50
+ racc (1.5.2)
51
+ rack (2.2.3)
52
+ rainbow (3.0.0)
53
+ rake (13.0.3)
54
+ rchardet (1.8.0)
55
+ rdoc (6.3.0)
56
+ rspec (3.9.0)
57
+ rspec-core (~> 3.9.0)
58
+ rspec-expectations (~> 3.9.0)
59
+ rspec-mocks (~> 3.9.0)
60
+ rspec-core (3.9.3)
61
+ rspec-support (~> 3.9.3)
62
+ rspec-expectations (3.9.4)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.9.0)
65
+ rspec-mocks (3.9.1)
66
+ diff-lcs (>= 1.2.0, < 2.0)
67
+ rspec-support (~> 3.9.0)
68
+ rspec-support (3.9.4)
69
+ semver2 (3.4.2)
70
+ thread_safe (0.3.6)
71
+ zpng (0.3.2)
58
72
  rainbow
59
73
 
60
74
  PLATFORMS
61
75
  ruby
62
76
 
63
77
  DEPENDENCIES
64
- bundler (>= 1.0.0)
78
+ bundler (~> 2.2.3)
65
79
  iostruct
66
- jeweler (~> 1.8.4)
67
- rspec (>= 2.8.0)
68
- zpng (>= 0.2.3)
80
+ jeweler (~> 2.3.9)
81
+ rspec (~> 3.9.0)
82
+ zpng (>= 0.3.1)
83
+
84
+ BUNDLED WITH
85
+ 2.2.3
data/README.md CHANGED
@@ -29,17 +29,26 @@ Usage
29
29
  Usage: zsteg [options] filename.png [param_string]
30
30
 
31
31
  -c, --channels X channels (R/G/B/A) or any combination, comma separated
32
- valid values: r,g,b,a,rg,rgb,bgr,rgba,...
32
+ valid values: r,g,b,a,rg,bgr,rgba,r3g2b3,...
33
33
  -l, --limit N limit bytes checked, 0 = no limit (default: 256)
34
- -b, --bits N number of bits (1..8), single value or '1,3,5' or '1-8'
34
+ -b, --bits N number of bits, single int value or '1,3,5' or range '1-8'
35
+ advanced: specify individual bits like '00001110' or '0x88'
35
36
  --lsb least significant BIT comes first
36
37
  --msb most significant BIT comes first
37
38
  -P, --prime analyze/extract only prime bytes/pixels
39
+ --invert invert bits (XOR 0xff)
38
40
  -a, --all try all known methods
39
41
  -o, --order X pixel iteration order (default: 'auto')
40
42
  valid values: ALL,xy,yx,XY,YX,xY,Xy,bY,...
41
43
  -E, --extract NAME extract specified payload, NAME is like '1b,rgb,lsb'
42
44
 
45
+ --[no-]file use 'file' command to detect data type (default: YES)
46
+ --no-strings disable ASCII strings finding (default: enabled)
47
+ -s, --strings X ASCII strings find mode: first, all, longest, none
48
+ (default: first)
49
+ -n, --min-str-len X minimum string length (default: 8)
50
+ --shift N prepend N zero bits
51
+
43
52
  -v, --verbose Run verbosely (can be used multiple times)
44
53
  -q, --quiet Silent any warnings (can be used multiple times)
45
54
  -C, --[no-]color Force (or disable) color output (default: auto)
@@ -54,7 +63,8 @@ Examples
54
63
 
55
64
  # zsteg flower_rgb3.png
56
65
 
57
- 3b,rgb,lsb,xy .. text: "SuperSecretMessage"
66
+ imagedata .. file: 370 XA sysV pure executable not stripped - version 768
67
+ b3,rgb,lsb,xy .. text: "SuperSecretMessage"
58
68
 
59
69
  ### Multi-result file
60
70
 
@@ -65,16 +75,34 @@ Examples
65
75
  meta A .. [same as "meta F"]
66
76
  meta date:create .. text: "2012-03-15T23:32:46+07:00"
67
77
  meta date:modify .. text: "2012-03-15T23:32:14+07:00"
68
- 1b,r,lsb,xy .. text: "Second cat is Marussia"
69
- 1b,g,lsb,xy .. text: "Good, but look a bit deeper..."
70
- 1b,bgr,lsb,xy .. text: "MF_WIhf>"
71
- 2b,g,lsb,xy .. text: "VHello, third kitten is Bessy"
78
+ imagedata .. file: 68K BCS executable
79
+ b1,r,lsb,xy .. text: "Second cat is Marussia"
80
+ b1,g,lsb,xy .. text: "Good, but look a bit deeper..."
81
+ b1,bgr,lsb,xy .. text: "MF_WIhf>"
82
+ b2,g,lsb,xy .. text: "VHello, third kitten is Bessy"
72
83
 
73
84
  ### wbStego even distributed
74
85
 
75
86
  # zsteg wbstego/wbsteg_noenc_even.bmp 1b,lsb,bY -v
76
87
 
77
- 1b,lsb,bY .. <wbStego size=22, data="xtSuperSecretMessage\n", even=true, mix=true, controlbyte="t">
88
+ imagedata .. file: FoxPro FPT, blocks size 1, next free block index 65537
89
+ 00000000: 00 01 00 01 00 00 00 01 00 00 00 00 00 00 00 00 |................|
90
+ 00000010: 00 00 00 00 00 00 00 00 00 00 00 01 00 01 01 00 |................|
91
+ 00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
92
+ 00000030: 00 01 01 01 00 01 00 00 00 00 00 00 01 01 00 01 |................|
93
+ 00000040: 01 00 01 01 00 01 00 01 00 01 01 01 01 00 00 00 |................|
94
+ 00000050: 00 00 00 01 01 01 01 00 01 00 01 00 00 00 00 01 |................|
95
+ 00000060: 00 00 01 01 01 00 00 01 00 01 01 01 00 01 00 00 |................|
96
+ 00000070: 01 01 01 00 01 00 00 00 00 00 01 01 01 00 00 00 |................|
97
+ 00000080: 00 01 00 01 00 00 01 01 01 01 00 00 00 01 01 00 |................|
98
+ 00000090: 00 01 00 01 00 01 01 00 01 00 00 01 00 01 00 00 |................|
99
+ 000000a0: 00 01 01 01 00 01 00 01 01 01 00 01 00 00 00 01 |................|
100
+ 000000b0: 01 00 01 00 00 01 00 01 00 01 01 01 00 00 00 00 |................|
101
+ 000000c0: 01 00 00 00 00 01 00 00 01 01 00 00 01 00 00 00 |................|
102
+ 000000d0: 00 00 01 00 00 01 01 01 00 01 01 00 00 01 00 01 |................|
103
+ 000000e0: 01 01 01 01 01 01 01 00 00 00 00 00 01 00 00 00 |................|
104
+ 000000f0: 00 01 01 01 00 00 01 00 00 00 01 01 00 01 00 01 |................|
105
+ b1,lsb,bY .. <wbStego size=22, data="xtSuperSecretMessage\n", even=true, mix=true, controlbyte="t">
78
106
  00000000: 51 00 00 16 00 00 74 0d b5 78 1e a1 39 74 e8 38 |Q.....t..x..9t.8|
79
107
  00000010: 53 c6 56 94 75 d1 a5 70 84 c8 27 65 fe 08 72 35 |S.V.u..p..'e..r5|
80
108
  00000020: 1f 3e 53 5d a7 65 8b 6e 3b 63 6b 1d bf 72 ee 27 |.>S].e.n;ck..r.'|
@@ -86,7 +114,7 @@ Examples
86
114
 
87
115
  # zsteg wbstego/wbsteg_blowfish_pass_1.bmp 1b,lsb,bY -v
88
116
 
89
- 1b,lsb,bY .. <wbStego size=26, data="\rC\xF5\xBF#\xFF[6\e\xB3"..., even=false, hdr="\x01", enc="Blowfish">
117
+ b1,lsb,bY .. <wbStego size=26, data="\rC\xF5\xBF#\xFF[6\e\xB3"..., even=false, hdr="\x01", enc="Blowfish">
90
118
  00000000: 1a 00 00 00 ff 01 01 0d 43 f5 bf 23 ff 5b 36 1b |........C..#.[6.|
91
119
  00000010: b3 17 42 4a 3f ba eb c7 ee 9c d7 7a 2b |..BJ?......z+ |
92
120
 
@@ -94,7 +122,7 @@ Examples
94
122
 
95
123
  # zsteg ndh2k12_sp113.bmp -b 1 -o yx -v
96
124
 
97
- 1b,rgb,lsb,yx .. zlib: data="%PDF-1.4\n%\xC3\xA4\xC3\xBC\xC3\xB6\xC3\x9F\n2 0 obj\n<</Length 3 0 R/Filter/FlateDecode>>\nstream\nx\x9C\x8DT\xC9n\xDB@\f\xBD\xCFW\xF0\x1C \x13\x92\xB3\x03\x86\x80\xC8K\xD1\xDE\\\b\xE8\xA1\xE8)K\x8B\xA2n\x91\\\xF2\xFB!5Zl\xD5v\v\x01\xD4\x90C\xBE\xF7\x86\x1A\n-\xC1\x9By\x01\x94'\x94`=d\xCF\xF0\xFA\x04_n\xE0\xF7\x10Gx\xFDn\xDA\xCE\xB0\x8F6\x80s$Y\xDD#\xDC\xED\b\x1CC\xF7\xBCBBF\x87^\xDE\xA1\xE9~\x9Amg\xF6\x8BZ\xCAYj", offset=4
125
+ b1,rgb,lsb,yx .. zlib: data="%PDF-1.4\n%\xC3\xA4\xC3\xBC\xC3\xB6\xC3\x9F\n2 0 obj\n<</Length 3 0 R/Filter/FlateDecode>>\nstream\nx\x9C\x8DT\xC9n\xDB@\f\xBD\xCFW\xF0\x1C \x13\x92\xB3\x03\x86\x80\xC8K\xD1\xDE\\\b\xE8\xA1...", offset=4, size=186
98
126
  00000000: 00 02 eb 9b 78 9c d4 b9 65 54 24 cc 92 36 58 b8 |....x...eT$..6X.|
99
127
  00000010: d3 68 e3 ee ee 4e e3 ee ee 0e 85 bb 3b dd 68 23 |.h...N......;.h#|
100
128
  00000020: 8d bb bb bb 3b 8d bb bb 3b 34 ee 6e 1f ef 7b ef |....;...;4.n..{.|
@@ -112,6 +140,11 @@ Examples
112
140
  000000e0: fd bb 13 a9 e6 3a c9 da 19 34 ae f0 43 bb 90 90 |.....:...4..C...|
113
141
  000000f0: 58 88 de 46 ce 91 6f aa 8d d9 7d b8 d6 88 a6 65 |X..F..o...}....e|
114
142
 
143
+ See also
144
+ --------
145
+ 1. https://29a.ch/photo-forensics/
146
+ 2. https://holloway.nz/steg/
147
+
115
148
  License
116
149
  -------
117
150
  Released under the MIT License. See the [LICENSE](https://github.com/zed-0xff/zsteg/blob/master/LICENSE.txt) file for further details.
data/README.md.tpl CHANGED
@@ -49,6 +49,11 @@ Examples
49
49
 
50
50
  % zsteg ndh2k12_sp113.bmp -b 1 -o yx -v
51
51
 
52
+ See also
53
+ --------
54
+ 1. https://29a.ch/photo-forensics/
55
+ 2. https://holloway.nz/steg/
56
+
52
57
  License
53
58
  -------
54
59
  Released under the MIT License. See the [LICENSE](https://github.com/zed-0xff/zsteg/blob/master/LICENSE.txt) file for further details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.3
data/lib/zsteg/checker.rb CHANGED
@@ -310,6 +310,8 @@ module ZSteg
310
310
  show_result result, params
311
311
  end
312
312
  if data.size > 0 && !result.is_a?(Result::OneChar) && !result.is_a?(Result::WholeText)
313
+ # newline if no results and want hexdump
314
+ puts if !result || result == []
313
315
  limit = (params[:limit] || @params[:limit]).to_i
314
316
  t = limit > 0 ? data[0,limit] : data
315
317
  print ZPNG::Hexdump.dump(t){ |x| x.prepend(" "*4) }
@@ -383,7 +385,7 @@ module ZSteg
383
385
  # t = data.
384
386
  # encode('UTF-16', 'UTF-8', :invalid => :replace, :replace => '').
385
387
  # encode!('UTF-8', 'UTF-16')
386
- # r = t.scan(/\p{Word}{#{MIN_TEXT_LENGTH},}/)
388
+ # r = t.scan(/\p{Word}{#{DEFAULT_MIN_STR_LEN},}/)
387
389
  # r if r.any?
388
390
  # rescue
389
391
  # end
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  module ZSteg
2
3
  class Checker
3
4
  module ScanlineChecker
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  module ZSteg
2
3
  class Checker
3
4
  module WBStego
data/lib/zsteg/cli/cli.rb CHANGED
@@ -112,6 +112,10 @@ module ZSteg
112
112
  @options[:min_str_len] = x
113
113
  end
114
114
 
115
+ opts.on "--shift N", Integer, "prepend N zero bits" do |x|
116
+ @options[:shift] = x
117
+ end
118
+
115
119
  opts.separator ""
116
120
  opts.on "-v", "--verbose", "Run verbosely (can be used multiple times)" do |v|
117
121
  @options[:verbose] += 1
@@ -120,7 +124,11 @@ module ZSteg
120
124
  @options[:verbose] -= 1
121
125
  end
122
126
  opts.on "-C", "--[no-]color", "Force (or disable) color output (default: auto)" do |x|
123
- Sickill::Rainbow.enabled = x
127
+ if defined?(Rainbow) && Rainbow.respond_to?(:enabled=)
128
+ Rainbow.enabled = x
129
+ else
130
+ Sickill::Rainbow.enabled = x
131
+ end
124
132
  end
125
133
  opts.separator "\nPARAMS SHORTCUT\n"+
126
134
  "\tzsteg fname.png 2b,b,lsb,xy ==> --bits 2 --channel b --lsb --order xy"
@@ -201,6 +209,8 @@ module ZSteg
201
209
  h[:order] = x
202
210
  when 'prime'
203
211
  h[:prime] = true
212
+ when 'zlib'
213
+ h[:zlib] = true
204
214
  else
205
215
  raise "uknown param #{x.inspect}"
206
216
  end
@@ -219,6 +229,8 @@ module ZSteg
219
229
  # zlib stream may contain extradata
220
230
  @img.imagedata
221
231
  @img.extradata[$1.to_i]
232
+ when /imagedata/
233
+ @img.imagedata
222
234
  else
223
235
  h = decode_param_string name
224
236
  h[:limit] = @options[:limit] if @options[:limit] != Checker::DEFAULT_LIMIT
@@ -234,7 +246,15 @@ module ZSteg
234
246
  end
235
247
 
236
248
  def extract name
237
- print _extract_data(name)
249
+ data = _extract_data(name)
250
+ if name['zlib']
251
+ if r = Checker::Zlib.check_data(data)
252
+ data = r.data
253
+ else
254
+ raise "cannot decompress with zlib"
255
+ end
256
+ end
257
+ print data
238
258
  end
239
259
 
240
260
  end
@@ -77,7 +77,11 @@ module ZSteg
77
77
  @options[:verbose] -= 1
78
78
  end
79
79
  opts.on "-C", "--[no-]color", "Force (or disable) color output (default: auto)" do |x|
80
- Sickill::Rainbow.enabled = x
80
+ if defined?(Rainbow) && Rainbow.respond_to?(:enabled=)
81
+ Rainbow.enabled = x
82
+ else
83
+ Sickill::Rainbow.enabled = x
84
+ end
81
85
  end
82
86
  end
83
87
 
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  require 'optparse'
2
3
  require 'stringio'
3
4
  require 'set'
@@ -42,10 +43,14 @@ module ZSteg
42
43
 
43
44
  opts.separator ""
44
45
 
45
- opts.on "-a", "--all", "try all possible sizes (default)" do
46
+ opts.on "-a", "--all", "try all possible sizes" do
46
47
  @options[:try_all] = true
47
48
  end
48
49
 
50
+ opts.on "-r", "--rewrite", "just rewrite the header, keeping imagedata as-is" do
51
+ @options[:rewrite] = true
52
+ end
53
+
49
54
  opts.separator ""
50
55
 
51
56
  opts.on "-O", "--outfile FILENAME", "output single result to specified file" do |x|
@@ -64,7 +69,11 @@ module ZSteg
64
69
  @options[:verbose] -= 1
65
70
  end
66
71
  opts.on "-C", "--[no-]color", "Force (or disable) color output (default: auto)" do |x|
67
- Sickill::Rainbow.enabled = x
72
+ if defined?(Rainbow) && Rainbow.respond_to?(:enabled=)
73
+ Rainbow.enabled = x
74
+ else
75
+ Sickill::Rainbow.enabled = x
76
+ end
68
77
  end
69
78
  end
70
79
 
@@ -150,12 +159,21 @@ module ZSteg
150
159
  h = @image.width*@image.height/w
151
160
  _reflow w,h
152
161
  end
153
- else
162
+ elsif @options[:try_all]
154
163
  # enum all
155
164
  2.upto(@image.width*@image.height/2) do |w|
156
165
  h = @image.width*@image.height/w
157
166
  _reflow w,h
158
167
  end
168
+ else
169
+ # smart all
170
+ w = 4
171
+ loop do
172
+ h = @image.width*@image.height/w
173
+ break if h < 4
174
+ _reflow w,h
175
+ w += 1
176
+ end
159
177
  end
160
178
  end
161
179
 
@@ -202,37 +220,41 @@ module ZSteg
202
220
  data = fi.read(4+4+4)
203
221
  fo.write(data[0,4] + [w,h].pack("V2")) # write new size
204
222
 
205
- # copy remaining header bytes
206
- fo.write fi.read(imagedata_offset-fi.tell)
207
-
208
- # FIXME: if scanline sizes differ in BITS, not bytes...
209
-
210
- # scanline padding needs to be respected...
211
- imagedata = StringIO.new
212
- @image.height.times do
213
- data = fi.read @old_total_sl_bytes
214
- imagedata << data[0, @old_significant_sl_bytes]
215
- #p data[@old_significant_sl_bytes..-1]
216
- end
217
- imagedata << fi.read # read extradata, if any
218
-
219
- imagedata.rewind
220
- imagedata_start = fo.tell
221
- h.times do
222
- fo << imagedata.read(new_significant_sl_bytes)
223
- fo << padding
223
+ if @options[:rewrite]
224
+ IO.copy_stream fi, fo
225
+ else
226
+ # copy remaining header bytes
227
+ fo.write fi.read(imagedata_offset-fi.tell)
228
+
229
+ # FIXME: if scanline sizes differ in BITS, not bytes...
230
+
231
+ # scanline padding needs to be respected...
232
+ imagedata = StringIO.new
233
+ @image.height.times do
234
+ data = fi.read @old_total_sl_bytes
235
+ imagedata << data[0, @old_significant_sl_bytes]
236
+ #p data[@old_significant_sl_bytes..-1]
237
+ end
238
+ imagedata << fi.read # read extradata, if any
239
+
240
+ imagedata.rewind
241
+ imagedata_start = fo.tell
242
+ h.times do
243
+ fo << imagedata.read(new_significant_sl_bytes)
244
+ fo << padding
245
+ end
246
+ file_size = fo.tell
247
+ imagedata_size = fo.tell - imagedata_start
248
+ fo << imagedata.read # write extradata, if any
249
+
250
+ # write new BITMAPFILEHEADER.bfSize
251
+ fo.seek 2
252
+ fo.write [file_size].pack('V')
253
+
254
+ # write new BITMAPINFOHEADER.biSizeImage
255
+ fo.seek 14+20 # BITMAPFILEHEADER::SIZE + 20
256
+ fo.write [imagedata_size].pack('V')
224
257
  end
225
- file_size = fo.tell
226
- imagedata_size = fo.tell - imagedata_start
227
- fo << imagedata.read # write extradata, if any
228
-
229
- # write new BITMAPFILEHEADER.bfSize
230
- fo.seek 2
231
- fo.write [file_size].pack('V')
232
-
233
- # write new BITMAPINFOHEADER.biSizeImage
234
- fo.seek 14+20 # BITMAPFILEHEADER::SIZE + 20
235
- fo.write [imagedata_size].pack('V')
236
258
  end
237
259
  end
238
260
  end
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  module ZSteg
2
3
  class Extractor
3
4
  # ByteExtractor extracts bits from each scanline bytes
@@ -15,7 +16,7 @@ module ZSteg
15
16
  end
16
17
 
17
18
  data = ''.force_encoding('binary')
18
- a = []
19
+ a = [0]*params[:shift].to_i # prepend :shift zero bits
19
20
  byte_iterator(params) do |x,y|
20
21
  sl = @image.scanlines[y]
21
22
 
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  module ZSteg
2
3
  class Extractor
3
4
  # ColorExtractor extracts bits from each pixel's color
@@ -35,8 +36,7 @@ module ZSteg
35
36
  end
36
37
 
37
38
  data = ''.force_encoding('binary')
38
- a = []
39
- #puts
39
+ a = [0]*params[:shift].to_i # prepend :shift zero bits
40
40
  catch :limit do
41
41
  coord_iterator(params) do |x,y|
42
42
  color = @image[x,y]
@@ -94,7 +94,7 @@ module ZSteg
94
94
  rescue
95
95
  t = data.force_encoding('binary')
96
96
  end
97
- if t.size >= Checker::MIN_TEXT_LENGTH
97
+ if t.size >= Checker::DEFAULT_MIN_STR_LEN
98
98
  ZSteg::Result::UnicodeText.new(t,0)
99
99
  end
100
100
  else
data/lib/zsteg/result.rb CHANGED
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  module ZSteg
2
3
  module Result
3
4
 
data/spec/cats_spec.rb CHANGED
@@ -3,7 +3,9 @@ require 'spec_helper'
3
3
  describe "cats.png" do
4
4
  subject{ cli(sample("cats.png")) }
5
5
 
6
- its(:size){ should < 4_000 }
6
+ it "size should be < 4k" do
7
+ subject.size.should < 4_000
8
+ end
7
9
 
8
10
  it "should get 2nd cat" do
9
11
  should include("Second cat is Marussia")
@@ -5,7 +5,8 @@ sample("newbiecontest/alph1-surprise.bmp") do |fname|
5
5
  describe fname do
6
6
  subject{ cli(fname) }
7
7
 
8
- it { should include "PE32 executable for MS Windows" }
8
+ it { should include "PE32 executable" }
9
+ it { should include "MS Windows" }
9
10
  it { should include "is program canno" }
10
11
 
11
12
  describe "--extract" do
@@ -7,37 +7,51 @@ sample('polictf2012_f200.bmp') do |fname|
7
7
  end
8
8
 
9
9
  describe "hidden BMP #1" do
10
- subject(:data){ cli(fname, "--extract", "4b,lsb,bY") }
11
- its(:size){ should == 416816 }
10
+ before(:all) do
11
+ @data = cli(fname, "--extract", "4b,lsb,bY")
12
+ end
13
+
14
+ it "should be 416816 bytes" do
15
+ @data.size.should == 416816
16
+ end
12
17
 
13
18
  it "should have BMP header" do
14
- data[0,2].should == "BM"
19
+ @data[0,2].should == "BM"
15
20
  end
16
21
 
17
22
  it "should have 7zip after BMP" do
18
- data.index("7z").should == 2005
23
+ @data.index("7z").should == 2005
19
24
  end
20
25
 
21
26
  describe "deeper" do
22
- let(:tname){ File.join("tmp", File.basename(fname) + ".bmp") }
23
- before(:all){ File.open(tname, "wb"){ |f| f<<data } }
27
+ before(:all) do
28
+ @tname = File.join("tmp", File.basename(fname) + ".bmp")
29
+ File.open(@tname, "wb"){ |f| f<<@data }
30
+ end
24
31
 
25
32
  it "should detect 7z & BMP" do
26
- out = cli(tname)
33
+ out = cli(@tname)
27
34
  out.should include('7-zip archive')
28
35
  out.should include('PC bitmap, Windows 3.x format, 100 x 55 x 24')
29
36
  end
30
37
 
31
38
  describe "hidden BMP #2" do
32
- subject(:data2){ cli(tname, "--extract", "2b,lsb,bY") }
33
- its(:size){ should == 103875 }
39
+ before(:all) do
40
+ @data2 = cli(@tname, "--extract", "2b,lsb,bY")
41
+ end
42
+
43
+ it "should be 103875 bytes" do
44
+ @data2.size.should == 103875
45
+ end
34
46
 
35
47
  describe "deeper" do
36
- let(:tname2){ File.join("tmp", File.basename(tname) + ".bmp") }
37
- before(:all){ File.open(tname2, "wb"){ |f| f<<data2 } }
48
+ before(:all) do
49
+ @tname2 = File.join("tmp", File.basename(@tname) + ".bmp")
50
+ File.open(@tname2, "wb"){ |f| f<<@data2 }
51
+ end
38
52
 
39
53
  it "should detect text" do
40
- out = cli(tname2)
54
+ out = cli(@tname2)
41
55
  out.should include('sticazziantanieancoraunavoltacomesefossestato')
42
56
  end
43
57
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ #coding: binary
1
2
  $:.unshift(File.expand_path("../lib", File.dirname(__FILE__)))
2
3
  require 'zsteg'
3
4
 
@@ -19,7 +20,7 @@ def sample fname
19
20
  end
20
21
 
21
22
  def cli *args
22
- @@cli_cache ||= {}
23
+ @cli_cache ||= {}
23
24
  args.map! do |arg|
24
25
  if arg.is_a?(String) && arg[' ']
25
26
  # split strings with spaces into arrays
@@ -29,7 +30,7 @@ def cli *args
29
30
  end
30
31
  end
31
32
  args.flatten!
32
- @@cli_cache[args.inspect] ||=
33
+ @cli_cache[args.inspect] ||=
33
34
  begin
34
35
  klass =
35
36
  if args.first.is_a?(Symbol)
@@ -52,6 +53,7 @@ def cli *args
52
53
  end
53
54
 
54
55
  RSpec.configure do |config|
56
+ config.expect_with(:rspec) { |c| c.syntax = :should }
55
57
  config.before :suite do
56
58
  Dir[File.join(SAMPLES_DIR, "**", "*.7z")].each do |fname|
57
59
  next if File.exist?(fname.sub(/\.7z$/,''))
data/spec/zlib_spec.rb CHANGED
@@ -1,6 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "samples/ndh2k12_sp113.bmp" do
4
- subject{ cli(sample("ndh2k12_sp113.bmp"), "-o", "all") }
5
- it { should include("%PDF-1.4") }
3
+ sample("ndh2k12_sp113.bmp") do |fname|
4
+ describe fname do
5
+ subject{ cli(fname, "-o", "all") }
6
+ it { should include("%PDF-1.4") }
7
+
8
+ describe "--extract" do
9
+ subject{ cli(fname, "--extract b1,rgb,lsb,yx") }
10
+
11
+ it { should_not include "%PDF-1.4" }
12
+ it { subject.size.should == 546750 }
13
+ end
14
+
15
+ describe "--extract zlib" do
16
+ subject{ cli(fname, "--extract b1,rgb,lsb,yx,zlib") }
17
+
18
+ it { should include "%PDF-1.4" }
19
+ it { subject.size.should == 202383 }
20
+ end
21
+ end
6
22
  end
data/zsteg.gemspec CHANGED
@@ -2,17 +2,18 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: zsteg 0.1.1 ruby lib
5
+ # stub: zsteg 0.2.3 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = "zsteg"
9
- s.version = "0.1.1"
8
+ s.name = "zsteg".freeze
9
+ s.version = "0.2.3"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.authors = ["Andrey \"Zed\" Zaikin"]
13
- s.date = "2013-09-20"
14
- s.email = "zed.0xff@gmail.com"
15
- s.executables = ["zsteg", "zsteg-mask", "zsteg-reflow"]
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Andrey \"Zed\" Zaikin".freeze]
14
+ s.date = "2021-02-18"
15
+ s.email = "zed.0xff@gmail.com".freeze
16
+ s.executables = ["zsteg".freeze, "zsteg-mask".freeze, "zsteg-reflow".freeze]
16
17
  s.extra_rdoc_files = [
17
18
  "README.md",
18
19
  "README.md.tpl",
@@ -100,34 +101,27 @@ Gem::Specification.new do |s|
100
101
  "writers/zlib_append.rb",
101
102
  "zsteg.gemspec"
102
103
  ]
103
- s.homepage = "http://github.com/zed-0xff/zsteg"
104
- s.licenses = ["MIT"]
105
- s.require_paths = ["lib"]
106
- s.rubygems_version = "2.1.4"
107
- s.summary = "Detect stegano-hidden data in PNG & BMP files."
104
+ s.homepage = "http://github.com/zed-0xff/zsteg".freeze
105
+ s.licenses = ["MIT".freeze]
106
+ s.rubygems_version = "3.2.3".freeze
107
+ s.summary = "Detect stegano-hidden data in PNG & BMP files.".freeze
108
108
 
109
109
  if s.respond_to? :specification_version then
110
110
  s.specification_version = 4
111
+ end
111
112
 
112
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
113
- s.add_runtime_dependency(%q<zpng>, [">= 0.2.3"])
114
- s.add_runtime_dependency(%q<iostruct>, [">= 0"])
115
- s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
116
- s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
117
- s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
118
- else
119
- s.add_dependency(%q<zpng>, [">= 0.2.3"])
120
- s.add_dependency(%q<iostruct>, [">= 0"])
121
- s.add_dependency(%q<rspec>, [">= 2.8.0"])
122
- s.add_dependency(%q<bundler>, [">= 1.0.0"])
123
- s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
124
- end
113
+ if s.respond_to? :add_runtime_dependency then
114
+ s.add_runtime_dependency(%q<zpng>.freeze, [">= 0.3.1"])
115
+ s.add_runtime_dependency(%q<iostruct>.freeze, [">= 0"])
116
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
117
+ s.add_development_dependency(%q<bundler>.freeze, ["~> 2.2.3"])
118
+ s.add_development_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
125
119
  else
126
- s.add_dependency(%q<zpng>, [">= 0.2.3"])
127
- s.add_dependency(%q<iostruct>, [">= 0"])
128
- s.add_dependency(%q<rspec>, [">= 2.8.0"])
129
- s.add_dependency(%q<bundler>, [">= 1.0.0"])
130
- s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
120
+ s.add_dependency(%q<zpng>.freeze, [">= 0.3.1"])
121
+ s.add_dependency(%q<iostruct>.freeze, [">= 0"])
122
+ s.add_dependency(%q<rspec>.freeze, ["~> 3.9.0"])
123
+ s.add_dependency(%q<bundler>.freeze, ["~> 2.2.3"])
124
+ s.add_dependency(%q<jeweler>.freeze, ["~> 2.3.9"])
131
125
  end
132
126
  end
133
127
 
metadata CHANGED
@@ -1,86 +1,86 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zsteg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey "Zed" Zaikin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-20 00:00:00.000000000 Z
11
+ date: 2021-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zpng
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.3
19
+ version: 0.3.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.3
26
+ version: 0.3.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: iostruct
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 2.8.0
47
+ version: 3.9.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 2.8.0
54
+ version: 3.9.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 1.0.0
61
+ version: 2.2.3
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 1.0.0
68
+ version: 2.2.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: jeweler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.8.4
75
+ version: 2.3.9
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.8.4
83
- description:
82
+ version: 2.3.9
83
+ description:
84
84
  email: zed.0xff@gmail.com
85
85
  executables:
86
86
  - zsteg
@@ -176,24 +176,23 @@ homepage: http://github.com/zed-0xff/zsteg
176
176
  licenses:
177
177
  - MIT
178
178
  metadata: {}
179
- post_install_message:
179
+ post_install_message:
180
180
  rdoc_options: []
181
181
  require_paths:
182
182
  - lib
183
183
  required_ruby_version: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - '>='
185
+ - - ">="
186
186
  - !ruby/object:Gem::Version
187
187
  version: '0'
188
188
  required_rubygems_version: !ruby/object:Gem::Requirement
189
189
  requirements:
190
- - - '>='
190
+ - - ">="
191
191
  - !ruby/object:Gem::Version
192
192
  version: '0'
193
193
  requirements: []
194
- rubyforge_project:
195
- rubygems_version: 2.1.4
196
- signing_key:
194
+ rubygems_version: 3.2.3
195
+ signing_key:
197
196
  specification_version: 4
198
197
  summary: Detect stegano-hidden data in PNG & BMP files.
199
198
  test_files: []