游戏包文件结构分析! |8 t/ S: Z% F
地狱门神
! t6 r0 c/ R3 K" k9 ]* f( X( r5 a
摘要:本文通过三个例子介绍了如何初步分析一个未知格式的游戏包文件(package file)的文件格式,并从中提取数据。5 U4 P3 ^1 w$ B( @2 d
+ ]+ S/ ^) B+ B声明:本文档按现状提供,仅用于研究和学习,因为使用本文档造成的任何损失,本人概不负责。
# C7 Y1 p z4 q5 g7 z; g6 _- s+ K! ]* M) R
& v2 @' v$ f2 n2 L1.背景
" a% w4 f' P" v- n, r' L& p" g" o# a& f4 E( _. \8 H
不久之前,一个网友问我怎样从某个游戏的包文件(package file)中提取资源文件,他想从该游戏中提取一个音乐文件作为手机铃声。由于我以前曾经实现过盟军敢死队系列的包文件管理器PCKManager(包含在盟军敢死队开发工具箱中,可以查看该系列的DIR、PCK、PAK文件),对包文件的一些共有特性有一些了解,很快就分析出来了该包文件的格式。后来觉得应该写一篇文章来说明一下,于是就有了这篇文章。文章中有三个例子,分别是盟军敢死队2的PCK文件格式、前面提到的游戏的包文件、盟军敢死队:打击力量的PAK文件格式。# H0 w( P9 H% |- B( r7 n
文档中有些地方会提到一些惯例或者背景的知识,希望大家不要觉得繁琐。1 U1 S, Y) d& J# r4 y S/ X
3 f: f9 q0 Y0 b7 x. n: [: ?
& U5 S& r/ R4 Y3 {8 x3 h2.包文件的共同特征- i# u8 J0 Y; z& T8 }% x% R; e+ Y
- t( u, X+ D2 t1 n包文件都有一些共同的东西:一个文件索引表和后面的文件数据。9 u, H: O) O" S, N# ~# J
这个文件索引表一般每条索引至少会包含文件名、文件位置、文件长度三个数据。
8 M) c. b W) \其中,有了文件位置(文件在包中的偏移量)和文件长度,一般就可以确定一个文件的数据。. y5 F( p1 L9 h* E, U! `% E& u
有一些包文件可能会使用文件名的散列值(Hash code)来代替文件名,这种情况很复杂,如果无法通过其他途径找到文件名,可能就没有办法重建文件名,本文暂不考虑这个情况,这里的例子都不存在这个问题。
" T* | I; }# R, J$ J# x) T( ~) j9 e9 v
, x+ r( e7 ^6 s3.本文需要用到的工具& _5 L4 ]' r! X9 t _2 M
9 Z0 W. r7 K7 |& K( _. `( n8 H( cUltraEdit
; O {3 N7 T2 `, s: R7 E9 P7 tVisual Studio/...或者其他任何可以用来编程的东西7 u5 g: ?3 ^ n
Windows自带的科学计算器(既支持16进制和10进制转换,又支持按位逻辑运算And、Or、Xor的好的计算器我没见过,可能以后我会自己做一个)
% z" F) O0 m4 h! X. e' H8 l" |; |2 ~7 u) _4 S0 g% r x
E9 w% F" B3 i# v
4.第一个例子——盟军敢死队2的PCK文件格式
4 M0 H1 @$ ?( x( [5 r( T5 @3 m3 Q0 w( g' Q, H, {
这个格式最简单,完全没有任何加密。但是文件索引表采用的一种基于文件夹的索引形式,比下一个例子略复杂,比最后一个例子效率略低(对游戏而言)。
. Y @. l& i. x' }2 Z" W这里你需要电脑上已经装好了盟军敢死队2的游戏。如果你没有这个游戏,可以等到下一节再开始动手操作,下一节的例子只要求下载一个10M左右的小游戏。9 l8 ~; P6 v* w
! ?5 Z5 g5 r* H ] i# a用UltraEdit打开DATA.PCK。是不是看到右边的一片“...”中夹杂了一些字符串?这些就是文件名了。 ^# c# @! L c( U2 u
# T9 w7 x8 w$ R3 M5 A& S9 Q/ E如果你从来没分析过文件的二进制结构,也不要紧张。
' K) j" ?6 q# F9 D1 \( t: k在UltraEdit的Hex编辑模式中,最左边一栏是该行最开始的字节的偏移量,中间一栏是文件的所有的字节数据,每一字节用两位16进制数表示。最右边一栏是这些字节数据的ASCII码解释。更准确的说,在中文的系统中,是GB2312的某一种衍生编码解释。因为中文是借用了128-255的扩展ASCII码的空间来表示开始的,所以会出现一些中文字的乱码,这纯粹是巧合。00用点表示,不存在对应的符号的用问号表示。6 c) z( c7 h( B5 I, ]# P; k
: ~( [5 `) v2 v+ n往下翻几页,你应该会注意到每一个文件名的开始到下一个文件名的开始正好是3行。也就是说,在文件索引表中,一条索引的长度固定为48。
+ F; z4 w7 |) i
% Z/ d* D7 }! v* u图1 盟军敢死队2 DATA.PCK文件头; q$ z: B1 D: }% P
00000000h: 44 41 54 41 00 00 00 00 00 00 00 00 00 00 00 00 ; DATA............
7 u% {2 Q- h) l: w6 V00000010h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
9 w) F4 {* n" h( u" ]00000020h: 00 00 00 00 01 00 00 00 FF FF FF FF 30 00 00 00 ; ........ |