Flex-SWFに自動try-catchを埋め込み( その1 )

概要

SWFファイルのABC-Code上にあるmethod-bodyを解析して、実行時の例外発生を検知する処理を埋め込んでみる。

こうすることで、FlashPlayer(non-debugging-version)のときでも例外情報をとることができます。

ABC-Codeをパッチすることになりますが、Tamarin-escのクラスを使用してパッチする先を特定することにします。

おおまかな手順

  • SWF CWS==>FWS化
  • ABC部の特定
  • ABCヘ自動try-catchを埋め込むパッチ
  • ABCをSWFに戻す
  • SWF FWS==>CWS化

今回は

SWFの CWS==>FWS化 / FWS==>CWS化を試してみます。

SWFは通常CWSとして圧縮され(ヘッダー以外)ていますので、中身をみようと思うときは解凍しなければなりません。

というわけで、rubyを使い、CWS<==>FWSの変換を行ってみました。

<SWF Converter (CWS to FWS)>

# SWF Converter (CWS to FWS) 
#!/usr/local/bin/ruby
require 'zlib'
inFileName = ARGV[0]
outFileName = ARGV[1]

if(outFileName == '') then
   p 'Output File Name is not specified.'
   exit! 1
end
infile = File.open(inFileName)
if(inFileName == outFileName) then
   p 'Output File Name is not currect.'
   exit! 1
end
outfile = File.open(outFileName,"wb")
header = infile.read(8)
if(header[0,3] != 'CWS') then
   p 'This is not CWS(compressed) File.'
   exit! 1
end
header = header.sub(/CWS/, 'FWS')    
outfile.write(header)
outfile.write(Zlib::Inflate.inflate(infile.read))

<SWF Converter (FWS to CWS)>

# SWF Converter (FWS to CWS)
#!/usr/local/bin/ruby
require 'zlib'
inFileName = ARGV[0]
outFileName = ARGV[1]
if(outFileName == '') then
   p 'Output File Name is not specified.'
   exit! 1
end
infile = File.open(inFileName)
if(inFileName == outFileName) then
   p 'Output File Name is not currect.'
   exit! 1
end
outfile = File.open(outFileName,"wb")
header = infile.read(8)
if(header[0,3] != 'FWS') then
   p 'This is not FWS(un-compressed) file.'
   exit! 1
end
header = header.sub(/FWS/, 'CWS')
outfile.write(header)
outfile.write(Zlib::Deflate.deflate(infile.read, Zlib::BEST_COMPRESSION))

圧縮するときはBEST_COMPRESSIONとすると、ちょうど良いようです。

実行例

cwsTofws.rbで解凍、fwsTocws.rbで圧縮してみました。


$ ls -l Make*.swf
-rwx------ 1 * * 96556 2008-08-18 12:51 MakeButton.swf
$
$ ruby cwsTofws.rb MakeButton.swf MakeButtonFWS.swf
$
$ ls -l Make*.swf
-rwx------ 1 * * 96556 2008-08-18 12:51 MakeButton.swf
-rw-r--r-- 1 * * 192534 2008-10-19 12:52 MakeButtonFWS.swf
$
$ ruby fwsTocws.rb MakeButtonFWS.swf MakeButtonCWS.swf
$
$ ls -l Make*.swf
-rwx------ 1 * * 96556 2008-08-18 12:51 MakeButton.swf
-rw-r--r-- 1 * * 96556 2008-10-19 12:54 MakeButtonCWS.swf
-rwx------ 1 * * 192534 2008-10-19 12:52 MakeButtonFWS.swf
$


次は、ABC-Codeのパッチまでやってみます。