我正打算做一个使用Quickbmsqu去解那些没有解包器的文档的教程。
- h; [& V, l8 g起步会很简单,然后越来越难,直到你学会并且编写你自己的脚本。
' o7 Y6 R% `4 S$ Y$ \5 w" g5 E我们需要如下的四个工具:/ r+ F) A1 x; D
1、16进制编辑器,比如HxD。(我用WINHEX)
* b6 k( u. i, A" e2、Quick BMS http://aluigi.org/papers/quickbms.zip(老外真废话,不用这个还写什么教程啊?), s- ^5 S- q1 s' d: i/ [
3、文本编辑器比如wordpad(我猜老外用的都是免费软件,我用EditPlus)
0 Z g# y, C7 z( ^* y5 G: M, @1 m O4、支持16进制的计算机,比如WINDOWS自带的
) d f+ z9 ]6 n1 Z( w7 g, w我们从一个叫做FEZ(Fantasy Earth Zero)的游戏开始3 h/ t& ]$ w; F! f1 b- H( J; y
这对某些人学习bms脚本来说是一个很大的文档格式。
3 U9 Q4 R( l: C7 j$ C' ?* y附上一些例子:5 n6 ~3 e3 |2 Y4 b
网站 http://tw.fez.gamania.com/ , l: b- ^$ O B
安装 http://tw.dl.gamania.com/fez/FEZ_1103.exe - ^, ]3 G6 u5 m, b, B1 n
这个游戏在主要思路上用不正常的文件头材质和一些TGA以及一些.MDL格式。1 a# m+ `1 O5 ~1 X
好了,你可以从这里下载到完整的安装或者一些样本片段文件。
- L1 `0 m6 ?2 B5 l1 p! yhttp://www.MegaShare.com/1029061$ s8 J! _. m5 p" T+ a
用16进制编辑器打开文件,你就能看到如下所示:" e/ } ~4 w- E7 ] x* b# G
% M8 K$ D2 w0 ~$ |& t$ H3 A: R# Z: e; @" ~- j9 [+ P
可以看到右面有一些可辨认的文字
( S1 y4 g5 m+ S9 {% g: q5 hEtc\\aura.tex , Etc\\cursor.tex , Etc\\mahoujin.tex , Etc\\env2.tex , and Etc\\kaze.tex .
5 y1 ^+ |5 z' p所以往下看我们就能知道在这个BIN文件里至少包含5个文件,如果把他们解包,则会被解包到一个叫做Etc的文件夹中。
# O7 @7 O, u# e0 ]8 S我们还是看看这个文件的文件头中的其他部分吧,从前面4个字节开始。
; i( p% b0 d- @
( F$ R* e0 N5 ^ i `3 W6 Z' [9 i P$ |' }- f
这四个字节是 05 00 00 00 & t M5 g$ \6 F3 R( F
我们处理的99%的游戏文档中,这个值是反向的。也就是说我们看到的05 00 00 00实际上应该是00 00 00 05或者说是5。 z; ^4 i5 I* K
好了,如果我们还记得前面我们曾经看到过5个文件名,并且这个文件的前四个字节就等于5.那么我们就得出一个结论,那就是这里保存的是文档中的文件数。! m0 Q& T9 C/ {
数据的保存方式有长整型(Long)4字节,短整型(Short)2字节以及字节型(Bytes),于是我们得出了我们脚本的第一部分
$ N) {1 E& I# `8 iget FILES long 2 z3 I' ~/ c _- g7 o7 U- R7 e
这就告诉Quickbms读一个长整型值并且把它保存为变量FILES。
3 Y% |) n6 d, S1 }接下来的4个字节74 00 00 00 对于quickbms解包没有用处,但是它表示的是文件头的长度。2 ~/ x3 r* x# d- J2 s B
: ^. q* H8 @$ }+ j+ w* m4 m3 v' {1 W9 g1 c- z% u$ f
于是我们可以写出下面一行quickbms脚本了" {& A- K2 ~6 R" {
get HEADERSZ long
: S/ @9 ?7 T& O2 o/ p( K将文件头的大小保存到变量HEADERSZ 中
) ?) ^* \/ F" t; C7 w) O现在,在文件名前面,我们又得到了两个字节,0C 00,我们知道这是短整型,但是00 0C代表什么呢?如果我们在16进制编辑器中把文件名部分选中,就能看到,它的长度正好是C。文件名长度可以写为:0 g% S1 ]. a; I9 A* Z3 Z# m
get NSIZE short
2 |* c. E% G' q0 g9 Z. o9 F把表示文件名长度的两个字节保存到变量NSIZE中。
: ^8 T2 R) A7 n1 ]- B
^2 M6 c j: K: r& `# P; T. ~ ! n! v6 k3 c& I
在bms语言中,保存文件名应该写成下面的样子:6 Z3 b; ~% P' o7 J4 \
getdstring NAME NSIZE 4 u+ w' M* s3 F3 q; y
这就是说,保存一个长度为NSIZE的字符串到变量NAME中。
( f! |1 S" y9 C( a) w: V+ o. o2 n" D好了,现在我们在文件名之后又得到了另外4个字节:7C 00 00 00/ X) F# i' T G5 }4 I0 q8 ~
我们已经知道了文件名,现在要解包这个文件,那么我们需要知道文件的大小以及保存的路径。
# u0 ?) v1 M! b很显然,作为文件的大小来说,7C不是一个很大的数字。那么让我们看看偏移量7C的地方是什么。
% K9 T( r2 y# L8 [" o* p# K在HXD中按下Ctrl+E,然后在开始偏移量和结束偏移量的地方都输入7C,再按OK键。$ u! h0 |9 s4 n
" ^9 H E) o* B. [9 k5 @- N6 j$ o p- N) M- @( F
我们就能看到下面的图
2 {+ l5 b* I4 K $ b1 t, {( N" `
这里好像是一个文件的文件头IMG0,于是我们写下这行表示这是文件的开头:
, `9 i; p! x; c$ p* r. Xget OFFSET long
6 @0 x5 i, ?8 f; J; a! \将4个字节保存到变量OFFSET中。
r5 c- l( f3 x" _/ g1 X+ f接下来的4个字节70 10 00 00看上去比较大,所以让我们看看这里是不是文件的长度。先翻译成00 00 10 70或者说是1070,从刚才的偏移量7C加上长度1070
5 o+ {( y" H6 F ) F0 {% g& s$ z" G. [, K) U# m# c, x
哦,我看到了TRUEVISION-XFILE,这是一个典型的TGA文件结尾。而且我们还看到了这个文件是以IMG0开头的。- m5 M5 [" M: |: W4 w
- Z7 p+ H+ J( ?7 C3 b
这意味着我们找到了文件的长度。记下:
* s e8 [2 b* u* B, x7 W9 Cget SIZE long
1 x2 H# ?( ]% A5 R: `把4个字节保存到变量SIZE中。: a5 L; {) A6 X) K B7 ]$ f) `! ]0 r
好了,现在我们下一个文件的两个字节,它们看上去挺相似的。* }- A2 M7 ?- L
把0E 00翻译成00 0E或者E. @5 r) s- \! \3 g
文件名前的两个字节就是文件名的长度,让我们看看是不是。5 [6 [! X1 {% q5 J" p
; V0 d4 ?5 q. @
的确,文件名的长度是E8 I4 J# z* m+ U! |* P
这意味着我们发现了文件头重复的部分,我们已经把需要解包的部分都识别出来了。现在我们就可以完成脚本生成我们的解包器了。
N6 N2 a5 i1 H对于重复的部分,我们设定一个循环,让它一直运行到没有剩余的文件为止。简单的写出来就是:
9 f& @1 W+ F! j! K- ?$ r! _for i = 0 < FILES ! g( p9 ^/ } i- v% M6 H& h
意思就是运行下面的命令从i = 0 直到i< FILES(这里的翻译和原文不同,我是按照语句的意思翻译的,原文没看明白)
8 s5 n* k6 P& ?" Q$ X8 P" B我们把它放到NSIZE变量前面,因为它是循环部分的开始。
- G8 U/ G1 x6 h: g/ r要把它保存到文件中并且记录日志命令要用下面的格式:
% N; F& G/ _& |6 {/ n7 J5 @log NAME OFFSET SIZE # g0 g# H$ C4 ]& {0 [! f
意思是把偏移量OFFSET开始,长度为SIZE的数据填写到文件里并保存。
* s, J" o% s, `8 z3 Y/ ~; T现在,重复这些操作,直到没有剩余的文件,我们还得加一句:) s Y4 e) `# P* [" `! U8 }
next i , t; g9 @5 t' ], l* L% W
在循环之后,这样循环就可以进行了。
2 c& B S8 B( o/ }' P* G好了,保存脚本文件并且命名为extract.bms,把Etc.pac、extract.bms 和quickbms.exe放到一个文件夹中。在这个例子中,我们假设是C:\\Temp/ l3 r+ W% q+ o. j! l7 ~3 j7 \* o
现在在命令行模式下,进到刚才那个目录中并且输入:2 U* I) J! H" I1 S( o& B
quickbms.exe -l extract.bms Etc.pac .
- Z; ?, L- y( T将会列出文件的信息和大小。如果脚本不正确将给出错误信息。! b6 r' P9 W5 N2 n, j6 D
耶,它运行了:/ G! A8 t: e1 t# N8 n/ D! [
/ I3 u5 ?2 {9 p, R- u现在让我们试着把它们解包到extracted 目录中,输入7 f# h$ L; j. F, [8 z `
quickbms.exe extract.bms Etc.pac extracted
, s# T+ w: V- D+ v7 L) D好,正确运行并且解包了。/ x1 q5 v# T$ n3 }4 I
( k, w4 \! M! m2 Z
脚本代码:
1 A) f# Q A( ` o5 [get FILES long i6 n4 {, u/ x' Y" c
get HEADERSZ long m/ M4 L; v$ s* E) H1 ^
for i = 0 < FILES
4 H6 n# f/ V% E3 t+ n$ Kget NSIZE short 8 M: Q6 z. P9 `- Y7 L# r @! M+ S2 l
getdstring NAME NSIZE
+ o. a- l: m$ C5 z9 |get OFFSET long
6 G" c. s& z0 w9 hget SIZE long ) u; F2 E& ^, `0 l$ y
3 _' l# h* s$ c5 g. w, e
log NAME OFFSET SIZE : J+ ], ~; r4 b8 g( V5 `
next i |