学逆向论坛

找回密码
立即注册

只需一步,快速开始

发新帖

487

积分

2

好友

29

主题
发表于 2020-6-9 01:39:14 | 查看: 2212| 回复: 0
                                                                                        文章目录

    • 前言
    • 数组逆向
      • 通过人物血量查找人物属性
      • 调call取对象
      • call内追局部变量
      • 逆向加密数组下标
      • 分析人物属性
    • 总结
前言  通过之前的分析,我们已经对数组结构有了一个简单的了解,这次就用幻想神域这个游戏来更加深入学习数组。
数组逆向通过人物血量查找人物属性  以人物血量为切入点,我们要找到所有的人物属性。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  首先搜索当前人物血量

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  接着通过换装备的方式修改人物血量,最后剩下两个结果,一个是当前血量,一个是最大血量。通过修改数据可以分辨。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  在OD中对这个地址下硬件访问断点。打开人物属性栏,会对人物所有属性进行访问,断点断下

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  这里在判断当前的人物血量是否为0,人物血量=eax+8。接着需要通过追踪eax的方式找到所有的人物属性。
  eax来源于上一句call

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  进到call内,eax来源[eax+C]
血量=[eax+C]+8
  上面有一句汇编将一个基地址赋值到eax,但这句代码实际上是没有执行的,所以这个地址是无效的。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  eax实际上是来源于上面的call。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  这个call内部的逻辑比较复杂,遇见这种情况可以用比较简单的方式,直接调用call来获取数据。
调call取对象  我们只要将这个call的参数分析出来,就可以直接调用call来获取返回值。这个call只有一个参数

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  参数eax是一个固定的值

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  往上追一下基址,就是一个基地址+0x40C

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  eax转成十进制之后像是一个ID

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  而调用这个call以后返回值[eax+C]+8的位置是人物的血量。这里可以大胆猜测一下,参数eax其实就是当前的人物ID,传入人物的ID以后会返回一个人物对象。对象加上偏移可以取到人物属性。
call内追局部变量  接着我们用正常的追踪方式继续追人物的血量基地址
血量=[eax+C]+8
  继续进到call追踪eax的值

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  eax来源于[ebx+0xC],替换一下偏移表达式,继续追ebx
血量=[[ebx+0xC]+C]+8

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  ebx来源于[ebp-4],继续追[ebp-4]
血量=[[[ebp-4]+0xC]+C]+8

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  [ebp-4]作为一个局部变量只能存在于当前的函数内,但是我们往上找发现并没有[ebp-4],那就说明[ebp-4]是来源于这个函数内的call

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  我们需要进入这个被执行的call找[ebp-4]的来源。
  追这个局部变量有两种方式,第一种是直接下断,单步跟每一行代码,看是哪行汇编改变了[ebp-4]。这种方式没啥技术含量,这里我们用第二种。
  局部变量想要传入call内被修改就必须通过指针的方式,这里我们可以查看一下这个call的参数

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  这个call有两个参数[ebp+8]和[ebp-8],其中和[ebp-4]最接近的就是[ebp-8],那么就有下面的等式
edx=ebp-8
  用上面的等式往[ebp-4]靠近
[edx+4]=[ebp-4]
  edx实际上是第一个参数
[edx+4]=[arg1+4]=[[ebp+8]]+4]=[ebp-4]
  那么我们进入内层call以后要追的实际上就是[ebp+8]

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  进入call内找[ebp+8],这里将[ebp+8]赋值给了eax,然后将ecx赋值给了[eax+4],这个[eax+4]就是我们要找的[ebp-4]。所以
血量=[[ecx+0xC]+C]+8
  继续往上追ecx

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  ecx来源于[ecx+4],ecx又来源于ebp-0x14
血量=[[[ecx+4]+0xC]+C]+8
血量=[[[ebp-0x14+4]+0xC]+C]+8
血量=[[[ebp-0x10]+0xC]+C]+8
  继续追[ebp-0x10]

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  [ebp-0x10]来自ebx
血量=[[ebx+0xC]+C]+8

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  ebx继续往上追,就找到了今天的目标数组了
血量=[[[eax+ebx*8+4]+0xC]+C]+8
  eax是数组首地址,继续往上追eax。ebx是数组下标,值等于0x34。下标暂时先不管,后面会有个彩蛋~

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  eax来源于[esi+0x14]
血量=[[[[esi+0x14]+ebx*8+4]+0xC]+C]+8

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  esi来源于ecx,返回上一层找ecx

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  ecx来源于esi,表达式不变,继续返回上层追esi。
  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mkllCxu0-1587787548269)(009 数据结构逆向—数组(困难版)].assets/1587483144194.png)
  esi又来源于ecx
血量=[[[[ecx+0x14]+ebx*8+4]+0xC]+C]+8
  来到函数头部,继续返回上层追ecx

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  ecx来源于ecx+0x410
血量=[[[[ecx+0x410+0x14]+ebx*8+4]+0xC]+C]+8

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  再往上,总算是追到ecx的基地址了
血量=[[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]+8
逆向加密数组下标  到这里我们就把人物的数组追到了,但是还有个问题就是数组的下标0x3E是怎么来的,我们需要知道这个数组的排列规则,以及当前的下标为什么是0x3E。
  所以这里就要考虑去追ebx的来源,看看这个0x3E是怎么得来的。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  回到刚才数组的位置追ebx,ebx来源于[eax+eax]
数组下标=eax*2
  eax继续往上追

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  来到这个地方,这段代码明显是一个加密的算法。通过上面的左移右移的指令就能看出来,到这里其实就没有必要继续往上追了,如果需要写代码,直接将这段加密算法抠出来。
  最后追出来的数组下标的算法为:
数组下标=(([0xF84B74]+0x40C*0x41]+[0xF84B74]+0x40C/4+0x9E3779B9) and [[0xF84B74]+0x410+0x20])*2
  到这里我们就清楚了人物数组下标的来源是通过加密的方式计算的。
分析人物属性  找完这个数据结构以后,我们来进行一个简单的分析。
血量=[[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]+8
  我们把+8的属性偏移去掉,查看一下人物对象
dd [[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]
  记得将ebx替换为加密的下标,我这里是0x34。

009 数据结构逆向—数组(困难版)

009 数据结构逆向—数组(困难版)
  其中+8的位置是人物血量,+0x10的位置是人物等级,+0x18是移动速度,+0x24是人物最大血量,+0x30是暴击伤害。
  其他的数据可以自己去分析,这里其实没啥技术含量,就是通过不断的对比和分析得出结论。
总结  到这里我们已经对数组有了一个深刻的理解,数组在所有的数据结构里属于最简单的一种,对于这类数据结构来说,只需要一直往上追就能找到想要的数据。如果遇到数据被加密的情况,可以逆推出加密算法,也可以直接将算法拷贝到自己的代码里。
  另外在追数据的过程中,偏移表达式每一次变化都要做一次检验,在数据窗口查看当前的表达式是否正确,否则到后面很容易翻车。
  最后,附上Github地址,里面有游戏下载链接和相关工具,需要请自取:
https://github.com/TonyChen56/GameReverseNote


温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的认可,还可以获得学币奖励,请尊重他人的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
嘿嘿

小黑屋|手机版|站务邮箱|学逆向论坛 ( 粤ICP备2021023307号 )|网站地图

GMT+8, 2024-11-23 18:05 , Processed in 0.121047 second(s), 38 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表