ok so set up our c:\temp directory bye extracting our file BoneObject.hsp
3 E* H7 _/ W7 A) H8 E" v! I1. to c:\temp1 ~+ x0 p2 Z, h/ j8 a `
2. create a new text document called astro.bms
; ^+ u" X! F7 [3. and place the newest version of quickbms in the folder also.4 E+ I0 }1 }$ L0 [- L5 i
7 F& |$ d% v0 GOk so open up BoneObject.hsp in your hex editor and lets take a look at it.
$ e3 T- c! N+ s! i
2 m: `5 B8 E" U) Ogood we have some plain text.
" u' P6 q* u7 J$ A% Byou will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
7 A) K# _7 N8 r, {5 Z% C0 Y6 O$ U, yhmm that seems familiar that is the file extension only backwards. this is know as the idstring0 r) i/ I7 f+ T: c7 u: V
so up until now you would think to write in bms
" _, Y5 Q" q% }9 I( M+ Dget IDSTRING long
3 h: V" D1 w% d5 ?9 [there is nothing wrong with that but there is a better command
' e" c; W7 `! v- X0 l1 ^& cidstring " PSH"
. O2 f/ G8 |) I! G1 t0 n4 B# V' pmake sure you include the quotes.
0 B1 V# N1 ?! hso open your bms string and on the first line type/ _5 z" I* N$ @: M
idstring " PSH"6 V8 b- J2 h! U5 z( z, H
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.3 L; y7 ~8 Y( ?; a8 q3 Y. g4 s; E
"aka noob proofing it"
+ \' ]/ g2 h! R1 i% U' n# b
: P7 V9 R* O0 z/ Z$ m! k' LOk so now lets look at what we can read I see * f4 U" R$ n; Z6 [9 U
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- ]: q2 k0 u+ c6 a
so I will assume there are 4 files in this archive.* W9 |3 p8 s8 D C/ ?
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& L, c7 v! c. E( R+ ^, V: D
so lets write that in bms language
* @4 Q" k8 _$ Y5 V/ nget UNK1 long4 i. u1 _6 i, J8 V' f# A! ^# @
this saves those 4 bytes as the variable UNK1.7 D$ u$ q8 V+ q& `: q7 v$ I
4 f0 k% ]8 y$ m) ?1 p6 iok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 4! Z& Y9 @- o8 u1 F% E3 Y. X
hey that is the number of files we counted so lets write that in bms9 m( z# O) K" o( `. w
get FILES long
/ [; C& _% @1 V- _) Kthis saves those 4 bytes as the variable FILES.( c3 y7 J% Y- G9 S# b2 K6 @' I. b
: a( @; R x7 i, [; T( f" o8 g1 T1 D% 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. `8 K! c6 f3 N$ T: r) l/ C
get NULL1 long5 q& N9 K6 {( T; j: Q8 d
this saves those 4 bytes as the variable NULL1' Q7 H+ r# Y0 J, l0 o8 b
; q! m- I0 i9 aok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds/ B0 L# n3 _5 j
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?
0 J' e% Y; b4 e; T1 \well lets look for a pattern
+ a# _& g$ c, j; Q8 QDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36
) Z: R# e1 i/ i! R, j. e: [Datas\Texture\BoneObject\Toon.bmp is 0x21
0 Q4 m; H$ a" O2 gDatas\Texture\BoneObject\Toon_a.bmp is 0x239 S. c' A; t' _+ F0 j2 a8 k
Datas\Texture\BoneObject\Toon_zero.bmp is 0x26
4 ^, x% G- t0 S8 g2 V: \1 a6 xhmm I don't see anything that makes that a pattern.
- B/ v7 J, Q+ D: dbut I do see all the names are followed bye a lot of zero's. how long is the name + the zeros of each file?
9 G# R6 I9 q; Q, d3 E; GDatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80
* H5 J5 r, M; a% E( l( KDatas\Texture\BoneObject\Toon.bmp + 0's is 0x80
& Z& N( `$ W: ~2 V! eDatas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80
7 u+ c; w) X3 j/ i( Q+ qDatas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80
' W, c" z5 m0 Bhey they are all the same size when I include the 0's
u: ]/ a3 {% i& o- Fso in bms I would write this as
# a! T _. p4 L3 I" i8 Hgetdstring NAME 0x80: D' _, b; @# @0 Y" P
this tells it to grab 0x80 bytes and store the text value of it
7 Q4 C, a( G# f# }; Y q' Nand as an added feature it will automatically remove trailing 0's
( `% o' e4 {6 t5 a; y+ v0 _& e+ q& M$ |
ok so now we have 0xC bytes before I see the next file name
& K% X1 N- c; P8 ?6 N# |; |which is 3 long values
3 a- j# U: ^" e. [so lets write those in and we will figure out what they represent later./ Z! c1 |. `( N4 ^
get UNK2 long# u# }5 B; n2 Q0 N5 w: r
get UNK3 long
3 G, |- j8 V& d' ?% G, j5 Mget UNK4 long
9 U- {$ D* Z* L/ I' c) X
" a$ u) r/ o( `1 `1 F. Z* b; l Dok so now we see the name again
9 R) h. B! |- q( x$ F' xwe have our pattern so lets write our script based on what we learned, j! n, B% B: S ~
so it would look like this up until now( u1 @5 `! c3 I, `9 f+ `
7 T3 `; I9 D4 q+ ~0 sCode:
5 a+ w: \& C$ C6 d+ M7 q! w5 Yidstring " PSH"
8 z8 l. u5 v b# L9 L3 u& |% {get UNK1 long
$ m7 b2 |7 F( V) d; n# Sget FILES long9 v8 }: v) h& Q* y0 g1 I7 }
get NULL1 long8 C9 g* p7 R3 G7 U' Y; V3 V+ @3 d
for i = 0 < FILES
! p+ e: j' d- w* F2 h2 b* I2 Ggetdstring NAME 0x80( e: m( f7 w( L& B
get UNK2 long
8 n8 Q% K3 f# _- |get UNK3 long+ }) g: v8 m0 G3 Y5 a
get UNK4 long
$ g" l4 |$ A& R; {clog NAME OFFSET ZSIZE SIZE
! s- t; o+ S2 b0 Onext i
' H0 L7 e5 [, H/ Q" \0 j
6 P( i4 w6 K" I6 D" P3 C& g4 I, F. L) K5 O9 O; T+ N, ]) [$ U7 ~( Y, e
ok this may look complex but it is almost identical to the first tutorial file except we added 1 more variable
: Q% d/ t/ F5 v$ f6 w- H/ N' xZSIZE this represents the compressed file size while SIZE represents the decompressed file size1 W6 U! m' u- E' I
and we also changed the log command to clog to represent it is a compressed file.- S* {8 a2 _" d
+ @+ o7 p2 g# Q' Z: ?! d9 E0 R. M$ Fok so now we have our loop and the commands to extract our files but we still need to fill in the variables* Z9 e6 Q' c1 V! [/ \& p
OFFSET ZSIZE SIZE# m" H. S* z! d2 f0 \; `) }
so that means our 3 unknown values must represent that but how do we know what order they are in?
4 p/ Q5 y* D; a1 l2 V5 z
6 K& s; ~- J) g# v# s, z: ]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
+ |4 L9 t( y$ {5 I- V9 Fthen add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B
) n, W4 m4 Q4 N8 @so now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F
& _" c0 G) z4 S& r- P# E- @& p # t+ }7 c w) O7 H. R
ok so we reached the end of our loop now what?
, ]) }7 _! X* v5 r. cwell 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.
/ _! ] P3 l7 k H3 j+ X78 9C represents the standard zlib compression header
+ ^, l1 N! i( D0 L4 |5 kok so this means our first file starts there which is at offset 0x240
- ^& }7 d( m# T* \# k! r5 B
- y" ?9 ?3 ]# P% d! N; m# Zwell lets go back to our first file in the list and look at those unknown variables.
0 h5 X7 `) h3 u/ r24 72 00 00 is = 00 00 72 24 = 0x7224& o9 K; D/ e4 | y7 K; N- |# \7 W
80 00 02 00 is = 00 02 00 80 = 0x200809 c2 Z, L8 T, x K2 T; B# @
40 02 00 00 is = 00 00 02 40 = 0x240
' T! a9 b! y$ b! g" A. MI think we have a winner so the third variable is 0x240 aka the offset8 m4 S, ~: k1 z9 R
so lets update our script
( R/ p" i. A. _* U4 ?( c% b$ V& S9 n
- R e- a) s8 w2 L) e0 B6 f: m' F( H+ U" W
Code:& K2 f& ?0 s7 w. v: w p$ a
idstring " PSH"7 O9 s) T* {' Y$ v3 B1 z
get UNK1 long
( G. J1 w/ T& s% G/ [get FILES long7 W1 K1 m' r! e6 N/ R( U' } ^. Q
get NULL1 long. `2 C# w+ U/ g, i) M0 W
for i = 0 < FILES6 {- @& N; S% z8 V& S: K
getdstring NAME 0x803 ]3 i& s P6 ?
get UNK2 long
4 h ^; |0 `% d, Vget UNK3 long
' A/ N5 k) {' v; o6 Mget OFFSET long
/ J5 q% c( r: P$ p3 \; tclog NAME OFFSET ZSIZE SIZE' M3 m8 y; C& ~) S1 |- h
next i
' U- i& j( n! H. G; F5 i% c* w) m& U* i3 R' X% i
" o6 x0 _& l* V: P
now that just leaves ZSIZE and SIZE
1 l6 l R6 Z; w+ `: G+ D' cwell bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables* X8 T2 V/ m5 s0 L
24 72 00 00 is = 00 00 72 24 = 0x7224
3 p7 l; v* E5 J8 J8 \80 00 02 00 is = 00 02 00 80 = 0x20080
; Q# a/ L9 I% ?) z2 Vwell 0x20080 is definitely bigger so we now know the last 2 variables6 u' a$ G$ N* A% a) w
2 P- Y, h, V5 d1 S4 c" f' O
: f0 u; H. ? X# p, }Code:
1 n8 q1 G* B5 g0 m; X7 C5 N3 tidstring " PSH"
1 e7 ~8 [2 c3 {; ]4 p! `4 {7 Kget UNK1 long
/ S4 \( b+ Z$ i& V. Y' vget FILES long2 T7 f& t7 j2 `4 l
get NULL1 long) _# [& n" A& Y& ^
for i = 0 < FILES
$ H( ~$ b0 T7 Xgetdstring NAME 0x80
5 M2 h; G, Q" |: U3 eget ZSIZE long3 D r- k# Y6 m# Y( N8 j4 G& ?
get SIZE long/ H% s: T) G7 J) I
get OFFSET long% p4 y9 e/ n9 y3 B1 v! }
clog NAME OFFSET ZSIZE SIZE. N9 n$ G/ U$ [- J) ~/ Z) |
next i( L8 ?- y) s# j# {0 x( S+ Z+ W
) `. u, w8 R/ ]+ K
$ B9 G- u+ L& f# |2 v
now try our code out on the file# a9 s& @ `' j; H2 j# w9 N
open the command prompt and change to the directory. Q7 K3 X& d: |& c: v. y
c:\temp( @' a% f0 S7 O
now type
$ O! ?* s8 r, N: ?- x4 \quickbms.exe -l astro.bms BoneObject.hsp .
* w# }3 C+ p2 k& [' uyay it listed our files without any errors now lets try extracting them
U+ }- x) S+ v. f. C( p# {create a folder called extract6 J) w( g [3 Z) G+ X$ {2 J" v
and type O! q9 B! _% G1 X& |) h- u7 ?
quickbms.exe astro.bms BoneObject.hsp extract5 F/ Z6 y$ q' Y" o+ x% i9 r2 \1 i
if we look in there we now have folders and in those folders are 4 pictures
3 C9 h" q9 l# } k+ I" H' q2 Cwe did it.
r: S) \8 x9 {' Q' Z0 a: {- _- B/ l3 m
Let me know if you want more pictures or any way I can improve the tutorials.3 n# C7 X9 a9 A
: S4 N# T6 a- e) Q
' y$ @. f8 P6 @; n+ {( B+ hLast edited by chrrox on Tue Jun 09, 2009 2:33 pm, edited 1 time in total. |