Flex-SWFに自動try-catchを埋め込み( その2 )
概要
SWFファイルのABC-Code上にあるmethod-bodyを解析して実行時の例外発生を検知する処理を埋め込んでみる、の続きです。
今回は、# ABC部の特定、# ABCヘのパッチの予定でしたが長くなるのでABC部の特定の途中までとします。
なお、パッチに関して結論をいうと、とある理由によりその目的を達成することができませんでしたので、そこら辺を書いてみます。
SWF内でのABC部の特定
参考資料:「 SWF File Format Specification Version 9 」
SWFファイルは以下の構造をもちますので、ABC Code の Tag(DoABC)をさがしていくことになります。
Header / FileAttributesタグ / タグ / タグ / ----- / タグ / タグ / Endタグ
なお、DoABCタグは複数存在することがありますので注意要です。
以下のロジックにて、DoABCタグの名前、start position、length を配列化しています。DoABCタグの名前とは、例えば、"frame1" "frame2"などです。
data = SWFファイル byteArrayvar _type:int, h:int, length:int;
var offset:int;
var abcOffsetArray:Array = [];
var abcOffset = {};loop:while (data.position < data.length) {
//----TagとLengthを取得する。
// Upper 10 bits: tag type
// if Lower 6 bits is 0x3F ?, RECORDHEADER(long)
_type = (h = data.readUnsignedShort()) >> 6;
abcOffset.doABCStart = data.position -2;
if ((length = h & 0x3F) == 0x3F){
length = data.readInt();
}
abcOffset.doABCLength = length;
switch (_type) {
case 0: // Endタグ
break loop;
case 82: // DoABCタグ
data.readInt();
abcOffset.abcName = readString();
length -= (data.position-pos1);
abcOffset.start = data.position;
abcOffset.length = length;
abcOffsetArray.push(abcOffset);
break;
default:
break;
}
data.position += length
}private function readString():String {
var s:String = ""
var c:int
while (c=data.readUnsignedByte())
s += String.fromCharCode(c)
return s
}
DoABCタグ
------------------------------------------------------------
Field Type Comment
------ -------------- ----------------------------------------
Header RECORDHEADER Tag type = 82
------ -------------- ----------------------------------------
Flags UI32 A 32-bit flags value, which may contain the following bits
set: kDoAbcLazyInitializeFlag = 1: Indicates that the ABC block
should not be executed immediately, but only parsed.
A later finddef may cause its scripts to execute.------ -------------- ----------------------------------------
Name STRING The name assigned to the bytecode.------ -------------- ----------------------------------------
ABCData BYTE[] A block of .abc bytecode to be parsed by the ActionScript 3.0
virtual machine, up to the end of the tag.
RECORDHEADER (short)
------------------------------------------------------------
Field Type Comment
----------------- ------ ----------------------------------
TagCodeAndLength UI16 Upper 10 bits: tag type
Lower 6 bits: tag length
RECORDHEADER (long)
------------------------------------------------------------
Field Type Comment
----------------- ------ ----------------------------------
TagCodeAndLength UI16 Tag type and length of 0x3F
Packed together as in short header
----------------- ------ ----------------------------------
Length SI32 Length of tag
SWFからABC部をとりだしパッチしてSWFにもどす
パッチは、EvalSupporterクラスを使いおこないますが、当該クラスの説明は次回まわし。
data = SWFファイル byteArrayvar newSwf = new ByteArray();
var startOffset = 0;
for(var i:uint=0; iABCByteStream : Tamarin/esc/src/bytes-tamarin.es にて定義
EvalSupporter : 次回へ。
今回はここまで。