Soul Sacrifice Delta (Vita)

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Soul Sacrifice Delta (Vita)

Post by chrrox »

Code: Select all

# Soul Sacrifice Delta (Vita)
# script for QuickBMS http://quickbms.aluigi.org
#made by chrrox
get name basename
endian big
Open FDDE PK 0
Open FDDE pfs 1
Open FDDE pkh 2
goto 8 1
get FOLDERS long 1
get TFILES long 1

for i = 0 < FOLDERS
   get FOLDERID long 1
   get FOLDERPARENT long 1
   get UNK long 1
   get SUBFLDR long 1
   get FILESTART long 1
   get FOLDERFILES long 1
   #print "%FOLDERID% %FOLDERPARENT% %UNK% %SUBFLDR% %FILESTART% %FOLDERFILES%"
   PutArray 3 i FOLDERPARENT
   PutArray 4 i FILESTART
   PutArray 5 i FOLDERFILES
next i

for i = 0 < FOLDERS
   get FOLDERNAMEOFF long 1
   PutArray 0 i FOLDERNAMEOFF
next i

for i = 0 < TFILES
   get FILENAMEOFF long 1
   PutArray 1 i FILENAMEOFF
next i

savepos NAMEBASE 1

for i = 0 < FOLDERS
   GetArray FOLDERNAMEOFF 0 i
   math FOLDERNAMEOFF += NAMEBASE
   goto FOLDERNAMEOFF 1
   get FOLDERNAME string 1
   #print "%FOLDERNAME%"
   string FOLDERNAME l FOLDERNAME
   PutArray 2 i FOLDERNAME
next i

for i = 0 < TFILES
   GetArray FILENAMEOFF 1 i
   math FILENAMEOFF += NAMEBASE
   goto FILENAMEOFF 1
   get FILENAME string 1
   #print "%FILENAME%"
   string FILENAME l FILENAME
   PutArray 7 i FILENAME
next i

set MEMORY_FILE binary ""

for i = 0 < FOLDERS
   GetArray FOLDERNAME 2 i
   GetArray FOLDERPARENT 3 i
   GetArray FILESTART 4 i
   GetArray FOLDERFILES 5 i
   math FOLDERFILES += FILESTART
   set FOLDERBASE ""
   #print "%FOLDERPARENT% %FILESTART% %FOLDERFILES%"
   if FOLDERPARENT > 0
   GetArray FOLDERBASE 6 FOLDERPARENT
   string FOLDERBASE += /
   #print "%FOLDERNAME%"
   endif
   string FOLDERBASE += FOLDERNAME
   PutArray 6 i FOLDERBASE
   #print "%FOLDERBASE%"
   if FOLDERFILES > 0
      for a = FILESTART < FOLDERFILES
         set NAME FOLDERBASE
         GetArray FILE 7 a
         string NAME += /
         string NAME += FILE
         #print "%NAME%"
         PutArray 8 a NAME
         #Put NAME LINE MEMORY_FILE
         # calculate checksum
         encryption crc 0x04c11db7 "32 -1 -1 1 0 0"
         string NAME E= NAME
         encryption "" ""
         #print "CRC %QUICKBMS_CRC|x%"
         string TEST p= "0x%08x " QUICKBMS_CRC
         string TEST += NAME
         #print "%TEST%"
         Put TEST LINE MEMORY_FILE
      next a
   endif
next i

goto 0 MEMORY_FILE

get FILES long 2
for i = 0 < FILES
   #GetArray NAME 8 i
   get NAME_CRC long 2
   get OFFSET long 2
   get SIZE long 2
   get ZSIZE long 2
   NameCRC NAME NAME_CRC MEMORY_FILE 32
   if ZSIZE == 0
      log NAME OFFSET SIZE
   else
      clog NAME OFFSET ZSIZE SIZE
   endif
next i
Last edited by chrrox on Sun May 15, 2016 12:41 pm, edited 1 time in total.
FireFly
Posts: 4
Joined: Mon Aug 03, 2015 7:51 am

Re: Soul Sacrifice Delta (Vita)

Post by FireFly »

