游戏包文件结构分析 Y: G( a; D* K
地狱门神
5 o- H3 d$ b4 }) ]
0 k& e2 ~: D, Z* D0 q0 W; ^. N0 \摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。
4 j" s/ |1 n- _ O& G e A
" q/ M: J: i( {1 B+ m" x声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。& l$ ~1 x5 Z6 G: s: y; J
) _. k( |- V `2 X
" U# K4 A4 n& D! [1.背景
$ J) G! I8 z3 v7 A, M
) q0 l: C5 m; _0 X; h0 ?不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。- B+ e9 F7 O8 e4 B5 B+ H
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。
1 r$ |+ a4 W+ Z4 c( k
% S- m, A S! i' c& G
& k* S! N# G0 N M9 O0 Q2.包文件的共同特征
. q6 }" {1 E* A4 A7 ? s% O" N" A: f: u3 c+ I( S+ R2 h$ {/ R9 p6 M
包文件都有一些共同的东西:一个文件索引表和后面的文件数据。
3 ^1 u5 k+ w4 [6 n9 w1 Q这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。) R1 x7 p- U: Q, Y8 A* m
其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。
, E# M5 X# }; M# ]3 a' r" O4 `+ j有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。+ V; M; J3 [, x l3 N* R
1 Q$ [7 b# p* X9 }" i0 m
$ F8 W6 \) p; Z$ D% q$ h3.本文需要用到的工具
& J1 h1 L @8 p5 k4 E, A3 t2 U
`' G- ]0 K! Y7 m7 M% v- J7 C: E6 K+ TUltraEdit
K* }' x' V" p O% F' P1 JVisual Studio/...或者其他任何可以用来编程的东西5 |1 s$ G: ~4 V# l: g9 C
Windows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)! c5 s9 C& }0 {1 x8 k) P8 F
1 r0 l! f+ P. ]. V+ ^, n& o3 U) ~0 x3 ~ z* @
4.第一个例子——盟军敢死队2的PCK文件格式/ B( A% D& z$ v! v0 R
% x4 o2 e" A7 n& ?0 W" n
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。
8 t% w( U/ k! d1 C# s3 z! \+ ~这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。! x8 C0 B6 w2 _ B s
4 r: N2 ]& |/ W3 V, P' d/ J/ d s
用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。
: e" q6 i( Q& n: P& e7 D8 l
* d. t; W% g1 e; m7 g# p如果你从来没分析过文件的二进制结构,也不要紧张。 n7 e5 W$ T7 \8 C! B& v
在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。# c G8 {7 k, R% f
9 y6 O' i7 W! ?% {. y
往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。% ~( \7 P1 B j, B" ^* u+ ?1 x
; W6 A0 T0 u- z: x& E4 n
图1 盟军敢死队2 DATA.PCK文件头
$ K& u" r5 c% }- M$ D# a- U00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
1 O$ X1 j& ]% n! k. r6 N; r00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................- T% R0 r5 D3 w( ~
00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |