SWF AS3 文字列入れ替え

AS3 の定数文字列は ABC の初めの方にある Constant Pool で定義されているそうで、これなら簡単に出来るだろうと PHP で入れ替え処理を実装しました。尚、openpear の IO_SWF や IO_Bit は今回使わずに実装してます。
int+ist

プログラム

処理プロセス

  • SWF => SWFHeader(8byte) + SWFMovieHeader + SWFMovie
    • If sig = CWS then zlib uncompress SWFMovie
  • SWFMovie => TAG + TAG + ...
  • TAG (DoABC) => TagHeader + flag(4byte) + name(string) + ABC
  • ABC => version(4 byte) + intList & uintList + doubleList + stringList + etc.
  • stringList => strlen(u30) + string(strlen byte) + strlen ...
  • string を入れ替える。
  • 各データ長フィールドの内容を再計算して上書き、最後に全データを連結。
u30

ABC の基本型である u30 のデータ構造が少し特殊で

  • 0 〜 2^7-1 => (1byte) 0XXXXXXX
  • 2^7 〜 2^(7+7)-1 => (2byte) 1XXXXXXX 0XXXXXXXX
  • 2^(7+7) 〜 2^(7+7+7)-1 => (3byte) 1XXXXXXX 1XXXXXXX 0XXXXXXX
  • ...以下同様

のように MSB を拡張ビットとして使い、可変長フィールドで表現します。(UTF-8 っぽい)

使い方

  • Usage
yoya@sakura:~/git/flashswf$ php swfas3strreplace.php 
Usage: swfas3strreplace.php <swf> # listing
Usage: swfas3strreplace.php <swf> <from> <to> [<from2> <to2> [...]]
  • SWF だけ渡すと AS3 文字列のリストを取得出来ます。
yoya@sakura:~/git/flashswf$ php swfas3strreplace.php topbg.swf
string_count: 34
	[0]: (null string)
	[1]: madoka_fla
	[2]: OP_1
	[3]: flash.display
	[4]: MovieClip
	[5]: madoka_fla:OP_1
	[6]: 
	[7]: mami
	[8]: hmhm
	[9]: anko
	[10]: syk
<略>
  • リスト中の適当な文字列(hmhm)を適当に書き換えます。
yoya@sakura:~/git/flashswf$ php swfas3strreplace.php topbg.swf hmhm yoyayoya  > output.swf
  • 結果確認。
yoya@sakura:~/git/flashswf$ php swfas3strreplace.php output.swf | grep -C 1 yoya
	[7]: mami
	[8]: yoyayoya
	[9]: anko

参考

swfmill でも Constant Pool の文字列を確認できます。

yoya@sakura:~/git/flashswf$ swfmill swf2xml topbg.swf | grep -A 42 "<DoABCDefine"
      <DoABCDefine flags="1" name="">
        <actions>
          <Action3 minorVersion="16" majorVersion="46">
            <constants>
              <Constants>
                <ints/>
                <uints/>
                <doubles/>
                <strings>
                  <String2 value="madoka_fla"/>
                  <String2 value="OP_1"/>
                  <String2 value="flash.display"/>
                  <String2 value="MovieClip"/>
                  <String2 value="madoka_fla:OP_1"/>
                  <String2 value=""/>
<略>

追記 (2013/05/14)

PHP5.4 だと動きませんでした。

PHP Fatal error:  Call-time pass-by-reference has been removed in /home/yoya/git/flashswf/as3abc.php on line 28
yoya@sakura:~/git/flashswf$