这篇是网络上找到的QuickBMS实战例子。- u5 P1 t5 z8 u4 U
- `5 B. j- F1 u5 N9 N* |& w4 k- J( P0 r9 R- l: B. i. ^2 T' ?
这几天的发现太惊人了。。。XeNTax才是mghack的最终目标。。一个坚持了20年的组织。 $ B/ P* i E. Z$ u& k: K
不多说了。。以AR为例子,讲解一下这个强大的通用解包器吧。。 & G2 O! B- |5 L# r% x7 N7 f' W- X
' v# f3 ]" V j) N) O( y
准备工具:
3 p5 S2 ?: z8 D# d' a7 t' n1.UE(或者其他hex编辑器)
: S" p2 C) q8 r5 R' `+ |2.QuickBms(这才是主角)
7 K; J0 m5 V, Y7 @; g4 P3.AstroRanger这个游戏的hsp资源文件(我们这里以附件中的BoneObject.hsp为例)
9 s& q! k& g* k
( L! J9 x" A' b教程开始: ; W4 {, b9 N2 a( }9 ?2 N4 M
1.首先在c:盘创建一个TEST目录,把QuickBMS和BoneObject.hsp放进游戏目录,准备研究解包。 " `; w" U4 r$ ^9 k9 P+ N* R
2.创建一个新文本文档,命名为Astro_hspfile.bms,保存到同样目录下。
4 Y+ z- f, T' j2 A% s% t
- Q$ L7 ^5 ]# c% R0 s) w0 j
! a7 Y# j0 X: S4 P2 z" d3.用十六进制编辑器打开BoneObject.hsp,我们将对这个文件进行分析。 0 e4 F1 R4 }2 b+ H( f
' w+ t O8 R" J4 y
; Z3 l% O# ?* D" o; A; ]我们在编辑器的右边看到一些类似文件名的文本。这说明AR对文件名并没有进行加密。
9 q L& }% s+ J& `+ v好了,别急着高兴,冷静分析出这个文件的打包方式才是我们的主题。 & ?) w( I S$ m5 U1 R" A
首先看到前4个字节20 50 53 48 或者 “ PSH”,倒转过来就是HSP加一个空格, 7 z0 P, X! f! t" x
一般windows的文件都会在文件前N个字节做上“ID记号”,这个“ PSH”就是hsp文件的"ID记号".
5 f. p" L- [% J. E/ F5 w用记事本打开Astro_hspfile.bms,我们写上脚本的第一行代码^_^.
' Y+ J. c; A1 n$ E1 l% H* |* J4 L, @+ K9 K
引用 , o% r- ?* c) x8 ?' A
idstring " PSH" 9 c; `4 ^7 e( @( C2 `7 ~# A
! Y/ z! Z9 a* Q- A
这行代码的意思是“如果访问的文件的最开始不是' PSH'的话,那么就不会尝试去访问它了” % g: V6 O: P1 K: h3 j; d9 z0 W" ~
/ ?, T R9 w }7 [. L- m好了,接下来我们找一些自己能看懂的东西,例如那些像是文件名的地方。
9 R$ {. @' U' B0 B. H2 W类似Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds这样的文件名一共有4个。
3 _+ u; v/ s! v; \2 Z
% i& e# N/ u2 r/ P喂,别老盯着那些文件名看了。就算一直看着他们,他们也不会自己蹦出来的。 , |9 ^6 L/ ]1 f! W
我们回到文件头那里继续,之后的4个字节01 00 00 00,经过倒转字节后就是00 00 00 01,也就是1。 ; V& Y3 a' b% Z( T1 k: m! D
到这里我们好像没有什么和1有关的信息,暂时把它定义为“未知字节(unknow)”吧。 2 J8 _& X7 [' p% q2 Q
于是我们应该在bms文件里写上这么一句代码: & C }3 e9 q& ] D; p. D# i
7 Q: s9 K0 n! T3 f+ ]. ]9 U. Q1 \引用 6 q1 _4 v) _ ]# i: V2 `
get UNK1 long
8 ^- `. W5 O* _" d4 |1 |5 P D6 @" g$ R' M8 v
这句的意思,就是从文件中获取4字节保存到变量“UNK1”中。 ( f, b0 Y& w T$ B+ k+ A ?
& T5 x: q2 |) M1 l, [. i
继续。。后4个字节是04 00 00 00,倒转后是00 00 00 04也就是4。
6 l$ m! Q' ~+ }! y8 W很眼熟吧,没错,刚才我们看到4个文件名,那么基本可以确定这个4就是“文件数量”了。 % D7 l+ B) y, k) W w1 P
所以我们得把这个好消息同样告诉"BMS". ! u$ a5 X* R& X) V. j# \) }
- C. G% F1 r: J, j7 n引用
3 r4 y1 e1 V6 r1 m% h1 A3 Nget FILES long 8 L5 Q! _. J/ x
8 T' @) R* _6 l
) m) H5 \6 M* v" y5 ]
之后是4个00 00 00 00,这里得到的值是0, ' Y/ ]* t6 d; w: S8 O& g- Z, G. G
我们也不知道是做什么的,暂时设为NULL(空)吧 : l9 m3 ]9 v! u% `8 k. B3 s/ D
* x. d, p7 ]3 i4 J8 U' z
引用
) u" ]( G- o3 c- [) w9 Zget NULL1 long
/ b) x& A& {" \) R' V- q
& q/ ?- J- C/ w6 R: z
+ Z' g9 r; T" P+ l) R, ^看到这里,接下来总算可以看文件名了。 # h2 J* m# ]8 G( d8 A7 Y! q# k
经过对比,每个文件名的文本加上其后的00一共是0x80也就是128字节.
' d2 E1 ~; ~: }7 r3 T. k0 `所以我会写上这样一行代码:
- P. \ x5 D* ]% p" D4 W' h S/ s: R4 Q$ o3 O( u; f6 x
引用
* c( Z0 i k4 v- Jgetdstring NAME 0x80
/ B* T% ], U9 r4 q& ?' O" ~$ d: o. r) E; a& y! ]3 i) c
意思是获取0x80字节保存到 文本型变量 NAME 中.
/ W' E: F9 C Q文本型变量在遇到00的时候会自动判断为文本结尾,所以文件名后的00都会在保存时候被自动删除^_^ $ e* e* M8 {2 c! l
4 {! U5 f9 V. U' X- }/ B奇怪,在第一个文件名和第二个文件名之间还有3个LONG长度的字节, 2 [" _1 I* L# K; E# h. M. e
以之前解PAK的经验来看,这里一般都是文件开始位置、文件长度、文件加密key之类的东西, % Y/ m: z6 B( z; V5 j
但是我们现在还不清楚具体哪个是哪个,就暂时定义为“未知数据”吧。
* M& Z* ]* z9 f) D' o; f* g' B' n% W& i
引用
4 _ \# o0 d0 D4 n! v# U$ v- o- |) nget UNK2 long
2 u W' \. @ _! ?: Mget UNK3 long 1 o8 G: }* ^- k+ M
get UNK4 long 9 i' T: G: p# w& L( U
; d4 V, R1 N% ~/ q! o2 b
5 n1 B' V$ _* O; ^6 Q
到此为止我们已经初步了解了文件列表部分的循环结构了 % ?& a& J$ ]5 V( Y9 t9 g
我们目前手头写的脚本代码如下:
7 s V: \' I; n
( E1 D+ q' n. e7 w- B" P引用 / u7 G x# H' t
idstring " PSH" & R3 e, J* @; r8 n0 J8 J! Z5 J
get UNK1 long
$ z7 X6 S! ?4 sget FILES long : t% J2 }$ Q8 ]" M, }6 K7 w7 h# n) N. N
get NULL1 long
* X8 R; `/ J! ?! }/ W! U2 ogetdstring NAME 0x80 # Q- O- f0 X9 [
get UNK2 long ) d/ K: d1 K; U0 s
get UNK3 long / j4 {, ]+ S/ E- O' ?% b
get UNK4 long ! E K" z/ C' i3 z% R
* I/ j' I: h" Z& x6 \
" x" c1 I2 s. K+ p& q光是上面的代码仅仅也就只能取到第一个文件名而已。
; Q4 }0 }6 {* E' r6 k: g8 a! g我们需要给他们加上一个循环脚本,让他们能读到所有文件名,代码如下: % Z9 A" T% R% A# i5 G
6 M$ U7 R; f8 N l6 s
引用 7 k. ?" `: j3 L4 c; F$ p9 T2 n3 C
idstring " PSH"
" M1 ], r3 N% f0 F. Cget UNK1 long
9 n# m& \0 V# K3 G* ^' Uget FILES long 6 p/ r6 B" q+ c, y* D% c! u
get NULL1 long
, [2 ~+ l) V' b0 X9 q0 |for i = 0 < FILES
3 h# H( `+ ~0 U0 Dgetdstring NAME 0x80 * R; _% r; f, ?* ?) K' S
get UNK2 long
; p7 Q6 ~3 A/ N" Z8 m6 G6 kget UNK3 long
* F3 ~. N* u" j3 E! [3 a- x' qget UNK4 long : z) _$ L( ?* K! J- J) r# T9 j
next i & O n: P. J' o$ Y& `
" K. X9 p; X+ q) D5 L/ W1 h
7 o2 }3 G8 g9 |& E- Y/ Z1 _% A+ N即使加了循环,我们还是没有能保存出文件,因为还没有加入log保存命令。
5 o( v1 j$ F8 q0 Lhoho,天亮了,暂时分析到这里。
0 h# J3 L2 i1 \* c最终代码如下。已经可以解包所有hsp文件喽: " V0 ^/ l6 t: F- ~* X
' Q2 R/ P6 }. J, i" T: F引用 6 u# E" e* u% X& @
idstring " PSH" / f" Y% G+ H$ I3 ?& b9 ^
get UNK1 long % T8 E! I0 u, }6 } O
get FILES long
& _( P( h, U, K: n) C9 v0 M) Eget NULL1 long
6 M) W% k" F, | f# R" s8 {for i = 0 < FILES
" m8 n* l' O. `/ M! |, Ygetdstring NAME 0x80
1 j2 b* R. B0 f" Vget ZSIZE long 7 _5 b9 g! h z- D* e% c
get SIZE long - S3 I: u4 n+ o8 s- p) e9 k
get OFFSET long 2 S/ k1 \/ [+ p# x# K
clog NAME OFFSET ZSIZE SIZE - s" h" p% E Z# \( N5 r) `
next i
, M4 k0 w8 H; h- G: Q
3 E8 I3 @# Q9 E0 x) G. s- L把上面的脚本保存后 ; P8 | U! k/ X& c! _
新建一个txt内容如下:
: T$ v3 o6 j1 T% j' `quickbms astro_hspfile.bms BoneObject.hsp .
: u$ B; w( \; J4 X& }注意保存最后的"."然后把内容保存为hsp_extractor.bat
5 o; V$ o' N! I5 k* e: c* p" K之后运行hsp_extractor.bat就能看到解包后的结果啦。。 2 O$ A# M, _0 _/ p8 M* ^! Z: O. @
睡觉睡觉。。。 |