ok so set up our c:\temp directory bye extracting our file BoneObject.hsp3 C# e! X* e+ j4 g* r: f% d3 C/ J! B
1. to c:\temp# ?( h R E; k
2. create a new text document called astro.bms3 T* _0 o8 v+ Q* ^ B5 S% Z
3. and place the newest version of quickbms in the folder also.. J& r4 S$ h8 V6 `, B4 v5 T3 t, X# T
2 ~, H8 F2 C: F: r+ N2 t
Ok so open up BoneObject.hsp in your hex editor and lets take a look at it.
: E H* F/ q; Y3 R$ R4 p% z ) c( o5 k {8 x* d# D
good we have some plain text.
7 q% R: E- t7 Lyou will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
& ]% J& _' o( K( J5 @hmm that seems familiar that is the file extension only backwards. this is know as the idstring `1 d5 f3 ~) x' Q
so up until now you would think to write in bms
0 k' J8 V! `1 b3 s# b% xget IDSTRING long' p: N# x$ _7 W- f: _/ |) A
there is nothing wrong with that but there is a better command
, R' X8 T( n/ z8 e' A* X5 m5 J2 Hidstring " PSH"
! E1 f+ V8 X. z' i7 W- V( v+ u+ emake sure you include the quotes.& O2 Y S. A) n+ y2 S& I
so open your bms string and on the first line type
9 B& @1 D5 l6 ^( ?. W; fidstring " PSH"
. T1 ?6 R* O5 ^the reason this command is better is it will tell the program not to run if it does not find that string don't try to extract that file.* J% g2 T% v/ J
"aka noob proofing it"
% a* _, K2 B* [7 `) [0 G
) \% I* Q: k1 V" P1 bOk so now lets look at what we can read I see
) ]/ I" C5 q& b: XDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds , Datas\Texture\BoneObject\Toon.bmp , Datas\Texture\BoneObject\Toon_a.bmp , Datas\Texture\BoneObject\Toon_zero.bmp
6 K! ?$ v1 x2 |' Iso I will assume there are 4 files in this archive.; z" s6 V0 _! @5 l' p" q
well lets look at the next 4 bytes and see what it is 01 00 00 00 hmm that is equal to 00 00 00 01 or 1 and we have more files in this archive than that so we do not know what this represents5 h9 w0 U7 R, B" t- ^& [5 b
so lets write that in bms language* g6 H. V! G; K2 [2 Y, u
get UNK1 long, u- ~' X8 Z2 k, T8 ~
this saves those 4 bytes as the variable UNK1.
0 n: M8 M& s: N6 d0 E
) L8 W3 m* p9 d0 @ok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 4" p7 g, y9 S$ o2 ]3 a) f$ F6 P
hey that is the number of files we counted so lets write that in bms
! l$ \" X% E+ dget FILES long. I# U* ~7 u: O4 S( O+ p- Q
this saves those 4 bytes as the variable FILES.
" R% N: ~4 F% S9 y) h2 ], D0 b5 C# { K/ N2 b
the next 4 bytes are 00 00 00 00 well that is equal to zero so for now I will write that in bms: o0 n! j$ [# K* A& e( m3 J! |
get NULL1 long' k. U1 w5 d9 D, i. z9 d
this saves those 4 bytes as the variable NULL1( _( k0 U* k8 U. P q
5 C4 ~+ \6 y6 j9 d. Y' wok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds
8 D; F3 T1 s) c5 Ythis is 0x36 bytes long but wait there was no indicator like the last file that told us how long the name is how do we write this?
% x/ q C& w5 m; T/ J4 Z; lwell lets look for a pattern
6 D. h8 H5 M5 i5 LDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36
3 U# O" ^" g F' p$ rDatas\Texture\BoneObject\Toon.bmp is 0x21
0 B5 [/ p9 A! G! iDatas\Texture\BoneObject\Toon_a.bmp is 0x23" H$ H7 }0 G! z0 q5 o7 a
Datas\Texture\BoneObject\Toon_zero.bmp is 0x26
5 S; |* `+ O" A( Y3 w+ Vhmm I don't see anything that makes that a pattern.6 E# }% G( j2 w1 V2 T6 X. h# n
but I do see all the names are followed bye a lot of zero's. how long is the name + the zeros of each file?) f. ^- @& _9 S, u$ f' @
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80" H, b- w0 X# g7 m m' T) r* Z
Datas\Texture\BoneObject\Toon.bmp + 0's is 0x80$ R# n/ L+ @/ e* P" j- P
Datas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80
$ r' W b2 u; N) F& T' H @Datas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80' m9 E2 h( ~4 c( F
hey they are all the same size when I include the 0's
' Y( b9 b: A s! Aso in bms I would write this as+ X4 z5 G: l/ x# J9 O8 B
getdstring NAME 0x80
% R4 E' w$ F8 J2 r. r) h& Sthis tells it to grab 0x80 bytes and store the text value of it- ?: a) q/ Z4 i: O9 Q" g
and as an added feature it will automatically remove trailing 0's
! e0 z3 c7 U" X7 q ~4 N/ u) k
/ Z& a$ {% f) o" R! ]! \+ E" Z: [ok so now we have 0xC bytes before I see the next file name- `0 n9 V! @+ G7 j, h
which is 3 long values
. k' E4 h* X! N* C ?& T2 nso lets write those in and we will figure out what they represent later.; ~; D% ]% m/ Q3 p. O) X) i% {
get UNK2 long, Z2 w! k+ j+ f [7 S$ s) A( }: E) Y
get UNK3 long
6 X" J- ]# c, I: Y* kget UNK4 long
) P1 A9 t- N" X8 _) J: M, s8 W1 P. e! k9 E U% z; b5 o" k; Q! u
ok so now we see the name again
' X' G- B) m! |we have our pattern so lets write our script based on what we learned
4 w; B& d; B& t1 Z: c7 Tso it would look like this up until now
( q1 o# h* X) k6 c4 G5 Z; y8 _3 D5 `/ d( @7 G4 a' ]9 T- l
Code:
, b' _) g# t3 u& Lidstring " PSH"9 a1 z [. P2 W: @' t8 p& i
get UNK1 long
0 ?2 G% z! f) Z& R) }get FILES long
, {5 H) A% @9 T" k8 ?+ ^5 U: q5 Bget NULL1 long. Y f7 E2 t2 z8 ]4 p1 y7 d
for i = 0 < FILES
) P1 ]0 r, y; v0 k6 @$ n9 m, Jgetdstring NAME 0x80
) u' \- E: `8 H" L* x Fget UNK2 long0 w! D2 l, r: [4 }# A y
get UNK3 long& u3 S0 k' D9 _6 C
get UNK4 long3 d' n0 V/ X$ N/ q9 ~3 A0 N- @
clog NAME OFFSET ZSIZE SIZE! I1 B8 h5 A2 q- I
next i
; P6 H; H. n/ F0 `3 S& v
2 {7 Y' d# y2 N% ], [% n) [, [/ o8 S% u+ v$ m8 h- D
ok this may look complex but it is almost identical to the first tutorial file except we added 1 more variable
3 g/ R* x* g+ _7 n# ~, u6 |ZSIZE this represents the compressed file size while SIZE represents the decompressed file size
* k/ {" i$ X, |$ r7 ^4 o( |and we also changed the log command to clog to represent it is a compressed file.
u" m/ p3 b; `5 R
. A, p5 k9 D. E9 N7 H% T! U; zok so now we have our loop and the commands to extract our files but we still need to fill in the variables
# Y* L. V! U- [$ W1 S0 [9 COFFSET ZSIZE SIZE: _% P/ u6 F9 j
so that means our 3 unknown values must represent that but how do we know what order they are in?
, B' @. \4 Y7 c+ g6 I" M! U% @7 e% p7 Z* u9 v. W
Well ill let you in on a cool trick follow the file loop to the end start at Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds and highlight the whole 0x80 length ]) H1 x1 b$ |- M. V L% |3 r3 a# E
then add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B
! L! w: p4 y& {6 ~so now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F/ y6 \; J& ~6 }
" l8 v) e! S8 M- Q# b5 U' s, c8 mok so we reached the end of our loop now what?0 i! s [2 E% `0 d; y6 D
well the next 2 bytes are 78 9C and this is an archive extractors best friend when you see this at the start of a file.. L- g' T8 g, v$ |* N
78 9C represents the standard zlib compression header & s3 `! h5 s7 c L
ok so this means our first file starts there which is at offset 0x240
7 t2 q' h1 s. l9 R9 J/ @8 E' ^8 k
well lets go back to our first file in the list and look at those unknown variables.6 [& A8 C: p- u5 d4 d) V
24 72 00 00 is = 00 00 72 24 = 0x7224
F6 K0 H& p* l; I- Y80 00 02 00 is = 00 02 00 80 = 0x20080
1 r) Y- ^' Y$ O1 i- Q40 02 00 00 is = 00 00 02 40 = 0x240
5 ~2 e5 ~" q1 N1 v/ ]+ \- }I think we have a winner so the third variable is 0x240 aka the offset
$ v e. l8 V# w/ ^9 i9 `; Mso lets update our script8 t- _5 k7 d3 ]+ Z) \2 R
4 Y7 ?( Q2 u H8 @' b7 m
' b) S9 x6 j. \' H3 s, e3 RCode:& l$ T6 O) P9 m& R0 J
idstring " PSH"
9 d1 V- e" G' b; n& Q3 ]3 `get UNK1 long3 L% ?' t! i" ]( b H1 t7 r
get FILES long# ]1 _7 X. ^" E! U1 P
get NULL1 long9 A* c/ `! I' I2 l7 V9 e
for i = 0 < FILES' x- K& N5 S/ s6 j, J$ D
getdstring NAME 0x80
+ @: ]2 p" I7 G. cget UNK2 long% t( { z& T3 U; j. I8 W
get UNK3 long
. _: [5 T0 x7 c0 |get OFFSET long
5 M5 B+ D: O. Bclog NAME OFFSET ZSIZE SIZE5 m/ i' w# I% P% G: M5 ?" Z$ L" j+ x
next i9 D9 w7 T; q) M- m2 o4 G/ t! N8 f
/ {6 c. Z% }: P
0 h9 h# ?* j' O. Z: ~now that just leaves ZSIZE and SIZE2 d3 i" P- ^7 Z# [: t
well bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables" i0 X5 T- Q9 J+ R- `$ l+ Z/ L
24 72 00 00 is = 00 00 72 24 = 0x72245 J1 F4 `0 | q R
80 00 02 00 is = 00 02 00 80 = 0x20080
0 a6 g: }) n2 w$ Y% J/ [5 x `; Wwell 0x20080 is definitely bigger so we now know the last 2 variables
9 b) y/ c# O0 R! K! X0 |8 H/ ?) E8 u3 }
8 U Y! D9 \8 W/ T7 Z
Code:
! | v7 B8 C* C# I6 C: oidstring " PSH"
. A. y; s! R7 j0 ~get UNK1 long' R% B) q# x, _: G3 K8 D9 @; ~
get FILES long
+ x0 `$ b5 o7 }get NULL1 long
% W. p4 ?1 h0 c2 Mfor i = 0 < FILES
$ }& Y5 E/ ^5 ?getdstring NAME 0x80
3 r( u$ r; k# C( G6 q7 B( p; Jget ZSIZE long
5 J! U) \7 j4 p1 D Qget SIZE long
' m- M% ^( X, |6 o% sget OFFSET long
" @% R: _" E, m+ fclog NAME OFFSET ZSIZE SIZE
, e P8 F$ A' R a; |0 cnext i6 R* v8 Q0 `% F; ]+ {* _
$ S& J0 q( | y$ |; ?% f
* `; O# I5 v: a8 Hnow try our code out on the file& o0 d: Q! R* I+ t* r
open the command prompt and change to the directory
% ~2 G& [, l+ O' q) e9 Sc:\temp3 s, v% M# a/ V/ ^! }* y
now type
$ r' s: k; V; H8 b( L/ n$ S4 Yquickbms.exe -l astro.bms BoneObject.hsp .
& L+ f) m \! R, a7 _# [" W- t8 Ayay it listed our files without any errors now lets try extracting them/ P6 O9 d1 W. x' y" ]& T
create a folder called extract/ B* J- K6 h! P* j! O* G0 y
and type) [( P: Z5 z/ |3 ~
quickbms.exe astro.bms BoneObject.hsp extract5 b" K1 u: C: U, S; V
if we look in there we now have folders and in those folders are 4 pictures % T) P/ D/ a" q" x. a
we did it.) c0 q# k+ h0 |
, g1 w8 @7 }$ P8 R5 f& t2 ~
Let me know if you want more pictures or any way I can improve the tutorials.6 i, x. y. Z6 M
7 I% G; T* t+ \* b% Y6 x
! ?5 r8 n+ L# M, @# D# U
Last edited by chrrox on Tue Jun 09, 2009 2:33 pm, edited 1 time in total. |