首页
社区
课程
招聘
[原创]英雄联盟客户端hack
发表于: 2013-8-22 09:57 46021

[原创]英雄联盟客户端hack

2013-8-22 09:57
46021

《英雄联盟》(League of Legends,简称LoL),是由Riot Games开发及发行的一款Windows和MAC OS X平台下的多人在线对战竞技游戏,该游戏有个功能,就是能够观战好友的游戏,下面我就通过逆向这个游戏客户端实现能够观看任何人的游戏,

英雄联盟的客户端是个Adobe AIR 程序, AIR 程序跟java一样都是通过一个虚拟机(AVM)来执行它的bytecode的。(AVM指令介绍http://www.adobe.com/content/dam/Adobe/en/devnet/actionscript/articles/avm2overview.pdf)。

分析英雄联盟客户端我主要用到这几个软件:
1.硕思闪客精灵破解版
2.JPEXS Free Flash Decompiler
http://www.free-decompiler.com/flash/download.html
3.Flash Builder
Adobe官网有的下,可以免费用60天

我主要硕思闪客精灵用来反编译出英雄联盟客户端的代码然后用Flash Builder来分析代码,最后用JPEXS 来修改和写入bytecode。

英雄联盟客户端LolClient.exe其实是一个改了图标的Adobe AIR  Launcher而已,通过查看进程查看其命令行就可以看得出,真正的代码在其AIR目录下mod和lib两个目录下,格式是*.dat,而关于观看好友比赛的代码就在\Air\mod\man\mod_man.dat,其实这是我通过把所有的.dat都通过硕思反编译出代码到同一个文件夹。然后Flash Buuilder建立工程来分析得出的,因为FB能够自动分析出跳转,能够很方便研究反汇编出来的代码,介于篇幅,怎么找到的就不写了。
用JPEXS 打来mod_man.dat,如图

在左边的列表里找到scripts\com\riotgames\platform\gameclient\chat\renderer\BuddyListTreeRenderer 然后选中,之后中间的ActionScript source窗口就能看到反编译出来的代码,右边的窗口能够看到相对应的bytecode,我们最后修改代码也就是通过修改bytecode实现的。
我修改的思路是实现可以添加任意的玩家到离线列表(离线列表放的是离线的好友以及己方添加对面未确定的玩家),然后使离线列表的玩家的右键菜单中的“观战”选项开启(只有上线的好友列表中才开启这个菜单项)

在BuddyListTreeRenderer中有几个重要的地方
1

      private function onContextMenuShow(param1:FlexNativeMenuEvent) : void {
         var _loc2_:PresenceStatusData = null;
         var _loc3_:* = false;
         var _loc4_:NativeMenuItem = null;
         var _loc5_:String = null;
         if(!(data  is  RosterGroup))
         {
            _loc2_ = PresenceController.getPresenceData(data.status);
            _loc3_ = data.online;
            _loc3_ = (_loc3_) && !this.chatController.inGame || !this.masterGameController.currentState == GameViewState.TEAM_SELECTION || !this.masterGameController.currentState == GameViewState.JOIN_QUEUE;
            _loc3_ = (_loc3_) && (this.spectatorController.canDropInSpectate(_loc2_)) && !this.applicationController.shutdownLawActive;
            _loc3_ = (_loc3_) && !GameVersionConfig.instance.isWorking;
            for each (_loc4_ in param1.nativeMenu.items)
            {
               _loc5_ = _loc4_.data.data;
               switch(_loc5_)
               {
                  case "inviteToGame":
                     _loc4_.enabled = (this.inviteController.allowedToInvite || this.inviteController.isInviteActive) && (data.online) && !(data.show == Presence.SHOW_DND);
                     if(this.inviteController.gameQueueManager.selectedGameQueueConfig)
                     {
                        _loc4_.enabled = (_loc4_.enabled) && !this.inviteController.gameQueueManager.selectedGameQueueConfig.teamOnly;
                     }
                     continue;
                  case "spectateGame":
                     _loc4_.enabled = _loc3_;
                     continue;
                  case "sendMessage":
                     _loc4_.enabled = data.online;
                     continue;
                  case "viewProfile":
                     _loc4_.enabled = LobbyConfig.instance.isSummonerSearchEnabled;
                     continue;
                  default:
                     continue;
               }
            }
         }
         else
         {
            param1.nativeMenu.getItemAt(0).enabled = this.chatController.isCustomRosterGroup(data as RosterGroup);
         }
      }
getlocal 4
getlocal_3
setproperty m[4178]"enabled"
 private function spectateGame() : void {
         var _loc2_:PresenceStatusData = null;
         var _loc3_:String = null;
         var _loc4_:Object = null;
         var _loc1_:RosterItemVO = data as RosterItemVO;
         if((_loc1_) && (_loc1_.online))
         {
            this.masterGameController.cancelGameFlow();
            _loc2_ = PresenceController.getPresenceData(_loc1_.status);
            _loc3_ = _loc2_.dropInSpectateId;
            if(_loc2_.gameType == PresenceStatusXML.GAME_STATUS_IN_SPECTATING && (_loc3_))
            {
               if(_loc3_.search(new RegExp("^featured_game_")) == 0)
               {
                  _loc4_ = jsonDecode(_loc2_.featuredGameData);
                  this.spectatorController.spectateFeaturedGame(_loc4_.gameId,_loc4_.platformId,_loc4_.encryptionKey,_loc4_.mapId,_loc4_.gameType);
               }
               else
               {
                  this.spectatorController.spectateSummoner(_loc3_);
               }
            }
            else
            {
               this.spectatorController.spectateSummoner(_loc1_.displayName);
            }
         }
      }
getlocal_1
convert_b
dup
iffalse ofs0027
pop
getlocal_1
getproperty m[14053]"online"
convert_b
ofs0027:iffalse ofs00bf
getlocal_1
convert_b
iffalse ofs00bf

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

上传的附件:
收藏
免费 5
支持
分享
最新回复 (43)
雪    币: 1906
活跃值: (712)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
多谢楼主分享,牛,呵呵
2013-8-22 10:02
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
3分钟的限制呢?
2013-8-22 10:24
0
雪    币: 341
活跃值: (138)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
求任购英雄。。。。
2013-8-22 10:45
0
雪    币: 297
活跃值: (265)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
5
求购任意符文。。。
2013-8-22 10:52
0
雪    币: 10939
活跃值: (2895)
能力值: ( LV5,RANK:71 )
在线值:
发帖
回帖
粉丝
6
求大神带我超神,垃圾的匹配机制呢
2013-8-22 11:02
0
雪    币: 217
活跃值: (41)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
只求查询rank值 那个段位太坑了,,经常匹配砖5的代练上去又掉下来了
2013-8-22 11:03
0
雪    币: 10
活跃值: (231)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
好高深的样子阿
2013-8-22 11:04
0
雪    币: 1042
活跃值: (495)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
全图··
2013-8-22 11:15
0
雪    币: 114
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
当年腾讯悬赏一万找做联盟外挂的,你抓紧弄个全图··
2013-8-22 11:34
0
雪    币: 53
活跃值: (528)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
碉堡了!!!!
2013-8-22 12:36
0
雪    币: 223
活跃值: (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
赞。楼主分享一个很棒的idea ~
http://quickfind.kassad.in/
像这样的,应该是更深入的结果咯
2013-8-22 13:13
0
雪    币: 118
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
这个真是屌爆了,必须前排留名
2013-8-22 13:19
0
雪    币: 69
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
如果能够花精力去研究lol客户端也是能够实现http://quickfind.kassad.in/的功能的,本来我之前想模拟国服客户端过程去实现登录-请求信息来获取观战信息的,不过国服的要比外服难弄,LOL国服的登录要先通过另一个程序(\TCLS\Client.exe)登录qq获取token再通过这个air客户端登录游戏,要逆向登录过程太麻烦了,我调试调试着就放弃了,不如这种直接修改游戏的方式来得轻松点
2013-8-22 13:40
0
雪    币: 1895
活跃值: (1642)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
牛叉。。。
2013-8-22 13:42
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16
不能观看了啊!!不能观看了啊!!!
2013-8-22 14:47
0
雪    币: 62
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
牛人啊,不服不行!
2013-8-22 20:09
0
雪    币: 24
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
膜拜啊。。。
2013-8-22 20:48
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
我相信楼主一定是 拳头公司的员工吧!!
2013-8-26 10:21
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
请问大神 现在还能看么?按照您的方法我摸索了一下,不行啊,被封了么?
2013-8-26 10:30
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
牛逼。。。。。
2013-8-26 10:52
0
雪    币: 69
活跃值: (26)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
http://www.sufile.com/file/1ed1c27065ff8c11.html 替换相关文件就OK了
2013-8-26 18:05
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
多谢!按照你的方法 我一步一步来 成功了。 修改后 要点2次保存,最右边的机器语言要保存下,然后左上角的保存也要点下!哈哈  大神真牛啊!
2013-8-26 20:14
0
雪    币: 143
活跃值: (263)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
24
居然是flex的, 小伙伴都惊呆了
2013-8-26 21:18
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
大大 现在不能观看了啊 有没有更新版本出来

急需啊!
2013-9-3 21:46
0
游客
登录 | 注册 方可回帖
返回
//