Page 18 of 33
Re: My quickBMS scripts
Posted: Tue May 29, 2012 12:04 am
by AlphaTwentyThree
sdu extractor for "The Suffering" (Xbox)
Uses my new version of the Xbox ADPCM header adder, so be sure to update that!
XMV movies can be converted with VGM Toolbox (at least in most cases).
Remember to decode the *.lwav files with toWAV because the vgmstream playback is errornous!
Code: Select all
# extract the *.sdu and *.vdu files from The Suffering (Xbox)
# (c) 2012-05-29 by AlphaTwentyThree of XeNTaX
include "func_header_XADP.bms" # be sure to have this file in the same directory!
idstring "SRSC"
get UNK byte
get UNK byte
get INFO long
get ENTRIES long # head/file/tail entries
goto INFO
get EXT extension
if EXT == "sdu"
callfunction sdu 1
elif EXT == "vdu"
callfunction vdu
endif
startfunction sdu
for i = 1 <= ENTRIES
get SIG byte # head/data/tail
get UNK2 byte #always 3?
get FILE_ID short
get UNK4 short # some identifier
get OFFSET long
get SIZE long
if SIG == 2
if FILE_ID != 0
savepos MYOFF
math OFFSET += 0x2c
goto OFFSET
get CH short
get BITS short # always 4
get FREQ long
goto MYOFF
endif
elif SIG == 4
get NAME basename
string NAME += "_"
string NAME += FILE_ID
#string NAME += "_"
#string NAME += UNK4
string NAME += ".lwav"
callfunction XADP 1
elif SIG == 5 # some file tail - do nothing?
endif
next i
endfunction
startfunction vdu
for i = 1 <= ENTRIES
get SIG byte # head/data/tail
get UNK2 byte #always 3?
get FILE_ID short
get UNK4 short # some identifier
get OFFSET long
get SIZE long
if SIG != 66
get NAME basename
string NAME += "_"
string NAME += FILE_ID
string NAME += ".xmv"
if FILE_ID != 0
log NAME OFFSET SIZE
endif
endif
next i
endfunction
Re: My quickBMS scripts
Posted: Tue May 29, 2012 2:11 pm
by AlphaTwentyThree
Midnight Mysteries 4: Haunted Houdini (PC) - Contents.dat extractor
Code: Select all
# extracts the Contents.dat from
# Midnight Mysteries 4: Haunted Houdini (PC)
# (c) 2012-05-29 by AlphaTwentyThree of XeNTaX
idstring \xce\xde\xed\xec
get UNK long
get INFO long
goto INFO
get FILES long
set NAMEBIAS FILES
math NAMEBIAS *= 0x10
math NAMEBIAS += INFO
math NAMEBIAS += 8
for i = 1 <= FILES
get UNK long # always 0 or 1
get OFFSET long
get SIZE long
get NAMEPOS long
if SIZE != 0 # folder
math NAMEPOS += NAMEBIAS
savepos MYOFF
goto NAMEPOS
get NAME string
goto MYOFF
log NAME OFFSET SIZE
endif
next i
Re: My quickBMS scripts
Posted: Tue May 29, 2012 3:32 pm
by AlphaTwentyThree
Fable (Xbox) - lug/met soundbank extractor
Code: Select all
# extracts the *.lug/*.met pairs from Fable (Xbox)
# (c) 2012-05-29 by AlphaTwentyThree of XeNTaX
open FDDE met 0
open FDDE lug 1
get DUMMY long 0
get FILES long 0
goto 0 0
for i = 1 <= FILES
get DUMMY long 0
get DUMMY long 0
get FILE_ID long 0
get NAMEL long 0
getDstring NAME NAMEL 0
get SIZE long 0
get OFFSET long 0
get CH short 0
get CODEC short 0
get FREQ long 0
log NAME OFFSET SIZE 1
next i
Re: My quickBMS scripts
Posted: Tue May 29, 2012 5:05 pm
by AlphaTwentyThree
Max Payne Xbox sound extractor
Files without extension in the SPU.EMM are soundbanks containing the main sfx. Split at the 0x20 zero bytes and add an SS2 header.
Code: Select all
# extract *.emm/*.dir pairs of Max Payne (Xbox)
# (c) 2012-05-29 by AlphaTwentyThree of XeNTaX
open FDDE EMM 0
open FDDE DIR 1
get BNAME basename
get FILES long 1
for i = 1 <= FILES
get NAME_CRC long 1
if BNAME == "SOUND"
get FREQ long 1
endif
get OFFSET long 1
get SIZE long 1
savepos MYOFF 1
callfunction NAME 1
goto OFFSET 0
get IDENT long 0
if IDENT == 0x70474156
string NAME += ".vag"
elif IDENT == 0x64685353
string NAME += ".ss2"
endif
log NAME OFFSET SIZE 0
goto MYOFF 1
next i
startfunction NAME
get NAME basename 1
string NAME += "_"
if i < 100
string NAME += "0"
endif
if i < 10
string NAME += "0"
endif
string NAME += i
string NAME_CRC p= "_0x%08x" NAME_CRC
string NAME += NAME_CRC
endfunction
Re: My quickBMS scripts
Posted: Wed May 30, 2012 12:35 am
by AlphaTwentyThree
Gun (Xbox) sound/music extractor
As far as I remember, the PC version uses the same structure but uses another codec. As soon as I get my hands on that one, I'll update this script.
Code: Select all
# extract the contents of the music_pcm and stream_pcm packets of Gun (Xbox)
# (c) 2012-05-30 by AlphaTwentyThree of XeNTaX
get BNAME basename
set NAME0 BNAME
set NAME1 BNAME
set NAME2 BNAME
string NAME0 += "0.wad"
string NAME1 += "1.wad"
string NAME2 += "2.wad"
open FDSE NAME0 1
open FDSE NAME1 2
if BNAME == "stream_pcm"
open FDSE NAME2 3
endif
log MEMORY_FILE 0 0
idstring "PDAW" 0
get UNK long 0
get FILES long 0
get UNK long 0
for i = 1 <= FILES
get NAME_CRC long 0
get FILE long 0
get OFFSET long 0
get SIZE long 0
get CODE short 0
get CH short 0
get FREQ long 0
get UNK long 0
get INTERLEAVE short 0
get BITS short 0 # always 4 (Xbox ADPCM)
get UNK long 0
set NAME BNAME
string NAME += "_"
string NAME += i
string REST p= "_0x%08x.lwav" NAME_CRC
string NAME += REST
if FILE == 0
log MEMORY_FILE2 OFFSET SIZE 1
elif FILE == 1
log MEMORY_FILE2 OFFSET SIZE 2
elif FILE == 2
log MEMORY_FILE2 OFFSET SIZE 3
endif
savepos MYOFF 0
callfunction XADP 1
goto MYOFF 0
next i
startfunction XADP
set MEMORY_FILE binary "\x52\x49\x46\x46\x18\x51\xa3\x0\x57\x41\x56\x45\x66\x6d\x74\x20\x14\x0\x0\x0\x69\x0\x2\x0\x44\xac\x0\x0\xcc\xc1\x0\x0\x48\x0\x4\x0\x2\x0\x40\x0\x64\x61\x74\x61\xf0\x50\xa3\x0"
set RIFFSIZE SIZE
math RIFFSIZE += 0x28
putVarChr MEMORY_FILE 0x04 RIFFSIZE long
putVarChr MEMORY_FILE 0x16 CH byte
putVarChr MEMORY_FILE 0x18 FREQ long
set VAR1 0x3073
math VAR1 *= CH
if FREQ == 48000
math VAR1 *= 44100
else
math VAR1 *= FREQ
endif
math VAR1 /= 22050
putVarChr MEMORY_FILE 0x1c VAR1 long
set VAR2 0x24
math VAR2 *= CH
putVarChr MEMORY_FILE 0x20 VAR2 short
putVarChr MEMORY_FILE 0x2c SIZE long
append
log MEMORY_FILE 0 SIZE MEMORY_FILE2
append
if NAME == ""
get NAME basename
string NAME += ".lwav"
endif
get SIZE asize MEMORY_FILE
log NAME 0 SIZE MEMORY_FILE
endfunction
Re: My quickBMS scripts
Posted: Wed May 30, 2012 1:38 am
by AlphaTwentyThree
Gun (Xbox 360) wad/dat sound extractor
Old script of mine. Not pretty but it did work back then.
Code: Select all
# extracts the wad/dat pair of Gun (Xbox 360)
# (c) 2012-05-30 by AlphaTwentyThree of XeNTaX
endian big
open FDDE dat 0
open FDDE wad 1
get FILES long 0
for i = 1 <= FILES
endian big
set MEMORY_FILE binary "\x52\x49\x46\x46\xb8\x59\xa7\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x20\x00\x00\x00\x65\x01\x10\x00\xd6\x10\x00\x00\x01\x00\x00\x03\xe3\x9a\x00\x00\x80\xbb\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x02\x00\x64\x61\x74\x61\x00\x58\xa7\x00"
get NAME_CRC long 0
get OFFSET long 0
get SIZE long 0
get FREQ long 0
get UNK byte 0
get ZERO short 0
get CH byte 0
append
log MEMORY_FILE OFFSET SIZE 1
append
set RIFFSIZE SIZE
math RIFFSIZE += 0x34
endian little
putVarChr MEMORY_FILE 0x24 FREQ long
putVarChr MEMORY_FILE 0x31 CH byte
putVarChr MEMORY_FILE 0x04 RIFFSIZE long
putVarChr MEMORY_FILE 0x38 SIZE long
math SIZE += 0x3c
get NAME basename 0
string NAME += "_"
string NAME += i
string NAME += ".xma"
log NAME 0 SIZE MEMORY_FILE
next i
Re: My quickBMS scripts
Posted: Sat Jun 02, 2012 3:33 am
by AlphaTwentyThree
Tongas Pack extractor (supports v1, v2 & v3)
Works for all three versions.
Code: Select all
# extracts from Tongas Pack v1/2/3 *.PAK archives
# supported games:
# - 3D Ultra Minigolf Adventures (XBLA) v1
# - 3D Ultra Minigolf Adventures 2 (XBLA) v2
# - Arkadian Warriors (XBLA) v1
# - Assault Heroes (PC/XBLA) v1
# - Assault Heroes 2 (XBLA) v1
# - Ice Age 4: Continental Drift (Xbox 360) v3
# - Tetris (PS3/PSN) v3
#
# (c) 2012-07-01 by AlphaTwentyThree of XeNTaX
comtype COMP_LZMA_86HEAD
getDstring IDENT 13 # "tongas_pack_v" in v2 & v3
if IDENT == "00#%&W&N$(0FL"
set VER 1
goto 0x12
get FILES long
else
getDstring VER 5
if VER == "20000"
set VER 2
elif VER == "30000"
set VER 3
else
print "Tongas pack version not supported! PM me at XeNTaX!"
endif
get FILES long
get UNK long
endif
for i = 1 <= FILES
get OFFSET long
get SIZE long
if VER == 3
get COMP long
else
set COMP 1
endif
get NAMEL long
getDstring NAME NAMEl
if VER == 1
string NAME -= 4 # remove ".wzm" at end
endif
savepos MYOFF
if COMP == 1
goto OFFSET
get UNK long
get DUMMY byte
get ZSIZE long
math ZSIZE *= 0x10
clog NAME OFFSET SIZE ZSIZE
else
log NAME OFFSET SIZE
endif
goto MYOFF
next i
Re: My quickBMS scripts
Posted: Sat Jun 16, 2012 3:14 pm
by AlphaTwentyThree
Jagged Alliance: Back in Action / Jagged Alliance: Crossfire - PAK extractor
Works for the unencrypted files.
Code: Select all
# extracts pak files from Jagged Alliance: Back in Action and Crossfire (PC)
# (c) 2012-06-16 by AlphaTwentyThree of XeNTaX
idstring "PKLE"
get UNK long
get DATASTART long # attention: last file name ends directly here!
get ZERO long
get UNK long
get ZERO long
do
get FIDENT long # folder ident, always 1 at start
get NAMEL long
get FILES long # files in folder
get ZERO long
getDstring FOLDER NAMEL
for i = 1 <= FILES
get NAMEL long
get SIZE long
get ZERO long
get OFFSET long
get ZERO long
get HASH long
get ZERO long
getDstring FNAME NAMEL
set NAME FOLDER
string NAME += FNAME
log NAME OFFSET SIZE
next i
savepos MYOFF
while MYOFF < DATASTART
Re: My quickBMS scripts
Posted: Sun Jun 17, 2012 1:29 am
by aluigi
you can use my script for Jagged Alliance BIA, it supports also encrypted archives:
http://aluigi.org/papers/bms/jagged_alliance_bia.bms
Re: My quickBMS scripts
Posted: Tue Jun 19, 2012 3:20 pm
by AlphaTwentyThree
Didn't check on your scripts - thanks for the info.

