swf文件修改总结

目标:

有一个网页内嵌swf文件,没有源代码,需要修改其功能。

步骤:

一、下载网页中的swf文件

    使用网页资源下载工具(mybrowse.exe),此工具能把浏览过的网页及其资源原封不动全部下载到本地电脑(此工具在本文章末工具包里面提供)。

我的浏览器

二、解密client.swf

用JPEXS逆向工具打开client.swf,看不到资源文件和脚本。说明已被加密过。需要解密!

JPEXS

JPEXS简介:

    JPEXS是目前最好用的开源免费swf逆向工具。官网地址为:

https://www.free-decompiler.com/flash/

JPEXS

    

解密工具(swfdump.exe)简介:

    尝试了多款swf解密工具,最终用swfdump.exe解密成功!swfdump.exe暴力直接!无论swf文件用什么工具加密的,swfdump.exe都能解密!

解密原理:因为swf文件必须先解密释放到内存中才能运行,swfdump.exe能够查找swf文件在进程内存中的特征字符串,然后把符合swf文件特征的整块内存复制保存下来,此内存块即为swf文件在内存中的解密文件!

(swfdump.exe在文章末工具包里面有提供。)

解密方法:

步骤一、先用flash播放器加载client.swf文件到内存中。(flash播放器为:flashplayer_sa.exe文章末工具包里有提供)

flashplayer播放器

步骤二、打开CMD,执行以下命令:

swfdump.exe flashplayer_sa.exe

flashplayer_sa.exe为加载client.swf文件的进程名。运行结果:

swfdump.exe

提取已解密的swf文件:

swfdump.exe

至此,文件解密工作大功告成!用JPEXS打开,结果为:(可以看到全部资源文件和脚本了!)

JPEXS

三、使用JPEXS对swf文件进行指令级修改。

一、在关键地方插入trace()调试指令代码。以下是调试通过的代码:
//trace("start crpt:");
findpropstrict Qname(PackageNamespace(""),"trace")
pushstring "start crpt:"
callpropvoid Qname(PackageNamespace(""),"trace") 1


//trace(_local_);
findpropstrict Qname(PackageNamespace(""),"trace")
getlocal_1
callpropvoid Qname(PackageNamespace(""),"trace") 1

//trace("price:"+this.K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K);
findpropstrict Qname(PackageNamespace(""),"trace")
pushstring "price: "
getlex Qname(PackageNamespace(""),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")
add
callpropvoid Qname(PackageNamespace(""),"trace") 1

    JPEXS目前只允许修改SWF字节码,直接修改源代码可能会导致发生不可预料的错误!修改地方为软件右边区域:

JPEXS修改字节码演示

二、修改类私有变量为公共变量:

    修改的目的是方便在另一个对象里面访问并取得该变量的值。

//原私用变量: private var K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K;

trait slot Qname(PrivateNamespace(null,"51"),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")
slotid 0
type null
value Undefined
end ; trait

//修改为公共变量: public var K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K;

trait slot Qname(PackageNamespace(""),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")
slotid 0
type Qname(PackageNamespace(""),"int")
value Integer(0)
end ; trait

//相应的所有对该变量的调用都要做字节码的修改: 
源代码:
K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K = _loc2_.basePrice;
字节码:
findproperty Qname(PackageNamespace(""),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")  //公共变量字节码
getlocal_2
getproperty Qname(PackageNamespace(""),"basePrice")
initproperty Qname(PackageNamespace(""),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")  //公共变量字节码
三、在另一个对象里面添加代码,获取以上公共变量的值。从而改变程序功能:
//这是在另一个类里面的代码,增加一行,取得以上公共变量的值,并在此值的基础上加300:
//源代码:
 K174937672F20993E874DFB970BCFFEBDC0FAE6445900K = ȵ(Ǻ.§˳§.§;§(ȵ)).K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K+300;

//字节码:
findproperty Qname(PrivateNamespace(null,"127"),"K174937672F20993E874DFB970BCFFEBDC0FAE6445900K")
findpropstrict Qname(PackageNamespace("ǹ"),"ȵ")
getlex Qname(PackageNamespace("ǻ"),"Ǻ")
getproperty Qname(PackageNamespace(""),"˳")
getlex Qname(PackageNamespace("ǹ"),"ȵ")
callproperty Qname(PackageNamespace(""),";") 1
callproperty Qname(PackageNamespace("ǹ"),"ȵ") 1
getproperty Qname(PackageNamespace(""),"K174936A5B31DB7B1424E2CBCE10F7E322C6AA2445899K")
pushshort 300
add
initproperty Qname(PrivateNamespace(null,"127"),"K174937672F20993E874DFB970BCFFEBDC0FAE6445900K")
四、对相应条件语句做修改,从而使某些代码永远不会被执行:

    这个修改起来比较简单。

//源代码:
 if(_loc4_ < 60000) //修改为:if(_loc4_ < 1),从而使if条件语句不会被执行!
//字节码:
etlocal_3
getlocal_3
pushint 1    //原:pushint 60000
ifnlt ofs006c

    修改完成后保存!经调试,成功改变了程序执行逻辑,达到了相要的效果!

    以上工具软件,在以下地址下载:

https://download.csdn.net/download/byc6352/11887435
Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