2979212646 发表于 2020-6-9 01:29:46

001 从人物血量学习数据查找

                                                                                        文章目录

[*]前言
[*]游戏选择与环境搭建
[*]查找人物血量
[*]查找血量基址

[*]第一条线(简单)
[*]第二条线(一般)
[*]第三条线(困难)
[*]总结
前言  本系列文章旨在从零开始学习游戏辅助的工作流程和开发方法,了解游戏背后的攻防对抗手段,重点侧重数据和call的追踪查找。
  侧重方向在于学习整个分析过程以及思路方法,最终实现的效果和游戏不是关心的重点。
  涉及到的技术有:

[*]windows API Hook
[*]dll注入
[*]汇编语言
[*]软件逆向
[*]Windows编程
[*]C/C++基础
  没有上述的前置知识建议劝退
游戏选择与环境搭建  这里用来进行分析的游戏是口袋西游,链接如下:
  链接:https://pan.baidu.com/s/1nXUoK8UUEI3t3-hgAQ5pBg
提取码:e57t
复制这段内容后打开百度网盘手机App,操作更方便哦
  下载以后直接解压缩,element文件夹中的ELEMENTCLIENT.EXE就是口袋西游主程序
  选择这个游戏的好处在于,这个游戏是老版本的口袋西游,不会一直更新,难度也非常适合新手,方便进行调试学习。
  在正式开始逆向之前建议先玩一段时间,熟悉一下游戏规则,后续操作起来会比较方便
查找人物血量  首先用CE附加游戏
  直接搜索当前的人物血量值810

  然后通过换装备的方式改变一下当前的人物血量,再次搜索,会得到两个值,一个是当前血量,一个是最大血量
  区分的方式是通过再次换装然后观察数据变化进行分辨,或者直接在CE中修改数据
查找血量基址  接下来我们要通过这个地址把血量的基址追出来。
  血量为零时角色会被判断死亡,血量不足最大值时会有一个回血的效果,而这些都会导致血量无时无刻被访问。

  接着在当前地址右键,找出是什么访问了这个地址,可以看到这里有四条汇编语句在访问当前这个血量地址
008199FA - DB 87 88020000- fild dword ptr
0055C062 - 8B 9E 88020000- mov ebx,
00482A36 - 8B 8E 88020000- mov ecx,
00482AA9 - 89 96 88020000- mov ,edx
  无论我们从哪条汇编开始追都能得到我们想要的基址,区别在于难度不一样。在学习阶段尽可能尝试所有的难度以应付后期的实战,这里先从第一条线开始追
第一条线(简单)008199FA - DB 87 88020000- fild dword ptr
  在这个地址下断
  这里很快就能追到基址

[*]edi+0x288是血量
[*]edi来自于eax+0x28
[*]eax来自eax+0x1C
[*]eax=
  最后得出血量基址公式为
血量=[[+0x28]+0x288]
  在CE里添加这个地址
  数值显示和当前血量一致,说明基址正确
第二条线(一般)0055C062 - 8B 9E 88020000- mov ebx,
  在这个地址下断,让程序断下
  用OD载入,直接在第一条汇编语句上面下断,这个时候esi+0x288的值是0x32A(810),也就是人物的当前血量。那么接着我们就要往上找这个esi来自于哪里。
  借助OD的寄存器高亮插件一直往上翻,可以找到一条给esi赋值的语句,也就是说
血量=
  而eax前面有一个call,所以可能是上面这个call的返回值,进入这个call

可以看到这个call内部进行了一些运算,从下往上进行逆推,我们很容易就能得出血量的基址为下面的值:血量=[[[+0x1C]+0x28]+0x288]
  这里的基址和第一条线是一致的,也没有问题。
第三条线(困难)  仔细观察,其实第三条线和第四条线其实是一个东西
00482A36 - 8B 8E 88020000- mov ecx,
00482AA9 - 89 96 88020000- mov ,edx
  两个地址很近, 来自edx,而ecx来自,那么我们就继续往上追esi
  在这个地址下断,让程序断下
  esi+288就是当前的血量值,接下来往上追esi的来源
  esi来源于ecx,继续到上层函数追ecx的值
  而这层函数里并没有找到对ecx赋值的语句,所以继续找到上上层函数

这里ecx来自于eax,所以我们要进到这个call里面继续找eax  这里有两个对eax进行赋值的语句,倒推出来可以得出
血量=[[+0x28]+288]
  返回刚刚的位置,继续追ecx
  这里ecx已经到了函数头,需要再往上找一层
  这里ecx来自于,我们在这个地方下个断点,这里eax=0,那么ecx就等于,血量地址如下:
血量=[[[+0x8]+0x28]+288]
  继续找ebp的来源
  这里ebp来自eax+0x8,血量地址就等于
血量=[[[[+0x1C]+0x8]+0x28]+288]
  eax则来自于
血量=[[[[[+0x8]+0x1C]+0x8]+0x28]+288]
  而ebx来自ecx,所以
血量=[[[[[+0x8]+0x1C]+0x8]+0x28]+288]
  这里已经到了函数头,继续返回上一层追ecx

这里下断 找到上层返回地址  ecx来自,所以
血量=[[[[[[+0x4]+0x8]+0x1C]+0x8]+0x28]+288]
  继续追edi
  这里edi来自ecx,那么血量就等于
血量=[[[[[[+0x4]+0x8]+0x1C]+0x8]+0x28]+288]
  这个地方又到了函数头部,所以继续找到返回地址向上跟
  这里ecx来自ebp,所以
血量=[[[[[+0x4]+0x8]+0x1C]+0x8]+0x28]+288
  继续找ebp
  往上翻的时候这里会看到ebp来自,实际上我们在这下个断点,会发现这个地方根本断不下来,说明这条语句不被访问。
  那么这个就是无效的,继续往上找ebp来源
  这里ebp来自于ecx,那么
血量=[[[[[+0x4]+0x8]+0x1C]+0x8]+0x28]+288
  这里也到也函数头,继续往上找ecx
  返回上层我们发现ecx=,下个断点,发现ebp的值是个基址,那么ecx就等于
血量=[[[[[[+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288
  到这里整个第三条线的基址数据就追完了
  在CE里添加这个基址,结果为810,正好是我们的人物血量
总结  在逆向分析数据的过程中会有很多条线路,无论是哪条都能追到我们想要的结果。区别在于有的是康庄大道,有的是荆棘丛生。
  最后我们得出了一条经验:在实际分析过程中如果感觉数据查找比较困难,赶紧劝退,换另外一种方式,曲线救国。
  https://github.com/TonyChen56/GameReverseNote

雪飘风过 发表于 2020-6-27 15:55:14

这游戏设计问题太多,很容易崩溃

xbaina 发表于 2020-10-26 08:36:43

非常不错啊,感谢楼主无私的共享精神!

xbaina 发表于 2020-10-29 08:48:12

非常喜欢学逆向论坛,资源我先收下了!

xbaina 发表于 2021-1-10 08:45:40

吃水不忘挖井人,我也去发帖分享好的资源。

xbaina 发表于 2021-1-11 09:15:21

看了LZ的帖子,我只想说一句很好很强大!

xbaina 发表于 2021-1-20 09:16:32

每天都有1次免费给楼主评分送学币的机会!

xbaina 发表于 2021-1-25 08:55:54

感谢分享,我会认真学习的!
页: [1]
查看完整版本: 001 从人物血量学习数据查找