游戏包文件结构分析
2 |" b* J0 F! N地狱门神; ]% h4 Q4 l! j. u
2 `: ?3 y* e( l0 W" F6 V摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。6 z; D1 l% M, [: ~- J
8 t; Q4 _2 `1 C" b
声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。0 B- H6 _4 a/ e$ j5 V4 N2 n
% ]- h. o+ z* h6 v+ G3 X# ^$ j/ D" y) u) t, L, T; J
1.背景
5 y7 b& Z9 W+ F6 F y4 ^
4 d8 | b5 f, G* Y( t, D8 |不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。' w+ H" ~+ ]' b5 }+ [8 `: r' R" J$ Y
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。0 ^1 e0 K4 L+ K1 H2 _: X
5 B. l5 z1 [) Z" c
3 h$ ]' k3 m; R6 s( p' d7 T; a1 R
2.包文件的共同特征 P. r/ H6 A9 J7 n
; S' W9 p! B2 k* h7 l* Z( E
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。: U$ X* N7 Y- E2 p! R$ y
这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。" B" T# q- ?9 J9 E
其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
" t' p$ |3 q! H5 j: ~- f有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
" ~( d8 D" N& _+ H. f: i2 P
$ w7 h) x4 t! ]* a7 y( I0 D5 K2 P# Z) n- S& Q
3.本文需要用到的工具% R5 e! C/ \2 e- p. B1 J! N
" J; e4 C9 b2 G, B/ }$ rUltraEdit+ v ?# g: t* K0 ~# c+ n
Visual Studio/...或者其他任何可以用来编程的东西
/ h& A0 ~3 V- }* w! d) `$ PWindows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)
( ~. u2 y) V i* v2 Z7 D; l6 |$ c( j, j1 Z& V2 C
% u# T1 ~9 j% O }
4.第一个例子——盟军敢死队2的PCK文件格式
" l& d( I# @ n! @1 U/ m
) @, l$ T2 i% x3 U/ v这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。. ~+ V0 {: K3 _% ]5 }
这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。
! P' U; J3 H0 w9 F: \/ K+ R9 H
9 ]$ q$ i+ k" q: G Q) D6 l6 d8 X9 x用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。& N" ~' [1 J0 A
7 H" Z; n, _ E: y. a' r4 i/ b如果你从来没分析过文件的二进制结构,也不要紧张。) O0 I* F e! {! v3 h
在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。
: f3 K. H9 Y" U. ]# G4 Q5 S) p" Y4 Q; I& q1 A( x% {. V
往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。
2 i8 u8 g7 O/ ]: H# v6 P
6 k8 m. l- j6 _7 Q: ]) O2 v图1 盟军敢死队2 DATA.PCK文件头
) w* W" D; g; l# T4 {( b00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
% S8 a, r; J, r$ q7 }) x00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................" t3 f4 \! ]5 ]' n! a
00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |