本文相關:
CE修改器:Cheat Engine(6 代碼注入)
(1)代码查找 (2)注入你的代码 (3)基本汇编指令
(4)游戏中的共用代码 (5)总结 (6)实战
點擊即可跳轉至關聯頁面。
關於Cheat Engine
Cheat Engine 是一款強大的遊戲修改器,
有關獲取Cheat Engine,請參照:
不出意外的话,本篇文章的基础部分就已经完结了,
我打算先结束掉这个没用的内容(笑),之后可能会更新一些其他的东西。
如果本教程还有下一篇的话,会以类似这样的标题发布:
CE修改器:Gamehack进阶教程 (A1 构建通用Lua脚本)
即只保留原标题CE修改器:的部分,
不过很可能不会再更新了,请大佬们放心接盘(咕咕咕)。
(现在想想还不如就写个官方教程的介绍,这篇教程在vikacg上实在是太过长了。)
摘要:
再一次回到Cheat Engine自带教程,
在前面的文章中,我们解决了这个示例教程的大部分内容,
今天让我们彻底通关Cheat Engine自带教程。
一、代码查找
相信步骤 2到步骤 4的内容大家都已经很熟悉了,让我们直接从步骤 5开始。
首先搜索到数值,然后找出是什么改写了这个地址。
再次改变这个数值后这里出现了汇编代码,这就是改写了这个地址值的汇编指令。
可以选择空指令替换掉这个指令,这样再次点击改变数值数值也不会发生改变了。
可以在这里看到你所保存的代码表。
现在无论如何点击改变数值数值都不会变了。
二、注入你的代码
步骤 6就是我们上一篇文章的指针内容,
我们直接来看步骤 7。(这里还不需要了解汇编指令)
找到使数值发生改变的指令,点击显示反汇编程序。
在弹出的窗口点击工具->自动汇编。
模板中的代码注入
自动填充了一小段代码
那这些代码是什么意思呢?
在这一步教程中,你将有一个健康值和一个每按一次将减少 1 点健康值的按钮,
你的任务是利用”代码注入”,使每按一次按钮增加2点的健康值。
我们只需要关注这一行
originalcode:
sub dword ptr [rsi+000007E0],01
sub 表示减法,
dword prt [rsi+000007E0]是sub的第一个参数,表示地址[rsi+000007E0]的值,
01是sub的第二个参数。
在此例中这串代码即表示将[rsi+000007E0]中存储的数值减1,即
[rsi+000007E0]= [rsi+000007E0]-1
也就是:
在这一步教程中,你将有一个健康值和一个每按一次将减少 1 点健康值的按钮,
你的任务是利用”代码注入”,使每按一次按钮增加2点的健康值。
红色的这一部分,
你要做的,就是把这串代码变成点击一次增加2。
现在我们需要汇编指令 add,它就是与刚才的sub意义相反的汇编指令。
originalcode:
add dword ptr [rsi+000007E0],02
你也可以把代码变成这样:
originalcode:
sub dword ptr [rsi+000007E0],01
add dword ptr [rsi+000007E0],03
最后点击下方的按钮,每次点击打我,数值就会增加2了。
你应该发现了,这个反汇编程序拥有很多功能,不过我们暂时不需要考虑这些问题,当然,如果你对此抱有兴趣的话可以自行了解。
三、基本汇编指令
要讨论汇编指令,我们需要对什么是汇编程序有一个基本的了解。
最早的编程是从在卡片上打孔开始的,
虽然这是直接修改硬件,所以通常不将此称为编程(但这确实是当时的计算机编程)。
到现在编程变成了直接处理一些二进制数。
毫无疑问的,处理一组二进制数要比处理卡片上的一堆孔洞要容易的多。
不过这对人类来说仍然是太复杂了:
89 83 80 04 00 00 8D 55 D4 E8 02 62 01 00 8B 55 D4 ...
不过我们可以把这个转化为更容易阅读的汇编程序:
mov [ebx+00000480],eax
lea edx,[ebp-2C]
call 00439D10
mov edx,[ebp-2C]
这就是汇编语言,它只是将人类难以识别的机器码转化为一种可读的语言,人类书写的汇编源码又可以供汇编器组装成字节码(机器代码)。
Cheat Engine 使用它自己的汇编器,它被称为“ Auto Assembler ”,但它能够理解的不仅仅是汇编,你可以在其中使用Lua代码等非汇编语言。
Cheat Engine 还提供了内存视图形式的自动汇编器(纯汇编)的子集,通常称为“汇编器”。
有关基础的汇编指令可以参考:
我随便在网上找的,如果失效了你就只能自己找了。
这些指令大略的分为三大类:
数据移动 mov push pop lea
算术/逻辑运算 add, sub inc,
控制流 jmp je, jne,… cmp call, ret
总之了解这些玩意是什么,现用现查就可以了
四、游戏中的共用代码
步骤 8 是上一次讲到的多级指针,因为是示例,所以很简单就可以找到基址,这里不再过多介绍。
让我们来看步骤 9。
在这一步骤中”绝不能”使用锁定HP的方法。
常常你在修改游戏的时候, 你找到了一个单位的健康, 或是你自己角色的健康, 你会发现一种情况: 如果你把健康相关代码移除的话,其结果是你的角色无敌, 但你的敌人也无敌了。
在这个步骤里面,游戏有4个角色,玩家1、2是我方,3、4是敌方。双方共用扣血代码,也就是说不能简单地删除扣血的代码,这样会使双方都无敌。
在这种情况下, 你必须想办法区分自己与敌人。
//// Actor(角色)类, 所有actors(角色实例)的基础类
class Actor(实体类型){
string Name = 'Actor';
Coord Coords = new Coord(0, 0, 0);
float 健康值 = 100.0;
...
}
//// Player(玩家类)
class Player(Actor){ //// Player(玩家类)派生于Actor(角色类)
string Name = 'Player';
int Team = 1;
...
}
编写游戏或引擎时,游戏可能会这样编写,玩家(Player)一般被定义一种特殊的角色(Actor)。
所以我们可以尝试找到玩家群体所属的结构。
在玩家结构中找到团队 ID
在找到修改健康的指令后,查找指令都访问了那些地址。
改变四个玩家的生命你就可以看到四个玩家的地址了。
你可以把这些值添加到地址列表
然后我们选择查看地址的分析数据
我们注意到这很像我们要找的值,他可能就代表了玩家与敌人的特征。
利用这个地址,我们来进行代码注入
依次点击CT表框架代码以及代码注入。
在自动汇编中添加这两行代码:
- cmp 是比较[rbx+14]与2的值并且将逻辑比较的结果放入标志寄存器中,
在这里若[rbx+14]为1(玩家),则返回小于,若为2(敌方),则返回等于。
- jb代表当标志寄存器中的值为小于时跳转,即为玩家时跳过扣血代码。
cmp [rbx+14],#2
jb exit
为了便于说明,以这样的代码为例:
- cmp 是比较[rbx+14]与1的值并且将逻辑比较的结果放入标志寄存器中,
在这里若[rbx+14]为1(玩家),则返回等于,若为2(敌方),则返回大于。
- ja ,当标志寄存器中的值为大于,则 ja originalcode这行代码被执行。
在这个代码里,originalcode:后的movss [rbx+08],xmm0是扣血代码。
- jmp 是无条件跳转,若执行jmp则会跳转到exit:,这就会跳过扣血代码originalcode。
简单来说就是先判断是否为敌人,若为敌人执行扣血,若不为敌人(友方)则跳过扣血。
cmp [rbx+14],#1
ja originalcode
jmp exit
originalcode:
movss [rbx+08],xmm0
exit:
jmp returnhere
然后点击重新启动游戏并自动执行即可完成本关
六、总结
在這一章節,我們
- 学会了注入汇编代码
- 能够简单的处理共用代码
七、实战
在完成步骤9后点击下一步,会弹出一个恼人的小游戏。
使用空格,方向键就可以对Player进行操作。
你要做的是:
- 任意方法,完成剩下的三个教程
如果看完本教程还意犹未尽的话,可以参考:
官方wiki:
官方论坛:
扩展程序:
问答:
下一篇:CE修改器:Cheat Engine (7 社群与搜索引擎)
到时候会直接贴在本章评论区置顶。
Enjoy!(咕咕咕)
凡凡星LV4
(๑ゝω╹๑)
看不懂捏~