SWFバイナリ編集のススメ第0回 (解析編)

こんにちは、クライアント基盤チームのよやです。

昨今、Flash Player の自作が流行りのようですが、デバッグやテストに苦労されているとも聞き及んでいます。

丁度タイミング良く、SWFバイナリ編集のススメでサンプルとして引用している IO_SWF パッケージが SWF 解析ツールとして充実してきました。折角ですので、この場で紹介させて下さい。

野良 Flash Player の開発者であれば自前で SWF 解析ツールを用意出来ると思いますが、何かあった時に verify check として利用頂けると幸いです。

IO_SWF のインストール

php と pear コマンドが入っていれば3つのコマンドでインストール出来ます。

これで、 /usr/share/php/sample/ 辺りに php の解析ツールがインストールされます。

これと別に IO_SWF を Subversion で取ってきて実行すると、必要に応じて PHP のコードを弄る事で、より深い SWF 解析が出来ます。お勧めです。

サンプル SWF

ケルベロス開発チームから頂いた SWF ファイル(CerberusQuest.swf)をサンプルにして説明します。

SWF 全体

swfdump.php

  • SWF の生の情報が分かります。

  • -h を付けると16進数ダンプの表示がつきます。

  • DefineMorphShape も解析できます。

swfheader.php

  • SWF のヘッダ情報を表示します。

  • FrameRate を書き換える事も出来ます。

FrameRate の 3072 は 0x100(=256) 倍の数が入っていて、12 frames/sec 相当の値です。これを 256 で上書きすると 1 frames/sec になります。

  • FrameSize も書き換えられます。

FrameSize.Xmax:4800 とありますが、内部的に TWIPS という単位で座標値が格納されていて、通常の pixel の 20倍です。ですので、240 相当です。
FrameSize.Xmin を負の値で上書きする事により、Flash が通常表示する枠より左側を表示させてみます。

Flash によっては表示枠外に何か隠されている事がありますが、このファイルには隠し事はないようです。

swfgreptags.php

  • 特定のタグを持つ SWF を探す

例えば、カレントディレクトリで DefineMorphShape タグを持つ SWF ファイルを以下のように探せます。

コンテンツ系

swfextract.php

  • SWF に含まれるコンテンツを吸い出します。画像、音声、MovieClip に対応しています。

結果

  • 指定した prefix (上の例では "t-" )に CharacterID を付けたファイル名です。
  • -m を付けると、MovieClip を SWF 形式で出力します。

  • 骸骨のキャラです。> t-41.swf (SpriteId:41 の MovieClip)

殆どの部分が上の方(Y < 0)に隠れてしまっています。

0, 0 をベースにデザインされているのが予想出来るので、先程の swfheader.php で FrameSize を弄ります。


表示フレーム枠を左上に半分シフトして (-120, -120)-(120, 120) にする事で、画像の全体が表示されました。

ムービークリップ系

swflistmovieclip.php

  • MovieClip の一覧を表示します。

MovieClip の内部ID(SpriteId), フレーム数、タグ数、名前と、可能性のあるターゲットパス名が表示されます。

アクション系

swflistaction.php

  • SWF に含まれる Actionバイトコードの一覧を表示します。

  • MovieClipの ID(spriteId), フレーム番号、バイトコードの命令数、バイト長の順で1行に表示します。

swfdeleteaction.php

  • SWF 中の ActionScript を消します。制御を無くして全フレーム表示させたい場合に便利です。

全消し (-a オプション)

  • 制御が全部消えるので、各々の MovieClip が無限ループで再生されました。
  • 条件を指定すると特定のアクションを削除します。-s でスプライト(MovieClip)指定、-l でバイトコード長指定が出来ます。

swfdump.php

  • swfdump.php で Actionコードを逆アセンブルした結果が表示されます。又、-l を付けると Branch 命令に関連する場所にラベルがつきます。

swfdecompile.php

  • ActionScript バイトコードを逆コンパイルします。但し、独自言語です。

Push Push SetVariable が = に変換されて表示されたり、他にもバイトコードのニーモニックそのものより見易い形式で表示されます。

SWF 解析が捗りますね!

最後に

この他にも便利なツールがありますので、是非お試し下さい。引数無しで実行するとヘルプが表示されるので、使い方はそれで何となく分かると思います。
特に、

  • swfdeformeshape.php (Shapeの線分を減らす)
  • swfcountshapeedges.php (Shapeの線分を数える)
  • swfwireframe.php (塗りを境界のみ表示する)

の3つは、Shape の構造を探る上で役に立つかもしれません。

尚、これらの解析ツールの半分は beketa 氏 の実装です。この場を借りて感謝します。

以上、Flash Player 作りでデバッグのお役に立てると幸いです。

P.S. ツールが欲しいと思った時に即興で作ったものばかりなので、ファイル指定で -f を付けたり付けなかったり、ファイル名も統一性がありませんが、どうかご容赦を。