SWF Binary Code Golf on FlashLite 1.1

Slides:



Advertisements
Similar presentations
FxUG in Toyama # Presented by wacky. 最近 AMF 3 の Encode/Decode を実装してみました。 そこで得た知識を共有したいと思います! 30分後には … AMF の基本構造が分かっている AMF の得手不得手が分かっている BlazeDS.
Advertisements

SWF Binary Hacks ~ eval のいばら道 ~ Shibuya.JS Technical Talk#3 – Shibuya.es 竹迫 良範.
Flash SWF ファイル書き換え PHP extension 2008 年 7 月 21 日 よや.
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
復習 配列変数の要素 5は配列の要素数 これらの変数をそれぞれ配列の要素と呼ぶ この数字を配列の添え字,またはインデックスと呼ぶ
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第4回 配列(2) 情報・知能工学系 山本一公
SWF研究会#2 発表#1 SWF の情報要素と バイナリの読み方
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第7回 データの基本型 情報・知能工学系 山本一公
データ構造とアルゴリズム 第10回 mallocとfree
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
基礎プログラミングおよび演習 第9回
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
第2回:Javaの変数と型の宣言 プログラミングII 2007年10月2日.
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング言語論 プログラミング言語論 プログラミング言語論 演習1 解答と解説 演習1解答と解説 1 1.
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
日本大学 文理学部 情報システム解析学科 谷研究室 益田真太郎
スクリプト言語を用いたPHITSの連続実行
IIR輪講復習 #5 Index compression
10: ファイル入出力 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
【プログラミング応用】 必修2単位 通年 30週 授業形態:演習.
情報処理Ⅱ 第2回 2007年10月15日(月).
行列による画像処理 デジタル表現論 担当者:劉 雪峰 2017年6月1日.
第二回 VB講座 電卓を作ろう.
プログラミング応用 printfと変数.
Cプログラミング演習 第7回 メモリ内でのデータの配置.
プログラミング 4 記憶の割り付け.
画像処理プログラムの説明.
プログラミング演習I 2003年5月7日(第4回) 木村巌.
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
第7回 プログラミングⅡ 第7回
デジタル画像とC言語.
4点FFT設計 ファイヤー和田 知久 琉球大学・工学部・情報工学科 教授
プログラミング基礎B 文字列の扱い.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
2013年度 プログラミングⅡ ~ 計算してみよう ~.
2015年度 プログラミングⅡ ~ 計算してみよう ~.
フロントエンドとバックエンドのインターフェース
情報処理Ⅱ 第2回:2003年10月14日(火).
プログラミング演習I 2004年5月19日(第5回) 理学部数学科・木村巌.
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
プログラミング演習I 2003年4月30日(第3回) 木村巌.
地域情報学 C言語プログラミング 第2回 変数・配列、型変換、入力 2017年10月20日
基礎プログラミング演習 第6回.
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
第6回レポート解説 条件1 条件2 条件3 月の入力 月、日、曜日の表示 日の入力 曜日の入力
12: コマンドライン引数 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
情報処理Ⅱ 第2回 2005年10月14日(金).
情報処理Ⅱ 第2回 2006年10月13日(金).
情報処理Ⅱ 2006年11月24日(金).
情報処理Ⅱ 第7回 2004年11月16日(火).
情報処理Ⅱ 2005年10月28日(金).
標準入出力、変数、演算子、エスケープシーケンス
プログラミング 4 文字列.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
岩村雅一 知能情報工学演習I 第8回(C言語第2回) 岩村雅一
プログラミング演習I 数値計算における計算精度と誤差
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
情報処理Ⅱ 第2回 2004年10月12日(火).
モバイルプログラミング第2回 C言語の基礎 (1).
情報処理Ⅱ 2005年11月25日(金).
printf・scanf・変数・四則演算
千代浩司 高エネルギー加速器研究機構 素粒子原子核研究所
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

SWF Binary Code Golf on FlashLite 1.1 サイボウズ・ラボ株式会社 竹迫 良範 http://labs.cybozu.co.jp/blog/takesako/

質問

Q. この意味が わかる人? ”CWS\006”

