Slide 1

Slide 1 text

JPEG を壊す話 Shimpei Makimoto (@makimoto) Kyoto.なんか #4 (18th Aug 2018)

Slide 2

Slide 2 text

誰? - Shimpei Makimoto - Software Engineer in Tokyo - 自分でも厳密な所属がわからない - https://twitter.com/makimoto - https://github.com/makimoto https://twitter.com/makimoto/status/1027473102437904386

Slide 3

Slide 3 text

JPEG - Joint Photographic Experts Group https://en.wikipedia.org/wiki/JPEG - 厳密には JPEG は画像圧縮手法のことを指す - 人間たちが JPEG と呼んでいるのは大体のケースで JPEG を用いて画像をファイ ルに保存するための形式である JFIF (JPEG File Interchange Format) のことを指 す - グリッチの文脈ではもっともロバストな画像フォーマットの1つ

Slide 4

Slide 4 text

いろいろな画像形式でグリッチを試すデモ - iTerm2 と Docker Hub の makimoto/glitch-playground イメージを使う - docker run -v /path/to/data:/data \ -i -t makimoto/glitch-playground

Slide 5

Slide 5 text

何これ? - https://hub.docker.com/r/makimoto/glitch-playground/ - https://github.com/makimoto/glitch-playground - ImageMagick と各種画像処理ライブラリをインストールした Docker コンテナの中 で画像を変換して sed して表示させるスクリプトを動かしている - iTerm2 で動く imgcat を使って表示させている https://www.iterm2.com/documentation-images.html

Slide 6

Slide 6 text

ロバスト #とは - JPEG 形式の画像は割と壊れない - PNG とか結構すぐ壊れる - GIF とか WebP とかは割と良い

Slide 7

Slide 7 text

何故壊れるのか - 壊してはいけない場所を壊す - 雑なヒューリスティックをする手もある https://github.com/makimoto/glitch/blob/9b5b9b3c59fbcddae15e40e2e4cd522964b8749e/commands.go#L98-L102 - (割とちゃんと動くんだけど) 雑すぎ - ちゃんと画像フォーマットを理解した上で壊せば壊れない

Slide 8

Slide 8 text

JPEG の仕様とか - https://www.w3.org/Graphics/JPEG/ - https://www.w3.org/Graphics/JPEG/itu-t81.pdf - 画像圧縮手法としての JPEG の仕様 - https://www.w3.org/Graphics/JPEG/jfif3.pdf - 画像フォーマット (JFIF) の仕様 - 読むのが辛い場合は Go のライブラリのコードを追うと良いかも - https://golang.org/pkg/image/jpeg/

Slide 9

Slide 9 text

xxd -g1 lena.jpg 00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 ......JFIF...... 00000010: 00 01 00 00 ff db 00 43 00 03 02 02 02 02 02 03 .......C........ 00000020: 02 02 02 03 03 03 03 04 06 04 04 04 04 04 08 06 ................ 00000030: 06 05 06 09 08 0a 0a 09 08 09 09 0a 0c 0f 0c 0a ................ 00000040: 0b 0e 0b 09 09 0d 11 0d 0e 0f 10 10 11 10 0a 0c ................ 00000050: 12 13 12 10 13 0f 10 10 10 ff db 00 43 01 03 03 ............C... 00000060: 03 04 03 04 08 04 04 08 10 0b 09 0b 10 10 10 10 ................ 00000070: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................ 00000080: (snip)

Slide 10

Slide 10 text

xxd -g1 lena.jpg 00000000: ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 ......JFIF...... 00000010: 00 01 00 00 ff db 00 43 00 03 02 02 02 02 02 03 .......C........ 00000020: 02 02 02 03 03 03 03 04 06 04 04 04 04 04 08 06 ................ 00000030: 06 05 06 09 08 0a 0a 09 08 09 09 0a 0c 0f 0c 0a ................ 00000040: 0b 0e 0b 09 09 0d 11 0d 0e 0f 10 10 11 10 0a 0c ................ 00000050: 12 13 12 10 13 0f 10 10 10 ff db 00 43 01 03 03 ............C... 00000060: 03 04 03 04 08 04 04 08 10 0b 09 0b 10 10 10 10 ................ 00000070: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................ 00000080: (snip) SOI APP0 DQT DQT

Slide 11

Slide 11 text

JPEG - JPEG (JFIF) 内で \xff から始まる値はマーカーとして扱われる - \xff\xd8 - SOI (Start of Image) - \xff\xe0 - APP0 (Reserved for application segments) - \xff\xdb - DQT (Define quantization table(s))

Slide 12

Slide 12 text

https://www.w3.org/Graphics/JPEG/itu-t81.pdf

Slide 13

Slide 13 text

マーカーのプレフィックスを壊すと即死 - ruby -e 'print ARGF.read.b.gsub("\xff".b, "\xfe".b)' lena.jpg > out.jpg

Slide 14

Slide 14 text

マーカーの後の2バイトの値を壊しても即死 - ruby -e 'print ARGF.read.b.gsub(/(\xff.)[^\xff]./n, "\\1\x00\x00".b)' lena.jpg > out.jpg - マーカーに続く2バイトは大体各セクションの長さを示すので破壊されると画像が開 けなくなる https://www.w3.org/Graphics/JPEG/itu-t81.pdf

Slide 15

Slide 15 text

jpegsan.gem - https://rubygems.org/gems/jpegsan - https://github.com/makimoto/jpegsan - ~/misc に転がっていた jpeg.rb を整えてさっき push した

Slide 16

Slide 16 text

使用例 [3] pry(main)> jpeg.data[4] => #

Slide 17

Slide 17 text

使用例 [4] pry(main)> jpeg.data[4].sequence_in_hex => "00 11 08 02 00 02 00 03 01 11 00 02 11 01 03 11 01"

Slide 18

Slide 18 text

使用例

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

他の例 - に の量子化テーブルを適用

Slide 21

Slide 21 text

他の例 - に のハフマン符号テーブルを適用

Slide 22

Slide 22 text

まとめ - 画像フォーマットを考慮して画像を破壊すると安全に壊せるし、逆に完全に壊さな い感じにもできる - フォーマットを意識してやるのはそれなりにコストがかかるのでできるだけ自動化し たいですね

Slide 23

Slide 23 text

About JPEG corruption Shimpei Makimoto (@makimoto) Kyoto.なんか #4 (18th Aug 2018)