Is there an easy way to determine those crypt keys?
Re: My quickBMS scripts
Posted: Tue Jun 19, 2012 3:21 pm
by AlphaTwentyThree
Re: My quickBMS scripts
Posted: Mon Jun 25, 2012 9:28 pm
by AlphaTwentyThree
WAVE format scanner
Long overdue script for a proper wave scanner. I know there are many raw scanner which have a *.wav option but they only find very certain wave files. I've encountered none that supports big endian wave files with RIFX identifier so far.
My old script didn't work properly and I had to change almost the whole script. Features of this script:
- supports little and big endian headers (RIFF and RIFX)
- automatic filesize correction in header (!)
- file name retrieval from first marker name
I've added comments about what happens in each line, so it's a nice example for getting familiar with QuickBMS.
Tip: Scanning the EN.pck from Darksiders II (PC, 2012) will get you the original file names which aren't saved in the file table at the start of the archive!
Code: Select all
# scan data for wave files
# RIFF and RIFX header supported
# note: There are wave files with a wrong file size after RIFF/RIFX
# This script takes the stream size, adds the header size and writes the correct size after RIFF/RIFX
# (c) 2012-06-26 by AlphaTwentyThree
#
# future update plans:
# - option to also write data between found wave files to disk
# - option to automatically transform the file to a playable or at least decodable format
for i = 1 # run through loop with count variable i
FindLoc OFFSET string "WAVE" 0 "" # search for "WAVE", save position as variable OFFSET
if OFFSET == "" # when nothing is found
cleanexit # the script exits (e.g. at end of file)
endif
math OFFSET -= 8 # jump to possible
goto OFFSET # RIFF/RIFX file start
getDstring IDENT 4 # read string of 4 bytes, save variable as IDENT
if IDENT == "RIFX" # differentiate between header possibilities
endian big # set endianness to big, if file has RIFX identifier
callfunction write 1 # see function section below
elif IDENT == "RIFF" # endianness stays little
callfunction write 1 # also run function
else # string "WAVE" found, but doesn't belong to wave file
set SIZE 0xc # do as if something with 0xc bytes was found to continue search from the right position
endif
set SEARCH OFFSET # set marker to position from where to search next
math SEARCH += SIZE # (that would be after the file that was found)
if SEARCH == FSIZE # in case the last found file ends with the main file, we exit
cleanexit
endif
goto SEARCH # if we haven't exited the script above, we set out cursor to after the last found file
next i
startfunction write # function "write" starts here, is called when a wave file is found above
get NAME basename # save name without extension under variable NAME
string NAME += "_" # add underscore to the name
string NAME += i # add the loop variable to the name
goto OFFSET # set cursor to the beginning of the found file
get DUMMY long # RIFF/RIFX identifier, not needed
get DUMMY long # riff size, not needed
get DUMMY long # "WAVE", not needed, we arrive at the "fmt " section
for # loop search for the "data" section at the start of the stream (get the stream size from there)
getDstring AREA_NAME 4 # name of area in header
get AREA_SIZE long # size of area in header
savepos MYOFF # save position we are at
if AREA_NAME == "data" # when we arrive at the needed "data" area:
break # we exit the loop
else # otherwise:
if AREA_NAME == "LIST" # that's the area of the marker names
callfunction retrievename 1 # see below
endif
math MYOFF += AREA_SIZE # not reached "data" area -> adjust cursor position...
goto MYOFF # ... and go there
endif
next # remember: the cursor is now directly at the stream start
set STREAMSIZE AREA_SIZE # the last AREA_SIZE is the size we need (size of the audio stream)
set HEADERSIZE MYOFF #
math HEADERSIZE -= OFFSET # calculate the size of the stream header (offset - offset = size)
set SIZE HEADERSIZE #
math SIZE += STREAMSIZE # calculate complete file size (header + stream = file)
log MEMORY_FILE OFFSET SIZE # write file to memory
math SIZE -= 8 # subtract 8 bytes to get the riff size
putVarChr MEMORY_FILE 4 SIZE long # write the correct riff size to the header inside the memory
string NAME += ".wav" # add extension to the name (the name could contain the name of the first marker if the file has markers)
math SIZE += 8 # add the subtracted 8 bytes again
log NAME 0 SIZE MEMORY_FILE # write file in memory to disk
endfunction # remember that we continue with our next i now!
startfunction retrievename # get possible file name from first marker name, rmember: our cursor is after the size of the LIST area
get DUMMY long # always "adtl", not needed
get DUMMY long # always "labl", not needed
get MSIZE long # size of the label area for this marker
math MSIZE -= 4 # subtracting 4 bytes leaves us with the length of the marker label
get DUMMY long # marker type, not needed
getDstring MNAME MSIZE # cursor is at the beginning of the label name, now get the marker name with the desired length MSIZE
string NAME += "~"
string NAME += MNAME # add the marker name to the file name
endfunction
Re: My quickBMS scripts
Posted: Tue Jun 26, 2012 12:42 am
by AlphaTwentyThree
Warhammer 40,000: Squad Command (PSP) - *.pak extractor
Code: Select all
# extracts *.pak files from Warhammer 40,000: Squad Command (PSP)
# (c) 2012-06-26 by AlphaTwentyThree of XeNTaX
get DATASTART long
get ENTRIES long
set INFO DATASTART
math INFO -= 4
goto INFO
get NAMEPOS long
goto NAMEPOS
get FILES long
savepos NAMEPOS
goto 8
for i = 1 <= FILES
get UNK long
get SIZE long
get UNK long
get UNK byte
get OFFSET long
savepos MYOFF
goto NAMEPOS
get NAMEL short
getDstring NAME NAMEL
savepos NAMEPOS
log NAME OFFSET SIZE
goto MYOFF
next i
Re: My quickBMS scripts
Posted: Thu Jun 28, 2012 5:25 pm
by AlphaTwentyThree
Just updated the Tongas Pack extractor with version 2!

Re: My quickBMS scripts
Posted: Fri Jun 29, 2012 12:24 am
by AlphaTwentyThree
Found a Tongas Pack v1 and updated the script!
