当前位置: 首页 > news >正文

3dsconv 使用教程:一个 Python 脚本,把 3DS 卡带镜像转成 CIA 安装包

3dsconv 使用教程:一个 Python 脚本,把 3DS 卡带镜像转成 CIA 安装包

【免费下载链接】3dsconvPython script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv

3dsconv 是一款用 Python 3 编写的开源小工具,能把任天堂 3DS 的卡带镜像文件(.3ds / .cci)一键转换成可以直接安装的 CIA 格式。本文从一个真实场景出发,带你从零跑通第一次转换,讲透加密检测、boot9.bin 配置和常见报错,新手也能在 10 分钟内上手。

从一堆"装不进去"的 3DS 镜像说起

想象这样一个下午:你翻出一个落灰的旧硬盘,里面整整齐齐躺着十几个.3ds文件——那是你早年用自制软件备份的 3DS 卡带镜像。你兴冲冲地把它们拷到 SD 卡上,准备装回主机重温,结果开机发现:根本装不了

这不是你的操作问题,而是格式问题。3DS 主机能识别的安装包是 CIA 格式(CTR Importable Archive,可以理解为"任天堂的数字安装包"),而卡带备份出来的镜像叫 CCI(CTR Cart Image,卡带原始镜像,扩展名通常是.3ds.cci)。两者结构完全不同,中间还隔着一道"加密"的坎。

这就是3dsconv存在的理由:一个命令行脚本,把 CCI 转成 CIA,顺便帮你处理加密问题。

先搞清楚它到底做了什么

3dsconv由开发者 ihaveamac 编写,以 MIT 许可证开源,整个项目只有一个核心文件3dsconv/3dsconv.py,加一个依赖库pyaes。它的定位非常纯粹:输入.3ds/.cci文件,输出可安装的.cia文件。

第一次接触 3DS 格式的人可能会被一堆缩写吓到,其实只需要记住这几件事:

缩写全称(人话版)在转换中的作用
CCI卡带镜像文件(.3ds/.cci)转换的输入
CIA数字安装包格式转换的输出,装进 3DS 用
NCSD卡带镜像的外层容器脚本靠它识别"这是个 CCI"
NCCH容器里的加密分区游戏本体就装在里面,也是加密/解密的主战场

一个诚实的提醒:3dsconv的作者在 README 里自己也说了,新版的 GodMode9、Decrypt9WIP 已经支持直接把卡带转储成 CIA,所以这个工具"部分过时"了。但如果你手里有现成的 .3ds 旧镜像,或者不想折腾自制系统的转储流程,它依然是最省事的批量转换方案。这正是它的价值所在。

第一次上手:三步跑通首个转换

第一步:拉代码 + 装依赖

git clone https://gitcode.com/gh_mirrors/3d/3dsconv cd 3dsconv pip install pyaes

pyaes是纯 Python 实现的 AES 加密库,负责解密环节。注意:如果你要转换的镜像本来就是未加密的,甚至可以跳过这一步,但建议还是装上,以防遇到加密镜像时抓瞎。

第二步:确认工具能用

不跟任何参数直接运行脚本,它会打印版本号和完整的帮助信息:

python3 3dsconv/3dsconv.py

正常的话你会看到类似这样的输出:

3dsconv.py ~ version 4.21 Convert Nintendo 3DS CCI (.3ds/.cci) to CIA Usage: 3dsconv.py [options] <game> [<game>...] Options: --output=<dir> - Save converted files in specified directory --boot9=<file> - Path to dump of ARM9 bootROM, protected or full --overwrite - Overwrite existing converted files ...

看到帮助信息,说明环境没问题。

第三步:转换第一个文件

python3 3dsconv/3dsconv.py my_game.3ds --output=cia_files/

这里有两个容易踩的细节,先记住:

  • --output=后面跟的是目录,不是文件名。转换结果会以"原文件名 + .cia"的形式保存在这个目录里,目录不存在会自动创建。
  • 必须写成--output=目录这种带等号的写法。如果你写成--output 目录-o 目录,脚本会把它当成"不存在的输入文件"直接报错(后面翻车现场还会提到)。

转换过程中会实时刷新一个进度条(百分比 + 字节数),结束后打印一句总结:

Done converting 1 out of 1 files.

如果一次有多个文件,直接并列写就行,还支持通配符批量匹配:

# 逐个列出 python3 3dsconv/3dsconv.py game1.3ds game2.3ds game3.3ds --output=cia_files/ # 或者用通配符一次扫完 python3 3dsconv/3dsconv.py "*.3ds" --output=cia_files/

看到这里,你已经完成了 90% 的日常使用。剩下需要关心的,就是"加密"这件事。

它凭什么能转换加密镜像?

3DS 的卡带镜像有三种状态,3dsconv自动识别,不需要你手动判断:

  1. 未加密(decrypted):最常见于 GodMode9 等工具转储后的文件,直接转换,零依赖。
  2. zerokey 加密:用的是一把全零密钥,3dsconv内置处理,同样不需要外部密钥文件。
  3. Original NCCH 加密(slot 0x2C):零售卡带的标准加密,需要一把特殊的密钥,而这把密钥藏在 3DS 主机的 ARM9 bootROM 里。