So I looked at this format recently at the request of a friend. I sorted the file table by offset, but even after that some files seemed to be a bit off from their true filenames based on comparing some locale-related images to what language appeared on the image. And even then, what would the point be in storing the table sorted on checksum and then sorting it when reading the file... it all seems weird to me, like we're missing something.

Apart from that, here's some notes that might be helpful. I don't know BMS, so I don't know what log vs. clog does, but compressed files are zlib-compressed, complete with zlib header and all. Additionally, for the pfs file I have all fields figured out I think: dirid, parentid, subdir_offset, nsubdirs, subfile_offset, nsubfiles. nsubdirs and nsubfiles give the #subdirectories and regular files that are direct children to this directory, and sub{dir,file}_offset give the index to the first subdirectory/file in terms of index into the dir table (pfs) or file table (pkh, though order is weird).
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Soul Sacrifice Delta (Vita)

Post by chrrox »

the file names look perfect they are just not lining up with the actual offset table. not sure what needs to change to make it work.
Barabus
Posts: 2
Joined: Wed May 04, 2016 8:45 pm

Re: Soul Sacrifice Delta (Vita)

Post by Barabus »

The HASH field may be result of hash-function with a filename or with a full path and filename. Like it is in the Dark Souls packages.
Barabus
Posts: 2
Joined: Wed May 04, 2016 8:45 pm

Re: Soul Sacrifice Delta (Vita)

Post by Barabus »

Correct. HASH is a result of CRC-32 checksum function for full name with path. For example:
Hash: CC2F8C6D
Offset: 1673354624
Size: 2998
ZSize: 1161
Index in PKH table: 40398
Path: resource/windows/camera.ico

You can check it here:
http://hash.online-convert.com/crc32-generator
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Soul Sacrifice Delta (Vita)

Post by chrrox »

Here is the correct script updated in first post
Ehm
Posts: 11
Joined: Sat Apr 02, 2016 10:25 pm

Re: Soul Sacrifice Delta (Vita)

Post by Ehm »

This format seems to show up in Yakuza Zero as well, but the script is incompatible. Here are some sample files.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Soul Sacrifice Delta (Vita)

Post by chrrox »

for yakuza just add
comtype gzip
to the start
Ehm
Posts: 11
Joined: Sat Apr 02, 2016 10:25 pm

Re: Soul Sacrifice Delta (Vita)

Post by Ehm »

Thanks a lot!
alanmugiwara
Posts: 16
Joined: Fri Jun 15, 2018 2:46 pm

Re: Soul Sacrifice Delta (Vita)

Post by alanmugiwara »

Thank You! I can use this scrip to decompress .PK from Nintendo Wii The Last Story
imusiyus
Posts: 1
Joined: Sun Jan 29, 2023 6:37 am

Re: Soul Sacrifice Delta (Vita)

Post by imusiyus »

Sorry for posting after so long, but I got errors using that script, tried both US, ASIA versions of SSD archive.pk, where ASIA could decompress 5%, while US popped up with errors at 0%
Please may there be any help?
I'm trying to repack the SSD texture back to the pk pkh pfs file after upsampling it through AI, and although there are a lot of tools for unpacking pk on the web, I can't find the repack tool, and this script reimport seems to be the only hope

Code: Select all

Error: the compressed zlib/deflate input is wrong or incomplete (-5)
Info:  algorithm   1
       offset      6174b3e0
       input size  0x000002b4 692
       output size 0x00000732 1842
       result      0xffffffff -1

Error: uncompressed data (-1) bigger than allocated buffer (3297592)
       It usually means that data is not compressed or uses another algorithm

Last script line before the error or that produced the error:
  111 clog NAME OFFSET ZSIZE SIZE

- OFFSET       0x6174b3e0
- ZSIZE        0x000002b4
- SIZE         0x00000732
  coverage file 0     5%   89659014   1649848936 . offset 6174b694
  coverage file 1    99%   1265599    1265607    . offset 00134fc7
  coverage file 2     5%   43924      800564     . offset 0000ab94
  coverage file -1  100%   2701274    2701274    . offset 00000000

Press ENTER or close the window to quit