正解: “CWS\006” = 43 57 53 06 SWFファイルを16進数でダンプ 000000 43 57 53 06 fa 00 00 00 78 9c 5d cf 41 0a c2 30 000010 10 85 e1 3f 6d 15 0d 45 8b 1b 37 29 d8 0b 48 45 000020 5c a7 58 70 5d 3c 41 97 7a 00 37 3d 48 a0 0b af 000030 22 de 4c a7 29 85 28 84 b7 78 f3 4d 60 6e 64 15 000040 49 06 a9 a2 8e 00 1b bf 24 dd 16 0e 65 09 97 7b 000050 d7 fd a4 69 72 b3 7e 46 f4 b8 14 ce 8f 61 e0 d3 000060 b8 f9 44 5c 22 db 27 ac b0 0d 4e 8f b5 47 7d c4 000070 95 00 c6 30 ba 95 6f 27 b3 ff 33 c7 c0 f8 56 8c 000080 0e 4c 31 a0 1d 45 2e 7d fd a1 59 2a 5a 6d df f2 000090 da 85 ff 73 a6 14 0a 2a 39 ed 0b 95 09 2f ff 00009f +00 (3byte) : File magic “FWS” or “CWS” – 圧縮 +04 (1byte) : File version 6

Adobe Player Licensing から入手可能 SWFファイルフォーマットの仕様書 Adobe Player Licensing から入手可能 http://www.adobe.com/licensing/developer/ メールアドレス(Adobe ID)を登録 ライセンスに同意する必要がある Flash6以降の情報のみしか記載されていない Alexis‘ SWF Reference (お勧め) http://sswf.sourceforge.net/SWFalexref.html Flash6以前の情報についても書いてある Flash 1.0 とか Flash 4.0 (FlashLite 1.1相当) 2001年からの蓄積(これはすごい)

Alexis' SWF Reference : : : : http://sswf.sourceforge.net/SWFalexref.html : : : :

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; };

SWFファイルを DISアセンブル しながら勉強したい…

swfdumpコマンドで DISアセンブル SWFTOOLS の swfdump コマンドを使うと SWFファイルの内容をダンプすることができる http://www.swftools.org/documentation.html > swfdump --full FlashProxy.swf [HEADER] File version: 8 [HEADER] File is zlib compressed. Ratio: 63% [HEADER] File size: 796 (Depacked) [HEADER] Frame rate: 20.000000 [HEADER] Frame count: 1 [HEADER] Movie width: 450.00 [HEADER] Movie height: 325.00 [009] 3 SETBACKGROUNDCOLOR (ff/ff/ff) [027] 4 DEFINESPRITE defines id 20480 [000] 0 END [038] 21 EXPORTASSETS exports 20480 as "__Packages.MTASC" [03b] 643 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

swfdumpは新しいアクションレコードが苦手 : (    8 bytes) action: unknown[8e] (remainder of 8 bytes:"\0\0\0\2)\0p\0") アクションレコード[8e]の抽出に失敗 … orz [8e] Declare Function (Flash Version 7 で追加されたバイトコード)

Sothink SWF Decompiler (試用期間30日) http://www.sothink.com/product/flashdecompiler/

DISアセンブル結果(Sothink SWF Decompiler)

あと CPAN の SWF::File もお勧め dumpswf.plx dumpswf Flash.swf Flash Flash.swf そのものを生成する Perlスクリプト「Flash.pl」を生成 Windows ActivePerl なら ppm install SWF-File ですぐに使えるよ http://www.nmt.ne.jp/~ysas/butaperl/swf/File.sjis.pod.html

Sothink SWF Decompiler (試用期間30日) DISアセンブルまとめ Swftools – swfdump タグやバイトコードのデータ構造を理解できる Flash V6相当のSWFファイルならそこそこいける Sothink SWF Decompiler (試用期間30日) できればフリーのがいいなぁ ぼく ActionScript わからないし(><) SWF::File – dumpswf.plx DISアセンブルした結果が「Perlスクリプト」になる さらにそれを修正してSWFを再生成できる

Flasm 知らなかった! (><) こんな便利なものがあったとは・・・ http://flasm.sourceforge.net/ Yossyさん情報より

本題 前フリ ここまで

いったい何バイトになるんだろう? (ActionScript で意味のあるコード) 世界で一番小さい SWFファイル いったい何バイトになるんだろう? (ActionScript で意味のあるコード)

最小の “Hello world!\n” プログラム Code Golf チャレンジ 57 byte 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 http://namazu.org/~takesako/swf/ hello57.swf traceを使わないパターンなので、開発環境がなくても表示可能 (traceを使ってよければもっと小さくなるかも)

hello57.swf コード解説 SWF File magic (4byte) 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; }

32bit整数(リトルエンディアン) ファイルサイズ情報 (4byte) 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 struct swf_header { unsigned char f_magic[3]; 'FWS' or 'CWS' unsigned char f_version; unsigned long f_file_length; } 57 = 4b 00 00 00

Rect構造体 (可変サイズ) が入っている swf_header_movie Rect構造体 (可変サイズ) が入っている 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; };

