第一关: 打靶子
经过多次尝试之后,靶子的血量值为float, 起始值为100。子弹数目使用(5 - Current Ammo)数量进行搜索(4Bytes, int类型)。很简单。
找到改变子弹的Instruction:
我们可以看到instruction为 add [rbx+6C],01
。就是每次往子弹地址的指针所值的子弹数加1。我们改成add [rbx+6C],00
之后子弹数就不变了,如图:
最终效果如下:
第二关: 打飞机
第二关的生命值是int类型,也就是4bytes, 直接搜索就信。
但是这一关需要注意我们自己的生命值扣除和敌人的生命值扣除是Share Code,也就是说共享了一个扣血Function。
首先找到扣血的instruction的地址:
instruction为sub [rax+60],edx
。edx存的值是2,所以每次扣2点血。按道理我们只要把edx变成0就可以无敌了。但是通过scan飞机扣血的函数也是同样的地址的instruction,所以我们需要分析敌人和自己的structure有什么区别。
找到共享的instruction, 右键Find out what addresses this instruction access。
我们找到3个address访问了这个instruction,第二个84肯定就是自己,另外两个就是敌人。我们全选然后右键dissect structure来分析三个object的structure有啥区别。
我们看到offset为70的时候敌人飞机为1,我们自己为0。所以这个很可能是两种不同class的identification。所以我们在修改instruction的时候需要判断offset为70的时候是否等于1。修改如下:
效果如下:
第三关: 跳跳人
这一关为2D游戏,先寻找小人的x,y轴的位置,再通过x,y定位到小人这个object的地址,找到小人的其它member,从而实现无敌飞天之类的功能。
首先寻找到改变x值的address(x,y的值一般为float):
我寻找的x地址为00137E54
。我们再memory view中查看这个address以及其附近的值。因为00137E54
已经在object的里面了。
经过测试我们可以看到 00137E54
是x的地址, 00137E58
是y的地址,就在两隔壁。
接下来判断人物死亡的变量的地址肯定也在这附近,经过多次死亡,查看值的变化,我找到了两个地址很符合判断死亡的参数:
附近的00137E50
和00137E70
在没死亡的时候都是0,在死亡的时候都变成了1
再经过多次修改这两个地址里面的值,可以大概判断出00137E50
存的是是否Visible, 00137E70
存的数据是是否死亡。因为附近有两个参数控制死亡。有两种方法可以无敌
第一种方法就是将write这两个地址的instruction改为不改变其值
第二种方法就是直接跳过死亡的Call。因为死亡重新开始游戏肯定是有一个function被调用了,我们只要把这个function跳过就行。
第一种类似第一关和第二关就不讲了。
说说第二种方法,首先找到改变死亡的instruction:
我们break and trace之后的代码,Call跳出的位置。
是否死亡这个参数就是在这个call里面被改变的,所以我们跳过这个call就不会被修改为死亡了。
最终结果如下:
Bingo,你已经无敌了,相信无敌之后过关对你来说很容易。
CE Tutorial Game只有三关。CE初级学习结束。
隐藏关:Bypass 数据检测
我们可以看到当我们打开任何一个修改,Tutorial的窗口上都显示 Integrity check error. 所以这个Tutorial是有数据检测的。
如何过掉这个检测呢?
首先我们在Memory View中找到你修改的地址,然后右键FInd what acess this address。我们发现所有我们修改的指令都被3个Instruction一直access,那么很可能就是在扫描了(另一种可能就是不断刷新UI,UI一直在access这个address)。所以过检测还是得测试一下。我们跳到access这个地址的instruction,如果有cmp很有可能是在对比原数据。
所以让扫描一直在循环里面就不会跳出循环,让程序一直扫描memory但是就是不结束扫描。
下面是扫描的instruction:
很明显这是一个while循环。我们让while条件失效,使得while循环不跳出,如下:
最终的Script在此处下载