前言
在数个月之前,完成了OjoDnfExtractor的开发,该软件用于提取Dnf的资源包文件。
在做Dnf这些资源包文件的解析过程中,我明白了文件结构该如何设计。(也尝试了去设计文件结构)
经过多番观察、推测,成功解析了NPK以及IMG-Ver1、2、4、5、6的文件结构(支持读写)。
正文
npk文件是dnf用于模拟文件目录结构所使用的,结构相对简单。
为了直观的展示其结构,直接插图。
Color | Name | Type | Remark |
---|---|---|---|
红色 | magic | char[16] | 文件标识 |
橙色 | count | int | 文件数量 |
黄色 | offset | int | 文件偏移 |
绿色 | size | int | 文件尺寸 |
青色 | name | char[256] | 文件名,加密过 |
蓝色 | hash | byte[32] | 文件头哈希值(sha256) |
# magic值
FILE_MAGIC = 'NeoplePack_Bill'
# 文件名加解密密钥
C_DECORD_FLAG = bytes('puchikon@neople dungeon and fighter %s\x00' % ('DNF' * 73), encoding='ascii')
由此可见,npk首先是由头部的magic进行验证是否为npk文件。
-
然后通过count取得文件数量,循环加载offset、size、name这些信息(三位一体)。
- 文件名加解密:使用密钥对文件名数据每一位进行位异或运算。(euc-kr编码)
-
加载完成后,通过hash可以对文件头部进行验证(毕竟都是关键信息)。
-
hash计算:取文件头数据左边,长度为整除17位再乘17位的部分,进行sha256运算。
hashlib.sha256(head_data[:len(head_data) // 17 * 17]).digest()
-
一般读取完成头部信息+hash值之后,当前位置就是文件数据了(file[0]['offset']),如前面的图所示,后面就是IMG文件的magic了。
当得到这些信息之后,即可通过offset以及size读取对应img/ogg文件了。
结语
有以上的信息,要实现npk的读写,已经是轻而易举了。
原来是打算一次写完的,不过当我写完NPK篇就已经花了不少时间,所以有空再更新IMG篇。