本文仅用于技术交流与学习探讨,请尊重相关版权。如本文内容涉及您的合法权益,请及时与我联系。
首先感谢 Azalea 的博客《Maimai 街机音游逆向!》。文中的大部分内容至今仍然有效,不过随着时间推移,其中部分步骤已经有了更加方便的替代方案。
由于我自己在折腾 Maimai App 解密与文件提取的过程中踩了不少坑,因此决定把整个流程重新整理一遍,希望能帮助后来者少走一些弯路。
准备工具
开始之前,你需要准备以下内容:
- 待解密的 App 原包
fsdecrypt.execalculate_iv.pyRStudioPortable.exe- unsega.exe
其中:
fsdecrypt.execalculate_iv.py
均可从 SEGA Decryption Guide 获取。
推荐方案:使用 unsega 快速解密
如果你的目标只是获取 App 内部文件,那么推荐优先使用 unsega.exe。
相比传统流程,它省去了手动获取 Key1、修改 Bin 文件等繁琐步骤。
使用方法
将 App 文件直接拖动到 unsega.exe 图标上即可。
程序会自动完成解密工作,并生成对应的 VHD 文件。
解密完成后,可以直接跳转至:
文件提取
传统方案:使用 fsdecrypt 手动解密
如果你希望了解解密流程,或者在使用 unsega 时遇到问题,可以使用传统方案。
获取 AES Key
首先需要一个包含 AES Key 的 Bin 文件。
如果暂时没有,可以尝试前往:
查找对应版本的 Key 文件。
如果不确定应该选择哪个 Bin 文件,可以尝试从 App 文件名称中寻找对应版本信息。
修改 Bin 文件
使用十六进制编辑器打开 Bin 文件。
这里以 Sublime Text 为例:

在文件末尾换行写入:
EB 52 90 4E 54 46 53 20 20 20 20 00 10 01 00 00如果你使用的是 Sublime Text:
- 请将字母转换为小写
- 使用英文输入法输入空格
随后保存文件。
第一次解密
在当前目录打开 CMD 或 PowerShell,并执行:
fsdecrypt <PCB CODE>.bin 0x200000 <path/to/app> <out.vhd>参数说明:
| 参数 | 说明 |
|---|---|
<PCB CODE>.bin | 修改后的 Bin 文件 |
<path/to/app> | App 文件完整路径 |
<out.vhd> | 输出的 VHD 文件名 |
执行时请去掉参数两侧的 < >。
成功后,目录中应出现类似:
out.vhd的文件。
获取 Key1
接下来需要使用 calculate_iv.py。
请确保系统已经安装 Python 环境。
为了避免一些异常情况,可以将脚本精简为:
import os
import glob
def byte_xor(ba1, ba2):
return bytes([_a ^ _b for _a, _b in zip(ba1, ba2)])
print("You must decrypt the opt first using fstools and the OPT.bin\nPlace everything in the same directory\nONLY HAVE ONE VHD IN THE DIRECTORY AT A TIME")
cwd = os.getcwd()
with open(str(cwd) + "/exfat.bin", "rb") as f:
exfat_HEADER = f.read(-1)
print("exFAT Header = " + str(exfat_HEADER.hex()))
placeholder = glob.glob("*.vhd")
vhd = str(placeholder[0])
with open(str(cwd) + "/" + vhd, "rb") as f:
key1 = f.read(16)
print("key1 =" + str(key1.hex()))请确保:
.py.vhd
位于同一目录下。
执行:
python calculate_iv.py程序会输出:
key1 = xxxxxxxxxxxxxxxx复制输出的 Key1。
随后重新打开 Bin 文件,将刚才写入的内容替换为 Key1。
第二次解密
再次执行:
fsdecrypt <PCB CODE>.bin 0x200000 <path/to/app> <out.vhd>至此即可获得最终解密完成的 VHD 文件。
文件提取
使用 R-Studio 打开镜像
打开 R-Studio:
- 点击左上角驱动器列表
- 选择「打开镜像」
- 加载解密得到的 VHD 文件
正常情况下,如果该 App 属于某个大版本的数据包,你应该能够看到:
internal_0如下图所示:

关于 internal\_1.vhd
这是很多人第一次解包时最容易遇到的问题。
如果打开镜像后发现出现的是:
internal_1.vhd通常说明当前数据包属于增量内容,而非完整数据包。
换句话说,它需要依赖上一大版本的数据才能正确读取。
解决方法
假设当前版本为:
1.41那么你还需要获取:
1.40对应的大版本 App。
随后:
- 解包 1.40 App
- 获取
internal_0.vhd - 打开当前版本的
internal_1.vhd - 在 R-Studio 中选择对应的
internal_0.vhd
完成后即可获得完整文件结构。
关于 OPT
opt的vhd解密方法和app完全一致,且不需要internal_0.vhd等其他文件,将vhd文件放入R-Studio就能得到opt的内容
脱壳
从 App 中提取出的游戏本体后,常见需要处理的文件包括:
AMDaemon.NET.dllAssembly-CSharp.dllamdaemon_api.dllamdaemon.exeSinmai.exe
不过建议先使用:
- Detect It Easy(DIE)
确认文件是否真的存在壳保护后再决定是否要脱壳。
常用工具
目前 CrackProof 相关保护已经有比较成熟的处理方案。
这里推荐两个工具:
Nyadecrypt
https://github.com/Naominet/Nyadecrypt
Senbei
https://github.com/Momoko-Ayase/Senbei
具体使用方式请参考各项目仓库中的 README 文档。
这里不再重复说明。
运行游戏
完成解包与脱壳后,如果需要运行游戏,还需要:
- Segatools
用于绕过游戏的机台环境检测。
这一部分先咕咕咕了吧,有空再写:P