Steam 游戏 《Crashlands2》(崩溃大陆2)的 修改器制作 - 附修改过程
日期:2025.04.16
博客期:182
星期三
【温馨提示】:
我现在把资源先放到开头,不想研究学习的就直接取用。如果修改器失效了,你们可以在博客园本页直接评论,也可以给我发邮件告诉我,就是不要到百度云上去说了,百度云我好久不登录一次的!大家给我发邮件的话,记得要注明是哪个游戏,内容当然是越详细越好啦!邮箱地址:nightskysxs@163.com
相关下载(CT文件【本文完结时发布】+简易修改器):
百度云网盘下载:https://pan.baidu.com/s/1vtidvugrvF3kKeJ1sNLexw 提取码:cras
夸克网盘下载:https://pan.quark.cn/s/f327cb3f8c6c 提取码: Yssm
当前最新研究的版本如下图:

当前最新的修改器图示:

前言
在修改分析方面,二代相比一代来说很多机制都有所改变,如武器没有了“品质改变”的情况、攻击力的计算机制等等。但不妨碍它们有很多共通性质的东西——基本只存在双浮点类型的数据 以及 物品数量的数据存在多份等等。这些共性无疑为我们去研究这款游戏的修改性提供了重要帮助!
如果你想把《崩溃大陆2》作为 CE 游戏修改的练习题,那么可以阅读一下这篇文章,了解一下我的修改思路以及看看对你的修改技术提升有没有帮助。
如果你已经看过我制作《崩溃大陆》一代这一期的博客并了解到了那一期的修改器思路,那么这篇文章可能对你的价值可能不是很高,请酌情阅读。
正文
本修改使用的工具是 Cheat Engine,其下载以及汉化请参考其他博客教程。
在游戏修改之前,我们可以事先根据一代的功能进行畅想——说这一代我到底要做哪些功能呢?
a. 与生命值相关:[ 无限生命 ] 、[ 一击必杀 ]
b. 与冷却时间相关:[ 技能无冷却 ] 、[ buff时间不减 ] 、[ 快速建造 ]
c. 与采集相关:[ 无限物品 ] 、[ 十倍采集资源 ]
d. 其他类型:[ 高级品质装备 ]、[ 超级移速 ]、[ 隐身模式 ]、[ 图纸限制解除 ]
好!我们暂且认为我们仍然要去实现以上功能,抱着这样的期待,我们进入游戏吧!
FUN A:--------------------------------------【无限物品】
无限物品功能实现的是可使用物品数量的无限,也就是说需要将玩家收集到的物品数值改到一个非常大的数值(可以在游戏中被视为用不完的程度)。如果你会一些 Cheat Engine的基础操作,很容易完成如下操作以实现单一物品的数量修改。
① 打开 Cheat Engine软件,点击左上角的小电脑选择 “Crashlands2”进程,选择“打开”!

② 选择数值类型为双浮点类型(如果是新游戏刚开始修改拿不准类型的话就选择所有类型——所有类型默认包括单浮点、双浮点和4字节整型);

③ 在游戏中查看你要修改的物品的当前数量(我搜索的是游戏中 “光草”的物品数量),将数值填入搜索框内,并点击 “首次扫描”;(如游戏中 光草 的数量为 5,则搜索框内填入5.00;这样基本可以筛选掉5.1、4.8等小数部分不为0的数值)
④ 在游戏中修改此物品的数量,并重新将更新的数值填入搜索框内,并点击 “再次扫描” (对结果进一步的筛选);
⑤ 重复上一步,直到剩下了无法被筛选掉的几项(本游戏中暂时为三项);

⑥ 按住 shift 热键 点击第一项和最后一项,完成三项地址的选中,鼠标右击,再点击 “改变已选中地址的数值”。

⑦ 在弹出的窗口的输入框内填入要修改的数值(如49999)完成修改(为什么是49999?因为我还没做一代修改器的时候,修改物品数量超过99999之后数据在保存时会被清零,后来我就改49999了)。

ok,会了以上步骤,你其实已经能够使用CE修改这个游戏里所有物品的数量值了!当然,绝大部分的CE使用者也都是停留在这个阶段的。那么有网友就会觉得每次修改都得走一整套上面的流程,这实在是太麻烦了!虽然节省了物品采集的繁琐步骤,但是实际上游戏里面几百种材料,我要来上这么几百次,累计的工作量也属实不小哦!就算我能够控制游戏中的 a物品 和 b物品 的数量保持一致,然后在查找时一次性找出 a物品 和 b物品的地址来一定程度上减少我查找的次数!但其实这实际上也不能够降低消耗的时间规模和操作复杂规模。所以需要采用 代码注入的方式 将 一部分汇编码 嵌入到源程序的代码中去,来使得我们的无限物品以 “自动化” 的方式运行。
<1> 我们分别双击第④步找到的三个地址,并按照次序依次命名为 “FValue”、“MValue”、“LValue” (First Value、Middle Value、Last Value 仅表示了其地址大小关系,与CT表中的值不一定对应,以 CT 表 的 Act 中跳转地址为准;简单来说,叫什么名字无所谓,不要过分纠结CT表中和本文中的名字问题)。由于我们需要拿这三个值当作实例,所以我们还是把它们的物品数量改回 8.00 ;

<2> 要想实现 “无限物品”功能,就需要找到所有修改 FValue、MValue、LValue三个值的代码,并把它们全部改写成一个 对游戏来说算是无限大的值 就可以啦(此后无限物品部分,我将使用49999这个值)!
<3> 在开始修改前我们也要想好——修改物品数量 都会在游戏中对应什么样的游戏操作。答案是:a. 采集物资 b.建筑模式放置以及拿回 c.工作台上消耗物品以及产生产品 d.任务中获取物资以及给出物资 e.技能中投掷物品消耗物品数量
<4> 考虑 “无限物品”功能的覆盖性,我们要考虑在完成上述五个操作对应的代码都要进行修改,也就是说理论上要我们找到 5 个模式下分别修改 3类值 的代码,对应要找 5×3 = 15 次!这真的是太麻烦了,对不对?哼哼~我才不会告诉你们这里面有很多是重复的呢!是的,一般游戏作者也不会去写那么多重复实现同一个功能的代码的。之后,咱们考虑按照功能验证的方式去实现咱们的 “无限物品”。就是先完成 采集部分对FValue的代码修改,然后在游戏中验证这个修改对15个点的覆盖情况。当有一种情况发现未被覆盖时,针对这种情况再做代码修改,依此类推直到完成了以上 15个点的覆盖。
接下来<5>到<30>,即为 采集部分对 FValue 的代码修改部分。
<5> 我们对 FValue 鼠标右击,选择 “找出是什么改写了这个地址” 。因为我们想要做出来的修改效果是:在我们获取了一个物品的时候(物品数量被改写的时候),就直接把数量改成 49999(无限)。如果选择“找出是什么访问了这个地址”范围就会扩大,并囊括出诸如 “罗列物品清单时”、“物品数量不降为负值的校验”等等。

<6> 在游戏中采集光草后(我这个物品数量是光草的数量),得到如下结果,点击“显示反汇编程序”,会弹出标题为 “Memory Viewer” 的内存查看器。

<7> 分析 mov [rbx],rax 一句,mov是赋值语句,左操作项是被赋值者,右操作项是要赋的值。用C来说的话就是:*(rbx) = rax 。由此对应到游戏的实际意义——在物品修改的代码运行到这里时,rbx 寄存器存储的是 FValue 的地址,即我们搜到的 28FA7B79250,而 rax 此时存储的是 要被修改成多少的那个数值。由此,我们知道了这一段代码是修改很多不同实际意义的双浮点类型数据的一段代码,可以给此处代码设一个书签(我这里是书签0)方便我们访问,如下图。

<8> 此处设置断点,我们发现断点一直处于激活状态,说明游戏的实时进程中对于此部分代码的复用程度很高。但我们需要的是只有在物品被修改时,这个断点才被激活,这样我们才能够确定物品修改所对应的CALL调用结构。有什么方法可以做到吗?那就是先通过代码注入的方式,将代码改造成 “带有是否来源于物品修改”的判定的代码段,然后预留出是物品修改的情况的单独代码段(就是预留出给咱们加断点的地方,哈哈)。注:别忘了把断点删除,并点击运行使游戏恢复运行。
<9> 选中 书签0 代码段 (上图 Crashlands2.exe+1EBC075 :mov [rbx],rax 一句),点击菜单栏选择 - 工具 - 自动汇编 (或者直接快捷键 Ctrl + A);