これ重要、テストにでます 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 | | 0110 0000 | 0000 0000 | 0011 1111 | 1100 0000 | 0000 0000 | 0011 1111 | 1100 0000 | | 6 0 | 0 0 | 3 f | c 0 | 0 0 | 3 f | c 0 | f_size = sssss(5bit) = 011000 = 12 ※次から符号付整数が12bit(可変)×4個並ぶ f_x_min = xxxxxxxxxxxx(12bit) = 0 twips f_x_max = XXXXXXXXXXXX(12bit) = +2040 twips (104px) f_y_min = yyyyyyyyyyyy(12bit) = 0 twips f_y_max = YYYYYYYYYYYY(12bit) = +2040 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; };

フレームレート(2byte) 例:12.0 frame/秒 swf_header_movie フレームレート(2byte) 例:12.0 frame/秒 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 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

swf_header_movie フレーム総数 (16bit整数) 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 struct swf_header_movie { swf_rect f_frame_size; unsigned short fixed f_frame_rate; unsigned short f_frame_count; }; 16bit整数 frame count 通常は自動計算

お疲れ様でした ここまで SWFヘッダ終了! 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 お疲れ様でした

SWFファイルの基本構造 図で表すと・・・ ・ SWFヘッダ情報(ファイル先頭) タグ情報(TagID、size) いろいろ ActionScriptのバイトコードも タグ構造体の中に入る ・ タグ情報(TagID、size) END で終了

[HEADER] File version: 4 [HEADER] File size: 75 [HEADER] Frame rate: 12.000000 [HEADER] Frame count: 2 [HEADER] Movie width: 102.00 [HEADER] Movie height: 102.00 [009] 3 SETBACKGROUNDCOLOR (33/33/33) [00c] 23 DOACTION ( 18 bytes) action: Push String:"o" String:"Hello world!\n" ( 0 bytes) action: SetVariable ( 0 bytes) action: End [025] 13 DEFINEEDITTEXT defines id 0001 variable "o" [004] 5 PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | 1.000 0.000 0.00 | mul 1.0 1.0 1.0 1.0 | 0.000 1.000 0.00 | add 0 0 0 0 [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END

(2) SWFタグ構造体(可変サイズ) 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 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)

4 3 0 2 タグ構造体のヘッダ(2byteの場合) 1. Sizeが62byte以下の場合 t1 t0 s5 s4 s3 s2 s1 s0 t9 t8 t7 t6 t5 t4 t3 t2 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 4 3 0 2 TagID = t0*2^0 + t1*2^1 + t2*2^2 + t3*2^3 + … t9*2^9 = t0*1 +t3*8 = 1 + 8 = 9 Size = s0*2^0 + s1*2^1 + s2*2^2 + s3*2^3 + … t5*2^5 = s0*1 +s1*2 = 1 + 2 = 3

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 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 3 f 0 3 TagID = t0*2^0 + t1*2^1 + t2*2^2 + t3*2^3 + … t9*2^9 = t2*4 +t3*8 = 4 + 8 = 12 Size = 2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 = 63 (0x3f) ← magic number 本当のSize情報は次の4byte(32bit整数) で表す a 6 0 1 422 byte 0 0 0 0

たとえば、タグのデータはこんな感じのバイト列に変換されます 演習問題 たとえば、タグのデータはこんな感じのバイト列に変換されます 3byteのデータ 442byteのデータ SetBgColor (TagID= 9, Size=3) → 43 02 RR GG BB doAction (TagID=12,Size=422)→ 3f 03 a6 01 00 00 xx … xx  PlaceObject (TagID= 4, Size=7) → 07 01 xx xx xx xx xx xx xx PlaceObject2 (TagID=26, Size=8) → 88 06 xx xx xx xx xx xx xx xx ShowFrame (TagID= 1, Size=0) → 40 00 End (TagID= 0, Size=0) → 00 00 ※ size の大きさは TagID の種類やデータのフラグによって異なります(可変長に対応)

(3) やっとここで doAction 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 TagID Size [00c] 23 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__(”96120000...”) がここに出現!

__bytecode__ について わかりやすい資料 参考 http://www.be-interactive.org/index.php?itemid=235 Powered by yossyさん

