Flex SDK と Tamarin を使って Flash バイトコードを abcasm でアセンブルしたり abcdump で逆アセンブルする方法を書きます。私は Mac で作業しましたが、他でも大体同じだと思います。
出来る事
良くわからない事。
- ABC ファイルを SWF に埋込んでブラウザから実行する方法。(知ってたら教えてください!)
使うもの
- Tamarin : abcasm, abcdump(avmshell) を利用。書いている時点でリビジョン 711。
- 2009年7月現在 avmshell の動作が変なので、そこだけ 2008 年末のバージョンを使う
- Flex SDK 3 : asc を利用
- Java
ツールの説明
- abcasm : abc アセンブラ。.abs アセンブルソース → .abc バイトコードを作成。Java で実装
- abcdump : abc 逆アセンブラ。.abc バイトコード → アセンブルソースを作成。ActionScript で実装
- asc : ActionScript コンパイラ。.as ActionScript ソース → .abc バイトコードを作成 Java で実装
- avmshell : ActionScript バーチャルマシン。abc バイトコードを実行。昔は avmplus と言った。
- java : Java バーチャルマシン。java プログラムを実行。
改めて書いてみると強烈にややこしい。。。
Flex SDK 3 の準備
http://www.adobe.com/products/flex/flexdownloads/ からダウンロードするだけです。
$ export FLEX=(flex_sdk_3 の場所)
と環境変数をセットしておきます。
Tamarin の準備
Tamarin のビルドに必要なコマンドラインを書きます。大体 https://developer.mozilla.org/ja/Tamarin_Build_Documentation の解説通りですが、hg update を使って古いバージョンで作業する所だけ違います。
$ hg clone http://hg.mozilla.org/tamarin-central/ $ cd tamarin-central $ hg update -r 703 # 作業ディレクトリをリビジョン 703 に戻す。 $ mkdir objdir-release $ cd objdir-release $ python ../configure.py --enable-shell $ make $ ./objdir-release/shell/avmshell # 動作確認 avmplus shell 1.0 build cyclone
動作確認します。ActionScript を Flex でコンパイルして Tamarin で実行します。
$ echo 'print("hello, world")' > hello.as $ java -jar $FLEX/lib/asc.jar hello.as $ ./objdir-release/shell/avmshell hello.abc hello, world
abcdump の準備
abcdump は ActionScript で書かれているので、一旦 abc にコンパイルして先ほど作った avmshell 経由で動かします。abcdump.abc の作成に必要なコマンドラインを書きます。
$ java -jar $FLEX/lib/asc.jar -import core/builtin.abc shell/ByteArray.as $ java -jar $FLEX/lib/asc.jar -import core/builtin.abc -import shell/ByteArray.abc utils/abcdump.as
util/abcdump.abc に出来上がります。以下動作確認です。abc ファイルの名前は -- の後ろに書きます。
$ ./objdir-release/shell/avmshell utils/abcdump.abc -- hello.abc > hello2.abs
abcasm の準備
折角なので、出来上がった hello2.abs をもう一度コンパイルしてみます。ただし、このファイルには前後に余計なコメントが付いているので、編集してアセンブラだけにしてください。こんな風になると思います。
$ cat hello2.abs function script0$init():* /* disp_id 0*/ { // local_count=2 max_scope=1 max_stack=2 code_len=15 0 getlocal0 1 pushscope 2 findpropstrict print 4 pushstring "hello, world" 6 callproperty print (1) 9 coerce_a 10 setlocal1 11 getlocal1 12 returnvalue 13 kill 1 }
次に、リビジョン 703 には abcasm が含まれていないので再びソースを 711 に戻します。
$ hg udpate -r 711
いよいよコンパイルして実行です。abcasm はシェルスクリプトで、内部で java を読んでいます。
$ ./utils/abcasm/abcasm.sh hello2.abs hello2.abs $ ./objdir-release/shell/avmshell hello2.abc hello, world
また、utils/abcasm/ ディレクトリに面白いアセンブルソースのサンプルが色々あるので、バイトコードの練習にいいと思います。