游戏包文件结构分析
/ P, `6 ?' r8 V) S8 B地狱门神
! n1 B! ~3 }+ x. n9 L' ^ l0 D, `9 r5 p( Y: ^* h* ?6 \
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。
c* k6 D/ t8 G( y
% W* i$ E* B+ \' |声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。" X2 o/ j: w4 f- M. h3 ~, r* q: i
( N' f, d; O5 b) [# i4 G7 z
8 W7 x. z2 x" f, C9 o5 w9 L& f1.背景. O% _8 {* Z2 k9 i, k3 u
* x! p7 n. W; Y) m" }! ~
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。
8 V/ q6 E. ~' l+ ] l文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。0 l. \( K5 [5 w+ ? q% s
2 _& ~- H1 q6 F/ X% w+ f$ d+ `, H v" }8 Q2 w
2.包文件的共同特征3 I* h8 ~2 R! M1 E' g% {
8 r& h# l0 ~3 ]$ w4 x V7 e1 Q" c
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。
& G4 q- f9 \5 y, y- E这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。4 e* p& n) p( ]9 I2 O
其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。3 z+ T' h3 y% l8 K8 o
有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
$ d( Y# \4 V: s: p1 z! x- U: m2 V3 `6 x) k
$ g7 D5 y: e2 {1 n
3.本文需要用到的工具
+ N# \6 |/ O4 E, i7 K# r4 F3 E
7 S/ \$ F3 k F2 C+ mUltraEdit
/ T* o$ s9 i' i' O/ bVisual Studio/...或者其他任何可以用来编程的东西
# a& G4 V }% D9 d" b2 TWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)
3 C$ M A! V& F7 o/ \% U8 g7 p; _4 i0 V6 R% |' s& I
. a, ^$ j7 b+ l: ~4 }4.第一个例子——盟军敢死队2的PCK文件格式
. |. R; P$ {# [3 ^0 t' D# ~$ K6 U+ _2 \- L/ g1 N$ n$ j
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。
# ]0 T* o3 N: F; L6 Y2 _这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
- n" d9 ?0 m" R: I& b* U# t# V" `/ U1 T7 m1 r
用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。0 K x, U: B7 {- b
, b/ {# S; H! E& s) r% L* F如果你从来没分析过文件的二进制结构,也不要紧张。& D }% {+ n- N: V+ ?8 O/ |+ `: e
在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。
) U- Q. ^/ X; {8 O8 Q- _$ U
$ _( k; P# {% K: d( g往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。" [; i5 G" R8 c1 z
5 K+ _1 v% b- ^# I" d5 }* U
图1 盟军敢死队2 DATA.PCK文件头! H; ^, t, H& s) l, W
00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
* k+ V; O B; h3 t/ }00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
* G) z. x3 N7 a" a# \' y; D00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |