游戏修改器制作教程三:内存与Cheat Engine

本教程面向有C\C++基础的人,最好还要懂一些Windows编程知识
代码一律用Visual Studio 2013编译,如果你还在用VC6请趁早丢掉它...
写这个教程只是为了让玩家更好地体验所爱的单机游戏,顺便学到些逆向知识,我不会用网络游戏做示范,请自重

本章介绍内存与Cheat Engine

计算机程序所有的变量、代码都是储存在内存里的,包括游戏里那些HP、MP、金钱等,那么只要能修改内存就能自由改变玩家的HP、金钱了(当然对于网游是没用的,这些数据都储存在服务器,客户端里的只是一个副本),常见的满血、金钱无限等游戏修改器大部分就是这个原理

想要修改指定的变量你要知道变量在内存里的地址,这时会用到内存搜索工具

Cheat Engine

Cheat Engine(以下简称CE)是最常用的开源的内存搜索软件,它还包括了很多调试工具

虽然看这名字就知道是用来游戏作弊的,但是也可以用于普通程序的内存搜索和调试

它的官网和GitHub库:
官网
GitHub库

你可以在官网或我的网盘下载到CE,我的网盘里的整合了中文补丁和一个中文版练习程序

本文通过CE自带的练习程序介绍用CE搜索内存的方法和常用的作弊手段,现在打开CE的练习程序,点击Next来到Step2

Step 2

这关是查找精确数值的练习,首先在CE中打开练习程序的进程:点击右上角选择进程的按钮,选中练习程序,打开进程

然后看看练习程序里的HP是100,那么搜索精确值100,类型选4字节(也就是int型)

左边会出来一堆内存地址,因为有很多地址的值为100嘛
然后在练习程序里点Hit me,HP变成了95,回到CE里再次扫描95

左边只剩下一个地址了,双击它把它加入下面的列表,然后再双击列表中的值,改为1000

回到练习程序里,Next按钮可以点了,过关~(这时你可以再点Hit me看看HP是多少)

Step3

这关没有给你精确数值了,只有一个血条,只知道HP范围是0到500

因为不知道数值,这次扫描类型选择未知的初始值,假设数值类型为4字节,点首次扫描

然后左边出现检索:365,568个地址,但是不显示在列表里(因为并没有什么用)

在练习程序里点Hit me,闪过个-5
既然知道减了5HP,CE里扫描类型选数值减少了...,值填5(如果连减少了多少值都不知道扫描类型就选减少的数值),再次扫描

只剩下6个地址了(其实可以看出就是第二个,因为HP范围为0到500)

重复上一步直到只剩下一个地址(或者你能看出是哪个地址),然后把值改成5000过关

Step 4

这关是练习浮点数的搜索,方法和Step 2一样,只是把数值类型换成浮点数和双浮点数,我就不重复说了,把HP和子弹都改成5000过关

浮点数运算是有误差的,CE也允许搜索的浮点数的值有一定误差

Step 5

既然代码也是储存在内存的,那么能修改内存就能修改代码了
当然内存里储存的可不是C语言,而是编译后的机器语言,它很难翻译成高级语言但是可以很容易翻译成汇编语言(反汇编),所以修改代码需要学习一些汇编知识
本章可以不用学汇编,照着做留个印象就好了

这关的要求是点击Change value后值不变,也就是把修改值的代码替换成什么也不干(汇编里的nop指令)

首先找到值的地址(同Step 2),然后右键,选择找出是什么改写了这个地址

然后再点一下练习程序里的Change value,指令列表里会出现改写了这个地址的指令

选中它,点右边的替换就会把它换成什么也不干的指令
关闭这个窗口,回到练习程序里点Change value过关

Step 6

有些变量的地址会变,比如动态申请内存的变量 int* p = (int*)malloc(10 * sizeof(int)); int* p = new int[10]; 但是不管怎么变总会有个静态的地址储存它的指针

本关要求是改变指针后值还是5000

首先找到值的地址,然后右键选择找出是什么访问了这个地址

再点击Change value,出现很多条指令,先双击第一条

(其实熟悉汇编的话这里就可以看出指针地址是Tutorial-x86_64.exe+0x2F7A50了,其中Tutorial-x86_64.exe表示这个模块的基址)

