首页
社区
课程
招聘
flash页游(webgame游戏)逆向的一点心得与疑惑!
发表于: 2015-7-29 04:56 33989

flash页游(webgame游戏)逆向的一点心得与疑惑!

2015-7-29 04:56
33989

最近在研究一款全中国目前最火flash游戏。大大们都说flash游戏不能找Call 找基址的。。看到别人的游戏辅助。。可以读取人物品等级这些关键信息的。。不是用找图找字这方式的。应该是读取内存里面的数据的。。请问他们是如何实现的呢?我反汇编了一下这个Main.SWF 是加过密的。还混淆过的。几经周折。最终从IE的内存中提取出来的。AS3的代码很多页,这里只贴出发包代码:
package socket2
{
   import flash.net.Socket;
   import flash.utils.ByteArray;
   import flash.events.Event;
   import view.Logview;
   import flash.events.ProgressEvent;
   import flash.utils.getTimer;
   import mirFcc._mirFcc_readSocketData_;
   import flash.errors.IOError;
   import mirFcc._mirFcc_doSend_;
   import mirFcc._mirFcc_doSend2_;
   import mirFcc._mirFcc_doSend3_;
   import mirFcc._mirFcc_transform_;
   import mirFcc._mirFcc_doSend4_;
   
   public class CustomSocket extends Socket
   {
      
      private static var SEVEN_BIT_MASK2:int = 127;
      
      private static var SYMBOL_BIT_MASK2:int = ~SEVEN_BIT_MASK2;
      
      public static var code_index:int = 0;
      
      public static var code_Key:int = 0;
      
      public static var buffMessages:Array = [];
      
      public static var messageArray:Vector.<Array> = new Vector.<Array>();
      
      private static var MESSAGE_HEAD:int = 5120;
      
      private static var BUFFER_MAX_LENGTH:int = 20000000;
      
      private static var PACKAGE_HEAD_LEN:uint = 4;
      
      private var _host:String;
      
      private var _port:int;
      
      private var bufferByteArray:ByteArray;
      
      private var time:int;
      
      public var receivedHandler:Function;
      
      public var receivedHandler2:Function;
      
      public var closeFunc:Function;
      
      private var sendTime:int;
      
      public function CustomSocket(param1:String = null, param2:int = 0)
      {
         bufferByteArray = new ByteArray();
         super(param1,param2);
         addEventListener("socketData",socketDataHandler);
         addEventListener("close",_closeFunc_);
      }
      
      protected function _closeFunc_(param1:Event) : void
      {
         Logview.log(CustomSocket,"socket連接已斷開---->");
         if(closeFunc != null)
         {
            closeFunc(param1);
         }
      }
      
      public function get host() : String
      {
         return _host;
      }
      
      public function get port() : int
      {
         return _port;
      }
      
      override public function connect(param1:String, param2:int) : void
      {
         this._host = param1;
         this._port = param2;
         if(param1)
         {
            super.connect(param1,param2);
         }
      }
      
      protected function socketDataHandler(param1:ProgressEvent) : void
      {
         var _loc2_:* = null;
         time = getTimer();
         readBytes(bufferByteArray,bufferByteArray.length,bytesAvailable);
         if(bufferByteArray.length > BUFFER_MAX_LENGTH)
         {
            _loc2_ = new ByteArray();
            bufferByteArray.readBytes(_loc2_,0,bufferByteArray.bytesAvailable);
            bufferByteArray.position = 0;
            bufferByteArray.length = 0;
            _loc2_.readBytes(bufferByteArray,0,_loc2_.bytesAvailable);
         }
         readSocketData();
      }
      
      private function readSocketData() : void
      {
         var _loc2_:* = null;
         var _loc1_:* = null;
         if(bufferByteArray.bytesAvailable < 3)
         {
            return;
         }
         _loc2_ = new ByteArray();
         _loc1_ = {
            "resule":0,
            "msgLen":0,
            "msgID":0
         };
         _mirFcc_readSocketData_(bufferByteArray,SEVEN_BIT_MASK2,SYMBOL_BIT_MASK2,_loc2_,_loc1_);
         if(_loc1_.resule > 0)
         {
            messageArray.push([_loc1_.msgID,_loc2_,_loc1_.msgID]);
            if(receivedHandler2 != null)
            {
               receivedHandler2();
            }
            return;
         }
         if(_loc1_.resule == -1)
         {
            throw new Error("非法协议,消息体过小msgID:" + _loc1_.msgID + " msgLen:" + _loc1_.msgLen);
         }
         else if(_loc1_.resule == -2)
         {
            throw new Error("非法协议,消息体过长msgID:" + _loc1_.msgID + " msgLen:" + _loc1_.msgLen);
         }
         else
         {
            return;
         }
         
      }
      
      public function doSend(param1:int, param2:ByteArray) : void
      {
         var _loc4_:* = 0;
         var _loc6_:* = null;
         var _loc3_:* = 0;
         if(param1 == 0)
         {
            throw new Error("请求消息号不能为0");
         }
         else
         {
            sendTime = getTimer();
            var _loc5_:ByteArray = new ByteArray();
            _mirFcc_doSend_(param1,param2,code_Key,_loc5_);
            if(code_Key > 0)
            {
               CustomSocket.code_index = CustomSocket.code_index + 1;
               if(CustomSocket.code_index > 32767)
               {
                  CustomSocket.code_index = 1;
               }
               _loc4_ = MIR_CRC.CRC.genSNO(CustomSocket.code_index,code_Key);
               _loc6_ = new ByteArray();
               _mirFcc_doSend2_(param2,_loc4_,_loc6_);
               MIR_CRC.CRC.reset();
               MIR_CRC.CRC.update(_loc6_);
               _loc3_ = MIR_CRC.CRC.getValue();
               _mirFcc_doSend3_(_loc5_,_loc3_,_loc4_);
               param2.position = 0;
               _mirFcc_transform_(param2,code_Key);
               param2.position = 0;
            }
            _mirFcc_doSend4_(_loc5_,param2,CustomSocket.code_index);
            try
            {
               this.writeBytes(_loc5_);
               this.flush();
            }
            catch(e:IOError)
            {
               trace("发包失败:---》",param1);
            }
            return;
         }
      }
   }
}
封包加密方式看上去还是很复杂的。加入了时间计算,加了CRC校验。加了封包序列号。等。
有几个关键的function 反汇编不出来。最终放弃了。
然后用OD调试。结果越调头越大,我是新手。百度。google搜索了一大堆。如何找flash基址,没有答案,折腾了半个月了。。实在不甘心呀。如果说没有基址,可是别人做出的辅助。可以改关键跳。去检测。达到游戏加速,写入内存实现暗杀,远程捡物,等变态功能呢?有时我在想是不是真的没有基址,还是我们还没有掌握这门新的技术呢。如果你也和我一样有这样的困境,可以私信我,加好友。。我们一起研究。如果你知道方法,希望还不吝赐教。谢谢


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (39)
雪    币: 205
活跃值: (155)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
也有相同的疑惑,需要大师出手解惑!
2015-7-29 08:19
0
雪    币: 71
活跃值: (920)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谁说不能找的call的,OD 照样上
2015-7-29 08:38
0
雪    币: 3366
活跃值: (1353)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
4
这样的话是否与浏览器关联?会不会出现在IE能用,到Chrome失效了?
2015-7-29 08:45
0
雪    币: 6541
活跃值: (4336)
能力值: ( LV10,RANK:163 )
在线值:
发帖
回帖
粉丝
5
AMF协议发包收包...
2015-7-29 09:02
0
雪    币: 205
活跃值: (155)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
rongkao 兄,能说得详细一点儿吗?
2015-7-29 09:45
0
雪    币: 96
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
1. 之前也研究过这个,as3的代码会被用叫做“炼金术”的技术加密
2. 所谓“炼金术”就是用c语言写代码然后生成swc文件,且不可被反编译成as3,估计楼主遇到问题的几个函数就是用炼金术写的
3. lz换个思路,反编译下现有辅助,看是用什么实现的
==
希望LZ如果有什么发现可以共享下,o(∩_∩)o 哈哈
2015-7-29 09:45
0
雪    币: 205
活跃值: (155)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
rongkao 兄,能说得详细一点儿吗?
2015-7-29 09:46
0
雪    币: 6541
活跃值: (4336)
能力值: ( LV10,RANK:163 )
在线值:
发帖
回帖
粉丝
9
libamf-master.zip
骚年发你个AMF库, 老老实实AMF或者模拟点击吧.
flash,JS游戏不是端游,没有CALL基址的.
上传的附件:
2015-7-29 22:22
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
谢谢,现在很多flash游戏,特别是角色扮演类,都不用AMF协议的。大家都说任何程序运行了都加载在内存中。并且是解密过的。能不能这样解理呢,flash游戏是有基址的。只是每重启一次。这个基址都会变。。
2015-7-29 23:14
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
其实我也想反汇编别人的辅助,看了一下他们加了VMP的壳并且网络验证的。他们一个月的收入都是十几万的。他们的辅助都保护得很好,我想卖个正版的,就怕以我目前的水平。也跟踪不出来。
2015-7-29 23:20
0
雪    币: 96
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
12
LZ方便说下游戏吗,我去看下
2015-7-30 14:51
0
雪    币: 995
活跃值: (669)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
LOL?
2015-7-30 22:05
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
传奇霸业
2015-7-31 09:47
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
全部封包实现的 老老实实用OD调吧  好像这传奇霸业的算法可以反编译出来
2015-7-31 17:00
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
楼主我也在研究这款.SWF,我这边也有资源,方便的话我们相互交流下
2015-7-31 20:08
0
雪    币: 231
活跃值: (2631)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
17
这游戏不是AMF协议 ,楼主是怎么吧混扰去的那么干净的,这AMFlib库是好东西 ,收下啦
2015-8-1 19:12
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
正在努力。混淆得太厉害。可惜AS3看不懂。。不知道还原对了没有
2015-8-2 15:24
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
kan kan  !
看看        !
2015-8-2 15:43
0
雪    币: 35
活跃值: (612)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
是没基值的  本地都是UI现实而已。。可以HOOK 微端UI显示的位置。 但控制还是要flash解析的
2015-8-2 23:29
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
还原对了,那几个关键function用了flascc,而你这个极有可能没有抓到主文件,你这个是登陆的发包函数。
2015-8-3 16:34
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
大大  请问能具体一点吗?通常hook哪些函数?谢谢啦
2015-8-4 10:44
0
雪    币: 127
活跃值: (34)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
加了。谢谢
2015-8-4 10:48
0
雪    币: 49
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
我qq今天才收到一个来加我的人,不知道是不是你,还有你那个dump出来的可能只是个登陆发包的。
2015-8-7 11:04
0
雪    币: 205
活跃值: (155)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
楼主,有没有什么好办法能在每次重启以后,定位到这个基址?
2015-9-28 00:15
0
游客
登录 | 注册 方可回帖
返回
//