ok so set up our c:\temp directory bye extracting our file BoneObject.hsp
2 t- V. b& P/ R* ~. z; ?; \1. to c:\temp
9 ?& y$ ?0 `) ^3 a4 F2. create a new text document called astro.bms
. R6 O2 ~6 W7 }$ Q8 y. |3. and place the newest version of quickbms in the folder also.
! s1 ?! b6 a3 U$ S$ l4 L
) Y2 O' i& }8 j$ a) HOk so open up BoneObject.hsp in your hex editor and lets take a look at it.
5 l& c5 W6 T$ ~4 N8 E h3 I! l W, U
good we have some plain text.$ i6 k! ]! l o. f9 O# e
you will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
' y1 u5 ?% b& F2 V( R) h& M& [hmm that seems familiar that is the file extension only backwards. this is know as the idstring
6 _( Y; m6 h. J$ Z4 kso up until now you would think to write in bms) v% n( L! V) Y4 p0 F8 O( t# ~
get IDSTRING long1 E1 ~# Z: C* F$ q+ \) j
there is nothing wrong with that but there is a better command6 I/ Y- L6 Z# g# K% `- I4 P
idstring " PSH"
& @" l; m2 y% g2 G" y2 ~make sure you include the quotes.
, o V7 Q6 f$ s! A0 m7 Pso open your bms string and on the first line type
6 K( b2 h( h+ q# Oidstring " PSH"
& e) b t: \5 n) Jthe 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.% Z# J8 u w3 `
"aka noob proofing it"$ D$ J# d" ^4 R; s5 I M4 V
: X: Z0 C5 w* L
Ok so now lets look at what we can read I see : T& j: G: I% w5 V3 N' ]" I) Y: y
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
. j& @$ X& g: T9 s! g8 u3 sso I will assume there are 4 files in this archive.
# W# D' X( Z5 c( Ywell 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 }. M% W+ N1 @
so lets write that in bms language
, q8 U" k3 j/ y$ {1 @9 ^get UNK1 long
2 S3 P9 v% n1 a' [ q& z( [this saves those 4 bytes as the variable UNK1.
8 u9 s9 U. y8 ?7 w& p+ g/ j/ ?% q- j# _7 L5 L' l( j3 l. i! y/ f. {
ok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 4
o: {* X2 \4 E" `& A9 Z) ]hey that is the number of files we counted so lets write that in bms
# h) u. v% J7 ]get FILES long
, W. S5 B' g3 E" U0 a$ I( Tthis saves those 4 bytes as the variable FILES.
# J0 ?0 m* @4 t# C
9 s2 j5 {* w6 U7 H' z0 I+ qthe next 4 bytes are 00 00 00 00 well that is equal to zero so for now I will write that in bms
+ l5 A/ t, y" F3 s2 I. iget NULL1 long1 p! {% w s/ Y4 S
this saves those 4 bytes as the variable NULL1
4 U; n3 s: D6 L, X* g$ d1 }4 m; _; U+ T
ok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds8 H% q9 k, N& _: P
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?
6 d' W% |* F6 u- dwell lets look for a pattern( C# E: k: E0 O
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36& c# ~/ Z9 R# _* V9 M
Datas\Texture\BoneObject\Toon.bmp is 0x21
T/ K) O) G! I; T. s2 j. pDatas\Texture\BoneObject\Toon_a.bmp is 0x23
9 F4 U+ O, T, G- jDatas\Texture\BoneObject\Toon_zero.bmp is 0x265 b+ n- O( |1 b
hmm I don't see anything that makes that a pattern.1 S8 D9 L5 z9 v4 [/ V* Y
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?
1 s; G* T; o; \/ H# E3 b7 ADatas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80
) _( |9 w/ r) b y6 ADatas\Texture\BoneObject\Toon.bmp + 0's is 0x80( X& {: C$ \6 e3 a
Datas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80
3 p, Y8 {9 L5 x' u( ~Datas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80. u! v8 {3 M% D- ^1 v. m. E6 k* D
hey they are all the same size when I include the 0's
8 Q: V `3 o$ I9 ?% {1 bso in bms I would write this as
$ @. l9 d) J7 H4 c" O. ugetdstring NAME 0x800 X/ I/ i; Y; y
this tells it to grab 0x80 bytes and store the text value of it$ |5 i1 {& |4 t5 l8 R2 i3 G
and as an added feature it will automatically remove trailing 0's
3 ^5 ]1 c) C+ h9 V
8 b7 v% ~9 U8 z4 @ok so now we have 0xC bytes before I see the next file name
9 p# F- ]: p% k- x+ \which is 3 long values1 B8 v3 v- K/ j6 h0 b8 m
so lets write those in and we will figure out what they represent later.* R9 U: ^7 U- u* `; w
get UNK2 long1 W6 L7 @4 ]* l
get UNK3 long* z" R' a* d6 E
get UNK4 long
7 X/ [6 I' {1 e) ~0 L9 ?& e& h* Y; e5 B+ r/ E5 R
ok so now we see the name again
7 ~5 u9 u. w9 G0 }; z& Mwe have our pattern so lets write our script based on what we learned7 \. J# O- W) X x& `+ i- Z' k7 u
so it would look like this up until now( y7 s0 Z" s1 `- s. }
) S- _" r$ X# j# @6 u
Code:6 q: H. [3 z! n1 `
idstring " PSH"( {, |, }1 n. _" ?
get UNK1 long
2 Z/ n9 P+ } a4 Oget FILES long' H( J! O. h5 M: H
get NULL1 long. x5 K9 @/ l. E1 `* {
for i = 0 < FILES: @" ]9 I: @; Q( |
getdstring NAME 0x80
) n* L( O. @' {: {get UNK2 long
' o! @; S3 h: j2 i& _: xget UNK3 long. l- W8 e5 z6 [6 ~* L' D
get UNK4 long
0 n z( \- D1 o2 H5 n8 Iclog NAME OFFSET ZSIZE SIZE0 c0 ~3 E- y( n' x1 a
next i
" }. `( Z( u2 _8 B! O- }( g, x; n% ~# W. S8 `
/ i3 x$ o9 C$ r4 z; h) r; z, yok this may look complex but it is almost identical to the first tutorial file except we added 1 more variable
* A6 v0 }( G0 d0 q0 P) Z. UZSIZE this represents the compressed file size while SIZE represents the decompressed file size% u# D. s ?3 W$ O
and we also changed the log command to clog to represent it is a compressed file.
9 D2 F, v+ p5 J- ~1 S. W) v: n
' K H# S/ l# `. R! x# v9 `ok so now we have our loop and the commands to extract our files but we still need to fill in the variables1 t1 M/ z2 l c( d
OFFSET ZSIZE SIZE
5 I$ ?- m& W2 d. q/ \( tso that means our 3 unknown values must represent that but how do we know what order they are in?' H6 c/ T3 |+ C) T
, @* B, J: @2 b$ i; d4 o
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
: J c" a' F) e! a% U5 H. f. Pthen add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B+ d- g# N% M7 S) s H/ p, m
so now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F* H5 S; x+ O1 u) K- u
, P; N. Z- v6 n) a8 qok so we reached the end of our loop now what?
3 o D: [8 L1 g0 F uwell 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.
0 x# r0 U6 t0 J$ i6 B2 K78 9C represents the standard zlib compression header
) Z3 y: t( Z# D4 yok so this means our first file starts there which is at offset 0x240
, w) c- U) g0 T( S' `2 w, a, Y7 V* u( M
well lets go back to our first file in the list and look at those unknown variables.( i& k1 v+ n& r0 n9 G
24 72 00 00 is = 00 00 72 24 = 0x7224$ h* Z0 G) P4 q% o, O+ l
80 00 02 00 is = 00 02 00 80 = 0x20080
( [$ {# K* `3 X {9 t/ G9 T40 02 00 00 is = 00 00 02 40 = 0x240+ J* D3 u- D+ P
I think we have a winner so the third variable is 0x240 aka the offset$ o: f1 d' a* n, K* X" [% P
so lets update our script. H' R* ]4 J; s% p* p4 T
( a2 V1 [2 f* m8 b8 t' | o
# v; X0 K+ ^- z/ R2 r! _
Code:! K h' @, S% E! b5 Q1 q" d r
idstring " PSH"+ p' i5 X% q2 R9 f( b
get UNK1 long9 Z2 k7 y$ A b" Q
get FILES long
% Q" x" Q9 @/ T/ S& pget NULL1 long4 h" l/ h i" p$ n
for i = 0 < FILES
8 o. ?- M' o, }& \2 k9 e8 Ggetdstring NAME 0x80. T/ M! ]) Z( j! S3 b% q' e
get UNK2 long2 s3 x7 U! c$ W* B: A
get UNK3 long
5 z( `, Q% W2 T$ Pget OFFSET long
* P7 P. s: p! Yclog NAME OFFSET ZSIZE SIZE
9 p* u- A+ c: Y3 n' e8 unext i
, Z4 W8 z4 \8 L. R' `) X0 u) s/ Y, b: T) Y& e% J5 h* D$ h
- f6 n6 H3 E2 F+ V, h' z9 g5 ?
now that just leaves ZSIZE and SIZE
. f# s* g7 @' K4 ?8 S4 ?$ \) Swell bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables
' P% G$ w) g4 H1 z/ ?9 w9 L24 72 00 00 is = 00 00 72 24 = 0x7224
9 h+ I& N9 F5 o, x80 00 02 00 is = 00 02 00 80 = 0x200803 S: ]* h, n5 f1 m5 }+ k8 o
well 0x20080 is definitely bigger so we now know the last 2 variables
# ~% D, _8 \% R3 T# E
+ G. k9 V% Q, T4 O
" f x8 x6 x- G2 E2 r& U) NCode:
1 |' M0 s% k# H. Y' c! Bidstring " PSH"
$ |2 O+ D1 }. z0 m9 Y uget UNK1 long
) `' u6 N2 x! k3 X; K) A* \( wget FILES long
2 [0 @5 b9 k& Q# [get NULL1 long
, \7 W7 V) M$ V+ z& X+ Xfor i = 0 < FILES1 u1 l, u2 L- `
getdstring NAME 0x80
0 A) ]% A6 V8 d8 r yget ZSIZE long
( V# [+ o' J* u1 c, o5 y# U& wget SIZE long' j+ z+ ]0 T+ N# Z' F
get OFFSET long6 M* `5 p9 d; q& A; K
clog NAME OFFSET ZSIZE SIZE! I* L1 f* y1 @) N! I4 Z
next i/ l0 J0 i; ^; e; {! W9 w
6 G+ Y9 j( `4 s; t; r9 G% H0 x' P8 r h1 V) u. \* ^) R
now try our code out on the file
/ ~6 H4 X4 g. x. G7 @! `4 Xopen the command prompt and change to the directory/ f# ?' @& \+ r1 G
c:\temp
' O' Y& t" q" _now type" E+ a4 y( f" q9 M+ o9 h4 g2 B
quickbms.exe -l astro.bms BoneObject.hsp .% R$ w% Y7 K+ ~. K6 `' B
yay it listed our files without any errors now lets try extracting them
( p- c# G2 E9 m( E/ {: Z* s2 ocreate a folder called extract _/ }6 t u! Q
and type
) m: S0 C7 N S/ p. u' o \1 xquickbms.exe astro.bms BoneObject.hsp extract
/ _* x. X _4 R- d4 e9 ^9 z8 Rif we look in there we now have folders and in those folders are 4 pictures
9 b. S$ c) p+ Uwe did it.# N0 P8 b, F# }! V: K p, u$ x7 e
2 w4 E" e. C/ J# o, M* b6 KLet me know if you want more pictures or any way I can improve the tutorials.
) r( G" ~4 @3 C; T. X
& |. [: {( _! `) U; | f$ @ t. ~7 J- J, F0 f* p) c I
Last edited by chrrox on Tue Jun 09, 2009 2:33 pm, edited 1 time in total. |