游戏包文件结构分析
- {! h2 O( Q3 X0 K- P. A地狱门神
9 ]8 Z# J) }. M! C! J' j f/ S4 u. c" i: B0 M4 Q
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。
) o; W" x/ J) s9 ~! {
' w( C2 B$ n$ H" q声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。) g4 T4 h% i7 q* Q# @; s; x
* G5 c4 @( f; u1 M/ L$ ^5 W$ w( S- e r6 O0 N K1 Z
1.背景
d( U8 }5 K/ y9 N9 a( V& E$ I6 t( ~8 k$ D2 Z8 J
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。/ Y4 G8 x/ \7 y% T3 ]5 X- v9 i7 T
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。
2 W# g" }+ {) i- Y. Z. b2 T: N4 z1 q$ W Q) v
+ L y/ m0 x( k y' P
2.包文件的共同特征
" e9 O9 B* p6 P: S4 Z" ]' L" [; u2 L0 ]5 x. V D
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。
6 c' D7 i( X! F" j( v% ?这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。
- e+ n9 t# q& u9 H其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
" M+ y6 [6 ~5 ^/ H0 m" [有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
) R( Z- u# N4 |% S7 [' F
& I3 J5 I8 t3 a) M0 R7 w' M& g* |4 S0 d" C4 ]
3.本文需要用到的工具( l9 i2 e. A' h: T
; z$ V/ v* M2 f# X
UltraEdit( d6 z% R- j) N6 I
Visual Studio/...或者其他任何可以用来编程的东西
& O5 j2 Y' b8 N3 A7 E6 B# cWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)
% p6 U% \" n& E, G/ l/ u
; {# ]9 A5 d P1 e9 H1 e- _$ D5 E3 a( t" H& S M0 A2 }
4.第一个例子——盟军敢死队2的PCK文件格式. I% F# Y- R( f) V* |1 o) [
# b& ]9 A8 |* W& P. @
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。
, Q, ?! B4 v8 L0 Y2 F这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
; e! p& d# j0 H0 D5 j5 Q
% D1 j: K( G$ w9 E# c9 T用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。6 y& i+ o0 r1 G4 g9 |- t, n ~, A
0 T) f2 n+ ~1 z
如果你从来没分析过文件的二进制结构,也不要紧张。. z0 f8 m, d5 L- O" Q1 R o
在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。) k {) }6 l* E F9 c9 w
2 Y4 |- w1 }+ _% L0 c+ O, ]2 E4 q) w6 f往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。
7 b C$ X) l" E4 n/ D0 i: G( W( I! R: m2 F
图1 盟军敢死队2 DATA.PCK文件头" {$ j9 K9 g) I' T; W9 N
00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
2 f y6 L/ \: @00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
' x4 B& L! ^/ U% }1 ]: { h+ ]. ^00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |