封包辅助“不得不说的秘密“(4)

2020-12-22 10:21:37 李良人 85

第四章数据逆向之文字结构字符串

在前几期中,我们“初体验”封包世界,也尝试完成了一个封包小功能——自己封装的封包吃药call。

 

可想要通过封包吃药,必须在发送给服务器的封包中带有 药品的ID 或者 药品在背包中的位置,总之需要提供相应的信息 服务器才能知道你要吃那瓶药。

 

在我们的老朋友——私服版幻想神域2中,我们必须要提供药品在背包中的位置下标 才能实现功能。但是我们分析封包吃药的真正目的,肯定是要实现自动使用补给品 这是实现自动化中的重要一环,不然挂机的时候被怪打残了 或者 蓝量不足了,总不可能手动输入药品位置吧,所以最好可以通过药品的名称来使用药品。

 

于是我们逆向遍历了背包的数据结构,如愿的得到了背包中所有的物品信息。但是上期还有一些问题没有解决,比如我们不好通过某些物品的特定信息 来取出某个特定的物品,像 我想要取出血药的物品信息...可以通过物品ID(上篇我们已经分析出这个属性了)这个唯一的特征来从背包结构中遍历 但是背包中的物品类型太多 全部使用ID表示为免太不方便、太不直观了,如果能通过物品的名字 来从背包结构中取出 那就方便太多了。

 

所有我们需要找到物品的名称属性,不过在那之前我们需要了解一下计算机是怎么存储文字信息的——经典数据结构:字符串!

 

飞郁网络培训有限公司 

 

如图所示,像游戏中所有显示的文字 实际上都是以字符串格式储存。字符串的重要性可想而知,不仅仅可以逆向它来得到我们想要的文字信息,并且由于它很显眼 很多时候也可以作为我们逆向的突破口,后几篇笔记中 我或许会以字符串为突破口,来优化我们的寻路函数。

 

没错,上次我们封装的寻路函数实际上是有问题的,一次两次的调用或许没有任何问题,但是一但频繁的调用.... 会出现两种问题:

1. 首先有可能游戏会崩溃。

2. 或者人物一直楞在原地无法操作。

 

..闲话扯多了,先让我们看看经典字符串的理论结构吧。

 

 

经典“C”字符串:

 

字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

 

下面的声明和初始化创建了一个 "Hello" 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 "Hello" 的字符数多一个。

 

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

 

在内存中实际上它就是一串以0结尾的数字,当然内存也只能存储数字。(如下图所示)

 

飞郁网络培训有限公司 

 

那数字和字符有什么关系呢?计算机怎么知道什么数字代表什么意思?

 

很简单——靠查表!最著名也是最初的字符编码表是美国发明的ASCii码表,一个字节表示一个字符,而一个字节8个比特,只能有255种情况,所以ASCii码表只能表示A-Z、a-z、0-9 还有一些符号。

 

不过由于ASCii码表是美国人发明的,发明的时候只考虑到了自己,ASCii码表显示所有单词都由26个字母表示的英文当然绰绰有余,但是在面对其他国家以万计 的文字字符数量 就有些捉襟见肘了——比如中文....

 

所以很多国家或者地区都发明了自己的字符码表,如中国的GBK表、中国台湾地区的BIG5表、还有国际比较通用的UTF-8表。

 

如此繁多的字符码表,也为我们的逆向工作增加了困难,毕竟很可能我们不清楚游戏遵循着什么样的标准,好在后来发明的字符编码表 都是基于ASCii码表扩充的,借此我们有办法在不清楚游戏编码标准的情况下 不受影响的逆向字符串,逆向出结果后再根据其数据去推导游戏使用的是什么编码。

 

角色名称字符串逆向实战:

 

想要寻找字符串属性,主要有两种方法,本章先说说第一种方法:懵着脑壳翻。

 

以寻找老朋友 私服版幻想神域2 中自己操作的游戏角色名称为例:

 

使用“懵着脑壳翻”的方法,我们最好先逆向出人物的对象,要想逆向出人物对象 我们需要选择其对象中的一种属性作为突破口(要想访问对象属性,必须先访问对象 所以我们可以在对象属性上下断点 借此就可以顺藤摸瓜)。

 

那什么样的属性时候作为突破口呢?一个优秀的突破口通常具备以下条件:

1. 我们可以直接看到具体的值(方便我们直接在CE中搜索)。

2. 我们可以很方便的改动它(方便我们在CE中筛选搜索的结果)。

3. 其本身数值不会无故频繁变化(频繁变化我们就来不及在CE中搜索筛选了)。

 

那人物对象上有什么属性死死的符合呢?想都不用想——血量和蓝量没跑了,特别是血量!甭管你是什么游戏,你可能没有蓝量 或者有什么怒气...金币...等等... 但是怎么说你人物总有个血量吧,而且通常来说在游戏中我们都是可以直接观察到自己血量的数值,就算不知道自己当前血量的具体数值 游戏肯定也会间接的方式 让玩家知道是不是快没命了 ,这是肯定的 游戏总要让玩家对自己的状态情况有个了解,不然咋玩啊。

 

所以用血量来作为突破口 十分的无脑和通用,看到这里大家因该明白为什么许多视频教程 前几节课动不动就去搜索逆向血量,其实血量对我们并没有那么重要,也没有那么招人喜欢 主要是因为血量是大家惯用的突破口罢了,谁不喜欢拿血量一点破面呢?

 

害,我估计是看多了网络上那些滥竽充数的圈钱视频,闲话越来愈多了,就不多扯了现在我们进入正题!

 

飞郁网络培训有限公司 

 