检测逻辑在源码里其实很短,大致是这样的(示意代码,非完整实现):

# 读取加密标志位 rom.seek(game_cxi_offset + 0x18F) encryption_bitmask = rom.read(1)[0] encrypted = not (encryption_bitmask & 0x4) zerokey_encrypted = encryption_bitmask & 0x1 if zerokey_encrypted: # 用全零密钥解密 key = zerokey elif encrypted: # 用从 boot9 里提取的密钥 + NCCH keyY 计算最终密钥 key = rol((rol(orig_ncch_key, 2, 128) ^ key_y) + 0x1FF9..., 87, 128)

所以处理加密镜像时,真正的问题是:去哪找 boot9.bin?3dsconv会按照固定顺序自动查找,找到即用:

查找顺序路径说明
1--boot9=参数指定的路径最高优先级
2当前目录下的boot9.bin完整版 bootROM
3当前目录下的boot9_prot.bin保护版 bootROM
4~/.3ds/boot9.bin用户目录下的完整版
5~/.3ds/boot9_prot.bin用户目录下的保护版

boot9 是 3DS 自制系统用户才有的东西:安装 boot9strap 后,开机按住START+SELECT+X就能在sdmc:/boot9strap/下导出。拿到文件后可以用 SHA256 校验一下是否完整(完整版boot9.bin的 SHA256 为2f88744feed717856386400a44bba4b9ca62e76a32c715d4f309c399bf28166f,保护版boot9_prot.bin7331f7edece3dd33f2ab4bd0b3a5d607229fd19212c10b734cedcaf78c1a7b98)。

除了解密,3dsconv在转换过程中还默默做了三件小事:

  • 哈希校验:逐块计算 SHA-256,并和镜像里的原始哈希比对,发现不一致会警告"文件可能损坏"。
  • ExtHeader 补丁:把可执行分区的扩展头打上补丁,让输出的 CIA 能被安装流程正常接受。
  • 图标提取:从 ExeFS 里把游戏的 SMDH 图标挖出来,写进 CIA 的 meta 区域,安装后能在主机菜单里看到正确的图标和标题。

进阶玩法:参数、环境变量与开发者模式

除了--output=3dsconv还提供了一批实用参数,全部在帮助信息里可见:

参数作用
--boot9=<file>手动指定 boot9 文件路径,优先级最高
--overwrite强制覆盖已存在的同名 CIA
--ignore-bad-hashes哈希校验失败也继续转换(慎用)
--ignore-encryption忽略加密标志位,按未加密处理(仅在你确定镜像实际未加密时使用)
--verbose打印详细信息:Title ID、各分区大小、密钥校验结果、各类哈希值
--dev-keys使用开发者主机(dev-unit)的密钥体系

两个进阶用法值得单独说:

1. 环境变量 BOOT9_PATH

如果你不想每次敲--boot9=,可以把路径写进环境变量:

export BOOT9_PATH="/path/to/your/boot9.bin"

之后运行脚本时会自动读取(优先级介于--boot9=和当前目录查找之间)。同理,把 boot9 放在~/.3ds/下也能被自动找到,一劳永逸。

2. 开发者版本游戏(--dev-keys)

某些用开发者密钥加密的标题(README 提到主要见于 SystemUpdater),需要用--dev-keys配合开发者证书链转换:

python3 3dsconv/3dsconv.py dev_game.3ds --dev-keys

脚本会按"当前目录 →~/.3ds/"的顺序查找certchain-dev.bin,找不到就报错退出。需要提醒的是:--dev-keys并不会改变输出的加密状态,转出来的 CIA 依然只能用开发机安装,不是给零售主机用的。如果你有开发者版 CIA,可以用ctrtool --certs=certchain-dev.bin title.cia把它里面的证书链提取出来。

新手最容易踩的 5 个坑

把这些报错背下来,你基本就不会卡壳了:

坑 1:加密相关功能全部失灵

Error: pyaes not found, encryption will not be supported Error: bootROM not found, encryption will not be supported

前者说明没装pyaespip install pyaes);后者说明没找到 boot9 文件。未加密镜像不受影响,加密镜像必须补齐这两样。

坑 2:文件名或参数写错

Error: "game.3ds" doesn't exist. Error: "-o" doesn't exist.

注意第二行的诡异报错——-o被当成文件了。记住:3dsconv只认--output=目录这种带等号的写法,不支持-o短参数。另外参数里如果带了通配符(比如*.3ds),在 shell 里最好加引号,避免被提前展开成不存在的路径。

坑 3:同名文件被拒绝

Error: "game.cia" already exists. Use `--overwrite' to force conversion.

输出目录里已有同名 CIA 时默认跳过,防止误覆盖。确认没问题就加--overwrite

坑 4:文件根本不是 CCI

Error: "xxx.bin" is not a CCI file (missing NCSD magic).

脚本会先检查文件头 0x100 处的NCSD魔数、再检查游戏分区里的NCCH魔数——连 3DS 的 NAND 备份(同样带 NCSD 头)都会被这道检查拦下来,避免误转换。报这个错说明你拿错了文件。

坑 5:哈希校验失败警告

This file may be corrupt (invalid ExtHeader hash). If you are certain that the rom is decrypted, use --ignore-encryption

这通常意味着镜像本身是未加密的,但头部标志位仍然写着"已加密",导致解密出来的数据对不上哈希。如果你能确认文件来源可靠,用--ignore-encryption--ignore-bad-hashes放行即可;如果文件是别人传的,先重新转储一次更稳妥。

收尾:合规提醒与延伸阅读

最后说几句掏心窝的话。

关于合规:请只转换你合法拥有的游戏备份,转换前后保留好原始文件,不要做任何形式的传播分发。3dsconv本身是 MIT 开源项目,工具无罪,但怎么用是每个人的选择。

关于原理:想深入研究的同学,整个转换逻辑都集中在 3dsconv/3dsconv.py 这一个文件里,代码风格相当直白。你可以顺着几条主线去读:开头是证书链和 ticket/tmd 的 base64 数据、中间是 NCSD/NCCH 头部解析与密钥计算(用到了rol循环移位)、后面是分区数据流式写出与三类 SHA-256 哈希的逐段更新。读懂它,你对 3DS 文件格式的理解会上一个台阶。

关于未来:由于 GodMode9 已经能直接产出 CIA,3dsconv的主要用武之地是"存量镜像"的批量化转换。但反过来看,也正是因为这种小工具的存在,才让很多玩家手里的旧备份重新变得可用。

现在,去把你的第一个.3ds文件拖进命令行试试吧。顺利的话,一杯咖啡的功夫,CIA 就能装进你的 3DS 了。

【免费下载链接】3dsconvPython script to convert Nintendo 3DS CCI (".cci", ".3ds") files to the CIA format项目地址: https://gitcode.com/gh_mirrors/3d/3dsconv

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

http://www.jsqmd.com/news/1398520/

相关文章:

  • 记录-boot项目校验字符串
  • 从零搭建蜜罐:T-Pot实战部署与威胁情报分析指南
  • x64汇编之堆栈工作原理理论篇
  • 从零构建AI Agent框架:深入解析ReAct循环、工具调用与长期记忆实现
  • Git高效合并远程代码与本地修改的实战指南
  • 从源码编译安装Nginx:定制化Web服务器的完整指南
  • Edge总卸不干净还自动装回?免费开源脚本EdgeRemover一次操作彻底移除
  • 青岛冷库聚氨酯保温喷涂企业,如何帮生鲜老板省下大笔电费? - 米諾
  • 同行申请近似商标,企业怎么提前发现?权大师把监测、风险判断和后续处理连起来 - 客啦啦视界
  • 电脑半夜像飞机起飞?5分钟用FanControl风扇控制把噪音摁下去
  • 免费获取网盘真实下载地址的 5 分钟上手路书:不装客户端,也能把文件交给专业下载器
  • 02.03.01.泛微OA Ecology10(创建连接ERP TipTop GP5.3的WebService接口)
  • 多物理场耦合仿真中的有限差分法应用与实践
  • 3步让Windows 10/11跑起经典DirectDraw老游戏:DDrawCompat免费兼容指南
  • 从零到一:用 diff-pdf 彻底解决 PDF 版本对比难题
  • 基于OpenClaw与RPA的滴滴司机位置查询智能体开发实战
  • 现代软件开发实践指南:AI 辅助编程、代码优化与架构设计
  • 2026年6月选购指南:工业液压配套服务商选择思路与参考
  • 2026年中华鸟巢酒 为大家带来诚意满满的高端庆功酒推荐 - 起跑123
  • 内存超频总蓝屏?用 ZenTimings 看清 Ryzen 时序、电压与频率的每一个细节
  • 深入解析CAS与自旋锁:从硬件指令到高并发编程核心
  • MTA: A Merge-then-Adapt Framework for Personalized Large Language Model
  • 2026 年上海优维智能科技:阳光房厂家直销的五大真相揭秘 - GrowthUME
  • 普通 PC 跑起 macOS:OpenCore 黑苹果从零到完美安装全攻略
  • Spark SQL中数据存储格式与压缩格式
  • 淘客工具箱:从选品到变现的实战工具系统搭建指南
  • (论文速读)C-GAN-VAE:行星变速箱少发细粒度跨域故障诊断的因果生成式对抗性变分自动编码器
  • PSO优化Kmeans在电力负荷分析中的应用与MATLAB实现
  • AI Agent白手起家16: DeepSeek云端部署与API调用实战指南
  • 如何零基础把飞书文档转成 Markdown:feishu2md 一条命令就够了