最近研究SWF逆向,可惜自身水平不足,遇到一些困难,希望大家能帮忙提点一下,应该如何分析flascc这类代码,我原来在代码里把它转换成汇编来看,但是这样还是没看出个东西,还有,看调用的地方是有参数的,但是flascc这里没看出来参数在哪里。先谢谢大家.AS3中加密的函数是:1.
public function construct()
{
super();
_cloader = new CLibInit();
_lib = _cloader.init();
ns = new Namespace("cmodule.rsa");
byteArray = ns::gstate.ds;
startpos=_lib.setStageDimension(1024); //这里可能是加密的地方
}
2.
public function EncryptEx(param1:ByteArray) : ByteArray
{
byteArray.position =startpos;//可能和这个startpos有关
byteArray.writeBytes(param1,0,param1.length);
_lib.setParticleData(param1.length); //这也可能是加密
byteArray.position = startpos;
byteArray.readBytes(param1,0,param1.length);
param1.position = 0;
return param1;
}
这个
setStageDimension只在不在AS代码里,是在一个叫
FSM_setStageDimension的类里
final override public function work():void
{
switch (state)
{
case 0:
public::mstate.esp = (public::mstate.esp - 4); //sub esp,4
si32(public::mstate.ebp, public::mstate.esp); //mov ebp,esp
public::mstate.ebp = public::mstate.esp; //mov ebp,esp
public::mstate.esp = (public::mstate.esp - 16); //sub esp,0x10
this.i0 =__2E_str3102; //来源在下面粉色的语句,但是赋值没找到
public::mstate.esp = (public::mstate.esp - 12); //sup esp,0xc
this.i1 = li32(public::mstate.ebp + 12); //[ebp+0xc]不知道是什么..
this.i2 =_stageWidth; //在CLintInit中分配内存,this._stageWidth= gstaticInitter.alloc(4, 4);赋值没找到
si32(this.i1, public::mstate.esp);
si32(this.i0, (public::mstate.esp + 4));
si32(this.i2, (public::mstate.esp + 8));
state = 1;
public::mstate.esp = (public::mstate.esp - 4);
public::mstate.funcs[_AS3_ArrayValue]();//not popped
return;
case 1:
public::mstate.esp = (public::mstate.esp + 12); //add esp,0xc
this.i0 = 119;
si8(this.i0, (public::mstate.ebp + -16)); //mov byte ptr:[ebp-0x10],119(0x77)
this.i0 = 115;
si8(this.i0, (public::mstate.ebp + -15)); //mov byte ptr:[ebp-0x0f],115(0x73)
this.i0 = 110;
si8(this.i0, (public::mstate.ebp + -14)); //mov byte ptr[ebp-0x0e],110(0x6E)
this.i0 = 100;
si8(this.i0, (public::mstate.ebp + -13)); //mov byte ptr[ebp-0x0d],100(0x64)
public::mstate.esp = (public::mstate.esp - 8);//sub esp,8
this.i0 = 0x0100;
this.i1 = 0;
si32(this.i1, public::mstate.esp); //mov dword ptr[esp],0
si32(this.i0, (public::mstate.esp + 4)); //mov dword ptr:[esp],0x100
state = 2;
public::mstate.esp = (public::mstate.esp - 4);//sub esp,4
FSM_pubrealloc.start();
return;
case 2:
this.i0 = public::mstate.eax;
public::mstate.esp = (public::mstate.esp + 8);
this.i2 = this.i1;
this.i3 = this.i0;
_label_1:
this.i4 = (this.i3 + this.i1);
si8(this.i2, this.i4);
this.i2 = (this.i2 + 1);
this.i1 = (this.i1 + 1);
if (this.i1 < 0x0100) goto _label_2;
this.i1 = 0;
this.i2 = this.i1;
do
{
this.i4 = (public::mstate.ebp + -16);
this.i5 = (this.i2 >> 31);
this.i5 = (this.i5 >>> 30);
this.i5 = (this.i2 + this.i5);
this.i5 = (this.i5 & 0xFFFFFFFC);
this.i5 = (this.i2 - this.i5);
this.i6 = (this.i3 + this.i2);
this.i7 = li8(this.i6);
this.i4 = (this.i4 + this.i5);
this.i4 = li8(this.i4);
this.i1 = (this.i7 + this.i1);
this.i1 = (this.i1 + this.i4);
this.i4 = (this.i1 >> 31);
this.i4 = (this.i4 >>> 24);
this.i4 = (this.i1 + this.i4);
this.i4 = (this.i4 & 0xFFFFFF00);
this.i1 = (this.i1 - this.i4);
this.i4 = (this.i0 + this.i1);
this.i5 = li8(this.i4);
si8(this.i5, this.i6);
si8(this.i7, this.i4);
this.i2 = (this.i2 + 1);
} while (!(this.i2 > 0xFF));
this.i1 = 0;
si32(this.i0, _mBox2);
this.i0 = li32(_stageWidth);
public::mstate.esp = (public::mstate.esp - 8);
si32(this.i1, public::mstate.esp);
si32(this.i0, (public::mstate.esp + 4));
state = 3;
public::mstate.esp = (public::mstate.esp - 4);
FSM_pubrealloc.start();
return;
case 3:
this.i0 = public::mstate.eax;
public::mstate.esp = (public::mstate.esp + 8);
si32(this.i0, _output);
public::mstate.esp = (public::mstate.esp - 4);
si32(this.i0, public::mstate.esp);
state = 4;
public::mstate.esp = (public::mstate.esp - 4);
public::mstate.funcs[_AS3_Ptr](); //not popped
return;
case 4:
this.i0 = public::mstate.eax;
public::mstate.esp = (public::mstate.esp + 4);
public::mstate.eax = this.i0;
public::mstate.esp = public::mstate.ebp;
public::mstate.ebp = li32(public::mstate.esp);
public::mstate.esp = (public::mstate.esp + 4);
public::mstate.esp = (public::mstate.esp + 4);
public::mstate.gworker = caller;
return;
_label_2:
goto _label_1;
default:
throw ("Invalid state in _setStageDimension");
};
}
internal const__2E_str3102:int = gstaticInitter.alloc(20, 1);这个setParticleData只在不在AS代码里,是在一个叫FSM_setParticleData的类里
public static function start() : void
{
var _loc1_:FSM_setParticleData = null;
_loc1_ = new FSM_setParticleData();
FSM_setParticleData.gworker = _loc1_;
}
override public final function work() : void
{
switch(state)
{
case 0:
mstate.esp = mstate.esp - 4;
si32(mstate.ebp,mstate.esp);
mstate.ebp = mstate.esp;
mstate.esp = mstate.esp - 0;
this.i0 = FSM_setParticleData;
mstate.esp = mstate.esp - 12;
this.i1 = li32(mstate.ebp + 12);
this.i2 = FSM_setParticleData;
si32(this.i1,mstate.esp);
si32(this.i0,mstate.esp + 4);
si32(this.i2,mstate.esp + 8);
state = 1;
mstate.esp = mstate.esp - 4;
return;
§§push(mstate.funcs[FSM_setParticleData]());//这里是什么鬼?return了还能push???
case 1:
mstate.esp = mstate.esp + 12;
this.i0 = li32(FSM_setParticleData);
this.i1 = li32(FSM_setParticleData);
this.i0 = this.i1 + this.i0;
si32(this.i0,FSM_setParticleData);
if(this.i0 >= 1025)
{
this.i2 = 0;
this.i0 = this.i0 + -1024;
si32(this.i0,FSM_setParticleData);
this.i1 = this.i1 - this.i0;
si32(this.i1,FSM_setParticleData);
si32(this.i2,FSM_setParticleData);
if(this.i1 <= 0)
{
this.i2 = 0;
this.i3 = this.i2;
}
else
{
this.i1 = 0;
this.i2 = li32(FSM_setParticleData);
this.i3 = li32(FSM_setParticleData);
this.i4 = li32(FSM_setParticleData);
this.i5 = li32(FSM_setParticleData);
do
{
this.i4 = this.i4 + 1;
this.i4 = this.i4 & 255;
this.i6 = this.i2 + this.i4;
this.i7 = li8(this.i6);
this.i5 = this.i7 + this.i5;
this.i5 = this.i5 & 255;
this.i8 = this.i2 + this.i5;
this.i9 = li8(this.i8);
si8(this.i9,this.i6);
si8(this.i7,this.i8);
this.i6 = li8(this.i6);
this.i6 = this.i7 + this.i6;
this.i7 = this.i6 >> 31;
this.i7 = this.i7 >>> 24;
this.i7 = this.i6 + this.i7;
this.i7 = this.i7 & -256;
this.i6 = this.i6 - this.i7;
this.i6 = this.i2 + this.i6;
this.i7 = this.i3 + this.i1;
this.i8 = li8(this.i7);
this.i6 = li8(this.i6);
this.i6 = this.i6 ^ this.i8;
si8(this.i6,this.i7);
this.i6 = li32(FSM_setParticleData);
this.i1 = this.i1 + 1;
}
while(this.i1 < this.i6);
si32(this.i4,FSM_setParticleData);
si32(this.i5,FSM_setParticleData);
si32(this.i1,FSM_setParticleData);
this.i3 = this.i1;
this.i2 = this.i1;
this.i1 = this.i6;
}
this.i4 = 0;
this.i1 = this.i0 + this.i1;
si32(this.i1,FSM_setParticleData);
si32(this.i4,FSM_setParticleData);
si32(this.i4,FSM_setParticleData);
if(this.i2 < this.i1)
{
this.i1 = this.i3;
addr415:
this.i0 = this.i1;
this.i1 = li32(FSM_setParticleData);
this.i2 = li32(FSM_setParticleData);
this.i3 = li32(FSM_setParticleData);
this.i4 = li32(FSM_setParticleData);
do
{
this.i3 = this.i3 + 1;
this.i3 = this.i3 & 255;
this.i5 = this.i1 + this.i3;
this.i6 = li8(this.i5);
this.i4 = this.i6 + this.i4;
this.i4 = this.i4 & 255;
this.i7 = this.i1 + this.i4;
this.i8 = li8(this.i7);
si8(this.i8,this.i5);
si8(this.i6,this.i7);
this.i5 = li8(this.i5);
this.i5 = this.i6 + this.i5;
this.i6 = this.i5 >> 31;
this.i6 = this.i6 >>> 24;
this.i6 = this.i5 + this.i6;
this.i6 = this.i6 & -256;
this.i5 = this.i5 - this.i6;
this.i5 = this.i1 + this.i5;
this.i6 = this.i2 + this.i0;
this.i7 = li8(this.i6);
this.i5 = li8(this.i5);
this.i5 = this.i5 ^ this.i7;
si8(this.i5,this.i6);
this.i5 = li32(FSM_setParticleData);
this.i0 = this.i0 + 1;
}
while(this.i0 < this.i5);
si32(this.i3,FSM_setParticleData);
si32(this.i4,FSM_setParticleData);
si32(this.i0,FSM_setParticleData);
}
}
else
{
this.i0 = 0;
si32(this.i0,FSM_setParticleData);
if(this.i1 >= 1)
{
this.i1 = 0;
§§goto(addr415);
}
}
state = 2;
mstate.esp = mstate.esp - 4;
return;
§§push(mstate.funcs[FSM_setParticleData]());
case 2:
this.i0 = mstate.eax;
mstate.eax = this.i0;
mstate.esp = mstate.ebp;
mstate.ebp = li32(mstate.esp);
mstate.esp = mstate.esp + 4;
mstate.esp = mstate.esp + 4;
mstate.gworker = caller;
return;
}
}
换过来调用就是FSM_setStageDimension(1024);和FSM_setParticleData(param1.length);
看到调用的地方是2个这样的函数都是一个参数,都是长度呀。。。很奇怪,输出的内容是加密了的最后,还有一个疑问,就是:没看到EncrptEx(param1)里面没有对param1操作呀,为什么还能输出加密的字符串??
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2019-9-19 12:05
被bugshunter编辑
,原因: