ok so set up our c:\temp directory bye extracting our file BoneObject.hsp
* s# {' J. u" h: h/ n" }1. to c:\temp, r- Y4 y' h- M, }# S
2. create a new text document called astro.bms
& d T9 c9 }' U3. and place the newest version of quickbms in the folder also.
f& z A6 m% H! w- n0 X0 W0 V. C0 q; u" A# [" z* F+ ]& f: g
Ok so open up BoneObject.hsp in your hex editor and lets take a look at it.3 _, Y, L5 P4 w3 V' Z2 i( t
3 W3 j* H$ Z% T; \good we have some plain text.& U# ~3 {, U$ z% d) m% ?% S1 Z: d
you will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
/ P' q0 n% m$ S1 _hmm that seems familiar that is the file extension only backwards. this is know as the idstring9 x! g3 z; |8 t- \8 v
so up until now you would think to write in bms
8 z: M/ \, Y9 I- Iget IDSTRING long+ u1 R! c1 T4 @0 D g! \$ o* U
there is nothing wrong with that but there is a better command# U" A7 ?2 B' L
idstring " PSH"
5 D- P0 v. Q$ y5 C. N7 U. ]2 [make sure you include the quotes." P4 G3 j; {0 x
so open your bms string and on the first line type
M; t% [8 t4 F. @idstring " PSH"
3 ^. X6 C: M% ~& ?7 |$ _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.! s9 H; o! P! v# j
"aka noob proofing it"
3 ^! F" b: {) v ]
' u; S ~ w! iOk so now lets look at what we can read I see $ b3 D3 P7 v# e% S) q/ I
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds , Datas\Texture\BoneObject\Toon.bmp , Datas\Texture\BoneObject\Toon_a.bmp , Datas\Texture\BoneObject\Toon_zero.bmp
1 _' R4 S8 |* Hso I will assume there are 4 files in this archive.
! s9 R' V7 b5 Pwell 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% Y8 {/ k2 L! C1 B) \/ z$ m0 `
so lets write that in bms language
3 U. ^( @. B& s' R7 M' `% Cget UNK1 long
9 J% r2 Y# y% \& J; [, x/ Dthis saves those 4 bytes as the variable UNK1.
6 v5 {# Z1 G% P5 Y& G
$ a( U- w0 b( \, s0 Y; {7 S; Sok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 44 A6 M" w0 S" z/ W3 Q% c3 h
hey that is the number of files we counted so lets write that in bms
2 M5 K2 \- Z/ a+ ~9 g0 [get FILES long, ]" @! \1 l# T8 B, X- s, r2 o
this saves those 4 bytes as the variable FILES.% y; }. v/ R+ J. A2 b1 T* X7 ~0 @
4 b! c8 T9 F, v2 z4 Xthe next 4 bytes are 00 00 00 00 well that is equal to zero so for now I will write that in bms# N6 V* R/ n* R2 k2 Q
get NULL1 long
; ~% E, w6 k3 H% p# N$ M/ Athis saves those 4 bytes as the variable NULL18 O7 U5 K* h+ X$ \- D6 P7 ]
7 A4 y" X( |9 i
ok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds
) {. k" m) P9 K5 Q: H' G/ G% _5 Athis 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?
8 W. V( r* w3 b+ A8 _+ t5 c, ^; [well lets look for a pattern( e7 h& @+ A, N2 W: L
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36
{/ Q$ r9 j( D& p! xDatas\Texture\BoneObject\Toon.bmp is 0x213 C9 R, S8 n6 d: z$ E4 k9 Z; @
Datas\Texture\BoneObject\Toon_a.bmp is 0x232 `7 ~ }' o: u1 b! i x
Datas\Texture\BoneObject\Toon_zero.bmp is 0x26$ \% L+ h, {+ O- }& I4 l( K
hmm I don't see anything that makes that a pattern.) F9 t2 E8 I' J8 [7 ~
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?/ S W; C" p3 I' o$ N
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80
9 Z) x' p, c1 ]+ j2 f- X7 ]Datas\Texture\BoneObject\Toon.bmp + 0's is 0x80
. F: t' ]. e0 t- eDatas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80
: K2 J6 W0 t. wDatas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80
s, a' A) R+ p' Ohey they are all the same size when I include the 0's
7 a+ O( B9 P& U9 r1 ~' h- [so in bms I would write this as
+ l8 x! T0 x4 p) o7 \) l; Jgetdstring NAME 0x80. U+ X3 Y; r8 a& D
this tells it to grab 0x80 bytes and store the text value of it5 e2 I/ S o! N- f, [; s% X
and as an added feature it will automatically remove trailing 0's
) z7 j) q Y7 Q n7 N6 L( c1 @( t# q' y# I
ok so now we have 0xC bytes before I see the next file name$ y: a7 Z* ]% P+ M4 A; _: h! _
which is 3 long values' e5 ?" l( S1 r: E) j$ I" q8 x8 f
so lets write those in and we will figure out what they represent later.
) E: R3 \/ Q+ f% ^$ Mget UNK2 long
5 j R) i W! X: `" l1 g, z- l' jget UNK3 long
- Q. a" a2 a) Q2 qget UNK4 long: A: A, [+ C% ]
9 P) }! L' r( k& F6 i7 J0 Z$ I
ok so now we see the name again' _/ v% a, v: v7 Q9 z. Y
we have our pattern so lets write our script based on what we learned
_7 T& K* i! z5 l9 Wso it would look like this up until now
4 U! Q9 `; l; y0 Q8 [ _7 ~0 `5 x6 r. N+ D' l% J
Code:
) o+ }2 d4 x+ H( c8 C7 Q' t( fidstring " PSH"
|+ K+ a. Z: q7 i5 lget UNK1 long
$ X( G4 X3 m7 h$ W, j. }get FILES long
& D( L* w! l; t( Q5 s9 [get NULL1 long
; c. |" o( n- j4 g/ J+ H, Ufor i = 0 < FILES, o' k2 H2 l( N
getdstring NAME 0x80; ?& o- Z5 K6 Q1 r6 Y
get UNK2 long0 E" h5 F0 j$ u) E
get UNK3 long
# y, m L) \2 V! g1 zget UNK4 long
( t. X9 T* g i4 O; H( {" Pclog NAME OFFSET ZSIZE SIZE, G: J+ R }/ P3 T7 P9 Z
next i' K- K' o5 Y5 P _: T
% ], H) h Z: [1 @" Q: f
$ t! `1 q5 w8 d; Q" R3 N- I7 nok this may look complex but it is almost identical to the first tutorial file except we added 1 more variable
; u0 B1 H2 x# J- Q* C7 x1 o/ lZSIZE this represents the compressed file size while SIZE represents the decompressed file size
+ l" W+ z! i" a9 rand we also changed the log command to clog to represent it is a compressed file./ K: v; }& h. O! l; w* N
; y2 A3 ~6 y5 r; f7 g4 v0 `, x) [" P+ m
ok so now we have our loop and the commands to extract our files but we still need to fill in the variables0 [1 s( [ r# P$ o2 {% [' H
OFFSET ZSIZE SIZE; J# {1 g; h- E6 G, S
so that means our 3 unknown values must represent that but how do we know what order they are in?
! c2 m2 Y: d; U8 @8 E& h
6 V2 x3 Y+ X2 l- j+ l4 Q* aWell 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 length7 A# v | F. P+ V
then add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B
H7 h) A. _+ V1 h2 k) a7 iso now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F5 U8 [$ m" ^( M" G2 `7 ?
8 |4 T+ B7 I3 |3 C) uok so we reached the end of our loop now what?
5 m0 c4 J4 q; f8 J$ H/ g0 pwell 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.4 V* }! `6 c+ a+ Y; U8 [; e8 `' l8 |
78 9C represents the standard zlib compression header , t$ [( b% Y' U+ P. C
ok so this means our first file starts there which is at offset 0x240; ^% F* @6 D' v4 t1 a# D" _+ Q
4 P" t; ?2 v# }4 \& M+ }0 w
well lets go back to our first file in the list and look at those unknown variables.
% @- b- q0 |6 w) d- `24 72 00 00 is = 00 00 72 24 = 0x7224
X5 T Z: D$ Y4 j80 00 02 00 is = 00 02 00 80 = 0x20080
5 e, K0 J( K& @/ R1 w: c, a' `40 02 00 00 is = 00 00 02 40 = 0x240
6 v( W+ ]& j, m+ q. @8 Y7 p2 f' KI think we have a winner so the third variable is 0x240 aka the offset
9 F, S: z4 K8 C# cso lets update our script+ {! O0 T5 y4 y; H$ m# {, V% p/ u
1 q4 r9 k7 t2 U) H
$ q: Q8 f/ k+ w2 d/ n7 b& ~2 FCode:
- ]8 N3 ~4 [! b" w( Aidstring " PSH"
+ O8 F; D& A; G1 ?get UNK1 long
7 o& b3 z4 B6 Q+ h1 ?get FILES long& C7 W. ~- l, [& k6 c6 D
get NULL1 long5 _: A F, z, I; w: Y
for i = 0 < FILES, M o& v$ I+ I3 I7 D+ `4 `
getdstring NAME 0x80; W @. U0 l" d2 c6 I
get UNK2 long8 x/ A% c$ n) L0 `6 G5 T$ G2 {
get UNK3 long' `+ j; u* o! O' b) w, g1 \
get OFFSET long9 a8 C7 ]4 J* R! `4 a; V
clog NAME OFFSET ZSIZE SIZE
9 K/ F% C" j o+ c4 Q _$ Onext i y( G6 y& Y3 x: s/ F/ G
. K# p/ f( @% h. x' C
) q. M9 a6 y& h7 F% X0 \" J; y4 qnow that just leaves ZSIZE and SIZE
6 K% F$ P( d7 E% n# ?well bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables
7 L3 }- h6 _. R: l# w. z24 72 00 00 is = 00 00 72 24 = 0x7224" a O( l( [' J) f
80 00 02 00 is = 00 02 00 80 = 0x20080' \8 i. ?! o+ C1 b( E' s* U, g
well 0x20080 is definitely bigger so we now know the last 2 variables* B/ i$ h6 [* A/ p- ^7 C
" ~, B- r i3 J' i5 D, G! H8 f+ j& J ?2 j! C0 d
Code:
, J1 p3 d7 R) w Hidstring " PSH"
) G. d) S* C, H7 r3 f, P iget UNK1 long
2 O; B3 E% R, O3 nget FILES long
3 O" \( V/ I& z& a. k) d Y& Hget NULL1 long& o' g! p( [& Z# p
for i = 0 < FILES) C# R) {2 Z7 O2 u$ S8 p3 I* Y
getdstring NAME 0x80
4 d! D+ Y# y; G* n1 Q' J' ^get ZSIZE long2 x. c; x9 ]9 z4 E. W% k2 Z4 f
get SIZE long
2 G6 ]9 e% F8 J$ D) M* eget OFFSET long
! m% ^4 l; [' z" Cclog NAME OFFSET ZSIZE SIZE6 S1 ^) b* C- w. J( Z
next i3 e9 k- y% g- R1 f3 {" ?
* @# F" D( ?8 Y% X Q) n d$ [) T/ Q% o/ r- o
now try our code out on the file7 H- |" k& L+ }5 \7 O* X' ~
open the command prompt and change to the directory8 N5 v0 f( E/ u" f6 W
c:\temp2 {8 l5 o4 h( u) [. w
now type
# r9 h% o5 s; L9 xquickbms.exe -l astro.bms BoneObject.hsp .8 t# Q8 o" i" v& F) H4 V+ i/ d0 k) D
yay it listed our files without any errors now lets try extracting them8 Z" p' U9 i2 g1 u9 X. F7 D. D
create a folder called extract
; C G2 w! Y8 U6 I9 L& Land type) G; z; b% D" ^1 Q1 H
quickbms.exe astro.bms BoneObject.hsp extract
1 K/ d9 w9 K9 L5 N! Nif we look in there we now have folders and in those folders are 4 pictures
% I6 i) Q! \8 w8 z$ |we did it.
T: Z& c5 ?8 _1 o3 `) ^) c! \# ?! ~( n( L' l% p% d; |% K% P( l7 j
Let me know if you want more pictures or any way I can improve the tutorials.4 D! I, G# `/ }9 F
9 G3 Y N7 q5 C8 `, Q
f6 S3 {) V5 |3 ] u5 [
Last edited by chrrox on Tue Jun 09, 2009 2:33 pm, edited 1 time in total. |