[PC] Sacred 3

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
brendan19
Posts: 144
Joined: Fri Aug 08, 2014 11:25 am

[PC] Sacred 3

Post by brendan19 »

So here's the first 10MB from an archive.

I know it uses aPLib compression for the archive.

A BMS script to unpack it would be great :)

Sacred 3 PAK
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

It was very difficult but I did it:
http://aluigi.org/papers/bms/sacred3.bms

Tested with both your files and the PS3 ones.
The format is quite chaotic and there are no offsets, just a sort of CRC/ID.
The files are archived as compressed chunks (so no reimporting is possible).
These files are FORK archives.
The script automatically dumps the content of these archives.
Sometimes there is no luck in retrieving the original filename and so it will use the offset.
Ah, the extraction is very very very slooooooow.
brendan19
Posts: 144
Joined: Fri Aug 08, 2014 11:25 am

Re: [PC] Sacred 3

Post by brendan19 »

Thank you so much Luigi :)
brendan19
Posts: 144
Joined: Fri Aug 08, 2014 11:25 am

Re: [PC] Sacred 3

Post by brendan19 »

Uploading additional packages from the DLC which the script doesn't like. Sorry, I should have included these in the first post :(

Sacred 3 DLC

EDIT: I am unsure if the 247950_1.pak was extracted. So here is 10MB from it.

Sacred 3
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

ok I have updated the script, hope it works now
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

Micro update: now if there is no "FORK" signature the script will extract the file as is.
brendan19
Posts: 144
Joined: Fri Aug 08, 2014 11:25 am

Re: [PC] Sacred 3

Post by brendan19 »

Okay, as far as audio is concerned it is just headerless little endian PCM. But the audio files aren't split into separate files as they're still clumped together after extraction.

Is there a way to automate the splitting of the files? Some are 44100Hz and others 48000Hz so I can't just use VGMToolbox's Advanced cutter to separate them because it doesn't allow for multiple terminator strings.

44100Hz - FEFF<CH #>0044AC0000301308000C001000160010000F0600000100000000001000800000AA00389B71
48000Hz - FEFF<CH #>0080BB000000EE02000400100016001000030000000100000000001000800000AA00389B71

I have seen 02 and 06 for channels
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

Do you have a sample just to be sure that there are no size values and for a test?
With quickbms is possible to do something but I suspect it will not fast in the job.
brendan19
Posts: 144
Joined: Fri Aug 08, 2014 11:25 am

Re: [PC] Sacred 3

Post by brendan19 »

aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

In my opinion the situation is a bit more complex and involves also other codes.

Take a look at this header parser made in quickbms:

Code: Select all

get TYPE short # 2 or -2
get CHANNELS short
get RATE long
get TOTAL_RATE long # CHANNELS * RATE
get BYTES_PER_SAMPLE short
get BITS short
getdstring DUMMY 0x18
savepos OFFSET

the first short is PCM if it's negative (0xfffe) otherwise it uses another codec (2) that I have not verified (it's not mp3).
There is an important field missing: the number of samples or the lenght of the track!

Without one of those two parameters it's almost impossible to separate the tracks, it would be an heuristic way with possible false positives.
spider91
Posts: 233
Joined: Sun Aug 24, 2014 5:26 pm

Re: [PC] Sacred 3

Post by spider91 »

aluigi wrote:It was very difficult but I did it:
http://aluigi.org/papers/bms/sacred3.bms

Tested with both your files and the PS3 ones.
The format is quite chaotic and there are no offsets, just a sort of CRC/ID.
The files are archived as compressed chunks (so no reimporting is possible).
These files are FORK archives.
The script automatically dumps the content of these archives.
Sometimes there is no luck in retrieving the original filename and so it will use the offset.
Ah, the extraction is very very very slooooooow.


This script is completely wrong. Here is script for pak

Code: Select all

