冒险岛079

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1|回复: 0

Day 7 -- 代码注入:在游戏的伤口上撒点盐

[复制链接]

701

主题

13

回帖

2235

积分

管理员

积分
2235
发表于 4 小时前 | 显示全部楼层 |阅读模式
Day 7 -- 代码注入:在游戏的伤口上撒点盐
Cheat Engine 从入门到住院 · Day 7

Day 5 我们学会了 NOP——把扣血代码删掉,让游戏不再扣血。简单粗暴,但也很"粗":只能删,不能改。

如果我想要的不是"不掉血",而是"每次被打反而加血"呢?或者"每次被打掉血的同时,金币加 100"呢?

NOP 做不到。你需要一个更强大的技能——代码注入。

简单说,代码注入就是在游戏的代码流程中"插队",让游戏执行你自己写的代码,然后再回到原来的流程。

━━━━━━━━━━━━━━━━━━━━

本文你将学到

  • 代码注入的原理
  • CE 的 Auto Assembler 模板
  • 如何编写简单的注入脚本
  • JMP + 跳板(Trampoline)机制
    阅读时间:15 分钟 | 实操时间:30 分钟 | 难度:进阶

    ━━━━━━━━━━━━━━━━━━━━

    CE Tutorial Step 7:代码注入

    进入 Step 7。照例是血量和 Hit me。

    任务:每次点击 Hit me,血量不但不减少,反而增加 2。

    不能用 NOP(那只是不减少),也不能用冻结(那是锁定不变)。你需要修改游戏的扣血逻辑,让它变成加血逻辑。

    ━━━━━━━━━━━━━━━━━━━━

    代码注入的原理

    游戏原来的代码流程是这样的:
    1. 指令 A:计算伤害
    2. 指令 B:血量 = 血量 - 伤害    ← 扣血代码
    3. 指令 C:更新血条显示
    复制代码

    代码注入的做法是:
    1. 指令 A:计算伤害
    2. JMP 到你的代码区域          ← 跳转到你的"跳板"
    3.   你的代码:血量 = 血量 + 2  ← 你的自定义逻辑
    4.   JMP 回指令 C              ← 跳回去
    5. 指令 C:更新血条显示
    复制代码

    核心思路:

  • 在内存中找一块空闲区域,写入你的自定义代码
  • 把原来的扣血指令替换成一条 JMP 指令,跳到你的代码
  • 你的代码执行完后,再 JMP 跳回到原来的下一条指令

    这块空闲区域就叫"跳板"(Trampoline)或"代码洞穴"(Code Cave)。

    ━━━━━━━━━━━━━━━━━━━━

    实操步骤

    第一步:找到扣血代码

  • 用老方法找到血量地址
  • 右键 → Find out what writes to this address
  • 点 Hit me,记录扣血指令
  • 选中指令,点击 "Show disassembler" 打开反汇编视图

    你会看到扣血指令在反汇编视图中高亮显示。

    第二步:打开 Auto Assembler

    在反汇编视图中,选中扣血指令,按 Ctrl+A(或菜单 Tools → Auto Assemble)。

    这会打开 Auto Assembler 窗口——CE 内置的汇编脚本编辑器。

    第三步:使用模板生成框架

    在 Auto Assembler 窗口中,点击菜单 Template → Full Injection

    CE 会自动生成一个注入脚本框架,类似这样:
    1. alloc(newmem, 2048)
    2. label(returnhere)
    3. label(originalcode)
    4. label(exit)
    5. newmem:
    6.   // 在这里写你的自定义代码
    7. originalcode:
    8.   // 这里是原始指令(CE 自动填充)
    9.   sub [rbx+000000EC], eax    // 原来的扣血代码
    10. exit:
    11.   jmp returnhere
    12. // 注入点
    13. "Tutorial-x86_64.exe"+2A123:
    14.   jmp newmem
    15.   nop
    16. returnhere:
    复制代码

    让我们逐行解读:

    1. alloc(newmem, 2048)
    复制代码
    :在内存中分配 2048 字节的空间
    1. newmem:
    复制代码
    标签:你的自定义代码写在这里
    1. originalcode:
    复制代码
    :原始指令(由 CE 自动填充)
    1. exit:
    复制代码
    +
    1. jmp returnhere
    复制代码
    :执行完后跳回游戏原来的代码
  • 最后几行:把原始位置的代码替换成
    1. jmp newmem
    复制代码

    第四步:修改脚本

    现在把框架中的
    1. originalcode
    复制代码
    部分改掉。原来是:
    1. originalcode:
    2.   sub [rbx+000000EC], eax    // 血量 -= 伤害
    复制代码

    改成:
    1. originalcode:
    2.   add [rbx+000000EC], 2      // 血量 += 2
    复制代码
    1. sub
    复制代码
    换成
    1. add
    复制代码
    1. eax
    复制代码
    (伤害值)换成
    1. 2
    复制代码
    (固定加 2)。

    第五步:执行脚本

    点击 Auto Assembler 窗口中的 Execute

    CE 会把你的代码写入内存,并在原始位置插入跳转指令。

    第六步:验证

    回到 Tutorial,点 Hit me。血量增加了 2。

    反复点几次,血量持续增加。点 Next,Step 7 通关。

    ━━━━━━━━━━━━━━━━━━━━

    Auto Assembler 语法速成

    你需要知道的基本语法:
    1. // 分配内存
    2. alloc(名称, 大小)
    3. // 标签(用于跳转的"书签")
    4. label(名称)
    5. // 基本指令
    6. mov [地址], 值       // 赋值
    7. add [地址], 值       // 加法
    8. sub [地址], 值       // 减法
    9. mul                  // 乘法
    10. nop                  // 空操作
    11. jmp 标签             // 无条件跳转
    12. cmp 操作数1, 操作数2  // 比较
    13. je 标签              // 相等则跳转
    14. jne 标签             // 不等则跳转
    15. jg 标签              // 大于则跳转
    16. jl 标签              // 小于则跳转
    17. // 启用/禁用段(用于脚本的开关功能)
    18. [ENABLE]
    19. // 注入代码
    20. [DISABLE]
    21. // 恢复原始代码
    复制代码

    ━━━━━━━━━━━━━━━━━━━━

    脚本的 ENABLE 和 DISABLE

    一个完整的 CE 脚本通常包含两个部分:
    1. [ENABLE]
    2. alloc(newmem, 2048)
    3. label(returnhere)
    4. newmem:
    5.   add [rbx+EC], 2
    6.   jmp returnhere
    7. "Tutorial-x86_64.exe"+2A123:
    8.   jmp newmem
    9.   nop
    10. returnhere:
    11. [DISABLE]
    12. dealloc(newmem)
    13. "Tutorial-x86_64.exe"+2A123:
    14.   sub [rbx+000000EC], eax
    复制代码
    1. [ENABLE]
    复制代码
    部分是启用脚本时执行的(注入你的代码),
    1. [DISABLE]
    复制代码
    部分是禁用脚本时执行的(恢复原始代码)。

    这样你就可以把脚本保存到 Cheat Table 中,随时打开和关闭。

    ━━━━━━━━━━━━━━━━━━━━

    注入代码的注意事项

    保护寄存器

    如果你的代码修改了某些寄存器的值,可能会影响后续的游戏逻辑。安全的做法是在修改前保存、修改后恢复:
    1. newmem:
    2.   push eax           // 保存 eax
    3.   mov eax, 2
    4.   add [rbx+EC], eax  // 血量 += 2
    5.   pop eax            // 恢复 eax
    6.   jmp returnhere
    复制代码
    1. push
    复制代码
    把寄存器的值压入栈中保存,
    1. pop
    复制代码
    再取出来恢复。

    指令长度对齐

    JMP 指令通常需要 5 字节(32位)或更多字节。如果被替换的原始指令不够 5 字节,CE 会自动用 NOP 填充剩余空间。

    如果原始指令超过 5 字节,CE 的模板会自动处理好对齐问题。

    ━━━━━━━━━━━━━━━━━━━━

    常见问题

    Q:执行脚本后游戏崩溃了怎么办?

    A:你的汇编代码写错了,或者破坏了寄存器/栈的平衡。重启游戏,检查代码,注意 push 和 pop 要配对。

    Q:Auto Assembler 的模板自动生成的代码能直接用吗?

    A:模板生成的是"原样执行原始指令"的框架,直接执行等于什么都没改。你需要在
    1. newmem
    复制代码
    1. originalcode
    复制代码
    之间插入你的自定义逻辑,或者修改
    1. originalcode
    复制代码
    的内容。

    Q:代码注入只能用于数值修改吗?

    A:远不止。你可以修改任何游戏逻辑:跳过条件判断、修改函数返回值、插入日志输出等。代码注入是所有高级修改的基础。

    ━━━━━━━━━━━━━━━━━━━━

    小结

    今天我们学会了代码注入——CE 最强大的武器之一:

  • 代码注入的原理:JMP 跳板 + 自定义代码 + JMP 返回
  • 使用 Auto Assembler 模板快速生成注入框架
  • 修改游戏逻辑(从扣血变为加血)
  • ENABLE/DISABLE 机制实现脚本的开关功能

    从"找数据改数据"到"找代码改代码"再到"写自己的代码注入游戏",你的 CE 能力已经完成了三级跳。

    明天 Day 8,我们要挑战多级指针——当指针指向的不是数据而是另一个指针时,你需要像剥洋葱一样一层层剥开。

    提前警告:明天的内容是公认的 CE 学习最大门槛。但别怕,搞懂了之后你会发现它的逻辑其实很简单。
  • 您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    果子博客
    扫码关注微信公众号

    Archiver|手机版|小黑屋|风叶林

    GMT+8, 2026-3-29 20:42 , Processed in 0.199223 second(s), 19 queries .

    Powered by 风叶林

    © 2001-2026 Discuz! Team.

    快速回复 返回顶部 返回列表