办公设备维修网
资讯中心 您所在的位置:网站首页 资讯中心 开罗游戏Steam版禁用/破解存档加密与校验的方法

开罗游戏Steam版禁用/破解存档加密与校验的方法

2024-06-17 09:25:31| 来源: 网络整理

0x0 引言

开罗在新历元旦时又上架了特惠 Bundle ,三款游戏三十元,遂补票之。本来想开 CE 把高速模式解锁掉,但又想到能不能直接改存档呢?试了下发现不行:我先解密了存档,改了几字节数据,再加密存档,进入游戏后提示存档错误。

为什么呢?一个猜想是游戏会对存档进行散列校验,比如比对 MD5 、CRC32 之类的,因为这存档文件的 4-8 字节一看去就感觉是散列校验值。于是又试着研究了下破除校验机制的方法,成功了,通过这个方法可以直接让游戏不再对存档进行加密与校验,这样的好处是:

1. 可以随意在不同设备间转移明文存档(原版游戏生成的存档是加密过的,不能转移,必须先解密);

2. 可以自由修改存档数据,不必关心散列校验能否通过。

修改所要用到的工具如下:

1. IDA

2. Il2CppDumper `https://github.com/Perfare/Il2CppDumper`

3. 010Editor

如果你不想了解修改原理,也可以直接进到文末,我提供了自动化的修改工具。

0x1. 原理

之前开罗游戏被国内的识君代理(坑惨)时,网上流传出了一些包含作弊菜单的 DEBUG 版开罗游戏,这是因为识君在国内应用商店所分发的开罗游戏 APK 在编译打包时没有使用 il2cpp ,其中的 DLL 文件可以很容易地反编译出 C# 代码并查看。

`https://www.52pojie.cn/thread-1247326-1-1.html`

将其中的 KairoLibrary.dll 拖到 dnSpy 里查看,搜索 Encrypt/Encode/Decode 这些关键词就能找到关于存档加密的逻辑:

WriteRecord

RecordStore.WriteRecord 方法实现了存档的保存:

1. 将游戏数据序列化为二进制格式;

2. 计算序列化数据的 CRC64 散列,得到校验值,将其添加到序列化数据之前(8个字节);

3. 将添加了校验值的序列化数据进行 XOR 加密(Encrypter.Encode);

4. 将数据保存为文件。

ReadRecord

RecordStore.ReadRecord 方法实现了存档的加载:

1. 读取文件,得到加密过的存档数据;

2. 将数据进行 XOR 解密(Encrypter.Decode);

3. 截取前8个字节作为校验值,与余下数据的 CRC64 散列做对比,如果不相等,抛出异常,终止加载;

4. 将数据反序列化并进入游戏。

那么,想要禁止游戏在读写存档时加密与校验行为,需要进行如下修改:

1. 修改 RecordStore.WriteRecord ,删除其中对 Encrypter.Encode 的调用语句。

2. 修改 RecordStore.ReadRecord ,删除其中对 Encrypter.Decode 的调用语句与异常分支。

STEAM版的开罗游戏都是启用了 il2cpp 的,没法直接拖到 dnSpy 里修改,要先使用 Il2CppDumper 分析 GameAssembly.dll ,再借助分析出的信息和 IDA 修改它。

0x2. 步骤

这里以STEAM版住宅梦物语DX为例。

0x1A. 准备工作

1. 进入游戏的数据目录 `C:Program Files (x86)SteamsteamappscommonDreamHouseDaysDX` 。

2. 使用 32 位的 IDA 打开 `GameAssembly.dll` ,等待分析完毕。

3. 命令行调用 `Il2CppDumper-x86.exe "C:Program Files (x86)SteamsteamappscommonDreamHouseDaysDXGameAssembly.dll" "C:Program Files (x86)SteamsteamappscommonDreamHouseDaysDXKairoGames_Datail2cpp_dataMetadataglobal-metadata.dat"` ,等待程序执行完成,再打开 `Il2CppDumper-x86.exe` 程序所在的目录,其中的 `dump.cs` 文件就是分析出的数据,以文本形式打开它。