<10> 在自动汇编窗口下,在菜单栏中依次选择 模板-CT表框架代码、模板-代码注入,代码注入时的弹窗不用管(因为我们是选中地址进行汇编的,默认就是从这句开始注入),直接点击 确认/OK,得到结果如下;
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBC075) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 mov [rbx],rax 13 mov rbx,[rsp+00000090] 14 15 exit: 16 jmp returnhere 17 18 "Crashlands2.exe"+1EBC075: 19 jmp newmem 20 nop 6 21 returnhere: 22 23 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+1EBC075: 30 db 48 89 03 48 8B 9C 24 90 00 00 00 31 //mov [rbx],rax 32 //mov rbx,[rsp+00000090]
<11> 我们需要调整代码逻辑为 “当此时来源于物品修改函数的CALL时执行一段空代码”!我突然很想说数学上的一个四字词语啊!就是 不难发现 啊,当 rbx 是 我们刚刚找到的光草物品数量的 FValue 时,此句在被执行的时候,肯定是恰好是物品修改的CALL。
<12> 我们把 originalcode 部分的源代码剪贴到 exit 部分的开头,之后在 originalcode 部分写上针对于 rbx 地址的判别跳转逻辑,以及符合条件的单独代码部分,如下部分。
cmp ebx,28C9E05BE10 // 比较 ebx 和 源地址的关系(rbx寄存器对应 8字节,ebx 对应 rbx 的后 4个字节,其实等价于 cmp ebx,9E05BE10。虽然不太严谨,但因为实现的实际效果基本一样,我就这样比较了。直接 cmp rbx,28C9E05BE10 会报错,需要先赋值一个 rax ,再写 cmp rbx,rax !但这样很麻烦!)
jne exit // 上次比较关系中比较的结果如果是 不相等,则跳转到 exit 这个 label 中去;
nop // 什么也不执行,用来代表物品被修改的情况(此时往下执行到 mov [rbx],rax一句过程中 rbx并未被修改)
jmp exit // 跳转到 exit
完整代码如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBC075) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C9E05BE10 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov [rbx],rax 19 mov rbx,[rsp+00000090] 20 jmp returnhere 21 22 "Crashlands2.exe"+1EBC075: 23 jmp newmem 24 nop 6 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+1EBC075: 34 db 48 89 03 48 8B 9C 24 90 00 00 00 35 //mov [rbx],rax 36 //mov rbx,[rsp+00000090]
<13> 写好代码后,在菜单栏中选择 文件-分配到当前的CT表,并命名为 “Break Point Check Test”(双击脚本的描述部分),再把勾打上表示激活,如图所示源代码已经注入成功;

<14> 我们下一步就是去 代表物品被修改的代码段设置断点,上图我们是跳转到了 7FF786B60000 。所以我们在代码处,鼠标右击选择 “转到地址” ,输入你要跳转的地址(我的是 7FF786B60000,系统给你生成的是什么可以参考上图你的代码改成了 jmp 哪里),然后!确认!
<15> 到了我们跳转的地址后进行,在nop一句中设置断点。(很重要:提前留意一下你修改的时候,游戏本体一定是窗口化的,而不是全屏。一来对照着游戏看CE里的信息方便一些;二来如果游戏设置了全屏,游戏被断点卡住进程的时候,会出现切不出CE屏幕的情况,那真是太好笑了。除非用 Topmost软件强制把窗口置顶)
<16> 回到游戏中,进行采集光草(物品)的活动,查看此时断点的堆栈情况(图中右下红框部分即为此时的堆栈表)。

<17> 但是很明显啊,这返回地址太假了!根本不是我们想要的!所以呢,接下来我们要把进程卡在Crashlands2进程的内存部分才好看出是调用的哪些CALL。我们按几次 “步过” 按钮,让程序继续执行下去,并跳回我们之前的 Crashlands2.exe+ ... 函数部分,如下图,此时查看堆栈情况。

这是 针对于物品采集的函数CALL 调用此公用代码段函数跳转的情况。以上分别为一级返回,二级返回,三级返回,四级返回 ... ...
<18> 请保存好前面几级的跳转返回地址,并在 Memory Viewer (内存查看器)的菜单栏中选择 视图-断点列表,右击我们刚刚设置的断点,把断点删除掉。再点击运行。

<19> 程序运行之后,把 “Break Point Check Test”的勾划掉(再点一次方框)。
<20> 拿出刚刚保存的 一级返回,二级返回,三级返回,四级返回的 堆栈表,跳转到第一返回地址(我这里是 Crashlands2.exe+1EBBA63,在<17>下的图上)的地址当中去(跳转方法不会的再看一下<14>);
<21> 在一级返回地址的前一个CALL,就是调用这个CALL我们才会在那个公用代码段里修改我们 光草物品数量的 FValue 值,直接在 CALL 这一句设置断点。注:可以看到这里断点被监测即将执行了,但是我们并没有在游戏中做物品修改的操作,这说明这个CALL这一句仍然属于共用代码;

<22> 【不必操作】跳转到第二返回地址(我这里是 Crashlands2.exe+1EE276F),重复 <21> 操作。再跳转到第三返回地址(我这里是 Crashlands2.exe+1F03797),重复 <21> 操作。注:得到的结果都是一样的,需要继续向前找;
<23> 跳转到第四返回地址(我这里是 Crashlands2.exe+108956E)重复 <21> 操作。诶~这次断点没有被监测到即将执行,回到游戏当中随便采集一个光草(物品),断点激活!这下没问题了,只有在执行这个CALL的时候,是采集物品数量修改函数调用的。
<24> 我们在第三返回地址前面这个CALL这一句这里进行基础汇编注入(自动汇编+CT表框架+代码注入,不会的回看<9>、<10>);
在声明部分定义一个8字节的变量 tag_of_ItemA,使用 alloc(tag_of_ItemA,8)声明,后面的 [DISABLED]部分写上释放代码 dealloc(tag_of_ItemA)
在声明部分将tag_of_ItemA注册为全局变量,使得其他的Script也能够使用该变量,[ENABLE]部分写 registersymbol(tag_of_ItemA) ,[DISABLED]部分写 unregistersymbol(tag_of_ItemA)
代码部分在 CALL 的前面部分 把 tag_of_ItemA 改为 1,CALL 之后 把 tag_of_ItemA 改为 0 (默认一开始 tag_of_ItemA 就是 0)。这样的话,如果其他脚本在执行到 tag_of_ItemA == 1 的情况时就知道哦,我在改 FValue 的值。
[不重要] - 最一开始的 alloc(newmem,100) 中 2048 改为 100 是不想让它分配那么大的空间(本身没用多少地方,属于优化项)。
所以把代码调整为如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1089569) 4 alloc(tag_of_ItemA,8) 5 registersymbol(tag_of_ItemA) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // Mark The Tag 15 mov [tag_of_ItemA],00000001 16 call Crashlands2.exe+1F036D0 17 mov [tag_of_ItemA],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+1089569: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_of_ItemA) 32 unregistersymbol(tag_of_ItemA) 33 "Crashlands2.exe"+1089569: 34 db E8 62 A1 E7 00 35 //call Crashlands2.exe+1F036D0
之后,分配到CT表中,并命名为 “Act Ⅰ:在 "Crashlands2.exe"+1089569 处标记 FValue 的采集函数”(命名步骤见<13>),此后在本博文的 “无限物品” 部分,它将被我简略描述为 “Act 1”。
<25> 将 “Act 1”激活,这样我们得到了 “FValue 数据 是否在采集函数的CALL中执行 ” 这样的一个 bool 值,接下来我们要做的是利用这个 bool 值来实现 “采集时将 FValue 值改为 49999”!
<26> 然后我们从跳转回 书签0 (还记得书签0是哪个地址吗?它是我们找到的修改 FValue 的代码段地址),我们从那个地址的上一句开始进行代码汇编 (自动汇编+CT表框架+代码注入,不会的回看<9>、<10>,后面不再重复)。
Q:为什么要从那个地址的上一句进行汇编呢?
A:(下图中 +...075是书签0,+...072是我们选择的汇编起始段)这是一个习惯问题。我们很容易看到如果对+...075汇编,那么它会占用 mov [rbx],rax 和 mov rbx,[rsp+00000090] 两句的位置,后面开发其它功能还要用到此公用代码的时候,代码的注入位置就很难去安排,但如果往前走一句,后面 mov rbx,[rsp+00000090] 我就可以在实现其他功能的时候注入了,从而使这两个功能的生效互相不会被干扰。而再往前其实我们的代码路线是不清楚的,因为我们不确定是执行完了 Crashlands2.exe+1EBC6D 这个 CALL 之后执行的 +...072 还是从 +...068 直接跳转过来的。综上,+...072为最佳注入地址。

