Steam游戏《Nine Parchments(九张羊皮纸)》修改器制作-[先使用CE写,之后有时间的话改用C#](2020年寒假小目标02)
日期:2020.01.09
博客期:122
星期四
【温馨提示】:
只是想要修改器的网友,可以直接点击此链接下载;
只是想要部分CT文件的网友,可以直接点击此链接下载;
没有博客园账号的网友,可以将使用百度云网盘进行下载:
下载链接:https://pan.baidu.com/s/1eCYN_ZV1ZNj9w8Kuj_ALXg
提取码:usyd
Git Hub下载地址:https://github.com/TwoStarsGodNightSky/GameTrainer
B 站测试视频 bv 号:BV1Qh411k7yc
如果修改器失效了,你们可以在博客园本页直接评论,也可以给我发邮件告诉我,就是不要到百度云上去说了,百度云我好久不登录一次的!大家给我发邮件的话,记得要注明是哪个游戏,内容当然是越详细越好啦!邮箱地址:nightskysxs@163.com
博客地址:https://www.cnblogs.com/onepersonwholive/p/12174160.html
博客前言:之前玩 Steam 游戏的时候,发现了这款游戏,发现单人通过难度很大,就希望能够有修改器的帮助,结果在网上搜寻了半天,根本没有一个链接可以提供我刚才那样要求的修改器的下载,这...唉~ 那就自己编吧,之前我是有学过 CE 的,也了解了一下基础的汇编语言,不过没有深究罢了,这一次寒假我要好好学一学。因为我们刚过完的这一学期学了 .NET 开发,我就想着多少复习一下吧,就开始准备了。刚刚重新拿《植物大战僵尸年度英文版》复习了一下CE的方法,感觉有点儿生疏了,诶嘿嘿!
《九张羊皮纸》这游戏的可修改性不如《植物大战僵尸》,但是这也方便了我们程序员,毕竟越多的需求,就是越多的编码时间啊!
(前面的提供程序员看,如果需求仅限于修改器下载的话,后面就可以不用看了)
游戏版本(v1.1.0 build 4722)[Steam]
目前挖掘的可修改项:玩家血量值+技能值+闪现恢复度 ( 基础地址如下:"THREADSTACK0"-00000168 )
1、玩家血量值 (4字节)
所在地址:基础地址 00000168 + 370 + C8 + 110 + 0 + 4BC
2、技能值(单浮点-Float)
PS: 下面的技能是按照当前游戏版本的顺序来的()
技能基础地址 所在地址:基础地址 ("THREADSTACK0"-00000168) + 370 + C8 + 70
//----------------------------------------------【火焰技能】
1、焰束 + 8 + 2C4
2、燃石 + 98 + 2DC
3、魔咒火球阵 + A8 + 2DC
4、火焰炸弹 + B0 + 290
5、烈焰弹串 + C0 + 2DC
6、小型火球 + A0 + 2E0
7、大型火球 + E8 + 2E0
8、烈焰弹幕 + B8 + 2E0
9、烈焰图腾 + C8 + 2DC
//----------------------------------------------【寒冰技能】
10、冰束 + F8 + 2C4
11、寒冰弹串 + 110 + 2DC
12、寒霜云 + D0 + 2DC
13、冰片飞刀 + D8 + 2E0
14、寒冰冲击波 + 108 + 290
15、寒霜喷雾 + 18 + 2FC
16、寒冰弹幕 + 100 + 2E0
17、疯狂雹暴 + 20 + 2DC
//----------------------------------------------【闪电技能】
18、闪电喷雾 + 78 + 2FC
19、闪电弹幕 + 70 + 2E0
20、闪电图腾 + 88 + 2DC
21、闪电波 + 90 + 290
22、闪电炸顶!(这里是原技能名称有“!”) + 198 + 2DC
23、闪电束 + 68 + 2C4
24、能量环 + 150 + 290
25、附著型能量环(这里是原技能名称写的“著”,不是我想写错字) + 178 + 290
26、闪电弹串 + 80 + 2DC
27、闪电球 + 0 + 2E0
//----------------------------------------------【死亡技能】
28、死亡波束 + 48 + 2C4
29、致命自杀炸弹 + 60 + 2DC
30、死亡光圈 + 40 + 2DC
31、传染性恶咒 + 118 + 2DC
32、死亡弹幕 + 58 + 2E0
33、死亡毒花 + 148 + 2DC
34、脉冲波环 + 158 + 2DC
35、限值死亡喷雾 + 30 + 324
36、死亡法术球 + 50 + 2E0
37、死亡之咒 + 128 + 318
38、连续死亡射弹 + 38 + 2E0
//----------------------------------------------【死亡生命技能】
39、生死曲线弹 + 180 + 2E0
40、盗命治疗弹 + 168 + 2E0
//----------------------------------------------【生命技能】
41、治疗喷雾 + E0 + 2FC
42、治疗弹幕 + 130 + 2E0
43、生命弹串 + 138 + 2DC
44、小型生命魔环 + 160 + 290
45、近程群疗 + 188 + 290
46、弧形跳跃治疗 + 28 + 2E0
47、大型生命魔环 + 120 + 2DC
48、治疗波束 + 10 + 2C4
49、大型治疗球 + F0 + 2E0
//----------------------------------------------【其他技能】
50、蒸汽束 + 170 + 2C4
51、阿玛迪斯的魔箱 + 190 + 2DC
52、穿心暗影 + 140 + 330
//-----------------------------------------------------------------------------------------------------------
第一偏转是上述偏转的第一个,由技能编号所决定,第一个是 0,第二个是 8,第三个是 10(因为是16进制嘛!)
第二偏转是由技能类型所决定的,2C4 是波束类,2E0 是属性球类,2DC 是投放型区域类,290是近距范围类,2FC 是喷雾类,还有 318、324、330 这三个应该是特殊的技能
如果没有看出关系来就看下面的表格
如想看全部,就下载吧:https://files.cnblogs.com/files/onepersonwholive/9P技能偏转表.zip
3、闪现恢复度(4字节)
所在地址:基础地址 00000168 + 370 + E8 + 0 + 80 + 3F4
完整的CT文件下载地址:https://files.cnblogs.com/files/onepersonwholive/nineparchments_64bit.zip
修改器部分:
好了,截至到 2020 年 1 月 15 日,我也用CE先制作了修改器,附下载链接:链接已经失效,请认准 最新地址
修改器截图:
嗯~基本页面写好了,现在是 2020 年 01 月 17 日0:36,我重新装了系统和 ViusalStudio 2017 , 开始编写 C# 的修改器:
下图是页面:
后续更新内容------[2020-01-20,更新内容]
我在 20 号,登录游戏挖掘技能的更多信息(发现了好多新大陆)
我就以小型火球为例子说明一下地址修改要素吧:
小型火球的最后一项偏转是 2E0 ,如果将 2E0 改为 ( 2E0-8 ) ——也就是 2D8 ,就会变成技能上限的地址。上图的相关信息都可以找到(+68 和 +6C 我搞不清是啥,只不过攻击值会随其变大而变大,我就猜了一个暴击率)
目前我没有找到与 恢复速度 相关的地址 ... ...
新的 CT 文件我就不发了,这是因为如果把所有技能配合上述实例的地址全找出来,CT 文件就太大了,所以要修改器的博友就可以要原来那个,要地址的博友就麻烦自己找到自己需要的地址了。
后续更新内容------[2020-02-10,更新内容]
我根据原来的地址找到了血量上限的地址:
基础地址 00000168 + 370 + C8 + 110 + 0 + 4B8
但是我发现找偏转找到的最后一级偏转是 5B4 !这就有问题了,说明开发人员在写代码的时候提供了另外一个数据访问路径,这个路径不是我们日常需要的那种循规调用的。所以我又开始找了好多的玩家血量值的地址!
第一种:"nineparchments_64bit.exe"+035C9920 + 118 + F0 + C8 + 128 + 5B4
第二种:"THREADSTACK0"-00000168 + 290 + 370 + C8 + 128 + 5B4
第三种:"THREADSTACK0"-00000168 + 370 + C8 + B0 + 10 + 5B4
现在我们采用第一种!因为 nineparchments_64bit.exe 是你的主进程,这样方便一些,我现在还不太懂这个 ThreadStack0 是个什么进程 !
找好了之后,我们来对比一下 野猪(初始 HP 为 600)的结构体 与 玩家结构体 之间的不同,如下图:
这是我找到的部分不同,上图中 绿色 标识 数据有巨大不同 , 红色 标识 完全一致的数据(不包括血量和血量上限),黑色是近似相等的(可能取浮点值就差不多了)
嗯!我写了一个 代码注入 ,但是总是会报错说 “ kernel32.dll 什么什么的”,怎么回事啊?这好不容易深造了一天,结果还没学好!
1 [ENABLE] 2 alloc(newmem,2048,"nineparchments_64bit.exe"+10E9511) 3 label(returnhere) 4 label(originalcode) 5 label(exit) 6 7 newmem: //this is allocated memory, you have read,write,execute access 8 //place your code here 9 10 originalcode: 11 cmp [rbx+rcx*4+5C],3E8 12 je exit 13 mov [rbx+rcx*4],edi 14 movzx r10d,word ptr [rbx+4E] 15 16 exit: 17 jmp returnhere 18 19 "nineparchments_64bit.exe"+10E9511: 20 jmp newmem 21 nop 3 22 23 returnhere: 24 25 [DISABLE] 26 "nineparchments_64bit.exe"+10E9511: 27 mov [rbx+rcx*4],edi 28 movzx r10d,word ptr [rbx+4E]
我最终发现代码的问题出在那里了,那个代码把 下面的一句遮住了,按照以上代码,走破解一路会不执行!所以我们要在 exit 里加上 这一句!另外,我发现 图上实际能用的就是 65535 对应的那个 + 14 的数据,所以最终的汇编代码如下:
1 [ENABLE] 2 alloc(newmem,2048,nineparchments_64bit.exe+10E9511) 3 label(returnhere) 4 label(originalcode) 5 label(exit) 6 7 newmem: //this is allocated memory, you have read,write,execute access 8 //place your code here 9 10 originalcode: 11 cmp [rbx+rcx*4+14],FFFF 12 je exit 13 mov [rbx+rcx*4],edi 14 movzx r10d,word ptr [rbx+4E] 15 16 exit: 17 movzx r10d,word ptr [rbx+4E] 18 jmp returnhere 19 20 nineparchments_64bit.exe+10E9511: 21 jmp newmem 22 nop 23 nop 24 nop 25 26 returnhere: 27 28 [DISABLE] 29 nineparchments_64bit.exe+10E9511: 30 mov [rbx+rcx*4],edi 31 movzx r10d,word ptr [rbx+4E]
提醒一下:上述代码在 ENABLE 状态下,如果跳出地图外死亡,本关会直接结束!因为修改的代码是 共用代码段——生命赋值,敌人和自己的加血和扣血都是用的这段代码!如果遇到游戏卡住,可以暂时将代码 恢复至 DISABLE 状态,等待游戏卡顿结束。
另外,今天不是学习了汇编嘛!也试着自己把 无限闪现技能 重新使用 汇编代码实现一下:
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"nineparchments_64bit.exe"+45BD70) 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 [rcx+r8*4],2 13 mov al,01 14 15 exit: 16 jmp returnhere 17 18 "nineparchments_64bit.exe"+45BD70: 19 jmp newmem 20 nop 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 "nineparchments_64bit.exe"+45BD70: 30 mov [rcx+r8*4],eax 31 mov al,01 32 //Alt: db 42 89 04 81 B0 01
技能无冷却的话,呃~我努力一下吧!
后续更新内容------[2020-02-11,更新内容]
唉~去学了半天浮点的汇编指令,到头来还不是直接赋值 float(四字节)的 Int 表示
1 [ENABLE] 2 //code from here to '[DISABLE]' will be used to enable the cheat 3 alloc(newmem,2048,"nineparchments_64bit.exe"+4A06D6) 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 [rcx+r8*4],1079246848 13 //movss [rcx+r8*4],xmm0 14 15 exit: 16 jmp returnhere 17 18 "nineparchments_64bit.exe"+4A06D6: 19 jmp newmem 20 nop 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 "nineparchments_64bit.exe"+4A06D6: 30 movss [rcx+r8*4],xmm0 31 //Alt: db F3 42 0F 11 04 81
嗯,很久以前,在我还是大一的时候,使用修改器改过 《崩溃大陆》,当时还不知道 搜索的那些 4字节的数字 1072.....其实是浮点数呢!当时我还找到了一些规律说它们之间的差没经过一个参数就会缩小至原来的一半,而这个参数是规律变化的!
比如 1.0 表示的是 1072693248 ,而 2.0 表示的是 1073741824 (浮点数的精确查法),3.0 是 1074266112 !嗯, 1074266112 - 1073741824 这个差 是 有规律变化的,具体见下表(来源于其他网站,历史久远忘记了来源),算了很难解释,就是看下面的 excel 表吧
规律很难用文字语言描述清楚,我就给大家看一下我临时制作的表格吧:
当时为了方便修改,写了这一个一定范围内的 Int 整数 转 浮点数的 Int 数值的 C 语言程序,因为是我在上大一的时候写的,所以特别粗糙!当然!大家也可以拿来练练手,不过现在回想起来还不如直接深造 CE 呢!
PS:我会制作新的 CT文件出来,另附新的修改器,感谢大家的支持,上一个版本将会被覆盖掉,也就是说——旧版本仅仅会保存在博主本人的主机上,至于博客园~空间小,实在是没有办法,望各位见谅哈!
下面是更新以后的 CT 文件 的内部项:
下面是更新以后的 修改器 的样式截图:
后续更新内容------[2020-03-11,更新内容]
好了,话不多说了,今天摸索修改器也没有多少进步,本来今天是《Ori2》的Steam PC版发行嘛,打算做这个游戏的修改器的,万万没想到 3dm 的大佬们居然早做好了!嗯?不是还没发行么?修改器早做好了是什么鬼?难道...已经开学第 4 个月了,我也要离开修改器领域一段时间了,不扯了~说说今天的更新内容,今天是为了大家玩这个游戏的时候,尤其是最后高难度的那一部分的怪物,真的是肉啊!四五类技能全放了都没死,真的是皮厚!那我今天就写一个秒杀的修改项。
我们知道要秒杀可以有两类方法来实现:第一类,找到 sub 语句(减血语句),之后将后面的减数 调成无穷大(相对无穷大,如果游戏内最高血量敌人是 2000,我们就可以设值无穷大为 2500);第二类,找到 mov 语句(血量赋值语句),之后将后面的参数调成 0 ,就把 “血量设值函数” 变成了 “处死函数” 了!
实际上我们采取第二种,原因是我们游戏通过找血量 “是什么语句修改了这段地址” 找到的是 mov 语句,也就没必要去专门找 sub 语句了 ,更避免了对于 无穷大 的分析。那么这里还有一个问题,这个游戏里可是有误伤系统的啊!你是能把周围怪物一下子秒了,但要是你也在这个周围内呢?砰砰,完成 “猪队友” 成就!我们还是按照之前的找 玩家结构体和敌人结构体的区别(实际上我们可以直接拿过来用),这也是共用代码问题的最基本的解决方法了。
给大家看一下 汇编代码:
[ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat alloc(newmem,2048,"nineparchments_64bit.exe"+10E950C) label(returnhere) label(originalcode) label(exit) newmem: //this is allocated memory, you have read,write,execute access //place your code here originalcode: mov [rsp+30],r15 cmp [rbx+rcx*4+14],FFFF je exit mov edi,0 exit: jmp returnhere "nineparchments_64bit.exe"+10E950C: jmp newmem returnhere: [DISABLE] //code from here till the end of the code will be used to disable the cheat dealloc(newmem) "nineparchments_64bit.exe"+10E950C: mov [rsp+30],r15 //Alt: db 4C 89 7C 24 30
之后我会更新CT文件和修改器的下载地址哦!
后续更新内容------[2020-07-14,更新内容]
嗯,想起来修改器每次都有的那个小 bug ——技能长条值意外显示的状况。我知道我是设置了一个无限大的值给技能值的地址,实际上这样做,就直接把游戏中的技能的技能值给改的特别大。这样会留下一个很严重的问题,就是在取消 “技能值不减”功能以后,技能的值仍然很大,仍然表现为 “不减的技能值”,这就和我们的要求不太符合了。而且这样做会使技能值显示部分的条状框件变成长条状影响美观。所以,今天我把技能赋值成上限值,我们看 CT 文件中小型火球的实例,技能值的地址 - 4 = 技能值上限的地址,我们使用 movss 语句,借助 xmm0 作为中介,将值赋好。
做好以后的 CT 文件和修改器截图如下:
!!!完结撒花!!!