游戏包文件结构分析
: D+ |; ]$ M8 f: V6 Y, t地狱门神$ q8 [9 @3 G/ I
6 \! ^% A) ^& j" G- ]2 a1 h) B/ P摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。' I3 U! Y+ e& [# X" y5 `4 l8 ~
- ~* Q/ u0 Z% x声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。7 ]7 }: v; U. z# E, Q; O
& f" Z3 y8 u+ S0 |: F- {$ |
0 U b. k# I' X1 W, o# L! e1.背景7 O9 m6 i/ ]' `0 C2 N1 q% ]
9 D/ ~- |! K9 u2 a不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。4 n, G, _9 r6 R$ z
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。$ a Y6 Z# O. u3 o$ @ m! |
# D o" M3 {4 Q3 a4 B' o4 T, R6 K. @
/ W2 X2 D9 U( u' ]! ] C
2.包文件的共同特征* M3 L2 J8 @& {4 L
3 r' R4 F; R' M2 u' K" K7 b
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。
0 M9 \1 _/ ~% Z0 x4 `6 W# k, s这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。
( w5 } ]+ t( S1 }其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。+ \* B0 r/ y6 g5 S7 z# o) ~
有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
$ q) k$ u; L$ t. U
& M( F: ? Q* P% o. v! x+ o) c6 w" k7 g; z& M
3.本文需要用到的工具
_' O) J7 n& l/ Q( B7 g
6 U& e$ x. o& K2 t! X( q2 FUltraEdit
6 O, @3 _0 y' m7 i( P6 @8 oVisual Studio/...或者其他任何可以用来编程的东西
& G. u6 ~ ?+ V' {9 ~& G IWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个): S9 |' Q0 L' Y- e# g6 k& M3 f8 p8 h
7 ^9 c8 ]. p# z! m+ K" n# p, ?
9 @/ S' E# H& e2 o# e3 x4.第一个例子——盟军敢死队2的PCK文件格式$ s( y7 j, q2 e; [
8 x3 A6 p) |. e. }% ]( k
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。1 h V% e+ q, A7 s5 |
这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
7 e+ J3 s% W" [- o
6 f) T6 g8 i# r- _/ F4 O Y用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。
! J7 D, }, ?: \* r1 g% P* }6 _6 N. Z) m1 O9 ~8 v7 |
如果你从来没分析过文件的二进制结构,也不要紧张。
1 ~/ {& g1 b# k3 ~+ d8 |在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。/ n: U9 C4 c- a5 {
f" ~+ q- r Q/ E& s往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。
6 P( x9 T8 M! y, Z: o1 e) C
6 i2 {2 J% q4 l( G# K图1 盟军敢死队2 DATA.PCK文件头
8 L9 _" d6 y. _# p3 Q, M% }00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............9 t( S! z4 E5 \; t( D E! J/ ^
00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
9 y+ p* }+ I" B+ P1 G3 @$ j- ^$ g00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |