本文仅用于技术交流与学习探讨,请尊重相关版权。如本文内容涉及您的合法权益,请及时与我联系。

首先感谢 Azalea 的博客《Maimai 街机音游逆向!》。文中的大部分内容至今仍然有效,不过随着时间推移,其中部分步骤已经有了更加方便的替代方案。

由于我自己在折腾 Maimai App 解密与文件提取的过程中踩了不少坑,因此决定把整个流程重新整理一遍,希望能帮助后来者少走一些弯路。


准备工具

开始之前,你需要准备以下内容:

  • 待解密的 App 原包
  • fsdecrypt.exe
  • calculate_iv.py
  • RStudioPortable.exe
  • unsega.exe

其中:

  • fsdecrypt.exe
  • calculate_iv.py

均可从 SEGA Decryption Guide 获取。


推荐方案:使用 unsega 快速解密

如果你的目标只是获取 App 内部文件,那么推荐优先使用 unsega.exe

相比传统流程,它省去了手动获取 Key1、修改 Bin 文件等繁琐步骤。

使用方法

将 App 文件直接拖动到 unsega.exe 图标上即可。

程序会自动完成解密工作,并生成对应的 VHD 文件。

解密完成后,可以直接跳转至:

文件提取

传统方案:使用 fsdecrypt 手动解密

如果你希望了解解密流程,或者在使用 unsega 时遇到问题,可以使用传统方案。

获取 AES Key

首先需要一个包含 AES Key 的 Bin 文件。

如果暂时没有,可以尝试前往:

AES128\_Nu\_ALLS

查找对应版本的 Key 文件。

如果不确定应该选择哪个 Bin 文件,可以尝试从 App 文件名称中寻找对应版本信息。


修改 Bin 文件

使用十六进制编辑器打开 Bin 文件。

这里以 Sublime Text 为例:

可以从这里用16进制打开

在文件末尾换行写入:

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:

  1. 点击左上角驱动器列表
  2. 选择「打开镜像」
  3. 加载解密得到的 VHD 文件

正常情况下,如果该 App 属于某个大版本的数据包,你应该能够看到:

internal_0

如下图所示:

如果你的app文件是大版本更新的数据包,那么右侧应该为internal_0


关于 internal\_1.vhd

这是很多人第一次解包时最容易遇到的问题。

如果打开镜像后发现出现的是:

internal_1.vhd

通常说明当前数据包属于增量内容,而非完整数据包。

换句话说,它需要依赖上一大版本的数据才能正确读取。

解决方法

假设当前版本为:

1.41

那么你还需要获取:

1.40

对应的大版本 App。

随后:

  1. 解包 1.40 App
  2. 获取 internal_0.vhd
  3. 打开当前版本的 internal_1.vhd
  4. 在 R-Studio 中选择对应的 internal_0.vhd

完成后即可获得完整文件结构。

关于 OPT

opt的vhd解密方法和app完全一致,且不需要internal_0.vhd等其他文件,将vhd文件放入R-Studio就能得到opt的内容


脱壳

从 App 中提取出的游戏本体后,常见需要处理的文件包括:

  • AMDaemon.NET.dll
  • Assembly-CSharp.dll
  • amdaemon_api.dll
  • amdaemon.exe
  • Sinmai.exe

不过建议先使用:

  • Detect It Easy(DIE)

确认文件是否真的存在壳保护后再决定是否要脱壳。


常用工具

目前 CrackProof 相关保护已经有比较成熟的处理方案。

这里推荐两个工具:

Nyadecrypt

https://github.com/Naominet/Nyadecrypt

Senbei

https://github.com/Momoko-Ayase/Senbei

具体使用方式请参考各项目仓库中的 README 文档。

这里不再重复说明。


运行游戏

完成解包与脱壳后,如果需要运行游戏,还需要:

  • Segatools

用于绕过游戏的机台环境检测。

这一部分先咕咕咕了吧,有空再写:P

最后修改:2026 年 09 月 20 日
如果觉得我的文章对你有用,请随意赞赏