Cheat Engine
- Cheat Engine 新手教程
- Step - 1 - 怎样通关【简介】
- Step - 2 - 数值搜索
- Step - 3 - 未知数值
- Step - 4 - 浮点类型
- Step - 5 - 代码查找器
- Step - 6 - 指针
- Step - 7 - 代码注入
- Step - 8 - 多重指针
- 第0重指针
- 第1重指针
- 第2重指针
- 第3重指针
- 第4重指针
- Step - 9 - 共享代码
Cheat Engine 新手教程
Cheat Engine是一款致力于游戏的修改器。它可以用来扫描游戏中的内存,并可以修改它们。它还附带了调试器、反汇编器、汇编器、变速器、作弊器生成、Direct3D操作工具、系统检查工具等。
悄咪咪:第一篇博文┳━(’?’)シ━┳—原来编辑博文是这样子的!!
·感觉已经把所有详细过程都贴出来了,如果什么地方说的不对/不清楚,欢迎留言哦!喜欢就点个赞吧~
打开Help->Tutorial
·Step1-5都比较简单,自己尝试的过程中没有截图,图源简书的喝豆腐脑加糖 1,用的是CE6.5
·Step6及以后用的是CE6.8.1
Step - 1 - 怎样通关【简介】
只要满足某些条件,Next按钮就可以点击到下一步。
Step - 2 - 数值搜索
要求是将我们的血量改为1000
首先点击加载进程,找到Tutorial。
搜索血量值:100 ,会找到很多;这时就需要不断点击Hit me来改变血量来锁定具体数值。
然后将找到的数据添加到下方的table中
更改为1000进入下一关。
Step - 3 - 未知数值
有些时候,我们看不到具体的血量,我们在攻击的时候可以看到减少的数值。将这个血量改为500
这就是本关的情景,点击 new scan 开始新的搜索。
将搜索类型改为未知
之后添加到 table 中,改为 500 即可。
Step - 4 - 浮点类型
将搜索的类型改为float double,其他和之前操作类似,更改为5000即可。
Step - 5 - 代码查找器
从这开始变难了~
储存数据的地址不是固定不变的,每一次重启游戏通常都会变动,甚至在你玩游戏的过程中地址都有可能改变。
这一关讲解:将写入“地址”的代码变成不做任何事情的代码,从而实现储存数据的地址不变。这时,点change按钮,你找到的这个值会没有反应(不跟着发生变化了),因为change修改了存储数的地址,而你找到的这个值地址此时已经不变化了(没有代码促使它发生变化)。
具体步骤如下:
找到数值添加到 table 中,点击 find out what writes to address
可以看到此处控制数据的变化,将这处汇编使用nop填充,之后数据的地址便不会更改。
其实是在这个地方会下一个断点,为了不影响以后操作将断点 stop 取消。
Step - 6 - 指针
哦,更难了
仅仅上面的 Step - 5 - 可以做到:让这个值不发生变化,或者你直接填入变化的值(表面的变化)
但做不到:找到设置所需值的地址,从而实现根本性的变化
这就是出现“指针”概念的原因。
在读tutorial自己做的时候可能会糊涂,本文以具体的例子一步步带着走
首先还是老套路,找到这个值,然后在下方看到它存储在哪个地址。
现在值为405,发现只change value而不改变位置的时候,它的存储位置目前是在0153FA50。
注:如果此时只双击405改掉,那么点change value 以后这个值还是会跟着变,但是点change pointer以后这个值就不会变了,(也就相当于你在游戏里面成功做了一次弊,但是之后你真正做任务的时候却也不能得到资源了),说明不能这么改,要改的让原本的机制没有变化才行。
再用16进制查0153FA50,目的为:知道什么地址存着“这个地址”(0153FA50)。此处找到1002CCA40,即在1002CCA40处存的是“0153FA50”这个地址,而0153FA50处存的是405这个值。
我们现在希望:change pointer时,我们可以手动改值,并且存储位置改变时数据依旧跟着改变,除非锁住(点一下前面的active框即可)。
思路:改1002CCA40地址指向的地址指向的值。
(?这是套娃?(???)?!)
做法:Add Address Manually 手工加地址
首先选上Pointer,然后写入地址1002CCA40,点击OK
看:1002CCA40是指向0153FA50的,自动出来了,然后这个0153FA50又是一个Pointer,指向它应该指的值405。
于是,多了这么一行,这样讲应该就很容易理解了。405为P->0153FA50->405,那么此时无论是change Pointer 还是change value都会让这个第三行的405发生相同的改变。(这样也好理解为什么第一行的405只是在change value时变化,而change pointer就不跟着变了)
为了做到我们人工改变值,暂时不被change pointer(理解为游戏定时的一种给你加减资源的机制)控制,双击value改成5000后,锁死active。发现next亮了,说明此关通过了。
Step - 7 - 代码注入
目标:将伤害由 -1 改为 +2
别人打你你还回血,太无耻了
说是点一下hit me,把原先的 -1 变成 +2 这么轻松,但是真正改起来,这一步需要用到汇编语言。
还是老套路,找到这个值,下方框框直接看它的地址;右键看谁写入它的地址
点击 hit me,自然的,出现指令语句
点击Show disassembler(反汇编)
原理:
解释一下这一行所蕴含的信息:[^1]
-
这个指令所在的地址为2D27B;
-
对应的字节码中,83代表指令集中的操作码sub,也就是减法操作;
-
AE为指针,指向
RSI加一个偏移量
,即指向register source index源变址寄存器加一个偏移量。RSI寄存器在01565480(下一步会讲是怎么来的)。偏移量即为00000780; -
最后的01代表减去的那个1
合起来就是说,AE指向的这个
RSI加一个偏移量
在hit me操作后,会减1。此步是为了解释上一步中RSI,我们双击这个框可得RSI寄存器的位置,01565480
其实,
这个RSI加一个偏移量
就是这个Address
01565480+00000780
=01565C00
那我们的目的很明显,把sub改成add,1改成2就行
发现next亮了,此关已过。
p.s. 其实需要修改的比较多/复杂时,可以自己写代码注入,我这是投机取巧的方法。正规具体操作为:用ctrl+A或者Tools->Auto Assemble
出来一个框,点击 Template->Code injection
模仿sub操作写一个add操作即可。(也可以按需来)
Step - 8 - 多重指针
二重指针类似于:一个地址A存的是另一个地址B,这个地址B存的是另一个地址C,C才真正存放值。四重则是在A前面还有地址M,地址M前面还有地址N。
分析:
第0重指针
先从最低层看起,其实不是个指针,便于理解写成第0层。
对应下图看:d为3508。
change value,搜索这个d,
得到了存储d值的地址c为0158B4C8。
第1重指针
进一步地,我们需要通过c知道b,故右键看0158B4C8的写入者。点 Find out what writes to this address,然后再change 一次值。此时新窗口中会出现指令。
前面的Count是change一次value就加1
双击指令,看到
RSI=0158B4B0
RSI+偏移量18=0158B4B0+00000018=0158B4C8,也就是刚刚的地址。地址b指向的c(这里的c是下文的c’)其实是RSI=0158B4B0,而c+18
(这里的c是下文的c’)这个地址才指向值d;换句话说,地址b指向c’。(下面按套路搜索可以知道b的地址)
所以我们下一步不应该搜索0158B4C8,而应该搜索0158B4B0,记作地址c’。
继续按套路搜索。发现这个c’存储在地址b=08EA18B0里。
因为:要直观地显示地址b->地址c的过程(之前是b->c’)
所以:我们手动添加指针,点Add Address Manually->Pointer->写上地址08EA18B0,但是还要注意有一个偏移量18(因为b实际上指向c’)
简单点说,就是c、d之间有直接关联,b、c’之间有直接关联,而c和c’是加一个偏移量的关系,根据他们的关系推出b和c之间的关系。
点OK后,新的条目就加上了,为了醒目,这个图上把描述改成了每一个条目对应说明的内容。
显而易见,如果点change value,只有最终值d(两个1422)会发生变化
但如果点 change pointer 再change value,那么会出现
左边的三行的所有数据都不跟着变动了,原因是原本的关系发生了变动:(此处为了简单,没有把C、C’等关系画出)
对照标了b、c、c’、d的图看,很显然它们确实不应该变化。
由于点了change pointer,刚刚的线路已经废了,我们删掉存档,重新来一遍。(嘿嘿 是不是似乎被坑了呢)
这是我们复原进行 change pointer 之前的所有操作的结果:
第2重指针
已经有了b->c->d,下面要找a->b的a。
前车之鉴告诉我们,不能再change pointer了。但是如果不change pointer 就没法看what writes to b。所以只能看what accesses b。
点击Find out what accesses this address->Find out what accesses this pointer
再点change value,显示了正在执行的指令
发现这个地方A是直接存的B,没有偏移量,所以我们再add address manually的时候,第二重指针的偏移量就为0了。(理解:C->D为直接值;B->C为第一重指针,偏移量为18;A->B为第二重指针,偏移量为0)
搜索B
手动添加A->B->C->D的指针,A为0158B548
到目前为止,已经找到二重指针了,A->B,B->C
第3重指针
同理,A前面如果还有指针M,那就是第三重指针
先看是否有偏移量(右键find what access,change pointer)
发现偏移量为18,那就是自己手动添加的时候要加一个18偏移量
查询存放A的地址M,查(0158B548-18=0158B530)即A’存储在哪里
发现M=0156CAE0
手动添加M->A->B->C->D
至此,第三重指针已添加完毕。
第4重指针
继续以类似方法推导第四重,在M前面加一个N。
偏移量为10。
M’=M-10=0156CAE0-10=0156CAD0,
手动添加n->m->a->b->c->d的指针。
从上到下依次是0~4重指针。
现在要做的是:
意思就是说你改一改指针,点change pointer,有3秒给你把值改到5000,在这三秒内必须改掉,否则前功尽弃。就改第四重的value就可以了。
next已亮,此时发现只有第四重指针能用,其他都废了,很容易理解。此关已过。
Step - 9 - 共享代码
有时候使敌人掉血的代码和使自己掉血的代码是同一个代码,单纯修改这个代码会使要么同时对自己和敌人有利,要么同时有害,而不是对自己有利,对敌人有害。
本关重现了这样一种情况:己方初始血量很少,且被攻击一次掉血很多,敌方初始血量很多,且每次攻击只掉1滴血。
需要做的是:不使用锁定,让己方不死,而敌方阵亡。
1.首先,我们还是用套路找到PLAYER1、PLAYER2、PLAYER3、PLAYER4的血值,用float搜索得到
对Player1、Player2、Player3、Player4分别看what writes to this address,change value 看是什么地址写入的,点show disassembler看反汇编,第一行的代码的意思是将eax放入(ebx+4)这个位置,发现四个在减血的时候执行的都是这行代码,不同的只是用到的寄存器里的值不一样。
所以,要看看这条指令究竟写了哪些地址,也就是多少人共用这一条减血的指令。
发现就这四个人,(两方)
思路就还是注入代码。
alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(no_decrese_health) // 在这里定义一个标签
label(exit)newmem: //this is allocated memory, you have read,write,execute access
//place your code here
// 在这里添加代码
cmp byte ptr [ebx+15], 44 // 判断 [ebx+15] 是否为 D
je no_decrese_health // 如果相等的话,则跳转到 no_decrese_health 标签
cmp byte ptr [ebx+15], 45 // 判断 [ebx+15] 是否为 E
je no_decrese_health // 如果相等的话,则跳转到 no_decrese_health 标签originalcode:
mov [ebx+04],eax
no_decrese_health: // 在这里使用这个标签
fldz exit:
jmp returnhere"Tutorial-i386.exe"+265B7:
jmp newmem
returnhere:
show disassembler->tools->auto assemble->template->code injection
其中,这个偏移量
的来源是:
more information->全选,右键->open dissect data with selected addresses->OK->OK->YES
发现0010偏移量显示的是team1和team2,对照着地址看是正确的。
参考文献:
-
[1] Cheat Engine — 封弊者
-
[2] [oeasy]教你玩转ce7(cheat engine游戏作弊器)使用教程