<27> 对代码进行一些预处理:mov [rbx],rax 一句移动到 exit 的开头, newmem 的分配空间调整为 100,此后我们开始加入一些代码;
<28> 代码中间部分的处理逻辑为 tag_of_ItemA 是 0,我就跳过不执行;如果 tag_of_ItemA 是 1,我就把 49999 的值 (Double:双浮点)赋值给 rax;
push rdx // rdx 入栈
cmp [tag_of_ItemA],00000001 // 判定 CALL 的来源
jne exit // 不属于 FValue 的采集 CALL ,直接跳转正常执行
mov edx,#49999 // 将 十进制数 49999 赋值给 edx ,也可以写 mov edx,C34F 。C34F 是 16进制数 ,我们手写时记作 0xC34F。“#”用来做进制转换
cvtsi2sd xmm0,edx // 将 edx 四字节数,转化为 Double(8字节浮点数),类似于 C语言中的 xmm0 = (double)edx
movsd [tmp_unItem],xmm0 // 将 xmm0 的 Double 数值的 8 字节值赋值给 tmp_unItem所表示地址 (因为 movsd rax,xmm0 的格式是不被允许的,只能是 movsd xmm0,[ ]或者 movsd [ ],xmm0 这样的格式;需要借助 tmp_unItem 变量完成赋值,需要用 alloc函数声明)
mov rax,[tmp_unItem] // tmp_unItem 赋值给 rax
jmp exit // 代码执行完毕跳回公共部分
pop rdx // 在 exit 中,rdx 出栈以保证堆栈平衡 (使用寄存器如果之前入栈了一些寄存器,代码执行完一定要保证所有代码执行路线的情况它们都出栈完毕)
<29> 这样看上去貌似,我们已经实现了对于 FValue 的无限修改已经完成了。但是基于我第一代的修改经验,这种代码会出现游戏实际中的逻辑问题,这个涉及到 【物品】 的定义,我们认为的 【物品】是指的材料、工作台这些,其实它还包括“武器”、“饰品”、“道具”、“图纸项目”、“宠物蛋” 等等。其中,“武器” 和 “饰品” 等有一个特性就是数量就是1,我们不能修改它的数值为49999。另外,还有一种情况就是物品数量从 1 到 0 的情况,这种情况对应的是第一版的 “ 拆解 ”功能。拆解时武器数量从 1 到 0 ,如果不多加判定会导致武器拆解完后数量绑定到 49999,从而拆解失败。但截至到目前为止我还没有看到 “拆解” 功能,但逻辑上还是提前做了准备(结果只是物品数量被改成0时,不做修改而已)。
此部分代码应放到 CALL 来源判定的后面。它先做 rax != 0 以及 rax != 1(Double)的判定,如果等于其中任意一个就跳转 exit 不做修改
mov [tmp_unItem],rax // rax的值 给到 tmp_unItem 地址中的值
movsd xmm0,[tmp_unItem] // tmp_unItem 地址中的值 给到 xmm0
cvttsd2si edx,xmm0 // edx = (int)xmm0 将 xmm0 中的 8字节数据按照 Double 类型转化为 4字节的 整型数
cmp edx,01 // 比较 edx 和 1
jna exit // if( edx <= 1) 跳转 exit jna,不大于,<=
此处的完全体代码如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBC072) 4 alloc(tmp_unItem,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov rax,[rsi] 14 15 // --------------------------------- [Insert Code] 16 // - edx --> var 17 push rdx 18 19 // --- When tag is True 20 cmp [tag_of_ItemA],00000001 21 jne exit 22 23 // --- The Item Now is Zero Or One ( value <= 1 ) 24 mov [tmp_unItem],rax 25 movsd xmm0,[tmp_unItem] 26 cvttsd2si edx,xmm0 27 cmp edx,01 28 jna exit 29 30 // --- change Item to 49999 31 mov edx,#49999 32 cvtsi2sd xmm0,edx 33 movsd [tmp_unItem],xmm0 34 mov rax,[tmp_unItem] 35 jmp exit 36 // --------------------------------- 37 38 exit: 39 pop rdx 40 mov [rbx],rax 41 jmp returnhere 42 43 "Crashlands2.exe"+1EBC072: 44 jmp newmem 45 nop 46 47 returnhere: 48 49 50 [DISABLE] 51 //code from here till the end of the code will be used to disable the cheat 52 dealloc(newmem) 53 dealloc(tmp_unItem) 54 "Crashlands2.exe"+1EBC072: 55 db 48 8B 06 48 89 03 56 //mov rax,[rsi] 57 //mov [rbx],rax
<30> 将此部分代码分配到 CT 表后,命名为 “Act Ⅴ:When tag is true & the item now is not 1 or 0, just make item to 49999”,并放到“Act 1”的子项结点下,并给 “Act 1” 设置上群组的子项同启用、同禁用,如下图(这样不会出现我把主项里的全局变量注销了,后面子项还在用这个变量进而引发报错的问题),此后这个子项称为 “Act 5”。

<31> 在 “Act 1”激活的状态下,激活 “Act 5”。做采集动作,然后看到的效果是只有 FValue 被修改了,说明需要再单独分析 MValue 和 LValue 的情况。

<32> 先把“Act 1” 和 “Act 5” 的 Script 关闭掉(去掉勾),暂时不需要激活它们了,还有把 FValue 改回 和 MValue、LValue 一样的值。这样我们算是对 FValue 的采集函数做完了分析,之后其实是一个重复的过程。
<33> 【不用操作】我们对 MValue 鼠标右击,选择 “找出是什么改写了这个地址” ,发现还是 Crashlands2.exe+1EBC075 这一句,和修改 FValue 是一样的,不妨大胆一点,对,LValue 也是这样的。
<34> 我们直接找到我们的“Break Point Check Test” 脚本!把里面的原本 FValue的地址 28C9E05BE10 改为 MValue 28C9E05BE40(cmp ebx,28C9E05BE10 → cmp ebx,28C9E05BE40),并开启此脚本。
<35> 继续在 nop 一句设置断点,回到游戏采集光草,回来点击 “步过” 按钮,直到进程跳回 Crashlands2.exe+...,观察此时的堆栈情况,如下图。

<36> 在<21>、<22>步中,已经帮助我们排除了图上 Crashlands2.exe+1EE276F 和 我这里是 Crashlands2.exe+1F03797 两个返回地址同属共用代码段了。所以我们直接在三级返回地址 Crahlands2.exe+10897E8 前的CALL处设断点,发现还是共用代码段!只有在采集光草时,这段代码被执行了!没问题!这就是我们要加标记的地方了!取消断点!仿照 “Act 1” 给这句汇编一下,加上标记,只不过标记不用新声明了,就用之前的 tag_of_ItemA 就行。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+10897E3) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1F036D0 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+10897E3: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+10897E3: 30 db E8 E8 9E E7 00 31 //call Crashlands2.exe+1F036D0
<37> 先把 “Break Point Check” 脚本关闭,再激活 “Act 1”,之后把代码保存到 CT表,并命名为 “Act Ⅱ:在 "Crashlands2.exe"+10897E3 处标记 MValue 的采集函数” (简称 “Act 2”),并把这个脚本放到 “Act 1”的子项群组中!

<38> 同理,我们可以用同样的方法,对 LValue 的采集修改函数 CALL 进行标记!(详细过程省略)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108BD2E) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1EE2F80 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+108BD2E: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+108BD2E: 30 db E8 4D 72 E5 00 31 //call Crashlands2.exe+1EE2F80
<39> 这样采集时完成 数据绑定 49999 的功能就完成了!接下来就要验证其他的操作是否也会修改光草物品的值!继续推进任务,在工作台制作光叶斧,发现 LValue 值减少了 20,FValue 和 MValue 未改变!可以得到的结论是 “在工作台制作上,需要将 LValue 的修改做进一步的补充(打补丁)”!