(4) DefinedEditText 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 TagID Size [025] 13 DEFINEEDITTEXT defines id 0001 variable "o" [004] 5 PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | 1.000 0.000 0.00 | mul 1.0 1.0 1.0 1.0 | 0.000 1.000 0.00 | add 0 0 0 0 [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END

(5) PlaceObject 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 TagID Size [025] 13 DEFINEEDITTEXT defines id 0001 variable "o" [004] 5 PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | 1.000 0.000 0.00 | mul 1.0 1.0 1.0 1.0 | 0.000 1.000 0.00 | add 0 0 0 0 [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END

まめ知識: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 の数値範囲を小さくすればさらに節約できる

(6) ShowFrame 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 TagID Size [025] 13 DEFINEEDITTEXT defines id 0001 variable "o" [004] 5 PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | 1.000 0.000 0.00 | mul 1.0 1.0 1.0 1.0 | 0.000 1.000 0.00 | add 0 0 0 0 [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END

(7) End 46 57 53 04 4b 00 00 00 60 00 3f c0 00 3f c0 00 0c 02 00 43 02 33 33 33 17 03 96 12 00 00 6f 00 00 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 1d 00 4d 09 01 00 60 0a 3e 80 0a 3e 80 60 08 6f 00 05 01 01 00 01 00 00 40 00 00 00 TagID Size [025] 13 DEFINEEDITTEXT defines id 0001 variable "o" [004] 5 PLACEOBJECT places id 0001 at depth 0001 | Matrix | CXForm r g b a | 1.000 0.000 0.00 | mul 1.0 1.0 1.0 1.0 | 0.000 1.000 0.00 | add 0 0 0 0 [001] 0 SHOWFRAME 1 (00:00:00,000) [000] 0 END

おわり

FizzBuzzやってみました おまけ

携帯でも動くよ FizzBuzzではじめるABC入門 FizzBuzz Binary Golf on FlashLite1.1/2.0 http://namazu.org/~takesako/swf/ 携帯でも動くよ trace使ってないので FlashLite1.1 で 251 byte まで (Flash4相当…)、 FlashLite2.0 で 159 byte まで削減できました! yossyさんのASバイトコードの話が聞けるっていうので、 予習として SWF Code Golf やってみました。

ベースのActionScriptの部分はこんな感じで。 FizzBuzz スタート ベースのActionScriptの部分はこんな感じで。 for (i = 1; i <= 100; i++) { 変数 x に以下の文字列を順に追記する ((i%15)?((i%5)?((i%3)?i:"Fizz"):"Buzz"):"FizzBuzz"); } DefineEditText で 変数 x を関連付け

しかし実際どのバイトコードの機能が使えるのかWebの情報からわからない FlashLite について FlashLite は Flash4ベース Flash5 の一部の機能も使える http://m-school.biz/event/files/2006_0602_flash_lite/FlashLite1x20060602.pdf しかし実際どのバイトコードの機能が使えるのかWebの情報からわからない (例)Math.sin は使えるけど、それはコンパイラが四則演算で近似値を求めるアクションのバイトコード列に変換してくれるから → ActionScriptの文法的に使える・使えないとは違う

FlashLite1.1で動くFlash5のバイトコード 鴨志田さん(サイボウズ・ラボ)調べによる http://labs.cybozu.co.jp/blog/kamoshida/ [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 からサポート

ASバイトコードをさらに最適化 とりあえず (1) 正解のFizzBuzz文字列をそのまま出力 -> 478 byte (FlashLite1.1) http://namazu.org/~takesako/swf/fizz478.swf http://namazu.org/~takesako/swf/fizz478.txt (2) FizzBuzzを計算しながら出力 -> 251 byte (FlashLite1.1) http://namazu.org/~takesako/swf/fizz251.swf http://namazu.org/~takesako/swf/fizz251.txt (3) FizzBuzzを計算しながら出力 -> 159 byte (FlashLite2.0) http://namazu.org/~takesako/swf/fizz159.swf http://namazu.org/~takesako/swf/fizz159.txt ここまで圧縮できました。

バイトコード最適化のテクニック 鴨志田さん情報 西尾さんのアイデア 社内でいろいろ教えてもらいました!(><)ノ まとめpush http://labs.cybozu.co.jp/blog/kamoshida/2007/01/flash_push.html http://labs.cybozu.co.jp/blog/kamoshida/2007/03/flashlite_2.html FlashLiteの剰余計算 http://labs.cybozu.co.jp/blog/kamoshida/2007/01/flashlite_1.html 西尾さんのアイデア 変数の初期化を省略 i=0 の場合は、変数を初期化しなくても i++ で 1 となる 圧縮率を考慮したプログラミング 圧縮率が高くなるよう変数のネーミングを変える 社内でいろいろ教えてもらいました!(><)ノ

(例) 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

SWF Binary Code Golf on FlashLite 1.1 以上、 ご清聴ありがとうございました