我正打算做一个使用Quickbmsqu去解那些没有解包器的文档的教程。3 ?3 J. |' M" d' ~5 M: w
起步会很简单,然后越来越难,直到你学会并且编写你自己的脚本。% [$ \% R+ \+ ]+ W. v
我们需要如下的四个工具:& B( ]1 d/ d5 ]/ a& e: M D |; h7 W
1、16进制编辑器,比如HxD。(我用WINHEX)
$ g, N {+ U& I; c2、Quick BMS http://aluigi.org/papers/quickbms.zip(老外真废话,不用这个还写什么教程啊?)
$ q) i) B3 Z' Q% N3 |3、文本编辑器比如wordpad(我猜老外用的都是免费软件,我用EditPlus)0 n0 K, l/ T0 z* D) w
4、支持16进制的计算机,比如WINDOWS自带的
2 c# L* @1 P8 _' {' [' a我们从一个叫做FEZ(Fantasy Earth Zero)的游戏开始% }1 i. w! ?6 O; }
这对某些人学习bms脚本来说是一个很大的文档格式。) J" g/ N2 o: W7 M: V* Z. _
附上一些例子:
4 I2 G# P& g- F4 e网站 http://tw.fez.gamania.com/
0 w6 d9 f% ^8 l# J, X% e' U. h安装 http://tw.dl.gamania.com/fez/FEZ_1103.exe 4 | O# j) ?' b- r3 F- g2 B. |
这个游戏在主要思路上用不正常的文件头材质和一些TGA以及一些.MDL格式。 u# ]0 D; [ n: O5 q/ K
好了,你可以从这里下载到完整的安装或者一些样本片段文件。9 W. r- k# G# {, e
http://www.MegaShare.com/1029061
/ t& b) L5 q: D( o0 S用16进制编辑器打开文件,你就能看到如下所示:# K5 f i0 c7 F
4 N( t, \% P" b( I2 B8 g
- `7 K7 r. Y6 Z; D
可以看到右面有一些可辨认的文字$ G9 i: y+ D2 f6 I
Etc\\aura.tex , Etc\\cursor.tex , Etc\\mahoujin.tex , Etc\\env2.tex , and Etc\\kaze.tex . ' m& m0 L: |0 `; X1 Z% Y2 @1 \
所以往下看我们就能知道在这个BIN文件里至少包含5个文件,如果把他们解包,则会被解包到一个叫做Etc的文件夹中。
5 [5 v9 }' j+ A我们还是看看这个文件的文件头中的其他部分吧,从前面4个字节开始。
# b% O2 [0 k3 |* E, D* P . }6 h" K2 A \7 P
. p6 \8 M# Z5 i- g$ K& B/ Z5 v0 f这四个字节是 05 00 00 00
, }3 M. E( o' a' Y0 J( s M我们处理的99%的游戏文档中,这个值是反向的。也就是说我们看到的05 00 00 00实际上应该是00 00 00 05或者说是5。
% N) y' d3 V# H" b, S4 \好了,如果我们还记得前面我们曾经看到过5个文件名,并且这个文件的前四个字节就等于5.那么我们就得出一个结论,那就是这里保存的是文档中的文件数。
) v9 `% ]3 q1 M- |+ ~$ V3 b4 y* @数据的保存方式有长整型(Long)4字节,短整型(Short)2字节以及字节型(Bytes),于是我们得出了我们脚本的第一部分
5 n. S3 z. j. Nget FILES long % r& `, v6 b# p: A, y
这就告诉Quickbms读一个长整型值并且把它保存为变量FILES。
9 Z F( L$ s# y4 [接下来的4个字节74 00 00 00 对于quickbms解包没有用处,但是它表示的是文件头的长度。
0 e2 I' }6 \6 [6 y4 i5 C, Q
, u5 W3 T& e+ X
/ J' x: i* Z4 N( a于是我们可以写出下面一行quickbms脚本了
. A* A8 f B* f' E1 t, lget HEADERSZ long & L: Q1 K5 p/ [- c6 ?0 R5 o
将文件头的大小保存到变量HEADERSZ 中8 \7 y0 J N0 |8 U, Y0 v
现在,在文件名前面,我们又得到了两个字节,0C 00,我们知道这是短整型,但是00 0C代表什么呢?如果我们在16进制编辑器中把文件名部分选中,就能看到,它的长度正好是C。文件名长度可以写为:
8 Q/ f5 ?: E+ u6 Y$ c! E- B; ^- zget NSIZE short
8 |" d# P( O* h0 k( E/ a% p4 D把表示文件名长度的两个字节保存到变量NSIZE中。
. C3 c1 k3 p" }) o+ J: U
* c2 ]% f5 Z8 n9 _+ h 2 ?9 h. Y/ p& p( r
在bms语言中,保存文件名应该写成下面的样子:
v/ V- ]( f9 A! r0 [9 [getdstring NAME NSIZE % ^+ @& H1 |, I
这就是说,保存一个长度为NSIZE的字符串到变量NAME中。
* n- U4 @ b) H$ R7 ?& T好了,现在我们在文件名之后又得到了另外4个字节:7C 00 00 00
& R- ]7 M/ t, I, G& i5 q我们已经知道了文件名,现在要解包这个文件,那么我们需要知道文件的大小以及保存的路径。
9 m$ h1 ^; d, h/ N. K& o! L( `很显然,作为文件的大小来说,7C不是一个很大的数字。那么让我们看看偏移量7C的地方是什么。 b4 f5 j) Y& a8 c
在HXD中按下Ctrl+E,然后在开始偏移量和结束偏移量的地方都输入7C,再按OK键。# H( ]% x; }0 h2 T6 r6 y2 M
; t$ `& x2 C2 A% w9 _ I
, j: M7 h6 R& n/ [
我们就能看到下面的图
/ U' p! E) E+ J, S, ^% I 4 X& t! h% ?0 s% w
这里好像是一个文件的文件头IMG0,于是我们写下这行表示这是文件的开头:2 J- Z2 y. ^+ [+ E- s2 Y
get OFFSET long
5 o2 U" Q) ?9 e8 o将4个字节保存到变量OFFSET中。' w' x; {0 y0 D' B
接下来的4个字节70 10 00 00看上去比较大,所以让我们看看这里是不是文件的长度。先翻译成00 00 10 70或者说是1070,从刚才的偏移量7C加上长度1070- [! r, ~( Q1 R4 _ p. ?* j
( A2 e8 `6 G7 M2 q# k
哦,我看到了TRUEVISION-XFILE,这是一个典型的TGA文件结尾。而且我们还看到了这个文件是以IMG0开头的。* J: H) s% v. o. G
( A; X) S% u: T# G这意味着我们找到了文件的长度。记下:
: i6 k% L m' bget SIZE long - P- U+ M: w8 s
把4个字节保存到变量SIZE中。2 _& U- R/ c0 E A- @+ m, s1 O
好了,现在我们下一个文件的两个字节,它们看上去挺相似的。
* e( d$ A1 o: x2 L6 ^' b8 b% J把0E 00翻译成00 0E或者E
5 B j$ b0 `: m文件名前的两个字节就是文件名的长度,让我们看看是不是。
5 {* q, B$ D: J" b $ t6 U8 L+ @+ u, z+ {
的确,文件名的长度是E/ T5 L6 ~; }* i& Q( ^2 c
这意味着我们发现了文件头重复的部分,我们已经把需要解包的部分都识别出来了。现在我们就可以完成脚本生成我们的解包器了。
! E, Q( G& Q2 _; `% t0 M5 O对于重复的部分,我们设定一个循环,让它一直运行到没有剩余的文件为止。简单的写出来就是:% ^# h' {8 d9 a4 J" @( e
for i = 0 < FILES ' q& L6 J8 g% D @7 z" v" o; @
意思就是运行下面的命令从i = 0 直到i< FILES(这里的翻译和原文不同,我是按照语句的意思翻译的,原文没看明白)
" I: ~$ l0 n8 V, d我们把它放到NSIZE变量前面,因为它是循环部分的开始。
4 ?" ^6 S# ~/ \: {" F要把它保存到文件中并且记录日志命令要用下面的格式:( x7 w# P2 Z* L; G/ \3 f
log NAME OFFSET SIZE # r. C* W0 S* B3 w' B" ^& F, g2 j
意思是把偏移量OFFSET开始,长度为SIZE的数据填写到文件里并保存。
! J |$ @7 \0 Z现在,重复这些操作,直到没有剩余的文件,我们还得加一句:
' W# D' W z0 O7 _$ m% U( T5 fnext i
6 R! j+ g' |5 d" v: g在循环之后,这样循环就可以进行了。# o9 w( h) ~6 R' E1 A' {' N" I
好了,保存脚本文件并且命名为extract.bms,把Etc.pac、extract.bms 和quickbms.exe放到一个文件夹中。在这个例子中,我们假设是C:\\Temp
7 F) f$ ?8 ^9 u8 P# S1 ^& h O现在在命令行模式下,进到刚才那个目录中并且输入:
; q, H7 h0 h% _1 r2 c% g2 b9 rquickbms.exe -l extract.bms Etc.pac .
6 A0 B, z' q8 E# e将会列出文件的信息和大小。如果脚本不正确将给出错误信息。4 g# o6 C+ w/ K F2 z; ~7 P
耶,它运行了:* w- o" U% K7 E& @2 |) c
4 l3 i- G c# c) v2 V; V' V9 D! G现在让我们试着把它们解包到extracted 目录中,输入
4 n, {) u; Q. Iquickbms.exe extract.bms Etc.pac extracted 2 R, z m1 D6 }$ w& w
好,正确运行并且解包了。+ k/ b. t. L2 X$ A4 u
; Y, E1 z1 Y5 p$ ]脚本代码: ) F% g" v% `3 d f1 k; h
get FILES long
; C, L' a/ F, U& m5 a% `7 N' \get HEADERSZ long
$ e$ A# ?7 p' n, nfor i = 0 < FILES 1 \1 z! W+ k+ |$ {2 s
get NSIZE short 5 O: k6 Y3 X. c9 [+ L
getdstring NAME NSIZE " X$ q( z% ~2 V) N; H" {
get OFFSET long ( R" Y% g/ Q& |( t4 Q( @! b( {; r
get SIZE long 7 D: n4 x1 r- Y; ?- u
3 L* Y0 r. s2 G" L
log NAME OFFSET SIZE ^( B2 V$ |1 l' Q k% F' T
next i |