这是一条读取0x01250C30的指令,这里显示指针的值可能是0x118,一看就很不靠谱,和0x01250C30差太多了,再看下一条

这是一条写入0x01250C30的指令,显示指针的值可能是0x01250C30,正好和值的地址一样,就是它了

然后搜索十六进制01250C30,出来一个地址,这就是指针的地址,并且地址是绿色的说明它是静态的
点手动添加地址,勾上指针,填指针的地址

然后把值改成5000,勾上锁定

回到练习程序点击Change pointer过关


为什么不直接搜索0x01250C30而要看汇编代码呢?因为指针的值不一定是0x01250C30,比如这个变量在一个struct里而且不是第一个成员,比如是下面这个struct的v2
struct Foo
{
    int v1;
    int v2;
};
那么应该搜索0x01250C2C并且添加地址时偏移量要填4

如果搜索出来的不是静态地址怎么办?说明这是多级指针,比如p1->p2->p3->p4->v,你要一直找到指针p1...

Step 7

这关要求是点击Hit me你的HP会+2,就是把HP-1的代码换成HP+2

按照Step 5找到写入HP的代码

点击右边的显示反汇编工具,双击这行代码,把前面的sub改成add,后面的01改成02

然后点击Hit me就过关了


不过这里add指令和sub指令的长度刚好一样,如果add的长度大于sub的长度就会破坏后面的指令了,这时要用到CE的代码注入功能

点击菜单里的工具-自动汇编

然后点菜单里的模板-代码注入

填入在哪条地址上跳转,这里是"Tutorial-x86_64.exe"+2C77B,就是那条sub指令的地址

然后把原代码的sub指令去掉,在newmem里写入add指令

点执行,完成代码注入

你可以看到原来的sub指令变成了jmp指令,就是跳到我们的代码

跟过去看看里面是我们的代码,执行完后跳回去继续执行后面的代码

Step 8

这关就是传说中的多级指针,目标是点Change pointer后值还是5000

和Step 6一样先找值的地址,找访问这个地址的指令

(其实会汇编的话看看前面的代码就知道结果了,但不是经常有读取指针的指令连在一起的情况,更多的是某个类中某个方法访问了成员对象中的某个成员...这样)

偏移量为0x18,搜索0x012A3B00得到一级指针,再找访问这个指针的指令

偏移量为0,搜索0x0123CA60得到二级指针,再找访问这个指针的指令

偏移量为0x18,搜索0x0123C220得到三级指针,再找访问这个指针的指令

偏移量为0x10,搜索0x0125B620得到四级指针,显示为绿色,是静态地址,终于不用找了...

点手动添加地址,勾上指针,点三次Add offset,填入顶级指针的地址和各级指针的偏移量

把值改成5000,勾上锁定,点Change pointer过关

Step 9

可能你和你的敌人减血用同一个代码,如果你删除了这个代码你的敌人也会受到影响

这一关你要注入代码分辨出减血的是你的队伍还是敌人,让你的队伍胜利,而且不能用锁定血量

先找出各玩家的HP地址(根据提示HP是浮点数)

其中在找第一个HP的二级指针时出了点问题,CE的反汇编是这样的

估计CE的x64反汇编还不完善,这里我用IDA反汇编是这样的

可以看出偏移量是0x7F8,应该搜索RBX寄存器的值0x0113CB90
(其实知道了后面三个HP的偏移量也能猜出第一个HP的偏移量,这明显是一个指针数组)

然后为了分辨出玩家还要分析一下玩家的数据结构,打开内存浏览器点菜单的工具-分析数据/结构

然后点文件-Add new group添加3个group,每个group填入各HP的地址(准确来说应该填入指向HP指针的值,这里也就是减去偏移量0x08,不过我已经知道前8个字节是没用的)

点击结构-定义新的结构并且让CE尝试填入基本类型

可以看出第一个是HP,第4个是队伍ID,第5个是玩家名字

那么分辨的方法有很多种,可以判断HP>100的是敌人,或者队伍ID不等于1的是敌人,或者判断名字,或者判断指针指向哪个玩家...

这里我就判断队伍ID吧,在减HP的地方注入代码:

点Restart game and autoplay过关~~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值