游戏包文件结构分析% P% |3 _/ |" C1 t3 @
地狱门神
5 Z2 F7 @& |2 x6 K2 f4 j% x8 x3 R& Q; H7 ?; Z+ Q. ~
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。0 F; `1 }5 O3 Q) f
8 o+ q" I. r. H4 U" K* J
声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。
9 S0 c7 h8 p' i+ }, g) ?$ h
2 _6 @ \$ r5 _# [
8 X, L6 A$ B7 ` h1.背景0 ]9 J' [! t# {' F; ^
; }) L1 x& A1 ]" J6 g
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。
3 F2 j9 D3 t) R' c" a4 B' T4 Z- \文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。9 h- S$ R: U) W8 ~0 G
3 B) z5 m4 |& @, e5 y
3 z# C& J4 o, f: b7 D% P2.包文件的共同特征
4 n! }. e2 y/ D! [* F8 ^0 x0 m, a" G% z
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。) x% G* M: R; M# p
这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。
0 p; u7 @# D* j其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
2 c4 [ a7 x9 E$ p" A有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
- B. q3 y4 W( g7 U+ V1 I1 H. d" y9 B+ Z/ ?+ c4 ]) M
5 u$ f$ H0 a* y% Y& _2 @3.本文需要用到的工具
5 B7 g3 v0 \' @ T
5 l1 q6 Q; |9 ^# {UltraEdit- _! ]% e9 e& U9 v0 g1 H/ c; n
Visual Studio/...或者其他任何可以用来编程的东西
5 U$ F2 |; X) w1 f1 QWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)
! D% Z$ O" t" j8 t. u
3 m4 q3 X% K& J1 z* e7 g$ h# }2 Q5 Y" h( d0 a
4.第一个例子——盟军敢死队2的PCK文件格式3 E4 v: s2 \3 O
# B3 M$ E# {2 l% T9 r7 Z这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。5 s5 P n3 t* f( n
这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
7 ]$ x: ` H, u* V! c* p, t
' O: _/ k, i7 A% j0 N2 C用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。
- V* w" m9 U2 [" n% ~# P- B! C4 v7 o C
如果你从来没分析过文件的二进制结构,也不要紧张。
# m3 G L3 }4 q M! v( r. ?0 k% r在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。
* j7 | a$ n$ Q+ _$ U2 I4 T: u, M/ T
往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。$ P* a v' j' u. ^: A) M) k
+ m$ y4 s8 \) y
图1 盟军敢死队2 DATA.PCK文件头
1 g9 b1 {8 }; {( a00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............! B" f8 `9 V1 a1 E7 s, x
00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................* c, l3 P& h8 Z
00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |