Hitman Blood Money (Xbox 360) - XBox2_Eng.str/.s##

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Hitman Blood Money (Xbox 360) - XBox2_Eng.str/.s##

Post by AnonBaiter »

So, there's this Hitman game in that it uses PCM codec for all sounds in the Xbox 360 version.
The thing is I know where this kind of information(offset, size, codec, frequency, etc.) come from, but I don't know how to deal with these kind of archives that are stored in separate files(.000, .001 and so on).
Here's the script if you're curious:

Code: Select all

# Hitman Blood Money - .str

get EXT extension
if EXT == "str"
    math TMP = 0x10000000
    math TMP *= 16
    if TMP == 0
        print "you must use quickbms_4gb_files.exe with big archives"
        cleanexit
    endif
endif
idstring "IOISNDSTREAM"
get STR_NUM long
get INFO_OFF long
get DUMMY1 long
if DUMMY1 == 0
   goto 0x18
   get DUMMY1 long
endif
goto INFO_OFF
for i = 0 < DUMMY1
   get UNK1 long
   get UNK2 long
   get OFFSET long
   get UNK4 long
   get SIZE long
   get UNK6 long
   get AUD_OFFSET long
   get UNK8 long
   get UNK9 long
   get UNK10 long
   get NAMESZ long
   get UNK12 long
   get NAME_OFFSET long
   get UNK14 long
   get LIP1 long
   get LIP2 long
   get LIP3 long
   get UNK18 long
   putarray 1 i AUD_OFFSET
   putarray 2 i NAME_OFFSET
   putarray 3 i NAMESZ
   putarray 4 i SIZE
   putarray 5 i OFFSET
   putarray 6 i LIP1
   putarray 7 i LIP3
next i
for i = 0 < DUMMY1
   getarray NAME_OFFSET 2 i
   getarray NAMESZ      3 i
   savepos TMP
   goto NAME_OFFSET
   getdstring NAME NAMESZ
   goto TMP
   putarray 8 i NAME
next i
for i = 0 < DUMMY1
   getarray AUD_OFFSET 1 i
   getarray SIZE       4 i
   getarray OFFSET     5 i
   getarray LIP1       6 i
   getarray LIP3       7 i
   getarray NAME       8 i
   goto AUD_OFFSET
   get CODEC long
   get AUD2 long
   get CHANNELS long
   get FREQUENCY long
   get BITS long
   get INTERLEAVE long
   get AUD7 long
   /*
   if LIP1 == 0x4
      math OFFSET += 0x1000
   endif
   if LIP3 == 0x1
   elif LIP3 == 0x2
      math OFFSET += 0x1000
   endif
   if CODEC == 0x2 || CODEC == 0xa
      callfunction PCM_1
   elif CODEC == 0x3
      set GENH_CODEC long 0xf
      callfunction GENH
   elif CODEC == 0x4
      string NAME R= ".wav" ".ogg"
      log NAME OFFSET SIZE
   elif COCEC == 0xb
      set GENH_CODEC long 0x0
      callfunction GENH
   elif CODEC == 0x11
      callfunction PCM_2
   else
      log NAME OFFSET SIZE
   endif
   */
next i
/*
if EXT == "str"
    sortarray 0 1
    math STR_NUM = 0
    math STR_OFF = 0
    get STR_SIZE asize
    for i = 0 < DUMMY1
        getarray INFO_OFF    0 i
        getarray AUD_OFFSET  1 i
        getarray NAME_OFFSET 2 i
      getarray NAMESZ      3 i
      getarray SIZE        4 i
      getarray OFFSET      5 i
      getarray LIP1        6 i
      getarray LIP3        7 i
      getarray NAME        8 i
        math TMP_OFF = OFFSET
        math OFFSET - STR_OFF
        if OFFSET u>= STR_SIZE
            math STR_NUM + 1
            string EXT p "%03d" STR_NUM
            open FDDE EXT
            math STR_OFF + OFFSET
            get STR_SIZE asize
            math OFFSET = 0
        endif
      log NAME OFFSET SIZE
    next i
endif
*/

/*
startfunction PCM_1
   getarray SIZE 3 i
    set MEMORY_FILE binary "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x61\x74\x61\x00\x00\x00\x00"

    set RIFFSIZE long SIZE
    math RIFFSIZE += 36
    set BLOCKALIGN long BITS
    set AVGBYTES long FREQUENCY
    math BLOCKALIGN /= 8
    math BLOCKALIGN *= CHANNELS
    math AVGBYTES *= BLOCKALIGN

    putvarchr MEMORY_FILE 4 RIFFSIZE long
    putvarchr MEMORY_FILE 20 1 short          # wFormatTag: Microsoft PCM Format (0x0001)
    putvarchr MEMORY_FILE 22 CHANNELS short   # wChannels
    putvarchr MEMORY_FILE 24 FREQUENCY long   # dwSamplesPerSec
    putvarchr MEMORY_FILE 28 AVGBYTES long    # dwAvgBytesPerSec
    putvarchr MEMORY_FILE 32 BLOCKALIGN short # wBlockAlign
    putvarchr MEMORY_FILE 34 BITS short       # wBitsPerSample
    putvarchr MEMORY_FILE 40 SIZE long

    log MEMORY_FILE2 0 44 MEMORY_FILE
    append
    log MEMORY_FILE2 OFFSET SIZE
    append
    get RIFF_SIZE asize MEMORY_FILE2
    log NAME 0 RIFF_SIZE MEMORY_FILE2
endfunction

startfunction PCM_2
   getarray SIZE 3 i
    set MEMORY_FILE binary "\x52\x49\x46\x46\x00\x00\x00\x00\x57\x41\x56\x45\x66\x6d\x74\x20\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x64\x61\x74\x61\x00\x00\x00\x00"

    set RIFFSIZE long SIZE
    math RIFFSIZE += 36
    set BLOCKALIGN long BITS
    set AVGBYTES long FREQUENCY
    math BLOCKALIGN /= 8
    math BLOCKALIGN *= CHANNELS
    math AVGBYTES *= BLOCKALIGN

    putvarchr MEMORY_FILE 4 RIFFSIZE long
    putvarchr MEMORY_FILE 20 1 short          # wFormatTag: Microsoft PCM Format (0x0001)
    putvarchr MEMORY_FILE 22 CHANNELS short   # wChannels
    putvarchr MEMORY_FILE 24 FREQUENCY long   # dwSamplesPerSec
    putvarchr MEMORY_FILE 28 AVGBYTES long    # dwAvgBytesPerSec
    putvarchr MEMORY_FILE 32 BLOCKALIGN short # wBlockAlign
    putvarchr MEMORY_FILE 34 BITS short       # wBitsPerSample
    putvarchr MEMORY_FILE 40 SIZE long

    log MEMORY_FILE2 0 44 MEMORY_FILE
    append
    log MEMORY_FILE2 OFFSET SIZE
    append
    get RIFF_SIZE asize MEMORY_FILE2
   string NAME += ".wav"
    log NAME 0 RIFF_SIZE MEMORY_FILE2
endfunction
Here's a sample.