查看原文
其他

2021南极动物厂游戏高赛竞赛决赛分析01

淡然他徒弟 看雪学院 2021-05-14

本文为看雪论坛精华文章

看雪论坛作者ID:淡然他徒弟



0x01 前言




没有参赛,看了下题目感觉不太难,蹭个热度,发个WP。
 
自我感觉,今年的题目好敷衍(初赛题是2018年的决赛题“hack.exe内存注入”,从看雪抄的 flag的算法太简单...)
 
然后感觉题目分数的提升应该会比较看重功能的实现。(FLAG解题其实都大同小异,没什么好拉开距离的地方,主要还是功能的实现,还有内卷程度。)
 
所以自瞄的另外实现,我用的是子弹穿墙追踪,有兴趣的,可以接着往下看哦~


0x02 过程




题目描述:


(1) shootgame是一个游戏,hack.exe是游戏shootergame的一个外挂程序。

(2) 运行shootgame游戏,运行hack.exe,成功执行外挂功能并分析外挂实现过程。

(3) 实现一个与hack.exe的功能相同的,但是游戏逻辑原理不同的外挂程序。

游戏逻辑原理不同:指外挂程序对读写游戏数据结构或代码的攻击内容不同,并不是读写内存方式、注入内存方式、外挂核心代码载体差异的不同。

题目分析:


题目描述:


(1) shootgame是一个游戏,hack.exe是游戏shootergame的一个外挂程序。
(2) 运行shootgame游戏,运行hack.exe,成功执行外挂功能并分析外挂实现过程。
(3) 实现一个与hack.exe的功能相同的,但是游戏逻辑原理不同的外挂程序。
(游戏逻辑原理不同:指外挂程序对读写游戏数据结构或代码的攻击内容不同,并不是读写内存方式、注入内存方式、外挂核心代码载体差异的不同。)

题目分析:


对hack.exe的详细分析


使用工具:IDA Pro 7.2、CheatEngine 7.2、x64dbg、PYArk


1. 直接打开了下hack.exe一闪而过,开游戏,再打开也是一闪而过。

2. IDA载入分析,一路查看执行的流程。


对代码前后逻辑分析完以后,发现会读取一个文件,读取失败就会返回。


此处为“读取出错进程就退出”的逻辑。文件名为hack.dat。

3. 接着读取出来的Buffer会跑进一个函数,进行解密之后会用解密出来的Buffer其中的字符当做进程名称。

然后会从进程列表中寻找对应的名称,暂不知道是哪个进程。(猜测是游戏进程,后面可以确定。)

4. 接着就是一大堆的解密,解密出来的数据会作为GetProcessAddress的参数(函数名称) 获取函数地址。

然后还调用了刚刚解密进程名称的函数,解密一个Buffer。然后这个Buffer会被写进目标进程内。

被写入的内存地址是由hack.exe申请出来的可执行内存,所以把这个Buffer Dump出来看看。

首先我们先在main函数下个断点,然后用x64dbg设置新的运行点,单步两下。

这时候打个广告“欢迎使用PyArk,一个无所不能的Ark,官网:http://www.pysafe.cn/”。我们使用Pyark把这个解密以后的内存dump出来。

1. IDA载入,发现这个DLL必须要依附于ShooterClient.exe,验证了前面寻找的进程就是游戏进程的猜测哦~

此时不知道这个dll有没有什么校验,例如判断是不是由hack.exe发起的注入, 随手拿起这个dll,用CheatEngine注入到游戏里面,显示了一行字,并且在游戏中按住右键,可以自瞄敌人。(啊~这~DLL注入以后竟然可以直接用)

2. 那这个时候回顾题目要求:
(1)求flag,这要分析解密hack.dat的函数,看了下原解密代码被优化了。看汇编挺吃力的,于是最后再看。
(2)写个"与hack.exe外挂功能相同,但实现原理与hack.exe不同的程序源码"的功能,那就要分析hack.dll是怎么实现的了。
hack.dll既然按住右键能自瞄,那就从这里入手,查看导入表,看看有没有判断热键的API,从而找到自瞄的攻击流程。哦~ 发现个GetAsynKeyState这样的API(判断热键状态),查找引用后发现整个dll只有这一处引用,并且下面有写入float内存的操作。看看这个被写入数据的内存地址是怎么来的,IDA查找引用。得到完整的数据,然后在CE中添加这个数据,随便改个值,游戏中的屏幕动了,确认这里就是跟自瞄有关的逻辑了。
所以hack.dll攻击的数据结构就是如上图这里啦~
那这个要写入进去的float类型的数据肯定跟敌人坐标有关了。往上分析以后可以看到敌人对象其实是来源于一个函数。对着函数进行分析以后,发现遍历了一个数组,从里面取出来所有符合的名字, 然后转换屏幕坐标之后,取出距离屏幕准星最近的敌人。
判断是否遍历完成。数组指针、数组大小。CmpName函数的分析

GetName函数的分析

 所以,就是从一个对象数组而不是一个敌人数组里面遍历出对象。
并且判断他的名字后缀是不是awn_C_ 来判断是否为活体目标(是否为敌人) 并且把活体目标的坐标转换成了屏幕坐标,然后取出屏幕坐标距离准星最近的敌人为自瞄对象。

用VS写个DLL,遍历看看,记得把多线程DLL调成多线程。


成功打印了。

本文附件可点击左下方阅读原文自行下载!
- End -




看雪ID:淡然他徒弟

https://bbs.pediy.com/user-home-620278.htm

  *本文由看雪论坛 淡然他徒弟 原创,转载请注明来自看雪社区。



《安卓高级研修班》2021年6月班火热招生中!



# 往期推荐






公众号ID:ikanxue
官方微博:看雪安全
商务合作:wsc@kanxue.com



球分享

球点赞

球在看



点击“阅读原文”,了解更多!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存