游戏包文件结构分析. D( s. A# H: T7 J2 u. S
地狱门神# F3 W1 ?4 y4 e6 f0 c
, ~# N& `" r' g# |$ ?: k+ }
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。' A% a$ Z, A+ _' S) z2 ^/ s7 W
* X2 j- ^% N( Q% v1 t声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。
J/ x7 s4 y: X9 ]3 d; |
5 X: {8 E, E& b; |6 ?: ~, D
! c3 I4 s* R$ b1 B# N, H2 ?1.背景
. n$ M4 c' i! a: Q# \" X1 D$ r! L( i* c" a! ~8 c$ f6 b8 W2 m
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。
5 w+ s0 m" z) b3 p/ ? d* ^文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。: ] w1 t P, d8 Q
/ M3 D* U* ]" v* m
2 b! Q( n/ ~2 g& _9 M' n2.包文件的共同特征2 t) |0 T9 o$ Q; s; r+ y) O
1 w$ Q$ i4 B" C6 Z
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。' U$ |# j( F* x" A
这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。: V% K Z$ V9 s* Z @
其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
7 j7 M* Q! S" g有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。2 l) B: \3 i, o7 X
( L, A. g5 p" U& e6 S
" f: J, a+ U' Z% K- N& I; [3.本文需要用到的工具7 I9 P8 t0 U5 Y: i
A6 Z; s* F, [+ S+ ]( WUltraEdit9 j+ q% G9 X5 ~
Visual Studio/...或者其他任何可以用来编程的东西
% r2 ]% S- D. g2 tWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)- o4 |. p* f7 W3 u: V3 \
( J1 M9 h V: E O& u
7 \% Y& `: X+ r( n$ n' m4.第一个例子——盟军敢死队2的PCK文件格式- I# h. \6 X; Q/ a! z' v/ t
% C' P% w% Z1 }+ X' p' e" L- R这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。
+ n9 ^, r* N5 m这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。6 M' y, c+ U" Z4 k
# w L# N! r, M y: g$ N$ o7 t! V; l; z9 E
用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。; ^4 ~5 e1 S; }+ w
" I5 t2 @$ s D1 W# A% g+ V如果你从来没分析过文件的二进制结构,也不要紧张。
: F% { m t3 U在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。% k( K: w% p/ j9 A
( w2 C8 g, I: x* E$ x! R0 c往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。2 D' K5 q6 I2 J0 N' Q) E
% v$ T/ m# O1 j( j5 I8 D图1 盟军敢死队2 DATA.PCK文件头
- z3 U4 ~- G/ h% C# |$ E00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............% c$ N7 J( _) b6 v$ _
00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
! ]: s- j/ H0 h: B00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |