纵横三国外挂手记(1) 分析篇

    技术2025-09-20  124

    本文来自http://blog.csdn.net/lijun84 ,引用必须注明出处!

     

    本文仅供个人学习研究之用,不得用于任何商业及非法目的,基于此产生的法律责任本人不承担连带责任之类的。

    当 我写这篇 Blog 时,已经决定告别这款玩了 5 年的游戏。我将尽量详细深入的揭示从分析游戏到如何实现一款可用的网游外挂程序。

     

    背景:

    我从小学就爱玩游戏。从 FC 玩到 SFC 到后来的 PS2 N64 01 年迷恋上了传奇,后来自己也写了一些辅助挂和后期的变态挂(那时技术不是很纯熟,刚开始做软件开发)。在玩了无数款网游后,对大多数网游都很失望,难以维系我游戏的热情。我一直对三国系列游戏情有独钟,那是 06 年的一天,我无意中发现了一款 2D 的三国游戏(那时叫乱世三国),这游戏画面不算酷, 45 度角 2D 表现,上手比较简单,后来的体验使我觉得它是一个美的系统,没有太多冗余,平衡性和可玩性也达到对称。

           现在看来才知道。原来上面都是老玩家。 80% 都是玩了至少 3 年以上的。有个游戏玩家很调侃的说:“我玩它时孩子还没出生,现在孩子都快 4 岁了,每次看到就叫爸爸又在三国了。”其实这款游戏的平均年龄估计在 28 岁以上, 30 岁以上也应该大有人在。它的人文气氛是我后期慢慢感觉到的。

           08 年春节前发布了春节期间双倍公告,可我春节很忙根本没空上游戏,那个郁闷啊心里不是滋味额。我终于做了个一直想做没做的决定(因为知道做外挂很烦,我很懒),写个可以自动打怪喝药并且放技能的外挂(我那时工作是做杀毒软件和防火墙,毕竟也做了 6 年软件,技术上已经很纯熟了)。废话不多说了,转正题,我们开始分析。

     

    分析游戏:

    其实按键精灵方式的挂我一直没考虑过,因为我觉得它性能有问题,并且框架并不好无法实现复杂的需求。我一开始就考虑做脱机挂(我当然知道分析的代价很高)。

           既然决定写脱机挂当然要从登录开始分析,分析的第一步就是抓包,我选的工具是 IRIS ,先打开任务管理器看看游戏的进程 ID, 然后打开命令行用 win 自带的 netstat ip –ao 看下它开了哪些端口, OK ,打开游戏开始,设置好 IRIS 过滤器开始抓包,登陆选择角色,离开停止抓包,保存报文,靠,居然帐号和密码都是明文。。。(勾起了我盗号的兴趣 .. 没多想,继续分析),发现登陆部分比较简单。先和游戏服务器建立连接,再用 HTTP Get 请求将帐号和密码发到帐号服务器做验证,返回成功标志。就可以开始和游戏服务器通讯了。

           好了,我们来分析下游戏创建角色和进入游戏加载角色信息吧。晕。抓下来后对应一些数值(血量等信息)只分析出 10% 不到的角色初始量。。。,郁闷了。看来必须找到一种更好方式,又初步分析下游戏的资源和二进制脚本文件,没啥有价值的发现。算了,用黑客常用的绝招 - 暴破法吧。

           这里介绍下,游戏分析的暴破法和 Crack 中用的方法不同,游戏分析暴破是用截获的报文进行探测性修改并对客户端发包,观察客户端里事物的变化从而猜测报文字段的意义。说白了就是把客户端当成服务器,对其发包,以恢复它在之前游戏中运行的画面状态。后期很多分析都用到这种技巧。因为只有这种技巧可以快速有效的破解 80% 以上的游戏报文。以至于我如果想的话都可以写它的 SF 了。

     

    分析时需要注意的:

    1,  如果服务器 IP 配置在文件中,自己改就 OK, 否则可能需要改客户端程序,不多说,用 UE 或者 winhex 就行。

    2,  对客户端发包可以用工具 WPE 写脚本可以,当然我一般自己写程序也很方便。

    3,  分析抓下来的报文时,最好先用正值表达式过滤成自己方便的查看的格式。在分析如技能或者买药等动作时最好多抓些此类报文并列放到一起看,这样通过列的对比可以看出复杂的规律来。

          

    分析就写到这,贴出部分我分析的报文(比较敏感的报文此处就不贴出了,请见谅),后期谈外挂实现时会用到。

     

    备注:

    灰色 = 固定字节

    蓝色 = 确定用途的字节

    紫色 = 未确定用途的猜测字节

    绿色 = 在一组值中循环复用的未确定字节

    黑色 = 待分析的未确定字节

     

    报文分析:

    下一个内容报文大小应答:

    DE 01 02 03 大小 (1b) 00 00 00 00 00

     

    移动请求:

    02 27 15 00 32 X(2b) Y(2b) 3D

    应答 (L) :( 56b

    16 角色显示 ID 00 X1 Y1 X2 Y2 FE 00 09 01 49

    00 00 00 E1 00 02 00 00 是否骑马 (0/1)(1b) (1b) 00 马鞍 (1b) 00 马嘴头 (1b) 00 马鬙 (1b)

    00 马蹄 (1b) 00 00 00 00 

    备注:一个移动请求,可能需要多个应答描述。

     

    吃东西请求:

    02 25 21 包裹中的位置 (1b) 34 00 00 00 00 3F

    备注:位置从包裹左上第一格开始数,以 0 计数。

     

    打怪请求:

    02 29 02 01 38 怪物 ID(2b) 02 00 33 00

    备注:此绿色部分从打 1 个怪到 N 个怪对于所有角色序列一样。

     

    检东西请求:

    02 20 63 01 31 X Y 3A

    应答 (20b)

    4C 角色显示 ID 00 00 61 82 B4 00 X Y X1 Y1 00 0C 00 E9 X11 Y 11 C 3 00

     

    传送员请求:

    02 0D 03 01 1C 传送员 ID(2b) 01 00 17

    应答:

    8B 00 返回码 (1b) 00 返回码:(魏 0-19, 20-39 ,吴 40-59 )公共地图的同一传送员,国家不同,返回码也不同,但同国家同传送员一定相同。所以可传送地可点击限制在客户端判定。

    85 FE 30 00 00 00 00 00 任务未完成,无法请求传送

     

    传送请求: (10b)

    1C 20 国代码 (1b) 00 31 菜单项 (1b) 00 01 00 3A

    备注:菜单项从 0 开始数第 N

    应答:

    86 74 00 A 5 DE B3 00 77 05 74 00 SX(2b) SY(2b) 角色类型码 (1b)

    0C 77 00 74 00 DX(2b) DY(2b) 00 (1b) 00 00 00 00 00

    00 00 00 00 01 00 00 00 00

     

    退出游戏请求: (10b)

    03 12 01 00 FF 00 00 00 00 08 (服务器检查开头 03 就够了)

     

    刷怪报文:

    怪物移动 : 20b

    0C 怪物 ID(2b) X(2b) Y(2b) X1(2b) Y1(2b) (FE| 9A ) 怪代码 (1b) 等级 (1b) 3C 00 (2b) 00 00

    怪物受攻击 :(15b)

    0F 怪物 ID(2b) X(2b) Y(2b) 怪代码 (1b) 等级 (1b) 费血数 (2b) 剩余血量 (2b) 00 00

    怪物攻击:( 13b

    0D 怪物 ID(2b) MX(2b) MY(2b) DX(2b) DY(2b) 怪代码 (1b) 等级 (1b)

    怪物死亡角色加值:

    0E 怪物 ID(2b) X(2b) Y(2b) 怪代码 (1b) 等级 (1b) 最后一下费血数 (2b) 42 54 00 20 E0 B3 00 3D 00 经验值 (8b) 01 00 00 00 0A 00 10 00

    掉钱 :

    DE X Y 00 00 钱数(2b) 00 00 00 00 ID 00 00     

    怪物消失

    11 怪物 ID(2b)

     

    掉东西:

    DE X Y 00 00 钱数量 (2b) 00 00 00 00

     

     

    最新回复(0)