<40> 所以重复之前的步骤,将 “Break Point Check Test” 脚本的比较项改为 LValue 观测返回地址,并重新打上标记!结果如下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108E056) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // Mark The Tag 13 mov [tag_of_ItemA],00000001 14 call Crashlands2.exe+1EE2F80 15 mov [tag_of_ItemA],00000000 16 17 exit: 18 jmp returnhere 19 20 "Crashlands2.exe"+108E056: 21 jmp newmem 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+108E056: 30 db E8 25 4F E5 00 31 //call Crashlands2.exe+1EE2F80
<41> 在之后对剩下的游戏流程操作做验证,发现这些代码足够覆盖到所有物品修改的场景,OK,此功能完成啦!
<42> 【可有可无】之后就创建一个表头名字叫做 “Fun A:Unlimited Items —— 【无限物品】”,把 “Act 1” 移动到这个表头的子项上。给表头设置上 同启用、同禁用 和 未启用时隐藏子项。给它们统一设置一个你喜欢的颜色用于代码区分!结果如下:

【功能小结】:其实这第一个功能看似很繁琐、劝退,但实际上核心就两点。第一点是把参数比较的代码注入共用代码段来区别并找到特殊限制条件下的CALL(找上级CALL的方法),第二点是通过CALL的限定把共用代码改造成为特定服务的代码(上级多层CALL嵌套共用代码段或调共用代码段参数构成不明显的情况)。
FUN B:--------------------------------------【无限生命】
无限生命在于解决玩家不断被怪物伤害或状态伤害削减生命的痛点。其主要方向是要找到玩家生命值的地址,然后锁定生命值不减血。而锁定生命值一可以通过找到玩家血量值的静态地址映射关系,也可以直接去找生命值的修改地址,当玩家扣血时,我们把代码扣血的逻辑删除!
① 数值类型设置为双浮点,搜索生命数值!
② 之后通过更改装备,完成血量上限和生命值的变化,再次搜索得到如下结果即为玩家血量上限和玩家血量的地址。

③ 可以通过修改其中一个数值,另外一个不变的方式,搞清楚到底哪个是上限(其实大部分游戏都是上限在前)。
④ 将血量数值绑定到 999999,回游戏中查看情况,发现确实玩家打不死了(除非超过上限)!
其实到这里,这对于大多数玩家已经够用了。只需要每次进入游戏后,搜一下数值,把数值改到很大,然后锁定就好!但这样会有一个问题哈,那就是地址的变动性!每次进入新存档或者在游戏中传送时,如果还锁定着之前的地址,就会导致游戏崩溃掉!这时候我们首选找静态地址映射关系的方法!如果找到一个稳定指向血量值的地址,就可以解决刚刚的问题!
<1>【不用做】对血量值的地址鼠标右击,选择 “对这个地址进行指针扫描”。

<2> 【不用做】选择最大级别为 6,高级选项的第一项的勾取消掉(地址必须是32位的)。

<3>【不用做】扫描结果出来之后退回主菜单重进(或直接重启游戏),重新按照 Double 类型的数值,对结果进行筛选。


<4> 【不用做】好吧,这样操作之后发现,根本没有固定的静态地址映射关系!看来这种方法是行不通了,我们还是看看血量修改的代码吧!
<5> 对 HP 值鼠标右击,选择 “找出是什么访问了这个地址”。

<6> 得到结果如下,其中我在游戏中进行了 “回血”、“改装备”的操作 。通过此处代码逻辑,可以知道第 2 项是修改 HP 的,第 1 项才是获取 HP 值的逻辑。

<7> 我们直接选择第一项,随时高频访问 HP 值的代码,点击 “显示反汇编程序”!并对此处代码设置 书签0。并采用特值比较代码注入的方法,找到是修改 HP 值的代码段。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBA7EA) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C8C81D2C0 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov rax,[rbx] 19 mov [rdi],rax 20 jmp returnhere 21 22 "Crashlands2.exe"+1EBA7EA: 23 jmp newmem 24 nop 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+1EBA7EA: 34 db 48 8B 03 48 89 07 35 //mov rax,[rbx] 36 //mov [rdi],rax
<8> 实际找到的是三级返回地址 Crashlands2.exe+131A4B4,在它之前的 CALL 一句上进行汇编,标记上这个来源。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4AF) 4 alloc(tag_Hp_perm,8) 5 registersymbol(tag_Hp_perm) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // --- 记录调用 CALL 的 Tag 15 mov [tag_Hp_perm],00000001 16 call Crashlands2.exe+1EE2A80 17 mov [tag_Hp_perm],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+131A4AF: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_Hp_perm) 32 unregistersymbol(tag_Hp_perm) 33 "Crashlands2.exe"+131A4AF: 34 db E8 CC 85 BC 00 35 //call Crashlands2.exe+1EE2A80
<9> 之后回到书签0(高频访问 数值 的源代码),重新在 "Crashlands2.exe"+1EBA7EA 处,进行汇编,具体代码如下:
cmp [tag_Hp_perm],00000001 // 比较 标记值
jne exit // 不相等,跳转到 exit
push rax // rax 入栈
mov eax,#99999999 // eax = 99,999,999
cvtsi2sd xmm0,eax // xmm0 = (double) eax
movsd [rbx],xmm0 // *(rbx) = xmm0
pop rax // rax 出栈
jmp exit // 跳转到 exit
<10> 汇编完后,分配到 CT 表中,取名 “Act Ⅱ:If Tag Access, Change HP To 99,999,999”,放到 “Act 1”的子项,并给 “Act 1” 分配 同激活、同禁用。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+1EBA7EA) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- When tag is True 13 cmp [tag_Hp_perm],00000001 14 jne exit 15 16 // --- change HP to 99,999,999 17 push rax 18 mov eax,#99999999 19 cvtsi2sd xmm0,eax 20 movsd [rbx],xmm0 21 pop rax 22 jmp exit 23 24 exit: 25 mov rax,[rbx] 26 mov [rdi],rax 27 jmp returnhere 28 29 "Crashlands2.exe"+1EBA7EA: 30 jmp newmem 31 nop 32 33 returnhere: 34 35 36 [DISABLE] 37 //code from here till the end of the code will be used to disable the cheat 38 dealloc(newmem) 39 "Crashlands2.exe"+1EBA7EA: 40 db 48 8B 03 48 89 07 41 //mov rax,[rbx] 42 //mov [rdi],rax
<11> 我们回到游戏中发现,诶血量值启用后。玩家已经不怕伤害了,锁死在了 10^9 - 1 ,这样我们也完成了无限生命的功能开发。最后我们设置一下样式,让CT表更整洁一些。

<12> 实际上游戏中左侧生命值展示栏也显示了我们的血量修改情况!

FUN C:--------------------------------------【技能无冷却】
技能冷却数值很容易能够找到,毕竟在游戏中玩家使用技能后,其冷却值会直接显示在对应的技能框上。而且这种技能冷却值在游戏进程中是处于时刻变化的,所以我们需要有一定的游戏暂停手段。除此之外,基于浮点值的筛选条件,我们每次筛选时输入的值应该间隔应该不低于2,所以我们还需要尽量挑选冷却时间比较长的技能作为我们的参考项。
<1> 我们以游戏中的 “隐形花” 为例,“隐形花” 的技能冷却值为 14 s 左右!在游戏中使用此技能后,看准游戏冷却值显示的值,快速按下 Esc 键(或M键),进入暂停状态。(图中各个菜单选项不全是暂停的,比如 “装备” 菜单只是慢速)

<2> 一般筛选两次就可以搜索到了,如下图:

<3> 如果把它修改成 0,然后锁定数值,就可以得到 “隐形花”的技能无冷却!
<4> 但是我们现在要的是所有技能的冷却值都不要有,所以还是需要注入一些小代码!
<5> 我们对搜索到的 技能冷却值 SkillCold 28C8C817610 选中,鼠标右键,选择 “找出是什么改写了这个地址”。

<6> 查找到了修改代码地址后,选择 “显示反汇编程序”!

<7> 可以看到是和无限物品修改地址类似的代码,所以一样的思路使用 Break Point Check Test 监测它的上级返回地址。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"Crashlands2.exe"+E73F2) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp ebx,28C8C817610 13 jne exit 14 nop 15 jmp exit 16 17 exit: 18 mov [rbx],rax 19 mov rbx,[rsp+30] 20 jmp returnhere 21 22 "Crashlands2.exe"+E73F2: 23 jmp newmem 24 nop 3 25 returnhere: 26 27 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+E73F2: 34 db 48 89 03 48 8B 5C 24 30 35 //mov [rbx],rax 36 //mov rbx,[rsp+30]
<8> 较为巧合地是,我们直接就可以使用一级返回地址来完成修改,而且在一级返回地址调用 CALL 到我们的修改地址之前,传入参数 rcx (或 r15 )恰好是我们的被修改的技能冷却地址。哦↑嗷↓嗷~现在我们知道 CALL Crashlands2.exe+E7360 之前的 rcx传入值就是被修改的值!!!

