使用 Cheat Engine 修改 Kingdom Rush 中的金钱、生命、星
最近想学习一下 CE,刚好看见游戏库里装了 Kingdom Rush 就拿它来研究吧。这里写的东西,需要一些 Cheat Engine 的基础,可以看看教程。
这里主要是看写的注释,来理解脚本。(如果什么都不想看,可以直接复制粘贴 CE 自动汇编(AA)脚本)
我学习的链接:
参考链接:
技术理解
我对一些用到的技术的简单理解:
- 代码注入:在程序运行时,将自己写的代码,替换掉原有的代码
- AOB:(Array Of Byte)在内存中搜索特定的一串数据,以决定注入代码的位置
- 人造指针:单独找个地方,记录变量所在的地址
数据存储结构
数据在内存中的存储结构:

Cheat Engine 相关汇编知识
此脚本用到的 CE 汇编指令:
| 命令例子 | 功能 |
|---|---|
| mov ebx,0000FFFF | Move,寄存器直接赋值 |
| mov ebx,eax | Move,将右边直接给左边 |
| mov ebx,[eax] | Move,将右边所指的值给左边。[ ]代表括号内的是指针,操作时,操作其指向的内存值 |
| cmp ebx,eax | Compare,比较两寄存器值,若相等则 ZF 位 置 1(左减右) |
je <label> |
Jump if Equal, ZF = 1 时跳转,可跳转至标记段代码 |
jne <label> |
Jump if Not Equal, ZF = 0 时跳转,可跳转至标记段代码 |
jmp <label> |
Jump |
此脚本用到的 CE 自动汇编函数:(Auto Assembler)
| 函数 | 参数 | 作用 |
|---|---|---|
| alloc | alloc(SymbolName, Size, AllocateNearThisAddress OPTIONAL) | Allocates a memory block of Size bytes and defines the SymbolName in the script, pointing to the beginning of the allocated memory block. |
| dealloc | dealloc(SymbolName) | Deallocates a block of memory allocated with alloc. |
| label | label(LabelName) | Enables the word 'LabelName' to be used as a symbol. |
| aobScanModule | aobScanModule(SymbolName, ModuleName, AOBString) | Scans the memory used by the module ModuleName for a specific byte pattern defined by AOBString and sets the resulting address to the symbol SymbolName. |
| registerSymbol | registerSymbol(SymbolName) | Adds a symbol to the user-defined symbol list so cheat tables and the memory browser can use that name instead of an address. |
| unregisterSymbol | unregisterSymbol(SymbolName) | Removes a symbol from the user-defined symbol list. No error will occur if the symbol doesn't exist. |
此脚本用到的 CE 汇编语言数据类型:
| 类型 | 占用空间 |
|---|---|
| Bit(整型) | 1 位 |
| Byte(整型) | 8 位(字节) |
| 2 byte(整型) | WORD(字) |
| 4 Bytes(整型) | DWORD(双字) |
| 8 Bytes(整型) | QWORD(四字) |
| Float(单浮点) | DWORD(双字) |
| Double(双浮点) | QWORD(四字) |
| String(字符串) | 任意长度 |
| Array of bytes(AOB) | 任意长度 |
CE 常用寄存器:
The x86 architecture has 8 General-Purpose Registers (GPR)
x86 架构有 8 个通用寄存器(32 位系统)
"E" (for "extended"), 32 bits.
General-Purpose Registers:EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
Cheat Engine 汇编代码
学过 CE 的,通过注释,应该能看懂
{ Game : Kingdom Rush.exe
Version:
Date : 2022-06-19
Author : Tsanfer
更改金钱、生命、星
(使用 AOB 和人造指针)
}
[ENABLE]
aobscanmodule(INJECT,lua51.dll,8B 29 8B 49 04 89 2C C2) // AOB 匹配入口
alloc(newmem,1024,INJECT) // 分配 1024 字节个内存,用于代码注入
alloc(man_pointer,24) // 动态分配内存,用于存放3个人造指针
// 注册全局符号
registersymbol(INJECT)
registersymbol(man_pointer) // 人造指针
// 声明标号
label(original_code)
label(return)
label(restore_reg)
label(check_is_gold)
label(check_is_gold_END)
label(check_is_live)
label(check_is_live_END)
label(check_is_star)
label(check_is_star_END)
// 数据存储结构:
// 偏移 数据 变量类型
// 0 具体值 Double
// 8 指向值所属的公共结构 指针
// └─> 0
// 10 此公共结构的名称 字符串
// 程序执行顺序:(汇编代码如没有跳转,默认从上往下执行)
// INJECT -> newmem -> check_is_gold -> check_is_live
// -> check_is_star -> reset_reg -> original_code -> return
// 注入代码段
newmem:
pushfd // 保存所有标志位
push eax // eax 压栈保存,为后续操作腾出一个寄存器
mov eax,[ecx+08] // 将当前值所属的公共类型所在的地址,给 eax
// 判断此值的类型是否为金钱(player_gold)
check_is_gold:
cmp dword ptr [eax+10],'play' // 内存双字比较
jne check_is_gold_END // 如不匹配,则停止后续比较,跳到此比较的结尾
cmp dword ptr [eax+14],'er_g'
jne check_is_gold_END
cmp word ptr [eax+18],'ol' // 内存字比较
jne check_is_gold_END
cmp byte ptr [eax+1A],'d' // 内存字节比较
jne check_is_gold_END
mov [man_pointer],ecx // 匹配成功,将指向此值的指针保存在申请的内存中(制作人造指针)
check_is_gold_END:
// 判断此值的类型是否为生命(lives)
check_is_live:
cmp dword ptr [eax+10],'live'
jne check_is_live_END
cmp byte ptr [eax+14],'s'
jne check_is_gold_END
mov [man_pointer+8],ecx // 将指针保存在第二个内存位置
// (64位系统的指针大小为 64 bit,每个内存地址大小为 8bit,则需要平移8个内存地址,8x8=64)
check_is_live_END:
// 判断此值的类型是否为升级用的星(total_stars)
check_is_star:
cmp dword ptr [eax+10],'tota'
jne check_is_star_END
cmp dword ptr [eax+14],'l_st'
jne check_is_star_END
cmp word ptr [eax+18],'ar'
jne check_is_star_END
cmp byte ptr [eax+1A],'s'
jne check_is_star_END
mov [man_pointer+10],ecx
check_is_star_END:
// 恢复临时使用的寄存器的值
restore_reg:
pop eax
popfd // 还原所有标志位
jmp original_code
// 原始代码
original_code:
mov ebp,[ecx]
mov ecx,[ecx+04]
jmp return // 跳到返回
// 程序入口
INJECT:
jmp newmem
return: // 返回
[DISABLE]
// 还原代码
INJECT:
db 8B 29 8B 49 04
// 注销全局符号
unregistersymbol(INJECT)
unregistersymbol(man_pointer)
// 释放内存
dealloc(newmem)
dealloc(man_pointer)
{
// ORIGINAL CODE - INJECTION POINT: lua51.dll+1BDA
lua51.dll+1BBC: 23 48 08 - and ecx,[eax+08]
lua51.dll+1BBF: 6B C9 18 - imul ecx,ecx,18
lua51.dll+1BC2: 03 4D 14 - add ecx,[ebp+14]
lua51.dll+1BC5: 83 79 0C FB - cmp dword ptr [ecx+0C],-05
lua51.dll+1BC9: 75 3A - jne lua51.dll+1C05
lua51.dll+1BCB: 39 41 08 - cmp [ecx+08],eax
lua51.dll+1BCE: 75 35 - jne lua51.dll+1C05
lua51.dll+1BD0: 83 79 04 FF - cmp dword ptr [ecx+04],-01
lua51.dll+1BD4: 74 36 - je lua51.dll+1C0C
lua51.dll+1BD6: 0F B6 46 FD - movzx eax,byte ptr [esi-03]
// ---------- INJECTING HERE ----------
lua51.dll+1BDA: 8B 29 - mov ebp,[ecx]
lua51.dll+1BDC: 8B 49 04 - mov ecx,[ecx+04]
// ---------- DONE INJECTING ----------
lua51.dll+1BDF: 89 2C C2 - mov [edx+eax*8],ebp
lua51.dll+1BE2: 89 4C C2 04 - mov [edx+eax*8+04],ecx
lua51.dll+1BE6: 8B 06 - mov eax,[esi]
lua51.dll+1BE8: 0F B6 CC - movzx ecx,ah
lua51.dll+1BEB: 0F B6 E8 - movzx ebp,al
lua51.dll+1BEE: 83 C6 04 - add esi,04
lua51.dll+1BF1: C1 E8 10 - shr eax,10
lua51.dll+1BF4: FF 24 AB - jmp dword ptr [ebx+ebp*4]
lua51.dll+1BF7: 0F B6 46 FD - movzx eax,byte ptr [esi-03]
}
然后再手动添加 3 个人造指针的地址(man_pointer 和 man_pointer+8 和 man_pointer+10),就行了
Cheat Engine 使用界面:

本文由Tsanfer's Blog 发布!
使用 Cheat Engine 修改 Kingdom Rush 中的金钱、生命、星的更多相关文章
- Cheat Engine 修改汇编指令
打开游戏 扫描阳光 扫描过程就不讲了 找到阳光的地址 显示反汇编 找到使阳光减少的反汇编代码 空指令替换 将阳光减少汇编指令,用空指令替换.这样阳光就不再减少了 指令替换 也可以将汇编指令修改,减少变 ...
- ce游戏内存修改器(Cheat Engine)
ce修改器(Cheat Engine)一款专门修改内存修改编辑的游戏工具它包括16进制编辑,反汇编程序,内存查找工具新版6.1 版的CE与6.0 最大的区别就是添加了修改器制作工具,比之前 5.6.1 ...
- (外挂破解)Cheat Engine(内存修改工具)V6.2中文版软件介绍
Heat Engine是一款内存修改编辑工具,Cheat Engine允许你修改你的游戏,所以你将总是赢.它包括16进制编辑,反汇编程序,内存查找工具.与同类修改工具相比,它具有强大的反汇编功能,且自 ...
- [Kingdom Rush]团队分享:如何做塔防手游
转自:http://www.gamelook.com.cn/2015/03/207324 GameLook报道/2014年11月,乌拉圭开发商Ironhide Studios发布的<Kingdo ...
- Cheat Engine TUTORIAL 教程 (8个步骤)
https://www.cnblogs.com/ae6623/archive/2011/04/16/4416874.html https://www.52pojie.cn/thread-828030- ...
- Cheat Engine 入门操作
Cheat Engine(简称CE,中文名-作弊引擎),用于查找.修改内存数据,是游戏逆向的基础工具. 本文仅介绍基础操作. 1.打开进程 运行游戏程序,并将CE附加到进程 2.寻找数据地址,并修改数 ...
- cheat engine lua
function CEButton1Click(sender) local x = getProperty(CETrainer.CEEdit1,"Text")--这句很重要,获取文 ...
- Cheat Engine 6.8 设置中文
下载翻译文件包 https://cheatengine.org/downloads.php 下载后解压到 "Cheat Engine 6.8.3\languages" 下面 修改 ...
- Cheat Engine 基本用法
打开游戏 当前血量2620 打开Cheat Engine 扫描2620 掉点血 再次扫描2600 此时,会根据第一次扫描结果,再次扫描 扫描成功 将数据放到修改区,点击箭头 修改数据 双击Value进 ...
随机推荐
- python基础练习题(题目 模仿静态变量的用法)
day27 --------------------------------------------------------------- 实例041:类的方法与变量 题目 模仿静态变量的用法. 程序 ...
- OV5640图像采集(一)VGA显示
vga控制器模块 1 引言 项目的背景是采集无人车间现场的工件图像并送往控制间pc端处理,最终实现缺陷检测.项目包括图像采集模块,数据传输模块,上位机,缺陷检测算法等四个部分.其中,图像采集模块又分 ...
- git-config配置多用户环境以及 includeIf用法
git-config配置多用户环境以及 includeIf用法 git-config配置多用户环境以及 includeIf用法 背景 介绍 配置 栗子 背景 开发人员经常遇到这样的问题,公司仓库和个人 ...
- HTML续集
计算机中PC:电脑 移动端:智能手机/智能电脑 html:超文本标记语言 图片标签<img src=" "> 图片的格式类型都有哪些? jpg,peg,gif(动图) ...
- GO语言学习——切片一
切片(slice) 数组的长度的固定的.是声明之后不能变的.是类型的一部分 切片是一个引用类型 切片的定义 声明切片类型的基本语法如下: var name []T 其中, name:表示变量名 T:表 ...
- 为什么不建议给MySQL设置Null值?《死磕MySQL系列 十八》
大家好,我是咔咔 不期速成,日拱一卒 之前ElasticSearch系列文章中提到了如何处理空值,若为Null则会直接报错,因为在ElasticSearch中当字段值为null时.空数组.null值数 ...
- 一窥 AJAX
一窥 AJAX 本文写于 2020 年 6 月 7 日 AJAX 这个词非常常见,如果使初学者,说不定还会非常害怕这个名字看起来非常高端.非常难的技术. AJAX,全称 Async JavaScrip ...
- JS作用域与闭包
JS作用域与闭包 在JavaScript中,作用域是可访问变量,对象,函数的集合. 变量分为全局变量和局部变量.全局变量在函数外定义,HTML中全局变量是window对象,所有数据对象都属于windo ...
- 好客租房53-context的使用
app组件要传递给child组件 该如何处理 更好的姿势 跨组件传递数据 Provider 用来提供数据 Consumer用来消费数据 1调用React.createContext() 创建provi ...
- 今天才发现ThinkPad的触摸板简直好用!傻乎乎的自己
最近经常看到这句话,天下武功,唯快不破. 今天才发现ThinkPad的触摸板简直好用! 今天才发现,傻乎乎的自己. 前一阵鼠标不好用了,没有滚轮,一直傻瓜式操作点击浏览器的滚动条... 遇到没有滚动条 ...