math TMP = 0x10000000
math TMP *= 0x10
if TMP == 0
    print "Error: you must use quickbms_4gb_files.exe for this archive"
    cleanexit
endif

comtype aplib

getdstring PAK_SIGN 4
if PAK_SIGN == "KPKl"
   endian little
elif PAK_SIGN == "bKPK"
   endian big
endif

get DUMMY long
get DUMMY long
get CHUNK_SIZE long
get TOC_OFFSET longlong
goto TOC_OFFSET
get FILES long
savepos TOC_OFFSET
math FILES -= 1
savepos OFFSET
xmath OFFSET "OFFSET + (FILES * 8) + 4"
goto OFFSET
get NAMES_OFFSET long
math NAMES_OFFSET *= 0x10
goto NAMES_OFFSET
get SIZE longlong

for i = 0 < FILES
   get ID long
   get NAMESZ long
   getdstring NAME NAMESZ
   putarray 0 i ID
   putarray 1 i NAME
next i

goto TOC_OFFSET

for i = 0 < FILES

   get ID long
   get OFFSET long
   math OFFSET *= 0x10
   savepos LAST_POS
   goto OFFSET
   get OUT_SIZE long
   get CHUNKS long
   savepos OFFSET
   xmath OFFSET "OFFSET + (CHUNKS * 4)"

   for k = 0 < FILES
      getarray CHECK_ID 0 k
      if CHECK_ID == ID
         getarray NAME 1 k
         break
      endif
   next k

        if CHUNKS == 0
      log NAME OFFSET OUT_SIZE
        else
           log TEMPORARY_FILE 0 0
      append
      for k = 0 < CHUNKS
         get CHUNK_ZSIZE long
         clog TEMPORARY_FILE OFFSET CHUNK_ZSIZE CHUNK_SIZE
         math OFFSET += CHUNK_ZSIZE
      next k
      append
      open "." TEMPORARY_FILE 1
      log NAME 0 OUT_SIZE 1
   endif

   goto LAST_POS

next i


And here is the one for FORKs.

Code: Select all

idstring  "FORK"
get DUMMY byte
get SKIPS byte
get ELEMENTS byte
get ZERO byte
for SKIP = 0 < SKIPS
   get DUMMY long
next SKIP
savepos TMP
goto TMP
for i = 0 < ELEMENTS
   endian big
   get FLAGS long
   get OFFSET long
   get ZSIZE long
   get SIZE long
   string NAME p= "%08x" i
   string NAME += ".dat"
   if ZSIZE == SIZE
      log NAME OFFSET SIZE
   else
      clog NAME OFFSET ZSIZE SIZE
   endif
next i


P.S.
Don't know why, but decompression with MEMORY_FILE is slower FOR HOURS, than the decompression with TEMPORARY_FILE. I thought is should be faster, is this some bug in quickbms?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

Well it was 2 years ago and it worked for sure with the provided sample if I wrote so :)

Regarding the memory_file the only reason behind the slowness is related to the chunks you append because they require to reallocate the memory, that's why in my script I used putvarchr before log MEMORY_FILE 0 0 for pre-allocating the memory.
spider91
Posts: 233
Joined: Sun Aug 24, 2014 5:26 pm

Re: [PC] Sacred 3

Post by spider91 »

It worked, but names were incorrect and not even all files had names. Btw each .pak is a standalone archive and also there's no need to use .packagedescription file for unpacking. Also it seems that in your script you're unpacking each FORK two times.

Regarding the memory_file i've tried putvarchr and it doesn't help a lot, still really slow, so it's better to use TEMPORARY_FILE.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: [PC] Sacred 3

Post by aluigi »

Are you sure to have used putvarchr with the correct final size that will have the MEMORY_FILE?
It's easy to check it, if "get TMP asize MEMORY_FILE" returns a TMP which is bigger than the original SIZE you used in putvarchr, then that's the problem.
In quickbms there is absolutely no difference in physical or memory files, latter are ever faster because there is no HDD operation.