mochicrpyt解密

好些国外网站的好玩的小游戏都经过mochicrypt进行了加密,效果就是打开swf会有个小锁,用asv打开swf里面看到的就是几个差不多的内容:

1、小锁、加载进度条等资源;2、configdata 二进制格式; 3、payload 二进制格式。
资源如下图:
 
 
代码如下图:
本着学习的目的想看下这个游戏的实现,这些看来是不可能了。
搜索mochicrypt相关内容,有这样一个帖子:
简单总结就是mochi的加密是个大公司搞的,但菜的让作者5分钟就解出来,网上也有网友提供的解密exe,但只支持某个版本,不能一定保证好使。
大牛可以5分钟搞定,那我这菜鸟可否一天搞定呢?可以,用了一天时间终于发现解密的方法。
方法就是将payload资源,即原始游戏的swf保存为二进制文件XX.bin,如果保存成swf文件会多一些字节,然后load这个bin文件,字节读取后按照preloader中的方法进行“解密”,最后存成swf,即原始的。
也想过直接加载真个swf然后读取payload资源进行处理,但是这样会在load时默认调用其文档类,报很多错误。
最后贴下代码:
package
{
        import flash.display.Loader;
        import flash.display.LoaderInfo;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.filesystem.File;
        import flash.filesystem.FileMode;
        import flash.filesystem.FileStream;
        import flash.net.URLLoader;
        import flash.net.URLLoaderDataFormat;
        import flash.net.URLRequest;
        import flash.system.ApplicationDomain;
        import flash.system.LoaderContext;
        import flash.utils.ByteArray;

        public class PayLoadDe extends Sprite
       {
               //        private static const VERSION:String="2.3c";//3.2c
//            private static const VERSION:String="3.2c";//3.2c
               private static const VERSION:String= "3.1c"; //3.2c
               //            private static const VERSION_ENCODE_CONSTANT:int=16;//32
               private static const VERSION_ENCODE_CONSTANT:int=32; //32
               private static const  SWF_PATH:String="F:/flash-stuff/games/softbody/stuff/" ;
               private static const  SWF_NAME:String= "softbody_d2_7";
               private var loader:URLLoader;

               public function PayLoadDe()
              {
                     loader= new URLLoader();
                     loader.dataFormat=URLLoaderDataFormat.BINARY;
                     loader.load( new URLRequest(SWF_PATH+SWF_NAME+ ".bin"));
//                               addChild(loader);
                     loader.addEventListener(Event.COMPLETE, onCompleteHandler);
              }
               private function onCompleteHandler(e:Event): void {
                      trace ("load over" );
                      var S:* = null ;
                      var i:*=0;
                      var j:*=0;
                      var k:*=0;
                      var n:*=0;
                      var u:*=0;
                      var v:*=0;
                      var data:ByteArray=(e.target as URLLoader).data
                      trace (data.length);
                      trace ("data2.length" , data.length);
                      if (data.length > 0){
                           S = new ByteArray();
                           n = (data.length - VERSION_ENCODE_CONSTANT);
                           i = 0;
                            while (i < 0x0100) {
                                  S.writeByte(i);
                                  i = (i + 1);
                           };
                           j = 0;
                           i = 0;
                            while (i < 0x0100) {
                                  j = (((j + S[i]) + data[(n + (i & (VERSION_ENCODE_CONSTANT-1)))]) & 0xFF);
                                  u = S[i];
                                  S[i] = S[j];
                                  S[j] = u;
                                  i = (i + 1);
                           };
                            if (n > 131072){
                                  n = 131072;
                           };
                            var _local2:int;
                           j = _local2;
                           i = _local2;
                           k = 0;
                            while (k < n) {
                                  i = ((i + 1) & 0xFF);
                                  u = S[i];
                                  j = ((j + u) & 0xFF);
                                  v = S[j];
                                  S[i] = v;
                                  S[j] = u;
                                  data[k] = (data[k] ^ S[((u + v) & 0xFF)]);
                                  k = (k + 1);
                           };
                           data.uncompress();
                     };
                     ;
                      var context:LoaderContext= new LoaderContext( false, ApplicationDomain.currentDomain);
                     context.allowCodeImport= true ;
//                   payloadLoader=new Loader();
//                   addChild(payloadLoader);
//                   payloadLoader.loadBytes(data,context);
                      var file:File= new File(SWF_PATH+SWF_NAME+ "_real.swf");
                      var fileStream:FileStream= new FileStream();
                     fileStream.open(file,FileMode.WRITE);
                     fileStream.writeBytes(data);
              }
       }
}

 具体到某个swf文件的解密需要根据其preloader中的解密算法修改程序。

总之,mochi的加密仍然解决不了swf被破解的命运,只是转成二进制还是太容易被破解了,不过这确实应该可以抵挡多数人的破解了,因为多数人可能直接选择没有加密的取破解了。

posted @ 2015-08-06 19:24  大神小石头  阅读(528)  评论(0编辑  收藏  举报