3.9K Views
March 09, 21
スライド概要
SWFの情報要素とバイナリの読み方
2012年9月25日(火) “よや“ <[email protected]>
自己紹介 • 六本木の方から来ました • 会社は着ているTシャツでお察し下さい • アウェイで発表頑張ります! • SWF バイナリ編集が趣味 (主に Flash Lite) • PHP の SWFバイナリ編集ライブラリを作ってます (動的生成が下火でそろそろ過去形 ;ω;) • http://sourceforge.jp/projects/swfed/ • http://openpear.org/package/IO_SWF
伝えたい事 • SWF フォーマットの読み方 • SWF に含まれる情報要素とその意味 • それらを SWF バイナリからどう切り出すか • SWF バイナリの切り出しのコツ • 幾つかのパターンが分かれば簡単 Little Endian (Byte) , MSB (Bit) , “tag_and_length” Byte Alignment , 8 bit Flags Length Dependency Optional Field , ¥0 Terminate Offset to foobaa , Offset Table.
SWF を触る目的 • ガラケー時代 > Flash Lite の制限に力づくで対応 • 最大100KB ⇒ 最小限のデータを SWF に載せる • 実行引数渡せない ⇒ SWF にパラメータ値を埋め込もう • 画像を動的に入れ替えし辛い ⇒ SWF の画像も入れ替えちゃえ \まさかの実行ファイル(SWF)動的生成/ • スマートフォン時代 > Flash Player 代わりの処理 • iOS に Flash Player が無い ⇒ JavaScript で SWF を解釈して何か表示 • Android も 4.1 から Flash Player が無い ⇒ じゃぁ、こっちも! \まさかの Flash Player 実装/
Flash Lite と SWF version • Flash と Flash Lite の SWF version Macromedia Flash MX 以前 省略 Flash 4 Flash 5 Flash Lite 1.x Flash Lite 1.1 Flash 6 Flash 7 Flash Lite 2.x Flash 8 Flash Lite 3.x Flash Lite 2.0 ガラケーのFlash というと、 大体コレがターゲット 互換性の問題で こっちもたまに見る 引用元) http://www.adobe.com/jp/devnet/devices/articles/develop_in_japan.html 以降 省略 以降 省略
SWFの仕様 • 公式仕様書 • http://www.adobe.com/devnet/swf.html • データ形式は(正確さはさておき) 詳細に書かれているが、 意味の記述が全然足りない • 自力で調べる必要あり • Flash Player のブラックボックス解析 • 2000年初頭の書籍を漁る (だって Flash 4 だし…) お勧め → オーム社の Macromedia Flash ActionScript バイブル
SWF 解説 • ここまで前置き ここから本題
SWF 全体構造 • Header と Tag のイメージ SWF Header Tag Tag \概念/ Tag Tag … Tag Tag (type:9 SetBackgroundColor) [Red:0, Green:0, Blue:0] (Black) Header Xmin Ymin Xmax Frame Rate Frame Count Ymax Tag (type:21 DefineBitsJPEG2) [CharacterID:1, ImageData: ] Tag (type:22 DefineShape2) [CharacterID:2,BitmapID:1, … ,ShapeRecords: ] Tag (type:26 PlaceObject2) [CharatorID:2, …, Matrix: … { 1 } 0 60 0 1 800 ]
SWF Header (仕様書) • SWF Header (仕様書)
SWF Header • Header 詳細 Little Endian Header Xmin Xmax FrameRate Ymin FrameCount Ymax Header Signature Version 3 bytes 1 byte FileLength Signature: FWS → 無圧縮 Version: 0x04 → Flash 4 FileLength: 0x00000a90 → 2,704byte FrameSize: (次ページで説明) FrameRate: 0x08.00 → 8 frames/sec FrameSize: 0x0028 → 40 frames (Rectangle) FrameSize FrameRate FrameCount 2 bytes 4 bytes FrameSize は 次ページで説明 2 bytes
SWF Header FrameSize • Header 詳細 bit packing Header Xmin Xmax Ymin 7 0 0 0 0 9 6 0 0 0 0 0 9 6 0 0 01110000 00000000 00001001 01100000 00000000 00000000 10010110 00000000 5 bits Ymax (Rectangle) FrameSize 14 bits 14 bits 勿体ないけど Nbits: 01110 → 14bits 3bits 捨てる Xmin: 000 00000000 000 → 0 twips → 0 pixel Xmax: 01001 01100000 0 → 4800 twips → 240 pixel Ymin: 0000000 0000000 → 0 twips → 0 pixel Ymax: 0 10010110 00000 → 4800 twips → 240 pixel FrameSize (Rectangle) Nbits Xmin Xmax 5 bits 14 bits 14 bits Ymin Ymax Nbits bits Nbits bits Nbits bits Nbits bits
SWF Tag example • ビットマップ画像を表示するのに最低限必要な Tag SWF Header Tag Tag Tag Tag Tag Tag 描画 背景色 Tag (type:9 SetBackgroundColor) DisplayList [Red:0, Green:0, Blue:0] (Black) Depth:1 Tag (type:0 End) Tag (type:21 DefineBitsJPEG2) [CharacterID: 1, ImageData: Tag (type:1 ShowFrame) ] Tag (type:22 DefineShape2) [CharacterID:2,BitmapID:1, … ,ShapeRecords: Tag (type:26 PlaceObject2) ] [CharatorID: 2, Depth:1, Matrix: { } 1 0 60 0 1 800 , … ]
SWF Tag type • SWF Tag type (仕様書の appendix B) Tag type
SWF Tag Categories • SWF Tag type Categories Definition tags Control tags Tag (type:0) Tag (type:21) End DefineBitsJPEG2 Tag (type:22) Tag (type:1) DefineShape2 ShowFrame Tag (type:33) Tag (type:9) DefineButton2 SetBackgroundColor Tag (type:10) インスタンス化 Tag (type:26) DefineFont PlaceObject2 Tag (type:39) Tag (type:12) DefineSprite DoAction … …
SWF Tag format (仕様書) • SWF Tag format (仕様書)
SWF Tag format (short) “ len≦0x3e ” • SWF Tag 共通 format (short) Tag Tag and Length Payload 2 bytes Length bytes TagCodeAndLength 1st byte Little Endian 2nd byte 10 bits tag code Tag type 2nd byte 4 3 0 2 0100 0011 0000 0100 RECORDHEADER 0~0x3e (short) 1st byte 6 bits type:9 length 0x3f RECORDHEADER (long) → (次ページで説明) 0000 0010 0100 0011 Length:3 0000001001 000011 ※ DefineBits 系は long形式を使う決まり Tag (type:9) SetBackgroundColor 00 00 00 → #000000 (black)
SWF Tag format (long) “ len≧ 0x3f ” • SWF Tag 共通 format (long) Tag Tag and Length Payload 6 bytes Length bytes TagCodeAndLength 1st byte b f 0 0 1011 1111 0000 0000 0~0xffffffff 2nd byte Length Type:2 Little Endian 2nd byte 1st byte 10 bits 6 bits tag code length 4 bytes RECORDHEADER (long) 0000 0000 101 11111 0000000010 111111 Tag (type:2) DefineShape 33 00 00 00 Little Endian 00 00 00 33 111111 = 0x3f Tag type 0x3f Length:0x33(=51)
ShowFrame, End • ShowFrame, End ( payload 無し) Tag (ShowFrame) Tag & Length 4 0 0 0 0100 0000 0000 0000 2 bytes 4 0 0 0 0000 0000 0000 0000 0 type:1 0000 0000 0100 0000 0000000001 000000 Tag (End) 0000000000 000000 Tag & Length 2 bytes type:0 0000 0000 0000 0000 0
SetBackgroundColor (背景色設定) • SetBackgroundColor (簡単な例) Tag (SetBackgroundColor) Tag & Length 2 bytes type:9 BackgroundColor 3 3 bytes 4 3 0 2 0100 0011 0000 0100 BackgroundColor Red Green Blue 1 byte 1 byte 1 byte type:9 0000 0010 0100 0011 0000001001 000011 Length:3 00 00 00 → #000000 (black)
DefineBitsJPEG (JPEG画像) • DefineBitsJPEG2 (殆どJPEG) (length) bytes Tag (DefineBitsJPEG3) Tag & Length 6 bytes Charater ID JPEG Data 2 bytes type:35 • JPEG 画像が( chunk の並びが違うだけで、)ほぼそのまま格 納されている。 • 詳しくは以下のサイトを参考 参考) http://labs.gree.jp/blog/2010/09/782/ SWFバイナリ編集のススメ第三回 (JPEG)
DefineBitsJPEG (JPEG画像) • DefineBitsJPEG3 (JPEG に透明度を追加したもの) (length) bytes Tag (DefineBitsJPEG3) Tag & Length 6 bytes Charater ID 2 bytes OffsetToAlpha 4 bytes JPEG Data (zlib compressed) BitmapAlphaData (OffsetToAlpha) bytes type:35 参考) http://labs.gree.jp/blog/2010/09/782/ SWFバイナリ編集のススメ第三回 (JPEG)
DefineBitsLossless (パレット形式) • DefineBitsLossless2 (透明度付き PNG/GIF 画像) • Format:3 (パレット形式) (length) bytes Tag (DefineBitsLossless2) Tag & Length 6 bytes type:36 Charater ID Format 2 bytes 1 byte Width Height 2 bytes 2 bytes Color TableSize (zlib compressed) ColorTable & ColormapPixelData 1 byte zlib infrate 3 ColorTable & ColormapPixelData ColormapPixelData ColorTable 4 bytes (4 x ColorTableSize) bytes (Width) bytes ColorTable (Color Alpha TableSize) Alpha bytes Alpha Red Green Blue Red Green Blue Red Green Blue … ColormapPixelData (Height) bytes
DefineBitsLossless (RGBA) • DefineBitsLossless2 (透明度付き PNG/GIF 画像) • Format: 5 (RGBA, DirectColor) (length) bytes Tag (DefineBitsLossless2) Tag & Length 6 bytes type:36 Charater ID Format Width Color Height TableSize 2 bytes 1 byte 2 bytes 2 bytes 5 4x(Width) bytes (zlib compressed) BitmapPixelData 1 byte zlib infrate BitmapPixelData (Height) bytes Red Green Blue Alpha … Red Green Blue Alpha … … 参考) http://labs.gree.jp/blog/2010/12/1902/ SWFバイナリ編集のススメ第五回 (PNG)
DefineShape (シェイプ:ベクター画像) • DefineShape • SWFバイナリ編集のススメ第七回 (Shape基本構造) • http://labs.gree.jp/blog/2011/04/2328/ ← こちらで説明
PlaceObject (シェイプorシンボルの貼り付 け) PlaceFlag • PlaceObject2 HasClipActions HasClipDepth HasName Tag (PlaceObject2) Tag & Length PlaceFlag 2 bytes 1 byte Type:26 HasRatio Depth 2 bytes 1 byte HasColorTransform HasMatrix HasCharactor 0000 000X Move • PlaceObject2 (全乗せ) Tag (PlaceObject2) Tag & Length 2 bytes Place Flag Depth Character Matrix ID 1 byte 2 bytes 2 bytes 1111 111X Color Transform Name Ratio 2 bytes MATRIX, ColorTransform (アフィン変換行列、カラー効果) ↓ (次ページ以降で説明) Clip Depth Clip Actions 2 bytes ClipActions ↓ SWF5 以降の情報要素なので略
MATRIX (アフィン変換行列) • MATRIX (最小構成) 0000 000X MATRIX Has Has Scale Rotate 1 bit 1 bit (= 0) (= 0) Ntranslate Bits 5 bit (= 0) 1 0 0 0 1 0 単位行列 Scale X Rotate Translate Skew0 X Rorate Skew1 Scale Y Translate Y • MATRIX (全乗せ) MATRIX Scale Scale Has NRotate Rotate Has NScale X Y Bits Skew0 Rotate Scale Bits 1 bit 1 bit 5 bits (Nscale (Nscale 5 bits (NRotate (= 1) (= 1) Bits)bits Bits) bits Bits)bits 2 0 0 0 1 0 Rotate Ntranslate Translate Translate X X Skew1 Bits (NRotate 5 bits Bits) bits (NTranslate (NTranslate Bits)bits Bits)bits アフィン変換の詳細は、LT で!
CXFORM (カラー効果) • CXFORM (最小構成) 00XX XXXX MATRIX Has Has AddTerm MultiTerm 1 bit (= 0) 1 bit (= 0) 何もしない (色味を弄らない) RedMultiTerm > 256 or RedAddTerm > 0 • CXFORM (全乗せ) MATRIX Has Has AddTerm MultiTerm 1 bit (= 1) 1 bit (= 1) NBits Red MultiTerm Green MultiTerm Blue MultiTerm Red AddTerm Green AddTerm Blue AddTerm 4 bits (Nbits) bits (Nbits) bits (Nbits) bits (Nbits) bits (Nbits) bits (Nbits) bits
後の資料は適当です m(_ _)m • バイナリの切り出し方のコツは殆ど出尽くしたので、後は最低 限の説明で。
DoAction (ActionScript実行コード) • DoAction type:12 1 byte =0 参考) http://labs.gree.jp/blog/2011/07/3259/ SWFバイナリ編集のススメ第八回 (Action – AS2 Bytecode編)
DefineButton (ボタンの振る舞い) • DefineButton Tag (DefineSprte) Tag & Length 2 or 6 bytes type:39 Button Id Characters Character EndFlag 1 byte =0 2 bytes Character (BUTTONRECORD) Chacater Actions Action EndFlag 1 byte =0 … Chacater Character (BUTTONRECORD) … ButtonState… CharacterID PlaceDepth PlaceMatrix この辺は PlaceObject に似てる ButtonState HitTest StateDown StateOver StateUp …
DefineSprite (シンボル) • DefineSprite (length) bytes Tag (DefineSprte) Tag & Length 2 or 6 bytes type:39 Sprite ID Frame Count 2 bytes 2 bytes ControlTags ControlTags Tag (PlaceObject2) Tag (ShowFrame) … Tag (End) • ※ Definition Tags は中に含められない。
まとめ • 16bits, 32bits値は LittleEndian で埋まっている • 基本、bit は先頭から切り出せば OK (いわゆる MSB) • tag_and_lenght だけ 16bits が一塊なので LittleEndian 処理 • 可変長フィールドは、数ビットの長さフィールドと、それで指定した分 • • • • の長さが後ろに続くのがお約束 フィールドがオプション扱いの場合は、その存在フラグ(1 bit)がある か、Tag の長さ的に余っているなら存在する。といった形で判断 長さフィールドがない可変長の場合は、Tag の長さから判断できる。 省略された場合は、デフォルトの値が適用される。(単位行列等) Byte Alignment が重要 • Matrix 等、情報要素によって(その先頭で) Alignment を取るか決まる • 8Bit 単位でフラグが並んでいる場合は仕様書になくても alignment を取る
ついでに少しだけ実装の話 (1/2) • Flash Lite 1.1 の SWF を一通り解釈出来るコードを C と PHP で公開してます • http://sourceforge.jp/projects/swfed/ SWFEditor • http://openpear.org/package/IO_SWF IO_SWF •S • qwfdump (IO_SWF) •q
ついでに少しだけ実装の話 (2/2) • Bitstream クラスを作って、フィールドの長さに応じたメソッドを 呼ぶのがコツ class IO_SWF_Type_RECT extends IO_SWF_Type { static function parse(&$reader, $opts = array()) { $frameSize = array(); $reader->byteAlign(); $nBits = $reader->getUIBits(5); $frameSize['Xmin'] = $reader->getSIBits($nBits); $frameSize['Xmax'] = $reader->getSIBits($nBits); $frameSize['Ymin'] = $reader->getSIBits($nBits); $frameSize['Ymax'] = $reader->getSIBits($nBits) ; return $frameSize; } 参考) http://www.slideshare.net/yoyayoya1/php-10133775 PHPでバイナリ変換プログラミング
以上です • ありがとうございました。