我正打算做一个使用Quickbmsqu去解那些没有解包器的文档的教程。
+ Z3 M; I% h) ^( H: @. Z起步会很简单,然后越来越难,直到你学会并且编写你自己的脚本。
- `: V" N2 \) p- p我们需要如下的四个工具:
. a" l7 r3 A x1 w7 P- J1、16进制编辑器,比如HxD。(我用WINHEX)
' V9 v, A% h5 B/ t2、Quick BMS http://aluigi.org/papers/quickbms.zip(老外真废话,不用这个还写什么教程啊?)( B; O# x N. j2 x( `2 U
3、文本编辑器比如wordpad(我猜老外用的都是免费软件,我用EditPlus): }8 X8 I# @& B
4、支持16进制的计算机,比如WINDOWS自带的4 Z. I' {: p$ d% w6 `; N$ W
我们从一个叫做FEZ(Fantasy Earth Zero)的游戏开始
" m: B* W7 q' \8 y) B7 w+ c/ R这对某些人学习bms脚本来说是一个很大的文档格式。
/ P+ z; I6 G( v附上一些例子:3 q; h( N% c* o) S$ Y9 `
网站 http://tw.fez.gamania.com/
}1 \3 b9 P% O0 t# I: V安装 http://tw.dl.gamania.com/fez/FEZ_1103.exe
( {9 H2 M: Y8 j这个游戏在主要思路上用不正常的文件头材质和一些TGA以及一些.MDL格式。% @3 S/ p; B9 F" G
好了,你可以从这里下载到完整的安装或者一些样本片段文件。
* Z% w5 Q! f7 M9 W2 uhttp://www.MegaShare.com/1029061; X: s O; t* c' w3 `0 I! S
用16进制编辑器打开文件,你就能看到如下所示:7 K2 | X/ M4 n9 i! f
! N# n3 w, x) f& [
S" t6 Z' r( ? m可以看到右面有一些可辨认的文字
$ h7 m) N1 L) G# }* hEtc\\aura.tex , Etc\\cursor.tex , Etc\\mahoujin.tex , Etc\\env2.tex , and Etc\\kaze.tex . , v- b6 m( R7 l
所以往下看我们就能知道在这个BIN文件里至少包含5个文件,如果把他们解包,则会被解包到一个叫做Etc的文件夹中。
! B4 N: o; z0 q我们还是看看这个文件的文件头中的其他部分吧,从前面4个字节开始。
3 W+ j& e3 Q. E$ n) R# U
9 g; e5 }" u/ Z
3 D$ k) z9 a; g. H$ H9 ^% L# k5 U这四个字节是 05 00 00 00 & O; z9 {- ]& C ~
我们处理的99%的游戏文档中,这个值是反向的。也就是说我们看到的05 00 00 00实际上应该是00 00 00 05或者说是5。. {, [# r. O+ @7 Y
好了,如果我们还记得前面我们曾经看到过5个文件名,并且这个文件的前四个字节就等于5.那么我们就得出一个结论,那就是这里保存的是文档中的文件数。! ]) Z2 o6 k7 b
数据的保存方式有长整型(Long)4字节,短整型(Short)2字节以及字节型(Bytes),于是我们得出了我们脚本的第一部分" k. |; ^3 |4 E' u8 I8 j
get FILES long
" L% A D7 e' l% F! q这就告诉Quickbms读一个长整型值并且把它保存为变量FILES。, N8 H5 N2 `2 z; R' S z
接下来的4个字节74 00 00 00 对于quickbms解包没有用处,但是它表示的是文件头的长度。/ p E0 M l6 L! A5 h8 m% |' z& w+ S
![]()
+ D; l& |! E. b1 z+ X: x
- B& b* v$ M- ~( T) D) K7 K L于是我们可以写出下面一行quickbms脚本了3 z; @" y2 K( u3 l, p! l8 e
get HEADERSZ long
1 Q4 G" B9 f- {将文件头的大小保存到变量HEADERSZ 中% V( K5 B* S' B3 G" P1 w
现在,在文件名前面,我们又得到了两个字节,0C 00,我们知道这是短整型,但是00 0C代表什么呢?如果我们在16进制编辑器中把文件名部分选中,就能看到,它的长度正好是C。文件名长度可以写为:
: B( s% C! T7 F: @! ?" n0 {: Pget NSIZE short . T; u* U/ v6 U% `
把表示文件名长度的两个字节保存到变量NSIZE中。
! j% ^- j. j; z' o![]()
& M5 V4 o$ C; z 7 x. J3 j( n0 H. d3 Z% h9 {9 k
在bms语言中,保存文件名应该写成下面的样子:$ `$ U! C9 `) X' X
getdstring NAME NSIZE & K: _; u: F, H y& c4 O$ V
这就是说,保存一个长度为NSIZE的字符串到变量NAME中。
: M4 `- y0 l6 N7 ^$ h8 m. o好了,现在我们在文件名之后又得到了另外4个字节:7C 00 00 00: c' e: A5 z: }& ^3 A h+ G& _
我们已经知道了文件名,现在要解包这个文件,那么我们需要知道文件的大小以及保存的路径。
' Y1 e+ ^; J7 l: s4 x9 Z z9 j. b3 |* n很显然,作为文件的大小来说,7C不是一个很大的数字。那么让我们看看偏移量7C的地方是什么。: f; {' R1 c6 I$ \! X# U; y3 C
在HXD中按下Ctrl+E,然后在开始偏移量和结束偏移量的地方都输入7C,再按OK键。) Y4 E0 M+ t2 T/ n% c* d
# V$ }7 F- l# a( K
1 K+ E( d i5 R4 u
我们就能看到下面的图0 y/ e4 D! B% O; o1 e% @: r, v( A
![]()
0 w& f0 p$ w6 O这里好像是一个文件的文件头IMG0,于是我们写下这行表示这是文件的开头:. P5 e# _8 o# R0 I- l
get OFFSET long
3 G. l" u: V$ p/ D: {) S将4个字节保存到变量OFFSET中。
. e* k- g1 I; \4 l5 m, o+ I. C接下来的4个字节70 10 00 00看上去比较大,所以让我们看看这里是不是文件的长度。先翻译成00 00 10 70或者说是1070,从刚才的偏移量7C加上长度1070+ W& `- s% s/ b( U. Y
3 t/ h x( i6 n/ q
哦,我看到了TRUEVISION-XFILE,这是一个典型的TGA文件结尾。而且我们还看到了这个文件是以IMG0开头的。3 r/ V5 b- j6 m0 X, E
+ Y/ G" b; \, D/ l9 ?+ Y
这意味着我们找到了文件的长度。记下:- Y+ C1 a3 p% x) L
get SIZE long
' y& v& A1 c5 p/ n* A8 I4 \把4个字节保存到变量SIZE中。. u/ m! F' o) ? R( G7 v
好了,现在我们下一个文件的两个字节,它们看上去挺相似的。
$ Q% H. u/ a& z: E+ c把0E 00翻译成00 0E或者E
" k1 V& [( i* p, o文件名前的两个字节就是文件名的长度,让我们看看是不是。
* ?! {7 i1 {) p8 @9 _ 3 \- ~: w2 D8 H, d' ?) c' t
的确,文件名的长度是E. z5 ?7 k* o% X, \2 _8 Z+ f. L
这意味着我们发现了文件头重复的部分,我们已经把需要解包的部分都识别出来了。现在我们就可以完成脚本生成我们的解包器了。
* P+ h9 d! k/ X. ?+ o. p" j- }" C3 n对于重复的部分,我们设定一个循环,让它一直运行到没有剩余的文件为止。简单的写出来就是:4 W. m4 `1 n3 W8 q; S4 J
for i = 0 < FILES
3 }4 G+ [$ d5 F意思就是运行下面的命令从i = 0 直到i< FILES(这里的翻译和原文不同,我是按照语句的意思翻译的,原文没看明白)' o' e, l$ p5 Q
我们把它放到NSIZE变量前面,因为它是循环部分的开始。: P, z2 p( D3 a0 `; Z8 T" J
要把它保存到文件中并且记录日志命令要用下面的格式:: @* Y4 i* S4 S4 ~- a) e
log NAME OFFSET SIZE
0 R* Z. M! X# Z+ F# J" `7 j意思是把偏移量OFFSET开始,长度为SIZE的数据填写到文件里并保存。
/ }" v9 S. P, h4 M! c现在,重复这些操作,直到没有剩余的文件,我们还得加一句:
$ g! y$ Q# B* g2 |( Jnext i : V) m5 L, E& T+ s; S0 T: p
在循环之后,这样循环就可以进行了。
8 ^* q) }# q$ S好了,保存脚本文件并且命名为extract.bms,把Etc.pac、extract.bms 和quickbms.exe放到一个文件夹中。在这个例子中,我们假设是C:\\Temp
2 g0 v1 d& }( M4 g6 h4 N" T9 m/ h现在在命令行模式下,进到刚才那个目录中并且输入:
: r I# m4 a: Nquickbms.exe -l extract.bms Etc.pac . 2 e+ ~% x1 B3 ]- N6 G1 p. j
将会列出文件的信息和大小。如果脚本不正确将给出错误信息。
7 u) i/ ^7 \1 _$ U" \9 T耶,它运行了:
4 x: }) t' I6 d; B& y2 b) y
3 U' M/ O5 {% Q4 n, K8 \5 n" }* s现在让我们试着把它们解包到extracted 目录中,输入, L4 A8 f w( f! T s
quickbms.exe extract.bms Etc.pac extracted
y. d4 ^3 I$ O$ Q& ]/ X好,正确运行并且解包了。
) a$ y$ \% n u; Y$ S; N ![]()
5 ]% F; e4 A4 Y, t脚本代码:
3 W# E+ d# G: p, b+ Y8 s% mget FILES long * H7 H( x0 T, H& B- h: A8 I1 U
get HEADERSZ long
: t5 |7 b5 b+ Lfor i = 0 < FILES
4 ^4 i# C; x6 b }) v" {/ uget NSIZE short - h8 P8 m/ ?/ w5 F% y) c7 N$ o
getdstring NAME NSIZE , f7 C6 a: j' S6 k( w
get OFFSET long
& N* Q, l N, C9 t' cget SIZE long - Y* ~! B8 ~# ^7 S
: }9 p, q9 T- w) h A- s0 Y7 _0 z
log NAME OFFSET SIZE 7 r; Y! e! h1 m+ ` \! H9 ~
next i |