好的,游戏左上角我们可以看到自己的血量,所以直接在CE中搜索4字节精确的数值,当然血量也很有可能是浮点类型,一般比较追求精度的游戏:比如MOBA类网游的血量会是浮点型,一般来说大多数游戏不在血量上斤斤计较,通常都是4字节 所以我们优先搜索4字节的类型,搜不到再换浮点也不耽误什么。

 

首次搜索就只剩下35个了,精确数值的搜索真好!还记得上次我们找寻路坐标的时候,搜索两数之间的浮点数一搜直接20多万个。

 

接下来,变化一下血量。

 

飞郁网络培训有限公司 

 

改变自己的血量我建议脱装备,一般装备都会有加血量的效果 我们脱一件这种装备就能让血量的数值产生变化了。而打怪挨揍,由于怪物不受我们控制,而且通常人物都会有自动回复血量,会给我们的搜索带来麻烦。

 

我们再次搜索变化后的精确数值,一下子就只剩下2个了,可以观察到它们的地址相距不远,应该是同一个对象下的属性,毋庸置疑的是当前血量与最大血量。

 

飞郁网络培训有限公司 

 

想要分辨出它们也十分简单,只需要穿上之前脱下的装备即可,如图所示一瞬间变化的是最大血量,慢慢上升回复的是当前血量。

 

打开OD附加游戏 在Command命令文本框中DD 当前血量,以便在数据窗口查看其周围属性值(CE也具有其相同功能,个人习惯OD)。

 

飞郁网络培训有限公司 

(对着血量的地址鼠标左键双击,就会以选中的地址为基地址 从而以偏移的形式显示其他地址)

 

现在只需要在其上,下一个内存访问断点就可以往上回溯人物的访问。不过,在那之前我先多几嘴,血量作为突破口 被大家用烂了 当然游戏厂商不会没有防备,很多都会在血量访问上下一些功夫,让你在血量上一下断就崩溃之类的...

 

不过并非找血量就没有用了,实际上我们可以在血量周围地址任意一处下断 只要有代码访问都可以,因为我们实际要追的是人物对象 不是其属性!属性只不过是 对象+偏移,只要我们获得对象,那找其中属性就是瓮中捉鳖(属性相对对象的偏移是不会变化的)。

 

周围地址也是其对象的属性,通过任何一个属性(只要有访问)都可以回溯,所以在一些显眼属性有处理反调试的地方 也没必要“啊~!我怎么突破啊”,周围皆为突破口 我们甚至都不用知道所下断点的属性是什么,只要注意不要下得太远了(万一出对象范围了),血量只不过是帮助我们打开局面的工具。

 

当然我们的老朋友没有这方面的处理,我们直接血量上下访问断点,在游戏中点一下角色属性查看的图标,此时游戏会去访问人物对象属性,从而断下。

 

飞郁网络培训有限公司 

 

这里很容易分析[eax+0x8]是人物血量,eax是人物对象 也是上面Call(函数)的返回值。

 

经过分析这个call一个参数也没有,纯粹就是为了取人物对象。这种情况很常见,因为游戏都是围绕着玩家操控的人物的,所以游戏程序本身在各处都要频繁的访问人物对象,所以一般要么是一个基地址保存着人物对象(比如某sgo),要么通过一个全局函数获取人物对象。

 

其实两者都差不多,我们进Call看看。

 

飞郁网络培训有限公司 

 

里面通过一个传ID取对象的Call取出人物对象,这个Call只有2个参数:一个ecx32位程序常用来传递this指针)、一个堆栈传递的ID参数。而这两个参数都来自于上面0xF84B74这个基地址,大同小异一个意思。

 

如果再进去分析的话,会发现call根据传入的对象ID去一个比较复杂的结构里面遍历出对象,那个结构应该装着程序里面所有的对象(这种好像有种花哨的叫法:对象池?),我们再去分析就比较麻烦了,再者写到自己代码里面也费劲,不如直接模仿游戏程序,直接调用上面2call的其中一个 直接获取人物对象。

 

纪录下2call之后,务必确认登录账号的游戏名称是英文+数字的,如下。

 

飞郁网络培训有限公司 

 

然后在我们找到的第一个call上下断点,以此获得人物对象。然后,在Command命令框中 dc人物对象地址并双击选中它。

 

飞郁网络培训有限公司 

 

我们慢慢往下翻,仔细看看有没有什么惊喜。

飞郁网络培训有限公司 

 

好像根本不用翻了,人物对象+0x100的地方发现了我们人物的名称。我相信大家都注意到了左上角的ASCII数据,dc命令的意思以ASCii编码的标准来查看数据。

 

我们的老朋友界面显示的都是繁体中文,显然是BIG5编码格式 为什么以ASCii标准查看也能行得通呢?

 

在上面已经说明了其他编码格式都是继承于ASCii编码,咋个继承法呢?——它们表示字母和数字的格式都是一样的...

 

我们再换个中文名称的账号试试。

 

飞郁网络培训有限公司 

 

凭鸡儿...(●ˇ∀ˇ●),重复上面的步骤查看人物对象+0x100处。

 

飞郁网络培训有限公司 

 

果然中文就乱套了,不要紧我们db人物对象地址,把人物对象+0x100处的字节码复制到GBKBIG5互转小工具上(编码互转百度一搜到处都是,简体中文系统默认编码GBK)。

 

飞郁网络培训有限公司 

 

点击BIG5GBK

 

飞郁网络培训有限公司 

 

显示出了人物的名称,验证了我们的结论是正确的。以后就算遇上不清楚其编码的游戏,只需要使用此方法确认字符串的位置,换一个非英文+数字的名称账号 复制其字节码 尝试出它的编码标准只是时间问题。

 

你学废了吗?




电话咨询
QQ客服