CE Tutorial Games--2

##
参照文档:https://www.52pojie.cn/thread-915447-1-1.html
开始CE Tutorial Game 第三关的再次尝试。

1

2D游戏就两个坐标,按照52某牛的说法,2D游戏一般是左负右正,上下的正负不一定。

先利用CE搜索到人物的坐标。首先选到单浮点数和未知初始值,多次移动人物再加上多次搜索后就可以确定一个值了,这个就是我们要找的横坐标。
1
这时候修改这个横坐标的值就可以让人物进行瞬移了.
配合上上篇Blog里修改变绿台阶数为12即可过关.
现在我们来找一下任务的纵坐标.
一般横纵坐标的值应该都放在同一个地方,所以我们可以试下查看横坐标在内存中的相邻区域.
2
然后选择以浮点方式查看内存,接着让人物跳跃、移动,就可以发现两个可疑数据
3
观察数据变化可以发现,横坐标在屏幕内的范围从左到右是(-1,1),纵坐标在屏幕内的变化范围从上到下是(-1,1)

2

接下来试下找到游戏里面的重力系统.

2-1

重力可以改变纵坐标的值,所以我们查看下是什么改变纵坐标的值.
4
发现有两个指令对其进行修改,其中有一条指令在人物跳起来时不会写入数据.
猜测应该是第一条对纵坐标进行了修改.
进入内存查看,剔除掉和纵坐标无关的指令,剩下的代码由52大牛整理如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gtutorial-x86_64.exe+4048D - 48 8B 43 28           - mov rax,[rbx+28]
gtutorial-x86_64.exe+40491 - F3 44 0F10 40 28 - movss xmm8,[rax+28] { 读取 Y 坐标 }
gtutorial-x86_64.exe+40497 - 48 8B 43 28 - mov rax,[rbx+28]
gtutorial-x86_64.exe+4049B - F3 0F5A 48 28 - cvtss2sd xmm1,[rax+28] { 再次读取 Y 坐标 }
gtutorial-x86_64.exe+404A0 - F3 0F5A 53 78 - cvtss2sd xmm2,[rbx+78] { 读取 Y 速度 }
gtutorial-x86_64.exe+404A5 - F2 0F2A C6 - cvtsi2sd xmm0,esi { esi 是毫秒数 }
gtutorial-x86_64.exe+404A9 - F2 0F5E 05 AF382400 - divsd xmm0,[gtutorial-x86_64.exe+283D60] { 除以 1000 }
gtutorial-x86_64.exe+404B1 - F2 0F59 C2 - mulsd xmm0,xmm2 { 速度乘时间 }
gtutorial-x86_64.exe+404B5 - F2 0F5C C8 - subsd xmm1,xmm0 { Y 坐标减去位移 }
gtutorial-x86_64.exe+404B9 - F2 44 0F5A C9 - cvtsd2ss xmm9,xmm1 { double 转 float }

......

gtutorial-x86_64.exe+40506 - F3 44 0F11 48 28 - movss [rax+28],xmm9 { 赋值给 [rax+28] }

感觉整个分析过程就是要甄别出真正有效的数据,然后找出他们的内在逻辑.

纵坐标的地址可以很容易找出: [[["gtutorial-x86_64.exe"+37DC50]+760]+28]+28(他这里好像写错了)
根据分析,速度地址应该是 [["gtutorial-x86_64.exe"+37DC50]+760]+78
手动添加地址后我们就可以直接修改速度了,但是这个速度会变化,所以我们可以设置热键,让速度分别变为1和-1,这样就可以比较好地进行控制.
根据同样的道理,水平方向的速度我们也可以进行更改.

2-2

这次来找重力加速度.
重力加速度会直接影响竖直方向上的速度,我们直接查看什么修改了竖直方向上的速度.
5
发现只有第二条指令会一直对速度修改,所以在内存中查看第二条指令

1
2
3
4
gtutorial-x86_64.exe+40709 - F3 0F5A 43 78         - cvtss2sd xmm0,[rbx+78] { 读取速度 }
gtutorial-x86_64.exe+4070E - F2 0F5C 05 52362400 - subsd xmm0,[gtutorial-x86_64.exe+283D68] { 减去 0.1 }
gtutorial-x86_64.exe+40716 - F2 0F5A C0 - cvtsd2ss xmm0,xmm0 { double 转 float }
gtutorial-x86_64.exe+4071A - F3 0F11 43 78 - movss [rbx+78],xmm0 { 写入速度 }

这个机制蛮简单的,每次速度减0.1.

3

这次来找敌人的位置.
只要找到敌人的横坐标,它们的地址+4就是他们的纵坐标了.和搜索自己的坐标方法类似,很快可以搜索到他们的坐标.
直接锁定他们坐标的值,发现可以锁定,但是当12个台阶都亮起时,他们还是会飞去守门.
这时候查看什么对它们进行了写入,借用大牛的图:
6
直接将第五条指令nop掉,就可以对他们的坐标进行修改了.

4

这次来查找开门的指令.
开门和已经变绿的台阶数量有关系,那么我们先查看有什么访问了这个变量.
查看后发现只有一条指令堆积访问,于是查看它在内存中的位置,发现有几个有意思的判断:(还是摘自大牛整理的代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
gtutorial-x86_64.exe+4098B - 48 63 93 88000000     - movsxd  rdx,dword ptr [rbx+00000088] { 读取已变绿平台数 }
gtutorial-x86_64.exe+40992 - 48 8B 43 30 - mov rax,[rbx+30]
gtutorial-x86_64.exe+40996 - 48 85 C0 - test rax,rax
gtutorial-x86_64.exe+40999 - 74 08 - je gtutorial-x86_64.exe+409A3
gtutorial-x86_64.exe+4099B - 48 8B 40 F8 - mov rax,[rax-08] { [rax-08] 为平台数组最大下标 }
gtutorial-x86_64.exe+4099F - 48 83 C0 01 - add rax,01 { 最大下标 + 1 即为总平台数 }
gtutorial-x86_64.exe+409A3 - 48 39 C2 - cmp rdx,rax { 比较已变绿平台数和总平台数 }
gtutorial-x86_64.exe+409A6 - 7C 17 - jl gtutorial-x86_64.exe+409BF
gtutorial-x86_64.exe+409A8 - 48 8B 43 60 - mov rax,[rbx+60] { 二级指针 }
gtutorial-x86_64.exe+409AC - C6 40 18 00 - mov byte ptr [rax+18],00 { 开门 }
gtutorial-x86_64.exe+409B0 - C6 43 7D 01 - mov byte ptr [rbx+7D],01 { 堵门 }
gtutorial-x86_64.exe+409B4 - 48 8B 43 68 - mov rax,[rbx+68]
gtutorial-x86_64.exe+409B8 - 48 89 83 80000000 - mov [rbx+00000080],rax
gtutorial-x86_64.exe+409BF - 48 83 7B 28 00 - cmp qword ptr [rbx+28],00 { 0 }

这里可以看到总台阶数并没有存在哪个变量里,而是由数组下标+1来表示.
我们可以推导出开门地址 [[["gtutorial-x86_64.exe"+37DC50]+760]+60]+18
以及[["gtutorial-x86_64.exe"+37DC50]+760]+7D
这样直接修改开门地址为0,堵门地址也为0就可以过关了.

内容太多了,下一篇Blog再来写破解碰撞检测的方法.