Ganlv 发表于 2018-4-14 23:22

CE教程:一个简单的迷宫游戏

本帖最后由 Ganlv 于 2018-4-16 13:39 编辑



这个游戏是由论坛里 (https://www.52pojie.cn/home.php?mod=space&uid=512961&do=thread&view=me&from=space&type=thread) 大神发布的一个小游戏,《[迷宫游戏,大家来挑战一下吧](https://www.52pojie.cn/thread-724334-1-1.html)》。

闲着无聊就拿来玩玩,顺便做个 CE 的教程,当然这个小游戏的代码甚至比 CE 的 Tutorial 的还简单,没有什么增加难度的地方,大部分的变量都在全局或静态变量区,可以作为一个入门级的练习。

## 过程

### 找到储存坐标的地址

我的想法是,应该在上下左右移动的时候会有一个变量记录当前的 X Y 坐标的内存地址会变动,或者是记录整个迷宫形状的一块方形的内存区域中的某一位会改变(当然这个可能性较小)。然后我们就开始模糊搜索吧。



我首先尝试 4 字节整数型,未知的初始值,进行首次扫描。然后改变一下当前位置(比如向右移动 1 格),选择改变了的数值,然后再次扫描。然后再向左移动 1 格,再次扫描。反复进行这个步骤,直到剩余的个数基本不变了。







在搜索过程中可以不改变位置(先向右 1 格,再向左 1 格),选择未改变的数值,然后再次扫描,这样可以去除一些本身就是不断变动的数值。



* 如果只剩了 1 个,那么算你幸运,改一下这个试试,如果可行的话那么恭喜你,你学会了 CE 的最基础的用法。
* 如果剩下了好几个,除了其中的 1 个或几个看上去像个坐标,其他几个都是成千上万的,或者不断变动的,或者是奇怪的负数,那么其他那些基本都可以排除在外了。可以尝试移动一下位置,然后看坐标是否 +1 或 -1,来验证自己的猜想。
* 如果剩下了几百个(当然这款游戏不可能,这种情况大部分都是大型3D游戏之类的,很多坐标都会跟随当前人物一起移动),具体请参考 [【原创】CE教程:实战篇](https://www.52pojie.cn/thread-692068-1-1.html)。

这款小游戏可以很轻松的找到 X Y 坐标的位置,而且都是全局变量,内存地址都是静态的(重启游戏之后地址不会改变),非常容易修改。

我们可以轻松地找到这两个内存地址

```plain
Y坐标 MazeGame.exe+1E340
X坐标 MazeGame.exe+1E344
```



把他们改成 50 和 50,再稍微移动一下当前位置,重新触发一下程序中的判断,可以发现这个地址就是我们想要的。



这样一个简单的外挂就做完了。

### 穿墙?

穿墙是什么原理?把碰撞检测去掉不就可以穿墙了吗~(对于 3D 游戏要小心,去除碰撞检测之后可能会掉入地下,可能需要自己重写算法)

选中这个地址,右键,查找是什么访问了这个地址。然后随意移动一下。可能会出现好几条指令,一定要注意指令的顺序和计数器。





我们分析一下:首先读取这个地址进行碰撞检测,如果可以移动,那么还会再写回这个地址,然后绘图的程序又会再次访问这个地址。

按我们的分析第一条应该是碰撞检测,我们再周围找一下判断跳转指令,nop 掉试试。

选择“在反汇编器中显示”



```asm
MazeGame.exe+2262 - mov ecx, { }
MazeGame.exe+2268 - mov edx, { }
MazeGame.exe+226E - imul eax,ecx,000000CB { 203 }
MazeGame.exe+2274 - cmp byte ptr ,01 { 1 }
MazeGame.exe+227C - je MazeGame.exe+229A
MazeGame.exe+227E - push edi
MazeGame.exe+227F - push edi
MazeGame.exe+2280 - inc ecx
MazeGame.exe+2281 - push ebx
MazeGame.exe+2282 - mov ,ecx { }
MazeGame.exe+2288 - call dword ptr { ->->win32u.NtUserInvalidateRect }
MazeGame.exe+228E - mov edx, { }
MazeGame.exe+2294 - mov ecx, { }
MazeGame.exe+229A - imul eax,ecx,000000CB { 203 }
```

分析一下这个代码,伪代码大概就是

```c
ecx = Y坐标;
edx = X坐标;
eax = ecx * 0xCB;
if (*((byte *)(eax+edx+MazeGame.exe+1E423)) != 0x01) {
    ++ecx;
    Y坐标 = ecx;
    绘图();
}
```

`MazeGame.exe+1E423` 这块内存中应该就是迷宫地图,再化简一下就是

```c
if (迷宫地图 != 0x01) { // 数组宽度是 0xCB
    ++Y坐标;
    绘图();
}
```

我们需要的只是修改一下 je 这条语句

```asm
MazeGame.exe+227C - 74 1C               - je MazeGame.exe+229A
```

* 方法1:改成 `90 90`(NOP掉)
* 方法2:改成 `74 00`(跳转到下一条指令,这样无论条件是否成立都会继续运行)

第一种方法最简单了,直接右键这条指令,选择“替换成什么也不做”。







回到游戏中测试一下,成功,把上下左右的碰撞检测都去掉,你就可以为所欲为了。



最后记得保存哦。

## 相关链接

* [迷宫游戏,大家来挑战一下吧](https://www.52pojie.cn/thread-724334-1-1.html)
* [【原创】CE教程:实战篇](https://www.52pojie.cn/thread-692068-1-1.html)
* [【原创】CE教程:基础篇](https://www.52pojie.cn/thread-691615-1-1.html)
* (http://cheatengine.org/)
* (http://cheatengine.org/download/ch_cn.zip) [使用方法](https://www.52pojie.cn/thread-691615-1-1.html#18713591_使用中文翻译文件)
* (https://github.com/cheat-engine/cheat-engine/releases)
* [爱盘下载](https://down.52pojie.cn/Tools/Debuggers/Cheat%20Engine%20v6.7.exe)

## 附件



墨辰 发表于 2018-4-23 11:09


请问方括号里面的是基址吗
如果是的话前面MazeGame.exe会变动的,能教下怎么解决吗
我是新手,问的问题很低级,望解答{:1_923:}

Ganlv 发表于 2018-4-23 20:11

墨辰 发表于 2018-4-23 11:09
请问方括号里面的是基址吗
如果是的话前面MazeGame.exe会变动的,能教下怎么解决吗
我是新手,问的问题 ...

MazeGame.exe是模块地址,通过 GetModuleInformation 获取(相关API:GetModuleHandle EnumProcessModules)。



65302666 发表于 2018-4-15 11:31

感谢分享,学习了···

xgameboy 发表于 2018-4-15 00:01

CE教程呢楼主?

遛你玩528 发表于 2018-4-15 00:02

{:301_975:}感谢楼主分享

小航 发表于 2018-4-15 00:08

学习了{:301_978:}

cqtyyd 发表于 2018-4-15 09:23

学习一下,看看能弄懂多少~{:301_978:}

shelly1314 发表于 2018-4-15 10:40

试一试,

Zhang.J 发表于 2018-4-15 11:29

楼主学习了

pjk 发表于 2018-4-15 12:52

学习加强己我{:1_921:}

stxxb 发表于 2018-4-15 16:09

看懂了 谢谢
页: [1] 2 3 4 5
查看完整版本: CE教程:一个简单的迷宫游戏