研究仅供学习交流目的,请勿用于任何违法用途
有一群小猴子喜欢打气球,打到第6代了,我也喜欢打气球。新手刚开始接触逆向,就拿我喜欢的这款游戏来练手吧,新人技术有限,请轻喷。
我们知道,塔防游戏每一局放置的塔都是受局内的金币限制的,开局初始金币,放置塔,然后打怪获得金币,然后继续放置塔或者升级塔。本局游戏结束后,局内的金币作废,下局开局时还是初始金币。
那么我们就围绕金币来做个逆向,看看如何让局内的金币无限。
传统单机游戏修改金币,我小时候都是用金山游侠,现在开始学习逆向了,就学着用Cheat Engine和x64dbg吧。
第一步,用金山游侠的方法,在CE中搜索到金币所在的内存地址A。

修改内存地址A中的值,发现游戏实际并没有修改金币,但该值确实在反映金币的当前值,也就是说,这个地址A只是显示当前的金币值,并不是金币值的实际存储位置,而实际的存储位置在CE中直接搜索是搜不到的。
推测:实际的金币值没有直接写在内存中,当实际的金币在被修改之后,会相对应的修改地址A的值。那么找到修改地址A的值的代码,看看有什么线索。
在CE中对右键单击地址A,点击“找出是什么改写了这个地址”

然后在游戏中消耗一下金币,就发现了这段代码

这句话的意思是将xmm6寄存器中的数值的低64位赋值给内存地址[rbx+28],这个地址就是刚才搜到的地址A。
这段代码出现在地址为0x7FF9A2BB797D的位置,而该位置位于文件GameAssembly.dll的基地址加上0xA1797D偏移。
第二步,使用x64dbg找到0x7FF9A2BB797D的位置。先关闭CE,释放CE对游戏进程的附加,然后打开x64dbg,附加该游戏进程,定位到0x7FF9A2BB797D,注意,这个过程中游戏不要关闭,否则游戏加载到内存的基址会发生变化。
定位到0x7FF9A2BB797D,这一段上下文的代码如下。

从代码中可以看到,xmm6在复制到[rbx+28]前,先由xmm1复制到的xmm6,那么就需要找出xmm1的值是怎么来的。
查看该段代码的函数是谁调用的,点击函数头的位置,查看函数调用

发现有太多函数来调用这个函数了,不好排查。
由于本人经验有限,此时陷入了僵局。
只能再从头来,看看有什么可以突破的地方。再次使用CE搜索到地址A,找出是什么改写了这个地址,双击打开找到的这条记录,发现了[rbx+28]中的基地址rbx为0x1F8AAD604B0

再次搜索内容为十六进制1F8AAD604B0的内存地址,发现有两个地址的存储内容为1F8AAD604B0

分别对这两个地址进行跟踪(找出是什么访问了这个地址),发现当游戏金币变化时,只有第二个地址B被访问过。

这里有3处代码访问过地址B,通过不断的放置塔和卖出塔,发现:
1、当塔在被点击的时候第一条指令的计数就会增加,每次增加很多
2、当塔被放置时,即金币减少时,第二条指令的计数就会增加1
3、当塔被卖出时,即金币增加时,第三条指令的计数就会增加1
那么我们就看第二条指令,只要分析出这一段代码的作用,就有机会能做到无限金币了。
这条指令所在的位置信息如下。

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!