Flash之swf文件的加密与破解 | 您所在的位置:网站首页 › 怎么破解加密软件加密的文件 › Flash之swf文件的加密与破解 |
Flash之swf文件的加密与破解 Flash,现在叫animate,风靡于PC网络时代,整个时代弥漫着无数经典的作品,现在是移动互联时代H5逐渐代替了她的位置。逐渐地,flash变成了制作H5的一个工具。 深呼吸一下……顺便追忆前世今生 。 好了,闲言少叙,且看flash的swf文件。 swf文件是一种公开标准的文件格式,一般由flash软件发布。 文件格式(SWF)详细说明书https://blog.csdn.net/yjfkpyu/article/details/4032202http://www.360doc.com/content/15/0112/12/9200790_440101266.shtml 用其开发软件可以承载交互丰富的多媒体内容。 为了保护软件内容不被轻易的盗取,一般都要进行加密。 一般swf加密方法,都是按照一定的算法将文件的bytearray进行变换,得到一个player无法识别的文件。 player播放时需要按照算法逆运算,就可以得到swf文件然后进行装载播放了。 说白了加密解密就是玩一个字符串的游戏。 常用的操作如下 异或、替换或增加数据、改变字节顺序、base64转换、压缩等 本来嘛,内容既要隐藏又要展现就是矛盾的。 软件可以扫描内存从中提取展示的swf文件。 不管怎样内容还是要给人看的,所以再怎么变换也有让别人拿走的机会。 因此这些加密的手法也只能做到在一定程度上的防备。 对于一个经验多一点的闪客来说,想要的都能想办法拿到。声明:本人遵纪、守法、讲道德,且一贯的尊重所有软件的知识产权。反编译代码仅为学习研究之目的,并无恶意。 下面举个栗子: 案例1 base64+增加数据实施对文件的加密。 反编译代码 package { import com.hurlant.util.*; import flash.utils.*; public class ByteCodeMix extends Object { public function ByteCodeMix(arg1:String) { super(); if (arg1) { _key = arg1 + innerKey; } else { _key = innerKey; } endkb = new flash.utils.ByteArray(); endkb.writeUTFBytes(endkey); return; } public function enCodeMix(arg1:flash.utils.ByteArray, arg2:int):flash.utils.ByteArray { var loc3:*; (loc3 = new flash.utils.ByteArray()).writeUTF(_key); var loc4:*; (loc4 = new flash.utils.ByteArray()).writeInt(loc3.length); loc4.writeBytes(loc3); loc4.writeBytes(arg1); loc4.writeBytes(endkb); var loc5:*; (loc5 = new flash.utils.ByteArray()).writeBytes(loc4, 0, arg2); var loc1:*=com.hurlant.util.Base64.encodeByteArray(loc5) + _key; var loc2:*; (loc2 = new flash.utils.ByteArray()).writeUTF(loc1); loc2.writeBytes(loc4, arg2); return loc2; } public function deCodeMix(arg1:flash.utils.ByteArray):flash.utils.ByteArray { arg1.position = 0; var loc3:*=(loc3 = arg1.readUTF()).replace(_key, ""); var loc2:*=com.hurlant.util.Base64.decodeToByteArray(loc3); var loc1:*=new flash.utils.ByteArray(); arg1.readBytes(loc1, 0, arg1.bytesAvailable); var loc4:*; (loc4 = new flash.utils.ByteArray()).writeBytes(loc2); loc4.writeBytes(loc1); var loc6:*=new flash.utils.ByteArray(); loc4.position = 0; var loc5:*=loc4.readInt(); loc4.position = loc4.position + loc5; loc4.readBytes(loc6, 0, loc4.length - loc5 - 4 - endkb.length); return loc6; } private var _key:String; private var innerKey:String="iZSBGbGV4IDQgQXBwbGljYXRpb248"; private var endkey:String="lt_xggh_fla.sprite185copy3_89"; private var endkb:flash.utils.ByteArray; }解密方法 loc1 = (loc3 = new ByteCodeMix("RpdGxlPjxkYzpkZXNjcmlwdG")).deCodeMix(flash.net.URLLoader(arg1.target).data as flash.utils.ByteArray);分析: 能看出 有用的加密的文件结构是 -------------------------------------------------------------------------- | RpdGxlPjxkYzpkZXNjcmlwdGiZSBGbGV4IDQgQXBwbGljYXRpb248 | -------------------------------------------------------------------------- | swf数据 | -------------------------------------------------------------------------- | lt_xggh_fla.sprite185copy3_89 | -------------------------------------------------------------------------- 案例2 改变顺序反编译代码 package { import flash.display.*; import flash.events.*; import flash.net.*; import flash.system.*; import flash.utils.*; public class DecryptLoader extends flash.events.EventDispatcher { public function DecryptLoader(arg1:String, arg2:String, arg3:Boolean=true) { super(); isEncode = arg3; _strUrl = arg1; _strKey = arg2; return; } public function get getUrl():String { return _strUrl; } public function get getKey():String { return _strKey; } public function set setUrl(arg1:String):void { _strUrl = arg1; return; } public function set setkey(arg1:String):void { _strKey = arg1; return; } private function validKey(arg1:Array):Boolean { arg1.sort(); trace(arg1); return arg1.every(sequential); } private function sequential(arg1:*, arg2:int, arg3:Array):Boolean { return arg1 == arg2; } public function startLoad(arg1:Function=null):void { var loc2:*=new flash.net.URLRequest(_strUrl); var loc1:*=new flash.net.URLLoader(); loc1.dataFormat = "binary"; loc1.addEventListener("complete", handleUrlLoadComplete); loc1.addEventListener("ioError", onErr); if (arg1 != null) { _progress = arg1; loc1.addEventListener("progress", arg1); } loc1.load(loc2); return; } private function onErr(arg1:flash.events.IOErrorEvent):void { dispatchEvent(new flash.events.Event("LoadFail")); return; } private function handleUrlLoadComplete(arg1:flash.events.Event):void { if (_progress != null) { arg1.target.removeEventListener("progress", _progress); } var loc1:*=arg1.target.data as flash.utils.ByteArray; var loc4:*=new flash.utils.ByteArray(); if (isEncode) { if (!decrypt(loc1, loc4)) { dispatchEvent(new flash.events.Event("LoadFail")); return; } } var loc2:*=new flash.display.Loader(); loc2.contentLoaderInfo.addEventListener("complete", handleByteLoadComplete); var loc3:*; (loc3 = new flash.system.LoaderContext()).allowCodeImport = true; loc3.allowLoadBytesCodeExecution = true; loc3.applicationDomain = flash.system.ApplicationDomain.currentDomain; if (isEncode) { loc2.loadBytes(loc4, loc3); bytes = loc4; } else { loc2.loadBytes(loc1, loc3); bytes = loc1; } loader = loc2; return; } private function decrypt(arg1:flash.utils.ByteArray, arg2:flash.utils.ByteArray):Boolean { var loc4:*=0; var loc6:*=0; var loc3:*=0; if (arg1.length < 2000) { return false; } if (_strKey.length != 20 * 2) { return false; } var loc5:*=[]; var loc7:*=[]; loc4 = 0; while (loc4 < _strKey.length) { loc5.push(_strKey.substr(loc4, 2)); loc7.push(_strKey.substr(loc4, 2)); loc4 = loc4 + 2; } if (!validKey(loc7)) { return false; } var loc2:*=[]; var loc1:*=new flash.utils.ByteArray(); loc6 = 0; while (loc6 < loc5.length) { loc2["byte" + loc6] = new flash.utils.ByteArray(); arg1.readBytes(loc2["byte" + loc6], 0, 2000 / 20); ++loc6; } arg1.readBytes(loc1); loc3 = 0; while (loc3 < loc5.length) { trace("byte" + loc5[loc3]); arg2.writeBytes(loc2["byte" + int(loc5[loc3])]); ++loc3; } arg2.writeBytes(loc1); return true; } private function handleByteLoadComplete(arg1:flash.events.Event):void { trace((arg1.target as LoaderInfo).loader); dispatchEvent(arg1); return; } public var loader:Loader; public var bytes:ByteArray; private const KEYLENGTH:uint=20; private const BUFFERSIZE:uint=2000; private var _strUrl:String; private var _strKey:String; private var _progress:Function; private var isEncode:Boolean; } } }解密代码 var loc1:*=new DecryptLoader(arg1, "0010170918061315121405160704110803021901"); loc1.addEventListener("LoadFail", loadFail); loc1.startLoad();分析: 很有意思的参数"0010170918061315121405160704110803021901"是0-19的组合 也是打乱顺序的规则。 100个字节为1组,打乱前20组。
|
CopyRight 2018-2019 实验室设备网 版权所有 |