|
 
- 帖子
- 880
- 积分
- 157
- 技术分
- 19
- 在线时间
- 402 小时
- 注册时间
- 2008-8-9
|
1#
发表于 2010-1-23 20:10
| 只看该作者
去doswf,swfEncrypt水印的方法
本帖最后由 askforone 于 2010-1-23 20:38 编辑
doswf破解版本很老且无用,最新的功能较强大且无破解版。试着用它加密过不下几百个,然后试图破解,只有2个完全成功。有些标签经过加密后,会让ASV和闪客精灵卡死。不过加过密的swf,很多都被部分损坏。
目前摸清楚了点原理,还在继续研究中。
doSwf基本上是用byteArray把原swf分解加工成ABC文件,然后用混淆过的builtin和类进行重组。而这种方法,是在swf10才有的。可以直接用abc文件的opcode和avm2debug代码,是伴随着alchemy出现的。所以针对swfencrypt6.04和doswf4来说,除了swf默认的文件格式,还得知道alchemy项目编译后的swf,有什么规律。这个因为本人不擅C语言,一点研究都没,暂时只做些推测。
很怀疑是不是doswf是直接addChild整个原swf,替换掉了stage。之所以这样认为,是因为一个有NN个addChild的swf,经过加密后,只剩下两个addChild,和一个removeChild。试图把这里的addChild和removeChild替换发现。原swf居然和doswf的水印居然是一个object。但是在as里写trace得知,原始的路径确实是在stage下面没错。
之间的代码大概是这样的
setTimeout(fun,5000) //给个缓冲时间,因为doswf加密后的东西,往往隔个1-2秒才出现。
function fun(){
trace(this.stage.numChildren())
}
我们可以发现,经过加密后,stage上的children变多了一个,即是水印。而通过修改上面说的两个addChild和一个removeChild的部分,如果取消removeChild部分,stage的显示列表下实际上是多了两个物件。第一个物件不详,并且修改之,会使得flash打不开。猜测很可能是原始的stage。最想不通的是为什么水印会和原始的swf里的物件在同一个层级中。这里还需要很多研究,而且doswf每次加密时都会生成随机的替换字符用来混淆,甚至用来作为byteArray解析的密匙。
另外,addChild部分做解密后大概是这样的: //替换stage没看到过相关的资料,也不一定确实可行,所以下面的伪码,实际效果可以实现,但是反推的代码很可能是错误的。
setTimeout(fun,time) //一定时间缓冲。可能怕水印加太早被其他物件覆盖。
addEventListener(Event.ADDED_TO_STAGE,fun1(e))
function fun(){
加水印到原swf的stage中
移除原来的stage
}
function fun1(e){
把整个stage加进场景
}
而因为类名都进行过混淆,且doswf一加密至少多出9KB,暂时还没找到。所以只能用以下拙劣的方法去水印了
addEventListener(Event.ENTER_FRAME,doswf)
function doswf(e){
var m=this.stage.getChildAt((this.stage.numChildren-1))
if(m.x==0&&m.y==0&&m.width==129&&m.height==30){
this.stage.removeChild(m)
removeEventListener(Event.ENTER_FRAME,doswf)
}
}
理论上,可以通过它的opcode来反推水印。无奈在不同的AVM模拟器中,得到的opcode不尽相同,且目前AVM模拟器对比官方的flashplayer10落后很多。如果不知道原理,反编译doswf加密的swf10,几乎是不可能的。
而非替换整个文件结构的加密,去水印则很容易。
swf.uncompress() //一切加解密都是在解压缩后操作的
for(var i=l2;i<l1;i--){ //通过判断byte中的数据,去掉目录里的水印的相关数据。
swfByte.readBytes(h,i,length)
if(h.toString()==" "){
重组swf
}
}
此数据位置因为是在 目录 中,所以在文件尾处倒着查起的某个范围中。对于不同的加密软件,参数都不一样。对于swfEncrypt之前的版本来说,基本上没加密且都在文件尾。。
另。
正因为doswf加水印是用addedtostage触发的,所以用onEnterFrame或setInterval都会有个小的时间差。等研究多一些时,应该写个方法,把去水印函数加在添水印的函数里才算完美。 |
|