<9> 所以我们就在 CALL 这一句进行汇编:先记录上我们的 rcx 地址值,在CALL完之后,根据保存的技能冷却地址,把冷却修改为 0!
mov [skill_cold],rcx // 保存 rcx 值 , *(skill_cold) = rcx
call Crashlands2.exe+E7360 // 源代码 CALL
push rcx // rcx 入栈
push rax // rax 入栈
mov rax,00000000 // rax = 0
xor rax,rax // rax = 0 ,自身异或操作等同于自身归零
mov rcx,[skill_cold] // rcx = *(skill_cold)
mov [rcx],rax // *(rcx) = rax
pop rax // rax 出栈
pop rcx // rcx 出栈(rax 和 rcx 是两个不同的寄存器,它俩之间的顺序没有那种先入后出的栈规则)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+15F8A3) 4 alloc(skill_cold,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [skill_cold],rcx 14 call Crashlands2.exe+E7360 15 push rcx 16 push rax 17 mov rax,00000000 18 xor rax,rax 19 mov rcx,[skill_cold] 20 mov [rcx],rax 21 pop rax 22 pop rcx 23 24 exit: 25 jmp returnhere 26 27 "Crashlands2.exe"+15F8A3: 28 jmp newmem 29 30 returnhere: 31 32 33 [DISABLE] 34 //code from here till the end of the code will be used to disable the cheat 35 dealloc(newmem) 36 dealloc(skill_cold) 37 "Crashlands2.exe"+15F8A3: 38 db E8 B8 7A F8 FF 39 //call Crashlands2.exe+E7360
<10> 再使用外表头和特定颜色改造一下,这样直接就完成啦!!!这个功能也是做起来非常简单的一个功能!

FUN D:--------------------------------------【无限滚动】
这个功能其实是有两种思路的,因为滚动这个技能比较特殊——它不仅有滚动技能恢复的冷却值,还另外存有一个目前可释放的滚动次数。那么两种思路也很明显了,要么把冷却缩短到 0,要么锁定了可释放的滚动次数。那我们到底要选哪一个呢?聪明的人都发现了:“诶呀!这个冷却值好像是个很抽象的数据啊,我们知道它是双浮点数,但是滚动的冷却本身恢复的就比较快。也就是说这个冷却值呢,不太好找!那另外一个可释放滚动次数呢?它不仅直接可以看到,甚至还是个整数——特别好搜!!!”这明眼人都知道要选第二种方法呀!
<1> 使用整数的浮点数搜索方法(整数+.00的值),搜索到 可释放滚动次数的地址,保存下来并命名为 “Roll Times”。

<2> 对 “Roll Times” 鼠标右击,选择 “找出是什么修改了这个地址”。
<3> 然后找到的地址是和修改技能冷却值一样的代码、一样的地址。那么,还是使用 “Break Point Check Test” 注入代码,监测 28C8C81B180 的数据的一级返回地址。
<4> 找到的 一级返回地址 是 Crashlands2.exe+148C93,那么我们在它之前的 CALL 一句进行汇编。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+148C8E) 4 alloc(tmp_unRoll,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [tmp_unRoll],rcx 14 call Crashlands2.exe+E7360 15 16 push rcx 17 // --- turn roll_value to 4 18 mov ecx,4 19 cvtsi2sd xmm0,ecx 20 mov rcx,[tmp_unRoll] 21 movsd [rcx],xmm0 22 pop rcx 23 24 exit: 25 jmp returnhere 26 27 "Crashlands2.exe"+148C8E: 28 jmp newmem 29 30 returnhere: 31 32 33 [DISABLE] 34 //code from here till the end of the code will be used to disable the cheat 35 dealloc(newmem) 36 dealloc(tmp_unRoll) 37 "Crashlands2.exe"+148C8E: 38 db E8 CD E6 F9 FF 39 //call Crashlands2.exe+E7360
<5> 再使用外表头和特定颜色改造一下,这样直接就完成啦!!!这个功能也是做起来非常简单的一个功能!

FUN E:--------------------------------------【快速感悟心得】
在制作这个修改之前,我们肯定需要先做好心得修改的特殊存档准备——首先要解锁了心得、其次每个心得的感悟时间不能太短(一开始格拉尔的感悟很快,这时候不太时候用于搜索数据,最好把好感度降到最低)、最后要准备好两个可感悟内容(一个感悟“修改”、一个感悟“暂停”)!
<1> 做好上述的存档准备,例如把任务推进到如下图这样,并做好存档备份(一旦修改过程中出现游戏崩溃,至少我们留存了存档的备份、快照)。

<2> 我们把 “挖泥巴” 当作主目标,“上桌” 作为暂停工具,开始 “挖泥巴” 的心得研究!数值类型仍然为双浮点类型,扫描类型为 “未知的初始值”。

<3> 此后随着 “挖泥巴” 的研究进度的增加,我们把 “上桌”的研究开启,这样 “挖泥巴” 的研究进度就停止了。我们搜素 “增加的数值”,搜一遍。
<4> 之后按照 “未变动的数值” 再搜索一遍,继续按照研究增加我就搜索“增加的数值”、研究停止我就搜索“未变动的数值”的模式对数据进行筛选;
<5> 直到我们就剩下两个双浮点的数据,其中只有第一个很明显是研究进度的数值(第二个也算是因为第一个数值变动才被搜索到的)。

<6> 将此数值加入到地址栏中,并命名为 “Research Value”,之后鼠标右击并选择 “找出是什么改写了这个地址”。
<7> 发现改动此地址的代码和无限物品中物品改动的代码是同一块儿代码,也就是 Crashlands2.exe+1EBC072,这也就表示后面我们注入的时候不能和无限物品的代码注入同一个地方!!!
<8> 不过我们还是先编写 “Break Point Check Test” 代码,查找可以用于标记研究进度函数的返回地址前的CALL。
<9> 最后,我们在三级返回地址前找到了可以标记的 CALL。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+2835D2) 4 alloc(tag_perception,8) 5 registersymbol(tag_perception) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_perception],00000001 15 call Crashlands2.exe+1EE2F80 16 mov [tag_perception],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+2835D2: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_perception) 31 unregistersymbol(tag_perception) 32 "Crashlands2.exe"+2835D2: 33 db E8 A9 F9 C5 01 34 //call Crashlands2.exe+1EE2F80
<10> 然后,在 "Crashlands2.exe"+1EBC078 处进行汇编,前面的 "Crashlands2.exe"+1EBC072 和 "Crashlands2.exe"+1EBC075 两句已经被视为已经注入!
cmp [tag_perception],00000001 // 监测是否来源于研究进展函数
jne exit // 不是的话,就跳转不修改
push rdx // rdx 入栈
mov edx,#69999 // edx = 69999 (4字节整型,十进制)
cvtsi2sd xmm0,edx // xmm0 = (Double) edx
movsd [tmp_pe],xmm0 // *(tmp_pe) = xmm0
mov rax,[tmp_pe] // rax = *(tmp_pe)
pop rdx // rdx 出栈
mov [rbx],rax // --- 因为要修改,把源码前面一句补充上
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBC078) 4 alloc(tmp_pe,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 // - 监测 Tag 标记 14 cmp [tag_perception],00000001 15 jne exit 16 17 // --- 修改部分 18 push rdx 19 mov edx,#69999 20 cvtsi2sd xmm0,edx 21 movsd [tmp_pe],xmm0 22 mov rax,[tmp_pe] 23 pop rdx 24 25 // --- 因为要修改,把源码前面一句补充上 26 mov [rbx],rax 27 jmp exit 28 29 exit: 30 mov rbx,[rsp+00000090] 31 jmp returnhere 32 33 "Crashlands2.exe"+1EBC078: 34 jmp newmem 35 nop 3 36 37 returnhere: 38 39 40 [DISABLE] 41 //code from here till the end of the code will be used to disable the cheat 42 dealloc(newmem) 43 dealloc(tmp_pe) 44 "Crashlands2.exe"+1EBC078: 45 db 48 8B 9C 24 90 00 00 00 46 //mov rbx,[rsp+00000090]
<11> 将 “Act 2” 放到 “Act 1”的子项里面,然后给 “Act 1”设置上子项同启用、同禁用;
<12> 再使用外表头和特定颜色改造一下,这样直接就完成啦!!!

FUN F:--------------------------------------【Buff时间锁定】
看上去很难做,实际上一点儿也不难!我们需要事先准备好 “技能无冷却” 功能 并 装备好 “隐身花” 技能!
<1> 开启 “技能无冷却” 功能,然后激活一次,观察左上角 隐身Buff 的持续时间。

<2> 对上述值进行精确搜索,注意不要让 Buff 消失(如果快结束了就再激活一次技能),可以按 Esc 或 M 键暂停 Buff 时间的变动,根据这样的规则筛选 Buff 时间数据。

<3> 我们找到了一个和 Buff 剩余的持续时间值相等的地址,但是通过锁定它无法改变 Buff 时间持续减少的情况。这种情况很明显就是被 “加密” 数据的情况,也就是说当前我们搜索到的这个地址是个 “看板”,它不能用就只能看!但我们要知道,这个游戏它只有双浮点类型的数据,我们可以通过未知初始值加上变动与不变动的筛选方式慢慢筛选。这里我已经通过这种方式找到了加密方式啦!哈哈!说加密,其实也算不上,它并不是和一代一样的 “持续时间”的模式,而是一种“已经持续时间”的模式。之前一代里我命名的功能叫做 “Buff时间不减”,二代这里叫做 “Buff时间锁定”,这也是为了提醒学习的朋友,这里变动了。
<4> 明白机理之后,我们可以利用 Buff Time 来搜索 Buff Continuing Time,计算公式为 Buff Time + Buff Continuing Time = Buff Max Time。
<5> 开始搜索!当 Buff Time = 5.55 ,搜索 3;当 Buff Time = 7.530725,就搜索 0;
<6> 最终我们找到了 隐身Buff 的已持续时间,我们把它记录到 CT 表内,命名为 “Buff Continuing Time”。

<7> 对 “Buff Continuing Time” 鼠标右击,选择 “找出是什么访问了这个地址”,代码是 Crashlands2.exe+1EBA7EA(这一看和Crashlands2.exe+1EBC075很近啊!) 。
<8> 编写 “Break Point Check Test” ,查找返回地址!

<9> 选择三级返回地址 Crashlands2.exe+490F78 ,找前面的 CALL 进行汇编标记!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+490F76) 4 alloc(tag_buff_time,8) 5 registersymbol(tag_buff_time) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_buff_time],00000001 15 call Crashlands2.exe+1EE2A80 16 mov [tag_buff_time],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+490F76: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_buff_time) 31 unregistersymbol(tag_buff_time) 32 "Crashlands2.exe"+490F76: 33 db E8 05 1B A5 01 34 //call Crashlands2.exe+1EE2A80
<10> 此后,查看可汇编地址。“无限生命”功能占用了我们的 mov rax,[rbx] 和 mov [rdi],rax 两句,那我们就从后面的 mov al,01这句开始汇编!

