一次搞定网易游戏资源提取:unnpk 解包 NeoX 引擎 NPK 文件实战指南
【免费下载链接】unnpk解包网易游戏NeoX引擎NPK文件,如阴阳师、魔法禁书目录。项目地址: https://gitcode.com/gh_mirrors/un/unnpk
想从游戏包里抠几张立绘、研究一段掉落表逻辑,结果 .npk 文件在解压软件里全显示成乱码?开源工具 unn</||DSML||parameter> pk 就是为解包网易 NeoX 引擎 NPK 资源包而生的。这篇文章我会用自己实际踩坑的经历,带你从零跑通解包、结构分析、脚本解密和批量处理的完整链路,新手也能照着做。
从一次"全军覆没"的解压开始
我最初的动机很朴素:想研究一下某款手游的美术资源是怎么组织的。拿到手的是一个几百 MB 的.npk文件,file命令只告诉我"data",WinRAR 打不开,7-Zip 也打不开,连xxd看开头都只有一串看不懂的魔数。折腾了大半夜,差点就准备自己写解析器了。
后来在社区里看到有人提到 unn</||DSML||parameter> pk——一个专为网易 NeoX 引擎 NPK 文件编写的解包工具,支持阴阳师、魔法禁书目录等游戏的资源包。编译完一试,一条命令就把包拆开了,文件还自动按类型分好了类。那一刻的爽感,值得写篇文章分享出来。
初次见面:unnnpk 到底帮我干了什么
这个项目很小,但分工很清晰,一共就两块:
- unnpk:主解包程序,负责读取 NPK、还原压缩数据、按类型归类输出;
- mapnpk:只读分析器,把包里的文件清单、偏移量、压缩状态打印成表格,方便你解包前"侦察";
- tools/ 下的三个 Python 脚本:针对脚本类资源(如阴阳师的 script.npk)做二次解密,这是普通解包器做不到的。
它适合三类人:想提取素材做 MOD 的玩家、想研究私有文件格式的开发者、以及刚入门逆向想找个真实练手对象的爱好者。不需要懂太多前置知识,能敲命令就行。
三步环境配置,五分钟跑通第一个解包
先装好一个依赖:libmagic
unnnpk 靠 libmagic 识别文件类型,不同系统装法不一样:
# macOS brew install libmagic # CentOS / RHEL sudo yum install file-libs file-devel # Debian / Ubuntu sudo apt-get install libmagic-dev编译
克隆仓库后一条make搞定,编译需要 gcc 和 zlib:
git clone https://gitcode.com/gh_mirrors/un/unnpk cd unnpk make编译成功后目录里会出现unnpk和mapnpk两个可执行文件。
第一个解包案例
用法就一行,两个参数:NPK 文件路径 + 输出目录:
./unnpk yys_assets.npk extracted/预期输出:终端会打印一张文件清单表格,同时extracted/目录下出现按 MIME 类型分类的子目录,像这样:
extracted/ ├── image/png/00000001.png ├── image/jpeg/0000002A.jpg ├── application/zip/0000005C.zip └── text/plain/000000F3.txt有两个细节值得注意:
- 解出来的文件没有原始文件名,用的是 8 位十六进制索引(比如
0A0D60DC),这是 NPK 格式本身就不存文件名的缘故; - 压缩数据会自动用 zlib 还原,遇到损坏或非 zlib 数据时,工具会把原始字节原样吐出来,而不是直接报错终止——这种降级策略在解包工具里很实用。
动手前先侦察:用 mapnpk 把包看个底朝天
第一次解包 500MB 的资源包,我连里面有什么都不知道。后来养成了习惯:先mapnpk看一眼,再决定要不要解。
./mapnpk -i yys_assets.npk它会输出包的总体信息和每个文件的索引、偏移量、压缩前后大小、校验位、是否压缩。支持导出 Markdown 表格或 CSV,数值也支持十六进制/十进制/原始字节三种显示方式:
# 导出 CSV,方便丢进表格软件里筛选 ./mapnpk -i yys_assets.npk -f csv -t int > file_list.csv # 十六进制查看偏移,方便配合十六进制编辑器核对 ./mapnpk -i yys_assets.npk -t hex预期输出(示意):
# mapnpk! File size: 58234168 Byte Map offset: 0x00000024 | Index | Offset | Size (Byte) | Unzip size (Byte) | Chk | Unzip Chk | Is zip | | --- | --- | --- | --- | --- | --- | --- | | 0x00000001 | 0x00000038 | 0x00000A5C | 0x00002541 | 0x00000000 | 0x00000000 | Yes |看到Is zip列是Yes,说明对应文件在包里是压缩存储的;Size和Unzip size差距越大,压缩收益越高。这一手在判断"哪些文件值得提取、包有多大水分"时特别好用。
重头戏:阴阳师 script.npk 的脚本解密流水线
如果你只是想要图片和音频,上面两步就够了。但如果你想要的是游戏脚本源码(比如掉落概率、活动逻辑),就得走完一整条解密链路。我以阴阳师的script.npk为例,这是我认为这个项目最有含金量的部分。
整个流程分四步:解包 → 解密脚本 → 修正字节码 → 反编译。
第一步:解出脚本文件
./unnpk script.npk script_raw/解开后你会发现很多没有扩展名的文件,因为脚本的二进制内容既不是图片也不是文本,无法被类型识别命中。
第二步:rotor + zlib + 字节反转
拿其中一个文件(比如0A0D60DC)跑 tools/script_redirect.py:
python tools/script_redirect.py script_raw/0A0D60DC > 0A0D60DC.dec这个脚本是作者逆向阴阳师官方redirect.py后改写出来的,内部做了三件事:
# 伪代码示意,完整逻辑见 tools/script_redirect.py data = rotor.newrotor(密钥).decrypt(data) # 1. ROTOR 流式解密 data = zlib.decompress(data) # 2. 解压 data = 反转并异或(data) # 3. 字节反转 + 异或 154密钥由asdf_dn、asdf_dt、asdf_df三段常量拼接而成,不同游戏可能不同。这点很关键,后面会再讲。
第三步:修正 opcode
0A0D60DC.dec已经是 Python 2.7 的 pyc 内容了,但还不能直接用,因为字节码的 opcode 被映射过(指令码被换成了一套自定义编号)。跑 tools/pyc_decryptor.py 把它映射回去:
python tools/pyc_decryptor.py 0A0D60DC.dec 0A0D60DC.pyc这个脚本依赖同目录下的 tools/pymarshal.py——一个自己实现的 Python marshal 序列化器,用来在读出 code 对象后重写co_code字节码。如果你对 Python 字节码格式好奇,这个文件本身就是很好的教材。
第四步:反编译成源码
uncompyle2 -o 0A0D60DC.py 0A0D60DC.pyc到这里,加密的脚本就变成了可以阅读的 Python 源码。
💡技术提示:解密用的
redirect.pyc其实就藏在script.npk里(某个版本对应FB54F059这个文件),文件名即它在包中的偏移量。想适配其他网易游戏,可以按 README 里描述的思路,先解包、再根据特征定位 redirect.pyc、提取出asdf_dn等密钥常量,就能复用整条流水线。
把解包变成流水线:批量处理与按需筛选
游戏更新很频繁,每次版本变更都要重新解包。手敲命令太傻,我写了个几行的批量脚本:
#!/bin/bash # 批量解包当前目录下所有 .npk for pkg in *.npk; do [ -e "$pkg" ] || continue out="${pkg%.npk}_out" mkdir -p "$out" echo "[*] 处理 $pkg ..." ./unnpk "$pkg" "$out" || echo "[!] $pkg 解包失败,继续下一个" done磁盘够快的话,用xargs并行更省时间:
ls *.npk | xargs -P 4 -I {} ./unnpk {} "{}.out"按需提取的思路则是:先用mapnpk导出 CSV,再用awk筛选出目标条目,只解感兴趣的包,避免全量解包浪费时间。
新手最容易搞错的四件事
误区一:以为 unnpk 能解所有网易游戏。不是的。NPK 外壳是统一的,但脚本层的加密参数因游戏而异。解图片音频大概率没问题,解脚本就要自己去找对应密钥了。
误区二:把 mapnpk 当成解包工具。它只读不写,负责输出清单和分析报告,解包请认准unnpk。这两个名字相似,别搞混。
误区三:以为解出来的 pyc 能直接跑。不行,脚本 pyc 的 opcode 被篡改过,必须先过pyc_decryptor修正,再补上标准 pyc 文件头,才能交给反编译器。
误区四:看到Z_BUF_ERROR/Z_DATA_ERROR就以为失败了。这其实是工具的容错设计:遇到无法解压的数据,它会保留原始字节原样输出,方便你后续自己研究,而不是让整个解包流程崩溃。
另外提醒一句:README 作者明确说 Windows 上"太折腾",建议用 macOS / FreeBSD / Linux 环境跑这套工具链。
源码里值得偷师的几手
unnpk.c只有一个文件、三百行左右,很适合当二进制解析的入门读物。几个亮点:
- 定位索引区:文件偏移
0x14处存着索引区起始位置,读完就得到文件清单; - 定长记录:每个文件一条 28 字节记录(7 个
uint32),分别存索引、偏移、压缩前后大小、校验位和压缩标志,结构简单到可以手推; - 类型嗅探:先用 libmagic 判断 MIME,再结合魔数(
KTX、RGIS、PKM)和文本特征(<NeoX、vec4、v / vt / f)推断出 ktx、glsl、obj 等格式,这套"内容识别"思路可以直接迁移到别的解析项目里。
二次开发的方向也很明确:往扩展名判断分支里加你关心的新格式;或者给脚本解密链写个一键化的 shell 封装;想做得更友好,还可以用 Python/Tk 套一层图形界面,把unnpk当子进程调用。
生态与同类工具对比
和那些动辄几万 star 的通用解包框架比,unnnpk 属于"小而美"的典型:两个 C 程序加三个 Python 脚本,没有花哨的 UI,但把特定场景做到了极致。横向对比一下:
| 方案 | 上手成本 | 对 NPK 的适配 | 脚本二次解密 | 适合谁 |
|---|---|---|---|---|
| unnpk | 低,一条命令 | 专为 NeoX 设计 | 自带工具链 | 想快速拿资源的玩家和开发者 |
| 通用解包框架 | 中高 | 不识别私有格式 | 无 | 处理通用格式的场景 |
| 自己写解析器 | 高 | 完全可控 | 自研 | 想深挖格式原理的逆向爱好者 |
README 用中文撰写,作者明确欢迎 PR 补充内容,社区研究脉络(比如当年 fate0 公开的阴阳师脚本解密思路)也直接写进了文档里。项目更新不算频繁,但作为格式研究案例,它的价值不在于版本迭代速度,而在于把一条完整的逆向链路浓缩成了可复现的步骤。
结语
从一个打不开的.npk开始,到脚本源码摆在眼前,中间只隔着一串命令和几段可读性很好的 C 代码。下次再遇到打不开的资源包,先别急着放弃——解包工具的思路,往往比工具本身更值钱。
📖延伸阅读:跑通
script.npk流水线后,建议再读一遍 README.md 里关于定位redirect.pyc的说明,那一段藏着适配其他网易游戏的钥匙;也欢迎把新游戏的适配经验以 PR 形式回馈给项目。
【免费下载链接】unnpk解包网易游戏NeoX引擎NPK文件,如阴阳师、魔法禁书目录。项目地址: https://gitcode.com/gh_mirrors/un/unnpk
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考