上次修复了NekoMiko汉化补丁的一些小问题之后,我膨胀了,开始觉得要不自己开始尝试汉化点游戏吧?然后我就瞄准了两三年前找到的一个想推的小拔作《おままごと ~母親少女とちやほやしっぽり~》。

首先看到文件结构,Unity引擎的游戏,和我之前跟着教程破解的《Alice in cradle》类似:

于是抱着试一试的心态打开"/Data/Managed/",果然看到了Assembly-CSharp.dll。

参考https://www.bilibili.com/video/av4740378,我用dnspy打开Assembly-CSharp.dll后,却没有直接找到文本。我像无头苍蝇一样重新翻找了一下文件,发现另一个文件夹“/GameMaterial/”中包含有voice、sound、bgimage等的文件夹,结合单词意思猜测游戏资源文件就在这个文件夹内。

经过排除法最后锁定在“/Scenario/”文件夹内,但是里面的文件后缀是我完全没见过的.dsm结尾。

直接打开是乱码,无法直接读取,应该是加了密。

之后只能再一边通过网上查询,一边继续看Assembly-CSharp.dll内的文件。然后我找到了这样一则帖子https://www.jianshu.com/p/2648a91cca96,跟随文章的指引我果然在Assembly-CSharp.dll中找到了LoadScenarioScript.cs,LoadScenarioScript.cs中也找到了三个解密的函数。

巧合的是,我也是门外汉,而且是unity和C#都完全不会那种,于是抱着顺便学一学的想法开始一边查资料一边学一边生啃代码的痛苦之旅。

首先我是对着ReadFile()顺了一遍思路,发现它和解密完全没关系,其作用是将需要解密的密文读取然后传递给DecryptString()进行解密。

而另一个参数“pass”很有可能就是密钥。

接着我对着DecryptString()啃,发现解密过程中的key和iv是固定的,GenerateKeyFromPassword()接收的函数中没有一个是和文本相关的:

然后我就把DecryptString()和GenerateKeyFromPassword()单独复制出来,稍加修改:

导入加密文本之后,对比导出结果,解密成功!

之后汉化工作就可以开始了,但是光是解密还不行,还得想办法加密回去游戏才能读取,于是我就开始尝试自己写加密代码了。

通过解密工作了解到这玩意儿应该只经过AES加密和Base64加密,盐和“pass”生成密钥,但是生成方式是固定的,所以PBKDF2算法我不需要去了解。由于对C#的不了解,我是想当然地觉得有加密就会有解密,于是查看官方帮助文档,看到相似的函数就用,比如有Convert.FromBase64String(),我就尝试用Convert.ToBase64String();有ICryptoTransform.TransformFinalBlock(),我就尝试用ICryptoTransform.TransformBlock()等等。

当然,无情的现实告诉我想当然是行不通的......

在经过一下午的无用尝试后,我就想着能不能直接用AES的加密方式套上去呢?然后我就去搜了并试了:

成功加密回上一步,接着最后一步变成原加密文本,我觉得这回用ToBase64String()总没错了吧,然后

成功加密回原加密文本,加密代码如下:

至此游戏文本的破解工作到此结束,应该可以开始愉快的汉化文本之旅了~


作者:Dax,如若转载,请注明出处:《一次Unity引擎galgame加密文本的破解记录》