We will be working with the game Astro Ranger
Here is the full client http://astro.nefficient.co.kr/astrorang ... client.exe
ok so set up our c:\temp directory bye extracting our file BoneObject.hsp
1. to c:\temp
2. create a new text document called astro.bms
3. and place the newest version of quickbms in the folder also.
Ok so open up BoneObject.hsp in your hex editor and lets take a look at it.
good we have some plain text.
you will notice I highlighted the first 4 bytes 20 50 53 48 or " PSH" that is a space followed bye P S H.
hmm that seems familiar that is the file extension only backwards. this is know as the idstring
so up until now you would think to write in bms
get IDSTRING long
there is nothing wrong with that but there is a better command
idstring " PSH"
make sure you include the quotes.
so open your bms string and on the first line type
idstring " PSH"
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.
"aka noob proofing it"
Ok so now lets look at what we can read I see
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
so I will assume there are 4 files in this archive.
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
so lets write that in bms language
get UNK1 long
this saves those 4 bytes as the variable UNK1.
ok the next 4 bytes are 04 00 00 00 hmm this translates into 00 00 00 04 or 4
hey that is the number of files we counted so lets write that in bms
get FILES long
this saves those 4 bytes as the variable FILES.
the next 4 bytes are 00 00 00 00 well that is equal to zero so for now I will write that in bms
get NULL1 long
this saves those 4 bytes as the variable NULL1
ok now we have reached the first file name Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds
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?
well lets look for a pattern
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds is 0x36
Datas\Texture\BoneObject\Toon.bmp is 0x21
Datas\Texture\BoneObject\Toon_a.bmp is 0x23
Datas\Texture\BoneObject\Toon_zero.bmp is 0x26
hmm I don't see anything that makes that a pattern.
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?
Datas\Texture\BoneObject\npc_nagoya_octopus01_body.dds + 0's is 0x80
Datas\Texture\BoneObject\Toon.bmp + 0's is 0x80
Datas\Texture\BoneObject\Toon_a.bmp + 0's is 0x80
Datas\Texture\BoneObject\Toon_zero.bmp + 0's is 0x80
hey they are all the same size when I include the 0's
so in bms I would write this as
getdstring NAME 0x80
this tells it to grab 0x80 bytes and store the text value of it
and as an added feature it will automatically remove trailing 0's
ok so now we have 0xC bytes before I see the next file name
which is 3 long values
so lets write those in and we will figure out what they represent later.
get UNK2 long
get UNK3 long
get UNK4 long
ok so now we see the name again
we have our pattern so lets write our script based on what we learned
so it would look like this up until now
Code: Select all
idstring " PSH"
get UNK1 long
get FILES long
get NULL1 long
for i = 0 < FILES
getdstring NAME 0x80
get UNK2 long
get UNK3 long
get UNK4 long
clog NAME OFFSET ZSIZE SIZE
next i
ZSIZE this represents the compressed file size while SIZE represents the decompressed file size
and we also changed the log command to clog to represent it is a compressed file.
ok so now we have our loop and the commands to extract our files but we still need to fill in the variables
OFFSET ZSIZE SIZE
so that means our 3 unknown values must represent that but how do we know what order they are in?
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
then add our 3 unknown variables so that means we are highlighting 0x8C for our length. the first file is from 0x10 - 0x9B
so now do this for the rest of the files and you end up at highlighting 0x1B4 - 0x23F
ok so we reached the end of our loop now what?
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.
78 9C represents the standard zlib compression header
ok so this means our first file starts there which is at offset 0x240
well lets go back to our first file in the list and look at those unknown variables.
24 72 00 00 is = 00 00 72 24 = 0x7224
80 00 02 00 is = 00 02 00 80 = 0x20080
40 02 00 00 is = 00 00 02 40 = 0x240
I think we have a winner so the third variable is 0x240 aka the offset
so lets update our script
Code: Select all
idstring " PSH"
get UNK1 long
get FILES long
get NULL1 long
for i = 0 < FILES
getdstring NAME 0x80
get UNK2 long
get UNK3 long
get OFFSET long
clog NAME OFFSET ZSIZE SIZE
next i
well bye process of elimination the decompressed file must be bigger than the compressed file so we compare the 2 variables
24 72 00 00 is = 00 00 72 24 = 0x7224
80 00 02 00 is = 00 02 00 80 = 0x20080
well 0x20080 is definitely bigger so we now know the last 2 variables
Code: Select all
idstring " PSH"
get UNK1 long
get FILES long
get NULL1 long
for i = 0 < FILES
getdstring NAME 0x80
get ZSIZE long
get SIZE long
get OFFSET long
clog NAME OFFSET ZSIZE SIZE
next i
open the command prompt and change to the directory
c:\temp
now type
quickbms.exe -l astro.bms BoneObject.hsp .
yay it listed our files without any errors now lets try extracting them
create a folder called extract
and type
quickbms.exe astro.bms BoneObject.hsp extract
if we look in there we now have folders and in those folders are 4 pictures
we did it.
Let me know if you want more pictures or any way I can improve the tutorials.