游戏包文件结构分析6 G* F6 ~; ~' I: b8 Z- D
地狱门神
# o9 K9 P( J; \# |% v$ N! C- ], [! X: W# t7 C
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。( w& Y y/ p9 F7 P# C5 M
1 M, z8 Y! `$ l. O! i, S8 d
声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。
: @' m; P0 Q+ Q
3 @- D8 `. Q. F( v4 m7 N" p" Q0 k# M# p
1.背景6 c6 O2 B4 `, ~: P
4 i' A9 X7 `- ]
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。& k2 {5 b0 ?6 h' ^6 o
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。
5 ^5 o! U! @7 l* _! c- s) H, x/ _+ V5 r9 h( E; E6 F
& |! q$ p" y% b: z! ^& {& q: a
2.包文件的共同特征* }/ ^/ |* ^) y! _/ J/ `3 y
9 D( W/ H( R& A1 O
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。
9 t0 ^6 e7 K! Z' Z. M4 H这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。1 S, i6 ^4 _/ W$ l
其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
: e* `9 h5 ?6 H5 c& ~ U: R有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。8 b% {- J+ d- E3 [& a
( y+ e3 d9 L- }9 q! u3 q/ e3 u, i+ L$ b
3.本文需要用到的工具2 R1 \- ` B, F- d8 N1 A9 ~
* O3 N7 Q) y) s$ {; f# aUltraEdit
- c4 p |# T1 n. a. `$ e! XVisual Studio/...或者其他任何可以用来编程的东西4 k# f4 j5 r, i* G& ~! X6 q5 |. N
Windows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)! b, ]; ` m# z
$ o6 \; T5 m! l( Q4 Z% B1 v; ~' z- S [7 v+ D' b$ h
4.第一个例子——盟军敢死队2的PCK文件格式
) b2 q+ ]8 z& o* a/ X! J1 V' B" e" }4 W' G$ g. N6 }6 y
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。6 S9 X% S4 b) {5 y
这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
0 q; x4 I D" E* W* Q, U N$ T' O
" H6 a5 _9 ?9 G/ |- o# M0 r用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。
; V" V2 j$ G5 Z E, ~. U9 C; U, ?2 C4 |5 Y, r, H, r2 I
如果你从来没分析过文件的二进制结构,也不要紧张。
, M0 K2 w4 }+ S! P& F2 J在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。
& @! z, g! D% v" c/ `) n7 ~
$ l$ h: B* R( o: I: x往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。
z% a) t6 r9 O! z% H( G1 ]4 P% ] i4 r
图1 盟军敢死队2 DATA.PCK文件头* I3 P0 n: i' h' w# H& x' `
00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
' p& [7 ~& L/ A+ n! `( I: f1 O00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
- T) l( E2 L& V$ |2 D5 M00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |