
一条命令解开网易游戏的 NPK 资源包unnpk 解包工具原理与实战【免费下载链接】unnpk解包网易游戏NeoX引擎NPK文件如阴阳师、魔法禁书目录。项目地址: https://gitcode.com/gh_mirrors/un/unnpk从游戏客户端里拷出的资源包file命令只回你一个冰冷的datahexdump 前几百字节毫无规律翻遍网络也找不到格式文档——这是每个想做 MOD、搞逆向研究的人都会撞上的第一堵墙。unnpk 就是为网易 NeoX 引擎 NPK 文件而生的解包工具阴阳师、魔法禁书目录这些游戏打包的资源一条命令就能拆回原形。这篇文章不罗列 API而是带你把 NPK 的格式谜题当案件来破最后用三步把阴阳师的加密脚本还原成可读的 Python 源码。破解之旅一份没有文档的二进制格式拿到一个未知格式的二进制文件第一步永远是找目录。书的目录通常在开头或结尾游戏资源包也一样。用十六进制编辑器扫过 NPK 的文件头你会发现在 0x14 这个固定偏移处存着一个 4 字节整数它指向的正是索引表作者称之为 map的起始位置// 读取map偏移量 fseek(npk, 0x14, SEEK_SET); uint32_t map_offset; fread(map_offset, 4, 1, npk);为什么是固定偏移这是引擎的取舍加载资源时只需读一次文件头就能以 O(1) 的代价拿到整张索引表的入口不必扫描全文件去猜结构。对一款要高频加载资源的游戏来说这个固定入口把定位成本压到了最低。线索一28 字节一条的索引记录拿到 map_offset 之后unnpk 从那里开始每隔 28 字节7 个 uint32读一条记录一直读到文件末尾——也就是说这张索引表铺满了文件尾部一整块区域数据区在前索引区在后for (int file_offset map_offset; file_offset npk_size; file_offset 7 * 4) { fseek(npk, file_offset, SEEK_SET); fread(file_info, 4, 7, npk); // ... }每条记录的信息密度相当高字段含义file_info[0]索引号解包后用作文件名file_info[1]数据在文件中的偏移file_info[2]压缩后大小file_info[3]解压后大小file_info[4] / [5]两个校验值file_info[6]是否压缩的标志注意到没有索引表里根本没有文件名。游戏运行时靠索引号直接寻址资源而不是靠路径字符串——省空间、省字符串比较还天然防窥探。代价就是解包之后你得到的是清一色的 8 位十六进制编号比如FB54F059unnpk 输出文件的命名就是这么来的。线索二压缩判定与宁可错杀的容错哲学有了偏移和大小理论上就能切数据了。但解包工具很快撞上第二个问题数据不一定是原始字节。unnpk 的判断很朴素——标志位为真或者压缩前后大小对不上就按 zlib 解压// file_info[2] 和 file_info[3] 大小不匹配说明数据压缩了 if (file_info[6] || file_info[2] ! file_info[3])更体现作者风格的是解压失败时的处理遇到Z_DATA_ERROR数据根本不是 zlib或Z_BUF_ERROR时它不报错退出而是把原始字节原样写出去只在控制台留一句警告。这个设计很聪明——索引表可能因游戏版本差异而有偏差硬解压只会让整个任务崩掉先把原始数据给你至少还能用别的工具继续分析不至于一无所获。线索三没有名字的文件怎么知道它是什么这是整个解包体验的关键。资源包里贴着图、装着模型、塞着 shader、躺着脚本和配置 XML……没有文件名和扩展名谁来认领它们unnpk 的答案是双保险先用 libmagic 按魔数识别出 MIME 类型再用内容特征签名兜底。magic_t cookie magic_open(MAGIC_MIME_TYPE); magic_load(cookie, NULL); file_out_type (char *)magic_buffer(cookie, file_out_buf, file_info[3]);MIME 能认出 png、jpg、mp4、zip、ttf、xls却认不出游戏特有的东西。于是代码里还藏着一串指纹匹配魔数KTX、RGIS、PKM这类移动端 GPU 纹理格式NeoX、FxGroup、SceneConfig这类引擎自定义 XML靠关键字vec4、tex2D判定的 GLSL shader靠v / vt / f行判定的 OBJ 模型。最终结果按 MIME 类型分文件夹存放文件名带上类型缩写大致长这样extracted/image/png/12345678.png extracted/text/plain/87654321.txt项目背后一场从 script.npk 开始的逆向长跑unnpk 不是实验室里的格式研究玩具它的出生点非常具体解开阴阳师的script.npk。项目 README 记录了完整战斗过程几个细节很能说明问题。网易的加密脚本不是简单异或。tools/script_redirect.py还原出的算法是三层叠加先用 Python 2 的rotor流加密密钥由asdf_dn、asdf_dt、asdf_df三段拼接而成再 zlib 压缩最后字节反转并异或 154。更妙的是解密所需的关键文件redirect.pyc本身就藏在script.npk里2018-03-27 的 3.0.3(1) 版本对应索引FB54F059——这把加密锁的钥匙居然就放在锁旁边。随后是字节码层面。pyc_decryptor.py的核心是一张 opcode 映射表把被混淆的指令逐一换回 Python 2.7 的标准指令再靠自研的pymarshal.pyPython marshal 模块的增强版重新序列化出合法的 .pyc 文件最后交给 uncompyle2 反编译。作者选择用纯 C 实现主工具依赖只有 zlib 和 libmagic——两个源文件、一个 Makefile干净利落。这种够用就好的克制恰恰是逆向工具最稀缺的品质依赖越少坑越少在别人的机器上越容易跑起来。上手体验编译、解包、解密三步跑通一条命令完成解包先装依赖macOS 用brew install libmagicCentOS 用yum install file-libs file-devel然后git clone https://gitcode.com/gh_mirrors/un/unnpk cd unnpk make编译产出两个可执行文件unnpk和mapnpk。解包只要一条命令./unnpk script.npk extracted终端会打印一张表格列出每个文件的索引、偏移、大小、是否压缩、MIME 类型和扩展名解包结果自动按类型归类。从加密字节到可读源码阴阳师脚本三步解密拿解包出的某个加密脚本文件README 里以0A0D60DC为例走完三步# 第一步rotor 解密 → zlib 解压 → 反转异或 ./tools/script_redirect.py 0A0D60DC 0A0D60DC.out # 第二步纠正被混淆的 opcode还原出标准 .pyc ./tools/pyc_decryptor.py 0A0D60DC.out 0A0D60DC.pyc # 第三步反编译成可读 Python 源码 uncompyle2 -o 0A0D60DC.py 0A0D60DC.pyc注意script_redirect.py和pyc_decryptor.py依赖 Python 2 生态rotor库、uncompyle2这是网易当年技术栈决定的属于历史包袱别拿 Python 3 硬跑。把 NPK 结构看个通透mapnpk如果只想先看懂一个包再决定怎么解用配套的结构分析工具 mapnpk 更合适./mapnpk -f csv -t int script.npk structure.csv-f选 markdown 或 csv 输出格式-t选 hex、int 或 original原始字节序展示数值-o可指定输出文件。对逆向分析来说csv 格式直接喂给脚本做批量处理非常顺手。避坑指南你大概率会踩的坑Python 2 依赖是最大的坑。rotor是 Python 2 专属库uncompyle2也只认 2.7 的字节码。先装好 Python 2.7 环境再跑解密链别在 Python 3 上浪费时间。asdf_dn/asdf_dt/asdf_df可能因游戏而异。README 明确提醒网易其他游戏的这三个参数可能不同也有可能相同。解别的游戏失败时先怀疑密钥而不是怀疑工具。opcode 映射表有版本限制。pyc_decryptor.py里的映射针对特定 Python 2.7 变体换游戏、换客户端版本指令集可能对不上需要自己重新整理映射关系。索引表可能不准。看到Z_DATA_ERROR警告别慌这是 unnpk 故意为之的容错——版本差异会让大小字段对不上但它会输出原始字节往往还能救回来。别在 Windows 上折腾。README 的原话是不建议使用 Windows 太折腾了libmagic 的安装、路径处理都够喝一壶macOS / Linux 顺畅得多。还能怎么玩从解包到再造游戏 MOD 与本地化是最常见的玩法把 XML 配置、文本资源解出来修改再回填。解包只是第一步回包通常要自己写工具此时 mapnpk 输出的 csv 结构表就是最好的参考。资源格式研究同样大有可为。KTX、RGIS、PKM 这些移动端纹理格式NeoX 自定义 XML、GLSL shader解出来就是一份现成的格式标本库研究手游渲染管线会非常顺手。说到底unnpk 教给我们的不是怎么抄一个解包器而是一套可迁移的思路任何没有文档的二进制格式都可以从找目录开始。下次再遇到打不开的资源包先别急着放弃——hexdump 扫一遍找找那个指向索引表的固定偏移说不定下一个解包工具就是你写的。【免费下载链接】unnpk解包网易游戏NeoX引擎NPK文件如阴阳师、魔法禁书目录。项目地址: https://gitcode.com/gh_mirrors/un/unnpk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考