我觉得代码很简单,所以就没有加详细解释!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EBA7F0) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- Exam the Tag 13 cmp [tag_buff_time],00000001 14 jne exit 15 16 // --- Change To 0 17 xor rax,rax 18 mov [rbx],rax 19 mov [rdi],rax 20 21 jmp exit 22 23 24 exit: 25 mov al,01 26 add rsp,28 27 jmp returnhere 28 29 "Crashlands2.exe"+1EBA7F0: 30 jmp newmem 31 nop 32 33 returnhere: 34 35 36 [DISABLE] 37 //code from here till the end of the code will be used to disable the cheat 38 dealloc(newmem) 39 "Crashlands2.exe"+1EBA7F0: 40 db B0 01 48 83 C4 28 41 //mov al,01 42 //add rsp,28
<11> 将 “Act 2” 设置为 “Act 1” 子项,开启子项 同启用、同禁用,并使用外表头和特定颜色改造一下!!!Complete!!!

FUN G:--------------------------------------【快速孵蛋】
<1> 做这个功能前,要把任务推进到 “鼻涕虫” 即将可以孵化的状态,如下图,只要放置上 大肚灯 就可以开始孵化了(把大肚灯收回,孵化就会停止)。

<2> 按照“未知初始值”并慢慢控制其数值增加、不变,对孵蛋进度值的数据进行筛选。

<3> 对筛选结果命名为 “Egg Process”,观察这个数据,它其实是孵蛋进度的百分比。当我们锁定 “Egg Process”的时候,发现孵蛋进程果然被暂停了!
<4> 对 “Egg Process” 鼠标右击,选择 “找出是什么修改了这个地址”。

<5> 使用 “Break Point Check Test”,监测返回地址,如此一级返回地址前的 CALL 是经典的 CALL Crashlands2.exe+E7360 一句(在做 “技能无冷却” 功能的第<8>步时,我们知道只需要在一级返回地址的CALL前记录rcx就能得到进度的地址)!

<6> 对一级返回地址前的 CALL 一句进行汇编,思路等同于 “技能无冷却”。(修改的值要变成绑定为 1.00 ,也就是 100%)
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1283BCB) 4 alloc(tmp_egg_time,8) 5 label(returnhere) 6 label(originalcode) 7 label(exit) 8 9 newmem: //this is allocated memory, you have read,write,execute access 10 //place your code here 11 12 originalcode: 13 mov [tmp_egg_time],rcx 14 call Crashlands2.exe+E7360 15 push rcx 16 // --- turn tmp_egg_time to 1 17 mov ecx,1 18 cvtsi2sd xmm0,ecx 19 mov rcx,[tmp_egg_time] 20 movsd [rcx],xmm0 21 pop rcx 22 23 exit: 24 jmp returnhere 25 26 "Crashlands2.exe"+1283BCB: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 dealloc(tmp_egg_time) 36 "Crashlands2.exe"+1283BCB: 37 db E8 90 37 E6 FE 38 //call Crashlands2.exe+E7360
<7> 好了,使用外表头和特定颜色改造一下!!!

FUN H:--------------------------------------【十倍采集资源】
<1> 十倍采集资源和无限物品从功能角度上来说就是冲突的——毕竟不能保证捡到物品后加十的同时绑定49999!
<2> 所以我们可以使用之前 “无限物品” 功能实现过程中注入的代码!但首先还是让我们把 “无限物品” 功能抱持关闭掉的状态,并参考物品的搜索方法找到 FValue、MValue、LValue;

<3> 这里搜到三个数值,但实际上我们也不知道这三个数值都对应我们之前 “无限物品” 里的那三个值,所以我们找到 “无限物品” 中标记采集函数的三个 CALL 的位置,分别设置断点,来查看在CALL执行完后哪个值被修改了就是对应哪个 Value;

<4> 回到游戏中采集物品(我还是用的 光草),观察数据的变化——发现先变化的是 LValue!之后暂停的地方是标记 MValue 采集函数的地方(也就是说下一个变化的是 MValue值)。

<5> 如下图,标记上变化数值为 MValue。当然,还剩下最后一个就是 FValue了!

<6> 由此我们还知道了这三个值的修改顺序:LValue→MValue→FValue,但是对于 MValue 和 FValue 来说这个位置并不全是它们的采集函数的代码!忘了吗?我们刚刚做完绑定采集函数时,使用工作台消耗的时候,这个位置把 MValue 和 FValue 全修改成 49999 了!所以还需要考虑这两个值在工作台消耗和采集时分别被修改的情况!
<7> 【无需操作】我们取消掉所有断点,只保留 MValue 采集函数的 CALL 用于做对比,堆栈对比结果如下图所示:

<8> 【无需操作】我们在上图 Crashlands2.exe+108B359 处,标记一层 Tag 这样再从这个 CALL 调用的位置就是采集函数的了。
<9> 貌似这样不太行啊,我们想要的不是单独 MValue 一个值的采集函数,而是整体采集函数的标记,所以进一步继续找 FValue 的采集函数来看 堆栈对比。

<10> 可以用的是上图中绿色部分。啊?问我为什么给上面几个地址打叉了?很明显 Crahlands2.exe+1ED3988 这不是执行了很多次吗?也就是说这肯定是一段共用代码啊(本身采集函数都和自己共用这一部分了)!
<11> 我们在 Crashlands2.exe+109ED26处设置断点,回到游戏工作台消耗发现断点被激活了...呃~情况很尴尬,我们继续在 Crashlands2.exe+B18351 处设置断点!重复工作台消耗,结果很完美的没有被执行!谢天谢地啊!
<12> 就在 这个 CALL 这里汇编设置标记,然后我们来整理我们的思路:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+B18351) 4 alloc(tag_ObtainFun,8) 5 registersymbol(tag_ObtainFun) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tag_ObtainFun],00000001 15 call Crashlands2.exe+109DAF0 16 mov [tag_ObtainFun],00000000 17 18 exit: 19 jmp returnhere 20 21 "Crashlands2.exe"+B18351: 22 jmp newmem 23 24 returnhere: 25 26 27 [DISABLE] 28 //code from here till the end of the code will be used to disable the cheat 29 dealloc(newmem) 30 dealloc(tag_ObtainFun) 31 unregistersymbol(tag_ObtainFun) 32 "Crashlands2.exe"+B18351: 33 db E8 9A 57 58 00 34 //call Crashlands2.exe+109DAF0
<13> 根据下图中的线性代码执行表,我们分析出了修改方法,那就是采集函数对应各自的标记,使物品额外增加数值9!

