下面纯粹出于一点兴趣,没有任何目的,希望不要惹来事非,源件:http://space.flash8.net/bbs/viewthread.php?tid=370332&extra=page%3D1。
我们比较熟悉的SWF文件的反编译器是SWFDecompiler和Action Script Viewer
它们现在公布已知的版本分别是4.5 和6.0 Alpha 4,前面的反编译(冗余)还是有问题的,后面的(简约)就是不能识别某类DoAbcTag(可参考AbcDump.as)
不要过分相信反编译器,毕竟有心人还是可以找出相对的策略...
从SWFDecompiler,我们可以得到反编译后唯一的Loader(Packer)的AS文件,如下:
代码:
package CYPL.utils
{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.system.*;
import flash.utils.*;
public class DisturbSWF extends Sprite
{
private var _c:Object;
private var _l:Object;
private var _p:Object;
private var _y:Object;
public function DisturbSWF()
{
this.addEventListener(Event.ADDED_TO_STAGE, initClass);
return;
}
private function initClass(param1:Event) : void
{
this.removeEventListener(Event.ADDED_TO_STAGE, initClass); // 暗事干好了,还留你就碍事
_c = new URLStream();
_c.addEventListener(Event.COMPLETE, completeHandler);
_c.load(new URLRequest(loaderInfo.url));
return;
}
private function completeHandler(param1:Event) : void
{
var _loc_2:int;
_p = new ByteArray();
_c.readBytes(_p);
_l = new ByteArray();
_p.readBytes(_l, 0, 4);
_p.position = _p[_p.length--] << 24 | _p[_p.length - 2] << 16 | _p[_p.length - 3] << 8 | _p[_p.length - 4];
_loc_2 = _p[_p.length - 4]; // Key
_p.readBytes(_l, 4); // Packed data
if (_loc_2 != 0)
{
_c = 4;
while (_c < _p.length)
{
if (_c % _loc_2 != 0)
{
_l[_c] = _l[_c] + _loc_2 & 255;
}
_c = _c + 1;
}
}
_y = new Loader();
_c = new LoaderContext();
_c.applicationDomain = ApplicationDomain.currentDomain;
addChild(Loader(_y));
_l.length = _l.length - 4; // 解码完毕,应该还可以精简,留给有心人做。
_y.loadBytes(_l, _c);
_l = null;
_p = null;
_c = null;
_y = null;
return;
}
}
}
SWF文件本身就是Overlay,这点可以利用ZLib进行解压、重压缩判定,解码的方法就不多说了,上面的字面应该简单的是。
我们看看这一句的代码片段:(很明显绝对是反编译器的Bug)
代码:
_p.position = _p[_p.length--] << 24 | _p[_p.length - 2] << 16 | _p[_p.length - 3] << 8 | _p[_p.length - 4];
_as3_getlex _p
_as3_getlex _p
_as3_getlex _p
_as3_getproperty length
_as3_decrement // 后面没有_as3_setproperty length,怎么能译为_p.length--;改掉不能识别的Tag,由ASV6译就没这错(_p.length - 1)
_as3_getproperty {}
_as3_pushbyte 24
_as3_lshift
_as3_getlex _p
_as3_getlex _p
_as3_getproperty length
_as3_pushbyte 2
_as3_subtract
_as3_getproperty {}
_as3_pushbyte 16
_as3_lshift
_as3_bitor
_as3_getlex _p
_as3_getlex _p
_as3_getproperty length
_as3_pushbyte 3
_as3_subtract
_as3_getproperty {}
_as3_pushbyte 8
_as3_lshift
_as3_bitor
_as3_getlex _p
_as3_getlex _p
_as3_getproperty length
_as3_pushbyte 4
_as3_subtract
_as3_getproperty {}
_as3_bitor
_as3_setproperty position