在正式开始《植物大战僵尸》中文版的修改之前,我们需要掌握一些基础知识,包括内存地址的概念、汇编指令的使用、字节存储方式等。本篇文章将作为科普篇,为后续的实操篇打下坚实基础。
一、地址类型:静态与动态
在 Cheat Engine(简称 CE)中,我们常会遇到两种类型的地址:
-
静态地址(绿色显示):在程序每次运行中保持不变,通常用于定位基础数据结构。
-
动态地址(黑色显示):每次运行时都可能变化,不能直接用于定位,需要通过指针推导。
为了修改动态地址,我们通常使用多级指针。其基本原理如下:
动态地址 = 静态基址 + 偏移量(Offset)
CE 的指针扫描功能就是基于这个原理,寻找稳定的修改入口。
二、AutoAssemble 简介(AA)
AutoAssemble(AA) 是 CE 提供的一种自动汇编工具,可用于编写和注入汇编指令,常用于制作修改脚本和注入代码逻辑。
下面是一些常用的汇编指令及其含义:
| 指令 | 全称 | 说明 |
|---|---|---|
cmp | Compare | 比较两个数值,通常用于与跳转指令配合 |
je | Jump if Equal | 相等则跳转 |
jne | Jump if Not Equal | 不相等则跳转 |
jg | Jump if Greater | 大于则跳转 |
jl | Jump if Less | 小于则跳转 |
jge | Jump if Greater or Equal | 大于等于跳转 |
jle | Jump if Less or Equal | 小于等于跳转 |
jmp | Jump | 无条件跳转 |
call | Call procedure | 跳入子程序,执行后返回 |
ret | Return | 从子程序返回 |
mov | Move | 将后一个值赋给前一个寄存器或内存地址 |
add | Add | 加法运算 |
sub | Subtract | 减法运算 |
push / pop | Push / Pop | 入栈 / 出栈操作(栈为先进后出结构) |
nop | No Operation | 空操作,占位用,不执行任何指令 |
这些汇编指令是我们修改游戏逻辑时的重要工具。
三、指令长度与字节限制
在使用 IDA 或 CE 修改指令时,需要注意汇编指令的字节长度限制。如果你要用一条更长的指令替换原有指令,而原本的位置字节数不足,就会导致程序崩溃或逻辑错误。
举例说明:
-
mov eax, ebx只占用 2 个字节; -
mov eax, 123456可能需要 5 个字节; -
如果原始指令位置只有 2 字节,则不能直接替换为
mov eax, 123456,可以考虑使用nop填充或跳转到其他地方执行。
因此,我们通常采用插入 jmp 指令跳转到一段空白代码区域,执行较长的指令后再跳回来,这就是“代码注入”的基本操作流程。
四、跳转地址的偏移计算
在汇编中,跳转指令通常使用相对地址进行跳转。下面是一个示例:
0BBD:0000 B80000 MOV AX,0000 ; 将 AX 设置为 0 0BBD:0003 EB03 JMP 0008 ; 跳转到地址 0008 0BBD:0005 050100 ADD AX,0001 ; 不会被执行 0BBD:0008 40 INC AX ; 将 AX 加 1
这里的 EB03 表示从地址 0003 向后跳过 3 字节(即跳过 ADD 指令),跳到 0008 执行。
计算偏移的通用公式为:
偏移量 = 目标地址 - 当前地址 - 跳转指令自身所占字节数
这类计算在手动编写跳转逻辑时非常常见。
五、字节存储方式:小端序
在 x86(32位)和 x86_64(64位)架构的 CPU 中,采用的是小端存储(Little Endian)方式。
小端存储的特点是:
低位字节存储在低地址,高位字节存储在高地址
举例:
-
十六进制数
0x12345678 -
在内存中存储顺序为:
78 56 34 12
理解这一点对调试内存值、查看地址中的变量非常重要。
结语
本篇作为《植物大战僵尸》系列修改文章的科普篇,主要介绍了修改过程中会用到的基础知识:包括静态与动态地址、汇编指令、字节长度限制、跳转偏移计算以及小端存储结构等。掌握这些内容后,我们将在下一篇进入具体的修改实践,一步步解锁《植物大战僵尸》的乐趣与技巧。
敬请期待!
植物大战僵尸修改基础科普
4165





