第52章 内存逆向(一):内存搜索与修改(Cheat Engine)、内存断点

内存逆向,说白了就是跟程序运行时的那块“临时记忆”打交道。你想想看,程序跑起来以后,所有的变量、状态、血量、金币……全都在内存里待着。我们只要能找到它们的位置,就能读它、改它,甚至控制它。

我个人习惯把内存逆向分成三步走:搜 → 锁 → 断。搜,就是用Cheat Engine这类工具把目标值从海量内存里捞出来;锁,就是把它固定住,不让它变;断,就是下个内存断点,看谁在动它。今天咱们就把这三板斧讲透。

1. 内存搜索:从“大海捞针”到“精准定位”

我第一次用Cheat Engine的时候,其实挺懵的。打开进程,看到那一堆地址,完全不知道从哪下手。后来才明白,核心就四个字:值的变化

举个例子,一个游戏里你的金币是100。你搜100,会出来几万个结果。然后你花掉10个,金币变成90。你再搜90,结果就少了一大半。重复几次,最后就剩一两个地址——那就是你要找的。

核心思路:利用“值的变化”来缩小搜索范围。每次变化都是一次过滤。

1.1 精确值搜索 vs 模糊搜索

搜索类型 适用场景 示例
精确值搜索 数值明确,如血量、金币 搜 100 → 变 90 → 搜 90
模糊搜索 数值未知,如进度条、百分比 搜“增加的值” → 再搜“减少的值”
未知初始值搜索 完全不知道数值 先搜“未知初始值”,再根据变化过滤

我在项目中遇到过一种情况:某个游戏的血量显示是整数,但实际内存里存的是浮点数。你搜整数死活搜不到,换成浮点数一下就出来了。嗯,这里要注意——显示值和存储值不一定相同

1.2 数据类型的选择

Cheat Engine支持多种数据类型。选错了,搜到天荒地老也找不到。

  • 2字节 / 4字节:最常见,大部分整数用这个
  • 浮点数:带小数点的值,比如坐标、百分比
  • 双精度浮点数:精度要求高的场景
  • 字节数组:搜固定模式,比如找特征码

小技巧:不确定数据类型时,先用4字节搜。搜不到再换浮点数。我一般会同时开两个搜索窗口,一个搜整数,一个搜浮点,对比结果。

2. 内存修改:从“观察者”变成“操控者”

找到地址之后,下一步就是改它。Cheat Engine里最常用的就是“锁定值”功能。你把地址加到列表里,双击数值,改成你想要的,再勾上“锁定”——好了,这个值就永远不变了。

但这里有个坑。我曾经改一个游戏的金币,锁定了99999,结果游戏直接崩溃了。为什么?因为游戏内部有校验。你改得太离谱,它检测到异常,直接报错退出。

避坑指南:我曾经遇到过游戏把数值存了两份——一份是实际值,一份是校验值。你只改实际值,校验值对不上,游戏就会强制重置。解决办法是:找到校验逻辑,一起改掉。

2.1 修改策略

  • 温和修改:只改一点点,比如血量从100改成500,别直接改99999
  • 锁定 vs 一次修改:锁定适合持续生效的场景,一次修改适合只需要触发一次的情况
  • 多级指针:有些值不是固定的,每次启动游戏地址都会变。这时候要用指针扫描

3. 内存断点:抓住“谁动了我的奶酪”

搜到地址、改了值,这只是第一步。真正有意思的是——你想知道是谁在改这个值。这时候就要上内存断点了。

内存断点分两种:

  • 写入断点:当有代码往这个地址写数据时,断下来
  • 访问断点:只要有代码读或写这个地址,就断下来

我个人习惯先用写入断点。因为大部分情况下,我们关心的是“谁在改这个值”。找到那条指令,就能顺藤摸瓜找到整个逻辑。

3.1 下断点的步骤

  1. 在Cheat Engine里找到目标地址
  2. 右键 → “找出是什么改写了这个地址”
  3. 触发游戏里的操作(比如扣血、加金币)
  4. Cheat Engine会捕获到一条汇编指令
  5. 双击那条指令,就能看到完整的上下文

关键点:下断点之前,一定要确保地址是“活的”。如果地址已经失效,断点也白搭。

3.2 分析断点结果

断下来之后,你会看到类似这样的汇编代码:

mov [eax+0x10], edx   ; 把edx的值写入eax+0x10的位置
add [ecx+0x08], eax   ; 把eax加到ecx+0x08的位置

这时候你要问自己几个问题:

  • 这个地址是全局变量还是堆分配?
  • 写入的值是从哪里来的?
  • 有没有多层间接引用?

我记得有一次分析一个网游的伤害计算,断下来发现写入的值是从一个函数返回值里取的。顺着那个函数往上翻,才找到真正的伤害公式。嗯,这种时候就得有点耐心了。

4. 知识体系总览

下面这张图是我自己整理的内存逆向核心流程。你看一遍,心里就有谱了。

内存逆向核心流程 内存搜索 内存修改 内存断点 搜索方式 精确值 / 模糊搜索 未知初始值 / 字节数组 数据类型选择 修改策略 温和修改 / 锁定值 一次修改 / 持续锁定 多级指针处理 断点类型 写入断点 访问断点 汇编指令分析 目标:定位 → 修改 → 溯源

5. 实战中的几个坑

讲到这里,我再说几个实际干活时容易踩的坑。

  • 地址失效:游戏重启后地址变了。解决办法是用指针扫描,找到基址。
  • 反调试检测:有些程序会检测Cheat Engine进程。我一般用CE的“隐藏进程”插件,或者换用x64dbg。
  • 多线程写入:断下来后发现好几个线程都在写同一个地址。这时候要分清主次,找到真正控制逻辑的那一个。
  • 数值加密:有些游戏会把数值做异或或加减混淆。你搜到的值不是真实值,需要逆向加密算法。

我的习惯:每次下断点之前,先确认地址是否稳定。我会反复触发几次操作,看地址是否每次都变到同一个位置。如果地址飘忽不定,那多半是指针没找对。

6. 小结

内存逆向这件事,说白了就是跟程序玩捉迷藏。你搜它、改它、断它,一步步摸清它的底细。Cheat Engine是个好工具,但工具只是手段,真正的功夫在于你怎么分析、怎么推理。

我个人觉得,内存断点是最能体现逆向功底的一环。你能从一条汇编指令里读出整个逻辑链,那才叫真的入门了。嗯,今天就先聊到这儿。下一章咱们接着讲指针扫描和代码注入,那又是另一番天地了。


公众号:蓝海资料掘金营,微信deep3321