4. `dump.cs` 中搜索 `class Encrypter` ,记录下其中 `Encode` 方法的所有重载的 VA = 0x102D24E0, 0x102D2540 。

5. `dump.cs` 中搜索 `class Encrypter` ,记录下其中 `Decode` 方法的所有重载的 VA = 0x102D2440, 0x102D23F0, 0x102D2360 。

6. `dump.cs` 中搜索 `class CRC64` ,记录下其中 `GetValue` 方法的 VA = 0x102CD1E0 。

7. 为防万一,可以将 `GameAssembly.dll` 文件与 `saves` 目录都备份到其他存储空间中,如果改错了可以重新再来。

0x1B 修改 ReadRecord 方法

1. `dump.cs` 中搜索 `class RecordStore` ,记录下其中 `ReadRecord` 方法的 VA = 0x103AA7D0 。

2. 在 IDA 中,跳转到 `ReadRecord` 的 VA 处,F5 后可以看到对 `Encrypter.Decode` 与 `CRC64.GetValue` 的调用,如图:

3. 把 `Encrypter.Decode` 与 `CRC64.GetValue` 的调用指令 `call ..` 给 NOP 掉(用 0x90 替换字节)。

4. 把 `CRC64.GetValue` 的调用指令 `call ..` 下面的第二和第三指令 `cmp eax, ..; jnz ..` 给 NOP 掉,完成。

0x1C 修改 WriteRecord 方法

1. `dump.cs` 中搜索 `class WriteRecord` ,记录下其中 `WriteRecord` 方法的 VA = 0x103AB430 。

2. 在 IDA 中,跳转到 `WriteRecord` 的 VA 处,F5 后可以看到对 `Encrypter.Encode` 的调用,如图:

3. 把 `Encrypter.Encode` 的调用指令 `call ..` 给 NOP 掉,完成。

0x1D 结束

保存修改后的 `GameAssembly.dll` 。

0x3. 使用

以上修改将 `GameAssembly.dll` 中关于存档加密、解密、校验的逻辑都删除了,现在游戏不会再以加密的方式加载和保存存档,也不再会对存档数据进行散列值校验。

如果游戏是新下载的,没有打开过,直接进入游戏就行;

如果游戏已经打开过,那么游戏还有旧的存档,保存在游戏目录的 `saves` 目录中,可以直接删除(舍弃旧存档),或者照我上个专栏的方法将存档解密为明文,明文存档可以被修改后的游戏正常地加载。

注意:在解密旧存档前不要打开修改后的游戏,否则游戏会生成新存档覆盖掉旧存档!

修改后的游戏不会进行存档加密与校验,因此可以在不同设备间随意流转,也可以自由地修改存档数据(开启高速模式、重命名玩家称呼,或是做一些有损游戏性的作弊行为),

010Editor,启动!

(BTW,本来想改出DEBUG菜单的,但是找到了Config类的静态构造函数一看,STEAM原版游戏中就已经把DEBUG静态field设为true了,即使如此,游戏运行时也是没有DEBUG功能的。。。。)

0x4. 自动化

上述修改方法应该适用于所有 STEAM 版本的开罗游戏(我测试了我买的 19 款开罗游戏,都能在修改后正常运行并生效);安卓和 iOS 版本的存档应该也是一样的道理,可能会有一些差别,但我没买移动端的开罗,就没有测试了。

我测试的 19 款开罗游戏中都是完全一样的修改步骤,因此我写了一个自动修改开罗游戏 dll 的脚本:

`https://github.com/twinkles-twinstar/TwinStar.ToolKit/blob/master/Script/Support/Kairosoft/Record/DisableVerify.ts`

要使用这个脚本,需要先安装我开发的工具软件(安装方法看我过去的视频),然后将游戏目录(如 SteamsteamappscommonDreamHouseDaysDX )输入给工具,选择 `Kairosoft Record Disable verify` 功能即可。

(这个脚本依赖了 Il2CppDumper-x86 ,需要下载该程序并配置 PATH 环境变量)



【本文地址】 转载请注明 

最新文章

推荐文章

CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备16040606号-1