我正打算做一個使用Quickbmsqu去解那些沒有解包器的文檔的教程。6 ?- s/ g/ B8 }, a$ ` 起步會很簡單,然后越來越難,直到你學會并且編寫你自己的腳本。 我們需要如下的四個工具: 1、16進制編輯器,比如HxD。(我用WINHEX) 2、Quick BMS http://aluigi.org/papers/quickbms.zip(老外真廢話,不用這個還寫什么教程啊?) 3、文本編輯器比如wordpad(我猜老外用的都是免費軟件,我用EditPlus) 4、支持16進制的計算機,比如WINDOWS自帶的! d% G- z* K, _2 {. z( b/ J8 J 我們從一個叫做FEZ(Fantasy Earth Zero)的游戲開始$ f1 l% h- ?" ~ 這對某些人學習bms腳本來說是一個很大的文檔格式。 附上一些例子: 網站 http://tw.fez.gamania.com/ 1 S' q, J, j* l+ [+ D* k$ q1 ^* c 安裝 http://tw.dl.gamania.com/fez/FEZ_1103.exe 這個游戲在主要思路上用不正常的文件頭材質和一些TGA以及一些.MDL格式。 好了,你可以從這里下載到完整的安裝或者一些樣本片段文件。% v* J& E8 p9 d+ h0 P* I4 z. L http://www.MegaShare.com/1029061 用16進制編輯器打開文件,你就能看到如下所示:6 a" s% c, `0 w9 K8 H. F- O$ }
8 m' c3 N' B' @5 T7 U 可以看到右面有一些可辨認的文字; N! P l. g" f3 @: y Etc\\aura.tex , Etc\\cursor.tex , Etc\\mahoujin.tex , Etc\\env2.tex , and Etc\\kaze.tex . 所以往下看我們就能知道在這個BIN文件里至少包含5個文件,如果把他們解包,則會被解包到一個叫做Etc的文件夾中。 我們還是看看這個文件的文件頭中的其他部分吧,從前面4個字節開始。/ q9 J, R" {: ^. W
這四個字節是 05 00 00 00 我們處理的99%的游戲文檔中,這個值是反向的。也就是說我們看到的05 00 00 00實際上應該是00 00 00 05或者說是5。6 k8 h( B8 O% h8 \& k 好了,如果我們還記得前面我們曾經看到過5個文件名,并且這個文件的前四個字節就等于5.那么我們就得出一個結論,那就是這里保存的是文檔中的文件數。) {/ C/ [+ L7 p4 ~) i 數據的保存方式有長整型(Long)4字節,短整型(Short)2字節以及字節型(Bytes),于是我們得出了我們腳本的第一部分; A6 T# X. I3 }' F# \& G: |8 V get FILES long 這就告訴Quickbms讀一個長整型值并且把它保存為變量FILES。 S. a3 z" B" @. o 接下來的4個字節74 00 00 00 對于quickbms解包沒有用處,但是它表示的是文件頭的長度。7 n2 b/ D% F) @3 b
 5 o6 O( ~ i; a6 Y B7 Q+ f 于是我們可以寫出下面一行quickbms腳本了! M5 r5 k8 m$ q' J( r$ u get HEADERSZ long 將文件頭的大小保存到變量HEADERSZ 中: c6 V0 Z3 N4 H/ u( S7 U! j) P 現在,在文件名前面,我們又得到了兩個字節,0C 00,我們知道這是短整型,但是00 0C代表什么呢?如果我們在16進制編輯器中把文件名部分選中,就能看到,它的長度正好是C。文件名長度可以寫為: get NSIZE short 把表示文件名長度的兩個字節保存到變量NSIZE中。
2 h7 m* _# H( s3 M - O; B. y) ?9 }+ P0 f 在bms語言中,保存文件名應該寫成下面的樣子: getdstring NAME NSIZE 這就是說,保存一個長度為NSIZE的字符串到變量NAME中。 好了,現在我們在文件名之后又得到了另外4個字節:7C 00 00 00 我們已經知道了文件名,現在要解包這個文件,那么我們需要知道文件的大小以及保存的路徑。 很顯然,作為文件的大小來說,7C不是一個很大的數字。那么讓我們看看偏移量7C的地方是什么。7 e1 W5 \9 r8 q, K( M) Q 在HXD中按下Ctrl+E,然后在開始偏移量和結束偏移量的地方都輸入7C,再按OK鍵。
' u& B6 z+ T/ q7 ? 我們就能看到下面的圖/ N- }& b' e" B" S# p
 這里好像是一個文件的文件頭IMG0,于是我們寫下這行表示這是文件的開頭: get OFFSET long $ s2 |4 z M( ?' p9 O2 K" E: } 將4個字節保存到變量OFFSET中。1 G3 l) G0 G4 l/ E& k F0 S 接下來的4個字節70 10 00 00看上去比較大,所以讓我們看看這里是不是文件的長度。先翻譯成00 00 10 70或者說是1070,從剛才的偏移量7C加上長度1070- q% t2 x j# a; x! L- J
9 p. G$ x4 D9 B0 u' ~: A3 |8 s 哦,我看到了TRUEVISION-XFILE,這是一個典型的TGA文件結尾。而且我們還看到了這個文件是以IMG0開頭的。0 N4 m# `4 z) X7 Z$ }0 c+ ~/ [9 u6 k
" i7 t4 K6 B4 S- G9 a& _ 這意味著我們找到了文件的長度。記下: get SIZE long 把4個字節保存到變量SIZE中。4 Q0 J+ z7 t' e' _3 [1 q0 v: N3 s 好了,現在我們下一個文件的兩個字節,它們看上去挺相似的。: [$ F% r% R2 v2 ~ 把0E 00翻譯成00 0E或者E 文件名前的兩個字節就是文件名的長度,讓我們看看是不是。" |5 ^7 `( J! ]1 {# P' s
- K) h( L, S; D" B: ]* e& t. B 的確,文件名的長度是E 這意味著我們發現了文件頭重復的部分,我們已經把需要解包的部分都識別出來了。現在我們就可以完成腳本生成我們的解包器了。 對于重復的部分,我們設定一個循環,讓它一直運行到沒有剩余的文件為止。簡單的寫出來就是:& F; V# \2 d3 O for i = 0 < FILES 意思就是運行下面的命令從i = 0 直到i< FILES(這里的翻譯和原文不同,我是按照語句的意思翻譯的,原文沒看明白)# X# c6 K+ |" B! q$ m! D2 K; [ 我們把它放到NSIZE變量前面,因為它是循環部分的開始。 要把它保存到文件中并且記錄日志命令要用下面的格式:' H& a+ x0 W& o log NAME OFFSET SIZE ( c6 C: {! ~$ M/ { 意思是把偏移量OFFSET開始,長度為SIZE的數據填寫到文件里并保存。 現在,重復這些操作,直到沒有剩余的文件,我們還得加一句:4 y! R- ~3 A9 Z; Y" d% R next i $ F! L( U+ b! z8 }% h( G 在循環之后,這樣循環就可以進行了。! ?" v/ T2 x% ~/ I8 M& R' _$ n; e* u 好了,保存腳本文件并且命名為extract.bms,把Etc.pac、extract.bms 和quickbms.exe放到一個文件夾中。在這個例子中,我們假設是C:\\Temp! u- X' o# m" G( r, E/ B 現在在命令行模式下,進到剛才那個目錄中并且輸入: quickbms.exe -l extract.bms Etc.pac . 將會列出文件的信息和大小。如果腳本不正確將給出錯誤信息。 耶,它運行了:
' ^; _& W; c8 w5 W- i- E' f+ ~ 現在讓我們試著把它們解包到extracted 目錄中,輸入 quickbms.exe extract.bms Etc.pac extracted - y5 i; j, m! S/ w% i0 | 好,正確運行并且解包了。
 腳本代碼: get FILES long get HEADERSZ long for i = 0 < FILES 8 ~0 I8 _2 n1 T' d+ X get NSIZE short getdstring NAME NSIZE get OFFSET long get SIZE long - s2 O3 d4 Y. u3 F0 |$ k! { log NAME OFFSET SIZE 3 j& O r# @( J6 y+ h0 ~2 Y: S5 v next i |
|