<14> 为了保证 FValue、MValue、LValue 一致性,我们统一在最后修改 FValue值的时候,同时把十倍物资的 FValue 同步给 MValue 和 LValue,这也需要我们在前两步记录上 LValue 和 MValue 的地址!
<15> 注意到我们在 "Crashlands2.exe+1EBC072"处要对于不同的采集函数标记做不同的操作,实际上需要在 "Crashlands2.exe"+108BD21、"Crashlands2.exe"+1089569、"Crashlands2.exe"+10897E3 三处设立不同的 Tag 用于区分这三处来源!那我们实际上分析 "Crashlands2.exe"+B15831 处设立的 Tag ,可以完全支持对这三处的修改。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+108BD2E) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // 查验标记是否成立 13 cmp [tag_ObtainFun],00000001 14 jne exit 15 16 // --- 记录调用 CALL 的 Tag - LValue -> 2 17 mov [tag_ObtainFun],00000002 18 call Crashlands2.exe+1EE2F80 19 mov [tag_ObtainFun],00000001 20 jmp returnhere 21 22 exit: 23 call Crashlands2.exe+1EE2F80 24 jmp returnhere 25 26 "Crashlands2.exe"+108BD2E: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 "Crashlands2.exe"+108BD2E: 36 db E8 4D 72 E5 00 37 //call Crashlands2.exe+1EE2F80
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1089569) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // 查验标记是否成立 13 cmp [tag_ObtainFun],00000001 14 jne exit 15 16 // --- 记录调用 CALL 的 Tag - MValue -> 3 17 mov [tag_ObtainFun],00000003 18 call Crashlands2.exe+1F036D0 19 mov [tag_ObtainFun],00000001 20 jmp returnhere 21 22 exit: 23 call Crashlands2.exe+1F036D0 24 jmp returnhere 25 26 "Crashlands2.exe"+1089569: 27 jmp newmem 28 29 returnhere: 30 31 32 [DISABLE] 33 //code from here till the end of the code will be used to disable the cheat 34 dealloc(newmem) 35 "Crashlands2.exe"+1089569: 36 db E8 62 A1 E7 00 37 //call Crashlands2.exe+1F036D0
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+10897E3) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 cmp [tag_ObtainFun],00000001 13 jne exit 14 // --- 记录调用 CALL 的 Tag - FValue -> 4 15 mov [tag_ObtainFun],00000004 16 call Crashlands2.exe+1F036D0 17 mov [tag_ObtainFun],00000001 18 jmp returnhere 19 20 exit: 21 call Crashlands2.exe+1F036D0 22 jmp returnhere 23 24 "Crashlands2.exe"+10897E3: 25 jmp newmem 26 27 returnhere: 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 "Crashlands2.exe"+10897E3: 34 db E8 E8 9E E7 00 35 //call Crashlands2.exe+1F036D0
<16> 这样我们就可以确定在 "Crashlands2.exe+1EBC072"处,这个 Tag 分别对应 2、3、4时,是修改我们 LValue、MValue、FValue值了,所以下面就是关键代码了,在 "Crashlands2.exe+1EBC072" 处进行汇编:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,200,"Crashlands2.exe"+1EBC072) 4 alloc(FValue,8) 5 alloc(MValue,8) 6 alloc(tmp_unItem,8) 7 registersymbol(FValue) 8 registersymbol(MValue) 9 label(returnhere) 10 label(originalcode) 11 label(exit) 12 label(fvalue_con) 13 label(mvalue_con) 14 15 newmem: //this is allocated memory, you have read,write,execute access 16 //place your code here 17 18 originalcode: 19 mov rax,[rsi] 20 push rdx 21 22 // --- 0 or 1 means not F M L Value Obtain Function 23 cmp [tag_ObtainFun],00000001 24 jbe exit 25 cmp [tag_ObtainFun],00000002 26 je fvalue_con 27 cmp [tag_ObtainFun],00000003 28 je mvalue_con 29 30 // --- tag_ObtainFun = 4! 31 // 32 // --- The Item Now is Zero Or One ( value <= 1 ) 33 mov [tmp_unItem],rax 34 movsd xmm0,[tmp_unItem] 35 cvttsd2si edx,xmm0 36 cmp edx,01 37 jna exit 38 39 // --- 为确保 三值的一致性,统一放到一起修改!!!(先修改 [rsi]) 40 add edx,09 41 cvtsi2sd xmm0,edx 42 movsd [tmp_unItem],xmm0 43 mov rax,[tmp_unItem] 44 mov [rsi],rax 45 46 // --- 修改 FValue 和 MValue 47 mov rdx,[FValue] 48 mov [rdx],rax 49 mov rdx,[MValue] 50 mov [rdx],rax 51 jmp exit 52 53 fvalue_con: 54 // 保存 FValue 地址 55 mov [FValue],rbx 56 jmp exit 57 58 mvalue_con: 59 // 保存 MValue 地址 60 mov [MValue],rbx 61 jmp exit 62 63 exit: 64 pop rdx 65 mov [rbx],rax 66 jmp returnhere 67 68 "Crashlands2.exe"+1EBC072: 69 jmp newmem 70 nop 71 72 returnhere: 73 74 75 [DISABLE] 76 //code from here till the end of the code will be used to disable the cheat 77 dealloc(newmem) 78 dealloc(FValue) 79 dealloc(MValue) 80 dealloc(tmp_unItem) 81 unregistersymbol(FValue) 82 unregistersymbol(MValue) 83 "Crashlands2.exe"+1EBC072: 84 db 48 8B 06 48 89 03 85 //mov rax,[rsi] 86 //mov [rbx],rax
<17> 前面的 label 是添加标签的语句,写上 label(fvalue_con) 之后,就可以写 fvalue_con 代表的代码,并考虑情况跳转到 fvalue_con 部分,如 jmp fvalue_con;
<18> 代码逻辑也算是比较简单,可以直接看代码里的注释。
<19> 之后把 Act 2~5 作为 Act 1 的子项,给 Act 1设置好 子项同启用&禁用。
<20> 好了,再使用外表头和特定颜色改造一下!!!

FUN I:--------------------------------------【统计任务速达】
<1> 这个功能实现起来很简单,它也不过是一个整数双浮点而已。但它的问题在于很容易卡关,尤其是这个数值影响着很多物资能否采集。比如,最后要有一个主线任务要采集17朵南瓜掌,如果目标值大于等于17,那南瓜掌的采集功能就会失效!此时,如果你没有开启无限物品,南瓜掌物品的数量低于17,无法交付任务,那么恭喜你!你存档成功的死掉了!所以,这个功能要配合无限物品来实现。无限物品的逻辑是物品数量只存在 0,1,49999!那我们的任务目标也就只存在 0,1,49999。它其实是和目标绑定一致!
<2> 首先,还是快速的搜索到这个统计项的数值,然后鼠标右击,选择 “找出是什么修改了这个地址”,发现代码地址是 令人亲切的 Crashlands2.exe+E73EF!

<3> 使用 “Break Point Check Test”,检索其多级返回地址。而且一级返回地址前的这个 CALL 我们可太熟悉了!

<4> 直接汇编,代码逻辑为 0,1,49999 →完成任务需求!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1418EB5) 4 alloc(tmp_total,8) 5 alloc(tmp_setag,8) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tmp_total],rbx 15 call Crashlands2.exe+E7360 16 push rcx 17 18 // --- The number Now is Zero Or One ( value <= 1 ) 19 mov [tmp_setag],rax 20 movsd xmm0,[tmp_setag] 21 cvttsd2si ecx,xmm0 22 cmp ecx,01 23 jna exit 24 25 // --- turn total_value to 49999 26 mov ecx,#49999 27 cvtsi2sd xmm0,ecx 28 mov rcx,[tmp_total] 29 movsd [rcx],xmm0 30 jmp exit 31 32 exit: 33 pop rcx 34 jmp returnhere 35 36 "Crashlands2.exe"+1418EB5: 37 jmp newmem 38 39 returnhere: 40 41 42 [DISABLE] 43 //code from here till the end of the code will be used to disable the cheat 44 dealloc(newmem) 45 dealloc(tmp_total) 46 dealloc(tmp_setag) 47 "Crashlands2.exe"+1418EB5: 48 db E8 A6 E4 CC FE 49 //call Crashlands2.exe+E7360
<5> 由此,仅兼容 “无限物品” 的 “任务需求速达” 功能就完成了,再使用外表头和特定颜色改造一下!!!

