ok so set up our c:\temp directory bye extracting our file BoneObject.hsp' ^+ n9 X2 W: v" S) r
1. to c:\temp# y6 h9 V* w5 B2 F
2. create a new text document called astro.bms( M( j; R7 g3 I3 W) i
3. and place the newest version of quickbms in the folder also.
2 q- |5 Z( v; t, O" |! Y
X3 H/ K. P, W- L" i7 ROk so open up BoneObject.hsp in your hex editor and lets take a look at it.3 ~& h3 A( |4 E
4 P# R1 d1 o: w3 w) i \
good we have some plain text.0 I) x0 b, n/ ~8 J/ Y
you will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
: M( i7 g" r% V- |- l4 z4 c% Vhmm that seems familiar that is the file extension only backwards. this is know as the idstring
2 z, v9 N- i" e* a! B4 E1 w Fso up until now you would think to write in bms* k2 A" I- M) ]
get IDSTRING long
6 Y- V; D2 y3 P3 O9 h# f" Ythere is nothing wrong with that but there is a better command) l1 R) G# ]5 B$ D
idstring " PSH"& @. ^% j M2 ~+ v" [, u$ i8 T: ^
make sure you include the quotes. C2 \7 }8 S) ?% P" R" R* J
so open your bms string and on the first line type
3 J) y1 a# M- n5 A! _& yidstring " PSH"4 A6 w5 s3 u% {
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.
; |$ U3 V% L: e* v6 a8 ~/ f"aka noob proofing it") I9 d. @2 M: [/ C, S
! `7 B' R2 h1 M$ ]1 a0 j. h4 iOk so now lets look at what we can read I see
/ [: j7 u+ [ h7 u+ `$ U7 @3 V- jDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds , Datas\Texture\BoneObject\Toon.bmp , Datas\Texture\BoneObject\Toon_a.bmp , Datas\Texture\BoneObject\Toon_zero.bmp6 f# F9 l7 h( h2 l2 x h% Y
so I will assume there are 4 files in this archive.# e9 k" d5 f) G5 X1 p
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 represents! i7 O9 t: H2 N
so lets write that in bms language
* e% c$ F# u' u M& X/ l* dget UNK1 long: `8 i# U0 }5 F6 ^: K7 c7 R: `6 R
this saves those 4 bytes as the variable UNK1.
( g5 ]/ U2 i8 \% f( l+ ^* \, _
8 P; r; M7 t& }- ^5 {2 b* C6 l8 }ok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 4+ W; A, C5 u, G
hey that is the number of files we counted so lets write that in bms) Q. H- q+ {" B: _5 I2 u
get FILES long1 ?5 D9 Z( k" j8 S2 a
this saves those 4 bytes as the variable FILES.
8 t9 S9 T/ {; _
. D1 g% G9 {8 }( t6 b5 Athe next 4 bytes are 00 00 00 00 well that is equal to zero so for now I will write that in bms
* E+ |- c; P9 Q! o jget NULL1 long
: S) a3 c" E5 zthis saves those 4 bytes as the variable NULL1
1 J; J* e$ x9 J) G" I
9 L0 p4 r: t3 Q. Q# {) Jok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds9 j }2 y Y( l- L% ?1 F5 B
this 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?
) f9 q$ n- \% C3 U" Gwell lets look for a pattern
+ a! k$ K( ^* a* c, j5 xDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36
% G. ?4 k% f! P* `$ D. O; pDatas\Texture\BoneObject\Toon.bmp is 0x21
# q# s/ G3 p! Y) G% vDatas\Texture\BoneObject\Toon_a.bmp is 0x23
1 x+ P) y# c5 [" p7 |3 Q. XDatas\Texture\BoneObject\Toon_zero.bmp is 0x26
4 m. \( K5 ~. o1 F) ^hmm I don't see anything that makes that a pattern.) s' k* J% q' x1 @
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?2 j" N- L, Z* A
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80
' w% B7 m/ Y3 g, x( k& ADatas\Texture\BoneObject\Toon.bmp + 0's is 0x80& e' n, K9 Y" W+ D
Datas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80. {, x* R% m1 Y% F/ _1 L) G! C# [
Datas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80
. I. ?& u, Y! S8 jhey they are all the same size when I include the 0's
0 [& o- R$ |. a$ W8 mso in bms I would write this as
! h; v0 k( n ]# L( n. ngetdstring NAME 0x80
. l" c, `/ f' S5 mthis tells it to grab 0x80 bytes and store the text value of it, x# |8 Q) z- f. N& v; O4 I
and as an added feature it will automatically remove trailing 0's 4 p1 U1 O& F: [6 n: w9 J! C- f& |
1 K1 V6 b2 d7 f/ X' pok so now we have 0xC bytes before I see the next file name4 E) o& [' l) |* u! d$ W' I2 P
which is 3 long values8 {/ b3 E! I, x3 `8 x
so lets write those in and we will figure out what they represent later.
6 `0 r* R! g! a5 C3 S4 j- Wget UNK2 long( ^: _3 a6 _$ O4 ]: S l
get UNK3 long4 N* \( c: A1 F. ?# }6 g+ K
get UNK4 long
9 E6 ^7 u) H" a" d7 O/ L0 w
1 k; h3 B% {& \. X4 J* p: Xok so now we see the name again
2 h( i. k/ H T: vwe have our pattern so lets write our script based on what we learned
1 ~6 {4 S7 e+ s! B5 }0 v1 j: eso it would look like this up until now
, U7 L5 S6 k* X( T1 C: O9 a/ x7 T- U8 w& O! ^9 O$ d
Code:# F3 P1 D+ C& B' _1 M6 A# d
idstring " PSH"$ l/ c& `% }$ A
get UNK1 long1 @6 n! ^8 X! v8 n3 {$ X C
get FILES long) R- s) k% a# o$ g
get NULL1 long
! I; B6 X( \ I: l3 H9 G c1 ofor i = 0 < FILES
6 f, A* ?9 H, c' K4 h1 C% P5 Lgetdstring NAME 0x80! b) S; `, D/ i8 l1 M
get UNK2 long
& \. P D: ~( ~, jget UNK3 long
+ Q) @3 d$ N& V' sget UNK4 long
b) V* N% k7 @# a3 eclog NAME OFFSET ZSIZE SIZE4 u( r+ Q2 s2 x( l- q- u
next i
; \& ]3 B8 x( }) S' k Y, N
/ q: m, l' h" b' q, R' ~
( z8 n4 H+ z# J8 dok this may look complex but it is almost identical to the first tutorial file except we added 1 more variable7 A1 Z6 M- t5 o. z. a# d6 v
ZSIZE this represents the compressed file size while SIZE represents the decompressed file size# d& s, q$ S+ a0 n& b
and we also changed the log command to clog to represent it is a compressed file.
, {8 V: W9 Y) H& a4 r) N! T s# U
" u! l: ^2 o+ y- L$ Y& dok so now we have our loop and the commands to extract our files but we still need to fill in the variables* O" j: Q/ _% }; d9 ^6 |$ f. @
OFFSET ZSIZE SIZE
6 u, O' x! [- V1 |4 q3 U! kso that means our 3 unknown values must represent that but how do we know what order they are in?: F0 a- r0 G" g1 ]
; \ y5 C" Q* ]5 J) ?7 q, t% nWell 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
1 k/ z2 k. ]4 h8 e+ sthen add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B
6 m3 Y6 \" C. e4 b+ Kso now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F5 A; u3 s6 [* d6 i7 ~
% [) y' u6 h( K) y' i! _7 l
ok so we reached the end of our loop now what?3 u% P( b& ]. ^7 a9 X& d# c
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.+ ~; a2 ~' \. W. N( [- C6 y
78 9C represents the standard zlib compression header
8 A/ s! y7 I) X- m$ gok so this means our first file starts there which is at offset 0x240
) L; Z4 ~& c O& O0 N6 V7 s! X4 |- a1 I! \! f8 j3 F t! Q( N" S
well lets go back to our first file in the list and look at those unknown variables.
7 J# c2 }( s! @24 72 00 00 is = 00 00 72 24 = 0x7224
1 x8 m' r9 E5 q0 ?+ H8 J( P80 00 02 00 is = 00 02 00 80 = 0x20080
3 D+ y/ Y/ D3 X$ p1 Y8 F! }40 02 00 00 is = 00 00 02 40 = 0x240% h. Z, p9 T0 [! E& L, C2 Y( w
I think we have a winner so the third variable is 0x240 aka the offset
/ `* ~1 k$ P! s' |) G8 ]* D0 T4 l# \so lets update our script- ?- b2 @6 @% I* C* B: r+ ?/ m! H% D$ h
: L- t# X- a) O! K
1 s0 _. V- Z) M! b3 I1 oCode:' ]' x: w& S( D/ ]; Q4 p4 T* }+ k
idstring " PSH" @ L- d E9 i" p( G: N" V
get UNK1 long
6 ^) o7 Y+ X/ b" \9 Gget FILES long
( v. q- n' C3 Jget NULL1 long/ Y, l( H. H1 y" c
for i = 0 < FILES) o0 {' {& p/ M K3 G- J3 p
getdstring NAME 0x80% C3 J8 q3 Q, L! T
get UNK2 long
8 A# H- s) {, i" G- c* O) l M: Xget UNK3 long
9 o7 J0 n! }+ \4 @get OFFSET long
9 d6 ]; E% H- y4 yclog NAME OFFSET ZSIZE SIZE4 d5 [' J1 ?- d# X
next i O* x5 N( }8 A% Y
- j) g& m; x4 J4 [/ C0 e
/ Y9 A- {9 i, }5 fnow that just leaves ZSIZE and SIZE
& N3 y( d' ^7 lwell bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables
2 X0 i* K! }0 P' A. }- m6 c24 72 00 00 is = 00 00 72 24 = 0x7224' T! Z7 e/ }9 X! p/ n) V
80 00 02 00 is = 00 02 00 80 = 0x20080
! Q9 _4 l- C8 h4 S, Jwell 0x20080 is definitely bigger so we now know the last 2 variables. ^! V9 g0 x( w% P' z
+ V: r. ]; ~& c$ U8 V* O
# @ ^. q$ e! D y ~' U" i R: m2 iCode:( y( F/ f& M6 S2 c
idstring " PSH"6 F, A& i( L" x5 T( Y
get UNK1 long4 }" R) h) {3 F' S2 X8 ~9 K! W' @. t2 y [
get FILES long
8 b, \- e: ? s( I: V3 Q& {get NULL1 long$ e4 o; h4 f |) y' u
for i = 0 < FILES, I5 p8 H5 f: b$ W7 A/ R2 R
getdstring NAME 0x801 i. V- i2 o, c% q
get ZSIZE long
) | l- t7 d/ [' K3 `- H+ @! }- iget SIZE long! E7 h9 d6 G- P0 R0 o
get OFFSET long9 d: D; U. r7 R( J, J) d8 }6 g
clog NAME OFFSET ZSIZE SIZE) h) R9 R5 B" j+ B& |* k
next i
) P H0 f4 I( q# P7 M- B3 m# @, M
' v [" t. }# R; m3 }# G
% i [! i1 S t6 H- L, y) H7 O1 l# }: unow try our code out on the file# B7 ~6 J- ?" @4 d
open the command prompt and change to the directory. K7 a6 H' M( T" H, W
c:\temp
- ?2 i5 D5 |) g T1 v9 R- [now type0 w* U. o+ A# q ]
quickbms.exe -l astro.bms BoneObject.hsp .9 {; _8 F6 H% |6 T
yay it listed our files without any errors now lets try extracting them7 l5 A) [$ k( o
create a folder called extract. f# _5 l$ Q( x7 a# u( b! b
and type5 u7 Y8 z! w6 ~) l( y* d
quickbms.exe astro.bms BoneObject.hsp extract f0 V& y7 z% T+ O, V. @
if we look in there we now have folders and in those folders are 4 pictures
0 `5 M$ ~, ]2 {8 W0 t) w2 h4 Qwe did it.
1 F& U6 x9 N( g+ |. {/ y) _
$ n# [. v# m2 I5 _" E) x* CLet me know if you want more pictures or any way I can improve the tutorials.! ?4 r" ?1 O: H& ]3 z
9 F7 h# f, Y. K- x6 l
5 X$ S1 n5 ]6 N% p/ g2 R% ]
Last edited by chrrox on Tue Jun 09, 2009 2:33 pm, edited 1 time in total. |