Download presentation
Presentation is loading. Please wait.
1
SWF Binary Code Golf on FlashLite 1.1
サイボウズ・ラボ株式会社 竹迫 良範
2
質問
3
Q. この意味が わかる人? ”CWS\006”
4
正解: “CWS\006” = 43 57 53 06 SWFファイルを16進数でダンプ
fa c 5d cf 41 0a c2 30 e1 3f 6d 15 0d 45 8b 1b d8 0b 48 45 c a d 3c a d 48 a0 0b af de 4c a b7 78 f3 4d 60 6e 64 15 a9 a2 8e 00 1b bf 24 dd 16 0e b d7 fd a b3 7e 46 f4 b8 14 ce 8f 61 e0 d3 b8 f9 44 5c 22 db 27 ac b0 0d 4e 8f b5 47 7d c4 c6 30 ba 95 6f 27 b3 ff 33 c7 c0 f8 56 8c e 4c 31 a0 1d 45 2e 7d fd a1 59 2a 5a 6d df f2 da 85 ff 73 a6 14 0a 2a 39 ed 0b f ff 00009f +00 (3byte) : File magic “FWS” or “CWS” – 圧縮 +04 (1byte) : File version 6
5
Adobe Player Licensing から入手可能
SWFファイルフォーマットの仕様書 Adobe Player Licensing から入手可能 メールアドレス(Adobe ID)を登録 ライセンスに同意する必要がある Flash6以降の情報のみしか記載されていない Alexis‘ SWF Reference (お勧め) Flash6以前の情報についても書いてある Flash 1.0 とか Flash 4.0 (FlashLite 1.1相当) 2001年からの蓄積(これはすごい)
6
Alexis' SWF Reference : : : :
: : : :
7
SWF File Header, SWF Tags…
struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; } struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; }; struct swf_csmtextsettings { swf_tag f_tag; /* 74 */ unsigned short f_text_id_ref; unsigned f_use_flag_type : 2; unsigned f_grid_fit : 3; unsigned f_reserved : 3; long float f_thickness; long float f_sharpness; unsigned char f_reserved; };
8
SWFファイルを DISアセンブル しながら勉強したい…
9
swfdumpコマンドで DISアセンブル
SWFTOOLS の swfdump コマンドを使うと SWFファイルの内容をダンプすることができる > swfdump --full FlashProxy.swf [HEADER] File version: 8 [HEADER] File is zlib compressed. Ratio: 63% [HEADER] File size: 796 (Depacked) [HEADER] Frame rate: [HEADER] Frame count: 1 [HEADER] Movie width: [HEADER] Movie height: [009] SETBACKGROUNDCOLOR (ff/ff/ff) [027] DEFINESPRITE defines id 20480 [000] END [038] EXPORTASSETS exports as "__Packages.MTASC" [03b] DOINITACTION adds information to id 20480 ( 206 bytes) action: Constantpool(22 entries) String:"FlashProxy" String:"_global" String:"target" String:"_root" String:"className" String:"dispatch" String:"flash" String:"external" String:"ExternalInterface" String:"addCallback" String:"addListener" String:"prototype" String:"Function" String:"apply" String:"event" String:"arguments" String:"id" String:"FlashProxy.onTrigger" String:"call" String:"main" String:"proxy" String:"ASSetPropFlags" ( 2 bytes) action: Push Lookup:0 ("FlashProxy") ( 0 bytes) action: GetVariable ( 0 bytes) action: Not ( 2 bytes) action: If 418
10
swfdumpは新しいアクションレコードが苦手
: ( 8 bytes) action: unknown[8e] (remainder of 8 bytes:"\0\0\0\2)\0p\0") アクションレコード[8e]の抽出に失敗 … orz [8e] Declare Function (Flash Version 7 で追加されたバイトコード)
11
Sothink SWF Decompiler (試用期間30日)
12
DISアセンブル結果(Sothink SWF Decompiler)
13
あと CPAN の SWF::File もお勧め
dumpswf.plx dumpswf Flash.swf Flash Flash.swf そのものを生成する Perlスクリプト「Flash.pl」を生成 Windows ActivePerl なら ppm install SWF-File ですぐに使えるよ
14
Sothink SWF Decompiler (試用期間30日)
DISアセンブルまとめ Swftools – swfdump タグやバイトコードのデータ構造を理解できる Flash V6相当のSWFファイルならそこそこいける Sothink SWF Decompiler (試用期間30日) できればフリーのがいいなぁ ぼく ActionScript わからないし(><) SWF::File – dumpswf.plx DISアセンブルした結果が「Perlスクリプト」になる さらにそれを修正してSWFを再生成できる
15
Flasm 知らなかった! (><) こんな便利なものがあったとは・・・ http://flasm.sourceforge.net/
Yossyさん情報より
16
本題 前フリ ここまで
17
いったい何バイトになるんだろう? (ActionScript で意味のあるコード)
世界で一番小さい SWFファイル いったい何バイトになるんだろう? (ActionScript で意味のあるコード)
18
最小の “Hello world!\n” プログラム
Code Golf チャレンジ 57 byte b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 hello57.swf traceを使わないパターンなので、開発環境がなくても表示可能 (traceを使ってよければもっと小さくなるかも)
19
hello57.swf コード解説 SWF File magic (4byte)
b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; }
20
32bit整数(リトルエンディアン) ファイルサイズ情報 (4byte)
b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; } 57 = 4b
21
Rect構造体 (可変サイズ) が入っている
swf_header_movie Rect構造体 (可変サイズ) が入っている b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; };
22
これ重要、テストにでます Rect構造体 60 00 3f c0 00 3f c0 をデコード
可変 5bit 12bit 12bit 12bit 12bit Zero padding | ssss sxxx | xxxx xxxx | xXXX XXXX | XXXX Xyyy | yyyy yyyy | yYYY YYYY | YYYY Y000 | | | | | | | | | | | | f | c | | f | c | f_size = sssss(5bit) = = 12 ※次から符号付整数が12bit(可変)×4個並ぶ f_x_min = xxxxxxxxxxxx(12bit) = twips f_x_max = XXXXXXXXXXXX(12bit) = twips (104px) f_y_min = yyyyyyyyyyyy(12bit) = twips f_y_max = YYYYYYYYYYYY(12bit) = twips (104px) 2^12 = -2047~+2047 の数値範囲 struct swf_rect { char align; unsigned f_size : 5; signed twips f_x_min : f_size; signed twips f_x_max : f_size; signed twips f_y_min : f_size; signed twips f_y_max : f_size; };
23
フレームレート(2byte) 例:12.0 frame/秒
swf_header_movie フレームレート(2byte) 例:12.0 frame/秒 b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; }; 8.8bit固定小数点形式 frame rate (例) 12.0 = 00 0c
24
swf_header_movie フレーム総数 (16bit整数)
b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; }; 16bit整数 frame count 通常は自動計算
25
お疲れ様でした ここまで SWFヘッダ終了! 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00
c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 お疲れ様でした
26
SWFファイルの基本構造 図で表すと・・・ ・ SWFヘッダ情報(ファイル先頭) タグ情報(TagID、size) いろいろ
ActionScriptのバイトコードも タグ構造体の中に入る ・ タグ情報(TagID、size) END で終了
27
[HEADER] File version: 4
[HEADER] File size: 75 [HEADER] Frame rate: [HEADER] Frame count: 2 [HEADER] Movie width: [HEADER] Movie height: [009] SETBACKGROUNDCOLOR (33/33/33) [00c] DOACTION ( 18 bytes) action: Push String:"o" String:"Hello world!\n" ( 0 bytes) action: SetVariable ( 0 bytes) action: End [025] DEFINEEDITTEXT defines id 0001 variable "o" [004] PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | | mul | | add [001] SHOWFRAME 1 (00:00:00,000) [000] END
28
(2) SWFタグ構造体(可変サイズ) 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00
c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 ややこしいことに bit計算しないとタグIDとサイズがわからない! struct swf_tag { unsigned short f_tag_and_size; f_tag = f_tag_and_size >> 6; f_tag_data_size = f_tag_and_size & 0x3F; if(f_tag_data_size == 63) { unsigned long f_tag_data_real_size; } else { f_tag_data_real_size = f_tag_data_size; }; 43 02 ↓ TagID:09 Size:3 SetBackgroundColor(TagID:09) → RR GG BB (3byte)
29
4 3 0 2 タグ構造体のヘッダ(2byteの場合) 1. Sizeが62byte以下の場合
t1 t0 s5 s4 s3 s2 s1 s0 t9 t8 t7 t6 t5 t4 t3 t2 TagID = t0*2^0 + t1*2^1 + t2*2^2 + t3*2^3 + … t9*2^9 = t0*1 +t3*8 = = 9 Size = s0*2^0 + s1*2^1 + s2*2^2 + s3*2^3 + … t5*2^5 = s0*1 +s1*2 = = 3
30
3 f 0 3 a 6 0 1 0 0 0 0 タグ構造体のヘッダ(6byteの場合) 2. Sizeが63byte以上の場合
t1 t0 s5 s4 s3 s2 s1 s0 t9 t8 t7 t6 t5 t4 t3 t2 f TagID = t0*2^0 + t1*2^1 + t2*2^2 + t3*2^3 + … t9*2^9 = t2*4 +t3*8 = = 12 Size = 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 = 63 (0x3f) ← magic number 本当のSize情報は次の4byte(32bit整数) で表す a 422 byte
31
たとえば、タグのデータはこんな感じのバイト列に変換されます
演習問題 たとえば、タグのデータはこんな感じのバイト列に変換されます 3byteのデータ 442byteのデータ SetBgColor (TagID= 9, Size=3) → RR GG BB doAction (TagID=12,Size=422)→ 3f 03 a xx … xx PlaceObject (TagID= 4, Size=7) → xx xx xx xx xx xx xx PlaceObject2 (TagID=26, Size=8) → xx xx xx xx xx xx xx xx ShowFrame (TagID= 1, Size=0) → 40 00 End (TagID= 0, Size=0) → 00 00 ※ size の大きさは TagID の種類やデータのフラグによって異なります(可変長に対応)
32
(3) やっとここで doAction 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00
c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 TagID Size [00c] DOACTION ( 18 bytes) action: Push String:"o" String:"Hello world!\n" ( 0 bytes) action: SetVariable ( 0 bytes) action: End 17 03 = TagID:12 Size:23byte __bytecode__(” ”) がここに出現!
33
__bytecode__ について わかりやすい資料 参考
Powered by yossyさん
34
(4) DefinedEditText 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00
c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 TagID Size [025] DEFINEEDITTEXT defines id 0001 variable "o" [004] PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | | mul | | add [001] SHOWFRAME 1 (00:00:00,000) [000] END
35
(5) PlaceObject b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 TagID Size [025] DEFINEEDITTEXT defines id 0001 variable "o" [004] PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | | mul | | add [001] SHOWFRAME 1 (00:00:00,000) [000] END
36
まめ知識:Matrix構造体も可変長 ここで、f_has_scale=0, f_has_rotate=0 とすれば2byte以上の節約、
struct swf_matrix { char align; unsigned f_has_scale : 1; if(f_has_scale) { unsigned f_scale_bits : 5; signed fixed f_scale_x : f_scale_bits; signed fixed f_scale_y : f_scale_bits; } unsigned f_has_rotate : 1; if(f_has_rotate) { unsigned f_rotate_bits : 5; signed fixed f_rotate_skew0 : f_rotate_bits; signed fixed f_rotate_skew1 : f_rotate_bits; unsigned f_translate_bits : 5; signed f_translate_x : f_rotate_bits; signed f_translate_y : f_rotate_bits; }; ここで、f_has_scale=0, f_has_rotate=0 とすれば2byte以上の節約、 TranslateX, TranslateY の数値範囲を小さくすればさらに節約できる
37
(6) ShowFrame b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 TagID Size [025] DEFINEEDITTEXT defines id 0001 variable "o" [004] PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | | mul | | add [001] SHOWFRAME 1 (00:00:00,000) [000] END
38
(7) End b f c0 00 3f c0 00 0c f 00 c 6c 6f f 72 6c a 00 1d 00 4d a 3e 80 0a 3e f 00 TagID Size [025] DEFINEEDITTEXT defines id 0001 variable "o" [004] PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | | mul | | add [001] SHOWFRAME 1 (00:00:00,000) [000] END
39
おわり
41
FizzBuzzやってみました おまけ
42
携帯でも動くよ FizzBuzzではじめるABC入門 FizzBuzz Binary Golf on FlashLite1.1/2.0
携帯でも動くよ trace使ってないので FlashLite1.1 で 251 byte まで (Flash4相当…)、 FlashLite2.0 で 159 byte まで削減できました! yossyさんのASバイトコードの話が聞けるっていうので、 予習として SWF Code Golf やってみました。
43
ベースのActionScriptの部分はこんな感じで。
FizzBuzz スタート ベースのActionScriptの部分はこんな感じで。 for (i = 1; i <= 100; i++) { 変数 x に以下の文字列を順に追記する ((i%15)?((i%5)?((i%3)?i:"Fizz"):"Buzz"):"FizzBuzz"); } DefineEditText で 変数 x を関連付け
44
しかし実際どのバイトコードの機能が使えるのかWebの情報からわからない
FlashLite について FlashLite は Flash4ベース Flash5 の一部の機能も使える しかし実際どのバイトコードの機能が使えるのかWebの情報からわからない (例)Math.sin は使えるけど、それはコンパイラが四則演算で近似値を求めるアクションのバイトコード列に変換してくれるから → ActionScriptの文法的に使える・使えないとは違う
45
FlashLite1.1で動くFlash5のバイトコード
鴨志田さん(サイボウズ・ラボ)調べによる [4D] Swap [4C] Duplicate [50] Increment [51] Decrement [60] BitAnd [61] BitOr [62] BitXor [3F] Modulo [63] ShiftLeft [64] ShiftRight [65] ShiftRightUnsigned FlashLite1.1 (Flash4相当)で これらのFlash5の命令が使える 残念ながら Modulo などの命令は FlashLite2.0 からサポート
47
ASバイトコードをさらに最適化 とりあえず
(1) 正解のFizzBuzz文字列をそのまま出力 -> 478 byte (FlashLite1.1) (2) FizzBuzzを計算しながら出力 -> 251 byte (FlashLite1.1) (3) FizzBuzzを計算しながら出力 -> 159 byte (FlashLite2.0) ここまで圧縮できました。
48
バイトコード最適化のテクニック 鴨志田さん情報 西尾さんのアイデア 社内でいろいろ教えてもらいました!(><)ノ まとめpush
FlashLiteの剰余計算 西尾さんのアイデア 変数の初期化を省略 i=0 の場合は、変数を初期化しなくても i++ で 1 となる 圧縮率を考慮したプログラミング 圧縮率が高くなるよう変数のネーミングを変える 社内でいろいろ教えてもらいました!(><)ノ
49
(例) fizz287.swf → fizz161.swf --- fizz287.flm +++ fizz161.flm -1,71 +1,48 -movie 'fizz287.swf' // flash 4, total frames: 1, frame rate: 12 fps, 104x104 px +movie 'fizz161.swf' compressed // flash 6, total frames: 1, frame rate: 12 fps, 104x104 px 287(Flash4圧縮なし) – 161(Flash6圧縮あり) = 126 byte の削減 frame 0 - push 'i', '0' - setVariable label1: - push 'i', 'i' + push '100', 'i', 'i', 'i' getVariable increment setVariable - push '100', 'i' oldLessThan - not branchIfTrue label6 - push 'x', 'x', 'x' - getVariable - push 'i' + push 'x', 'x' push 'i' push '15' - divide - int - push '15' - multiply - subtract + modulo branchIfTrue label2 push 'FizzBuzz' branch label5 label2: push 'i' getVariable - push 'i' - getVariable push '5' - push '5' branchIfTrue label3 push 'Buzz' label3: push 'i' getVariable - push 'i' - getVariable push '3' - divide - int - push '3' - multiply - subtract + modulo branchIfTrue label4 push 'Fizz' branch label5 label4: label5: concat push ' ' setVariable branch label1 label6: end // of frame 0 end
50
SWF Binary Code Golf on FlashLite 1.1
以上、 ご清聴ありがとうございました
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.