<6> 之后是关于 此部分功能的优化,先禁用这个功能,然后返回 Act 1 所汇编的位置,设置好断点。

<7> 准备好我们的任务——巨型机器人(最好是南瓜掌的那个任务)!

<8> 禁用其他功能后,收集上图大块头来激活断点以观察堆栈情况。

<9> 找到一级返回地址 Crashlands2.exe+1D2FDFB ,对它前面的 CALL 汇编加 Tag,之前的 “Act 1” 要变成 “Act 2”。
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1D2FDF6) 4 alloc(tag_obtain_mission,8) 5 registersymbol(tag_obtain_mission) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 // --- 记录调用 CALL 的 Tag 15 mov [tag_obtain_mission],00000001 16 call Crashlands2.exe+1418700 17 mov [tag_obtain_mission],00000000 18 19 exit: 20 jmp returnhere 21 22 "Crashlands2.exe"+1D2FDF6: 23 jmp newmem 24 25 returnhere: 26 27 28 [DISABLE] 29 //code from here till the end of the code will be used to disable the cheat 30 dealloc(newmem) 31 dealloc(tag_obtain_mission) 32 unregistersymbol(tag_obtain_mission) 33 "Crashlands2.exe"+1D2FDF6: 34 db E8 05 89 6E FF 35 //call Crashlands2.exe+1418700
<10> 将 “ Act 2” (原本的 “Act 1” )改造一下,使得它在采集函数过程中,只听从 采集物品值,即不按照我们直接49999的规则修改!
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1418EB5) 4 alloc(tmp_total,8) 5 alloc(tmp_setag,8) 6 label(returnhere) 7 label(originalcode) 8 label(exit) 9 10 newmem: //this is allocated memory, you have read,write,execute access 11 //place your code here 12 13 originalcode: 14 mov [tmp_total],rbx 15 call Crashlands2.exe+E7360 16 push rcx 17 18 cmp [tag_obtain_mission],00000001 19 je exit 20 21 // --- turn total_value to 49999 22 mov ecx,#49999 23 cvtsi2sd xmm0,ecx 24 mov rcx,[tmp_total] 25 movsd [rcx],xmm0 26 jmp exit 27 28 exit: 29 pop rcx 30 jmp returnhere 31 32 "Crashlands2.exe"+1418EB5: 33 jmp newmem 34 35 returnhere: 36 37 38 [DISABLE] 39 //code from here till the end of the code will be used to disable the cheat 40 dealloc(newmem) 41 dealloc(tmp_total) 42 dealloc(tmp_setag) 43 "Crashlands2.exe"+1418EB5: 44 db E8 A6 E4 CC FE 45 //call Crashlands2.exe+E7360
<11> 重新使用外表头和特定颜色改造一下!!!

FUN J:--------------------------------------【一击必杀】
<1> 一击必杀的制作方向比较明显的有两条:① 找到玩家血量的地址,修改扣血的代码——玩家以外的血量值扣血直接扣成 0 ;② 找到玩家攻击力的代码,之后想办法把攻击力调整到 MAX(高于敌人最大血量值)。
<2> 很遗憾,我没有找到攻击力的数据,甚至我现在都没有搞清楚这个游戏的伤害机制,所以我们自然而然地选择第一种方法。还是先找到之前的 HP Value 和 HP Upper 两个值!
<3> 我们在无限血量中已经找到了 HP 的高频访问函数 在 Crashlands2.exe + 131A4AF 处的标记,我们在它的前面和后面分别注入代码用于 一击必杀功能中的 HP 的高频访问函数标记!

<4> 注入代码,以达成 Fun B 中 Act 1的效果。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4A6) 4 alloc(tag_Hp_perm2,8) 5 alloc(HP_Address,8) 6 registersymbol(HP_Address) 7 registersymbol(tag_Hp_perm2) 8 label(returnhere) 9 label(originalcode) 10 label(exit) 11 12 newmem: //this is allocated memory, you have read,write,execute access 13 //place your code here 14 15 originalcode: 16 mov edx,[Crashlands2.exe+310CEA8] 17 // --- 记录调用 CALL 的 Tag 18 mov [tag_Hp_perm2],00000001 19 20 exit: 21 jmp returnhere 22 23 "Crashlands2.exe"+131A4A6: 24 jmp newmem 25 nop 26 27 returnhere: 28 29 30 [DISABLE] 31 //code from here till the end of the code will be used to disable the cheat 32 dealloc(newmem) 33 dealloc(tag_Hp_perm2) 34 dealloc(HP_Address) 35 unregistersymbol(HP_Address) 36 unregistersymbol(tag_Hp_perm2) 37 "Crashlands2.exe"+131A4A6: 38 db 8B 15 FC 29 DF 01 39 //mov edx,[Crashlands2.exe+310CEA8]
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+131A4B4) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 movaps xmm0,[rbp+000002E0] 13 // --- 取消记录调用 CALL 的 Tag 14 mov [tag_Hp_perm2],00000000 15 16 exit: 17 jmp returnhere 18 19 "Crashlands2.exe"+131A4B4: 20 jmp newmem 21 nop 2 22 23 returnhere: 24 25 26 [DISABLE] 27 //code from here till the end of the code will be used to disable the cheat 28 dealloc(newmem) 29 "Crashlands2.exe"+131A4B4: 30 db 0F 28 85 E0 02 00 00 31 //movaps xmm0,[rbp+000002E0]
<5> 然后需要在原来绑定 HP Value 值为 99,999,999 的代码处,读取 HP Value 的地址。故对 HP Value 设置 “Break Point Check Test”,停止后一步步 “步过” 直到程序返回到了一级地址!如图,此时 rdi 的值是 HP Value的地址,故在此汇编,将此地址数据保存下来 (向上、向下找都可以)。

1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+1EE17DF) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 mov r15,[rsp+30] 13 14 // --- 发现被标记的高频函数时,将 HP 地址记录上 15 cmp [tag_Hp_perm2],00000001 16 jne exit 17 mov [HP_Address],rdi 18 jmp exit 19 20 exit: 21 jmp returnhere 22 23 "Crashlands2.exe"+1EE17DF: 24 jmp newmem 25 26 returnhere: 27 28 29 [DISABLE] 30 //code from here till the end of the code will be used to disable the cheat 31 dealloc(newmem) 32 "Crashlands2.exe"+1EE17DF: 33 db 4C 8B 7C 24 30 34 //mov r15,[rsp+30]
<6> 之后,对 HP Value 的值鼠标右击,选择 “找出是什么修改了这个地址”,之后回到游戏中让怪物摸你一下!

<7> 就在这个地址注入汇编代码,逻辑是 把玩家以外的血量 设置为 0;
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,100,"Crashlands2.exe"+B60FDD) 4 label(returnhere) 5 label(originalcode) 6 label(exit) 7 8 newmem: //this is allocated memory, you have read,write,execute access 9 //place your code here 10 11 originalcode: 12 // --- 当 未记录 上 HP_Address 时,直接跳过不修改!!! 13 push rax 14 push rdx 15 cmp [HP_Address],00000000 16 je exit 17 18 // -- 监测伤害是否提供给玩家 19 mov rax,r15 20 mov rdx,[HP_Address] 21 cmp rax,rdx 22 je exit 23 // --- 生命值归 0 24 xor rax,rax 25 cvtsi2sd xmm6,eax 26 jmp exit 27 28 exit: 29 pop rax 30 pop rdx 31 movsd [r15],xmm6 32 jmp returnhere 33 34 "Crashlands2.exe"+B60FDD: 35 jmp newmem 36 37 returnhere: 38 39 40 [DISABLE] 41 //code from here till the end of the code will be used to disable the cheat 42 dealloc(newmem) 43 "Crashlands2.exe"+B60FDD: 44 db F2 41 0F 11 37 45 //movsd [r15],xmm6
<8> 整理代码,并使用外表头和特定颜色改造一下!!!


浙公网安备 33010602011771号