The Getaway

Extraction and unpacking of game archives and compression, encryption, obfuscation, decoding of unknown files
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

The Getaway

Post by aluigi »

Script updated to 0.2 for supporting the PACK_EE.PAK archive:
http://aluigi.org/bms/getaway.bms
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

I don't know what the hell am I doing, if that's the forsaken script's fault or it's just me but it's time for me to report this:
PACK_IOP.PAK:

Code: Select all

  633b7000 620756997  compressed/spanish/

Error: incomplete input file 0: E:\THE_GETAWAY\-\PACK_IOP.PAK
       Can't read 49152 bytes from offset 714ab000.
       Anyway don't worry, it's possible that the BMS script has been written
       to exit in this way if it's reached the end of the archive so check it
       or contact its author or verify that all the files have been extracted.
       Please check the following coverage information to know if it's ok.

  coverage file 0    76%   1445152291 1900720128

Last script line before the error or that produced the error:
  41  log TMP_NAME OFFSET SIZE


PACK_EE.PAK:

Code: Select all

  offset   filesize   filename
--------------------------------------
- SCRIPT's MESSAGE:
  Error: unsupported type bin, contact me


- 0 files found in 1 seconds
  coverage file 0     0%   36         2582970368

Here are the samples, but if you have the files then it's no problem.
Oh yeah, and I forgot to mention that these files came from an new version of the game.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: The Getaway

Post by aluigi »

Fixed in 0.2.1 but compression (or what I think it's compression) is not supported yet so it's useless for the "animation" files.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

Well, the script extracted half of the archive files. I want to know if this si something to worry about(besides compression issues)?

Also...

Code: Select all

Error: incomplete input file 0: E:\THE_GETAWAY\THE_GETAWAY_AUS\PACK_IOP.PAK
       Can't read 64 bytes from offset 0000020124c08000.
       Anyway don't worry, it's possible that the BMS script has been written
       to exit in this way if it's reached the end of the archive so check it
       or contact its author or verify that all the files have been extracted.
       Please check the following coverage information to know if it's ok.

  coverage file 0    63%   1209137204 1900720128

Last script line before the error or that produced the error:
  46  log NAME OFFSET SIZE
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: The Getaway

Post by aluigi »

It's a strange format. The error is caused by the reading of the fields outside the table with the information so they are not the real offsets.
I don't have a solution at the moment because the references are correct and the extracted data is right.
Maybe the 63% of coverage is caused by the 0x800 bytes padding of the 7828 files.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

Well, you have a point.
Anyway, if you have a solution to spare let me know. After all I've never stumbled across a strange format before...
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: The Getaway

Post by aluigi »

In my opinion you have already extracted everything correctly.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

Well, I did see though the hex editor that there are more files beyond what the script can extract, but let's just leave it at that.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

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

Re: The Getaway

Post by aluigi »

No, sorry, I give up on this format... ENG_CUT.PAK has 0 folders and 0 files referenced and in fact there are no information about offsets and sizes in the first 0x800 bytes.

The script will remain as is.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

Oh...
In the meantime take a look at this:
https://github.com/performous/performous/tree/master/tools

Maybe I should start researching .pak files too, but I'll fear it'll be no simple task. I know I'm being stubborn and I need to stop bugging you about that file, but it's just some kind of opportunity I need to think about for now.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

So after further investigation regarding London Studios' game library, I reached to a conclusion that the .PAK file was used across some of the games they developed during the PS2 era, with varying structures.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

I think I might be getting somewhere with this...

So, I decided to work with those .PAK archives that have a general structure(such as This is Football 2002 and the first Singstar game) and not those "merged structure" ones as you see in The Getaway.

Basically there's this three-byte variable, followed by two four-byte variables that contain both the offset and size info, and following that there's the filename itself. Obtaining these names weren't as easy as I thought as even if I decided to do something like "get NAME string" it would still surprass a few bytes here and there. It doesn't help that the names themselves are continuously compressed as the "table" goes on, with not a single way to actually retrieve the missing characters.

After all that there's one-byte variable type that is actually a marker for some extension the file is based on. The whole extension thing starts at offset 0x114.

That's all for now. Any questions are welcome.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

Okay, I think I got the gist of these .PAK files now.

Now I know why there are these "merged structures" as seen in The Getaway. Basically, there's this dedicated index that starts with the 0x190 offset of each .PAK file that seems to cover only the compressed files. The script will simply stop there if it finds anything like that.

EDIT#01: Updated the script for a more "cleaner" way of obtaining the filenames. It can also support "merged structures" now.
---
EDIT#02: The script has been completely restructured. Now the initial header info can be read with just a few variables, and the whole "structure" thing has been handled differently. For starters, the whole "TOTAL_FILES" cycle was discarded in favor of a "do... while" cycle that reads the whole table through way of memory(that is, MEMORY_FILE) since the app could crash with the script if the TOTAL_FILES number was way below what was indicated during the "cycling" part. The whole "folder" thing has been kept as-is.
---
EDIT#03: The whole "folder" extraction part has been changed. ENTRIES3 isn't used for the extraction process anymore as it would often clash with the actual structure of the archive that comes after that "folder" part. ENTRIES1 is instead used and blank "entries" are now discarded during extraction.
AnonBaiter
Posts: 1125
Joined: Tue Feb 02, 2016 2:35 am

Re: The Getaway

Post by AnonBaiter »

well, my job here is done...

Code: Select all

math INFO_OFF1 == 0x190

getdstring ARCHIVE_TYPE 8
if ARCHIVE_TYPE != "SceeWhPC" && ARCHIVE_TYPE != "SceeWhPk"
   break
endif
getdstring TIMESTAMP 20
get TABLE_SIZE long
get TOTAL_FILES long
getdstring RANDOM 0x80
for t1 = 0 < 28
   get DUMMY03 long
next t1

goto INFO_OFF1
get FOLDERS1 long
get SIZE1 long
if FOLDERS1 != 0 && SIZE1 != 0
   # copy-pasted straight from aluigi's getaway.bms script
   savepos INFO_OFF2
   xmath FOLDERS2 "FOLDERS1 * 0x74"
   xmath INFO_OFF2 "INFO_OFF2 + FOLDERS2"

    for FOLDER = 0 < FOLDERS1

        getdstring EXT2 4
        getdstring NAME2 0x60
        get ENTRIES1 long
        get ENTRIES2 long
        get ENTRIES3 long
        get OFFSET2 long

        savepos TMP1
        math OFFSET2 + INFO_OFF2
        goto OFFSET2
      
      if ENTRIES2 == 0 || ENTRIES2 == 1
         if ENTRIES1 > ENTRIES3
            math ENTRIES == ENTRIES1
         elif ENTRIES1 < ENTRIES3
            math ENTRIES == ENTRIES3
         elif ENTRIES1 == ENTRIES3
            math ENTRIES == ENTRIES3
         endif
      else
         xmath ENTRIES "(ENTRIES3 - ENTRIES2) + 1"
      endif

        string NAME2 + \
      math i2 = 0
        for i = 0 < ENTRIES
            get FSIZE2 long
            get FOFFSET2 long
            if ARCHIVE_TYPE == "SceeWhPC"
                get NAME_CRC2 long
            endif
         math i2 + 1
         
            math FOFFSET2 * 0x800
            if FSIZE2 != 0
            string NAME3 p "%s%d.%s" NAME2 i2 EXT2
                if FSIZE2 & 0xc0000000 # 0x40000000 and 0x80000000
               savepos TMP2
               goto FOFFSET2
               get FZSIZE1 long
               goto TMP2
                    math FSIZE2 & 0x3fffffff
               string TMP_NAME2 p "%s[compressed_0x%08x]" NAME3 FZSIZE1
                    log TMP_NAME2 FOFFSET2 FSIZE2
                else
                    log NAME3 FOFFSET2 FSIZE2
                endif
            endif
        next i

        goto TMP1

    next FOLDER
   
   xmath INFO_OFF3 "INFO_OFF2 + SIZE1"
   log MEMORY_FILE2 INFO_OFF3 TABLE_SIZE
else
   xmath INFO_OFF4 "INFO_OFF1 + 8"
   log MEMORY_FILE2 INFO_OFF4 TABLE_SIZE
endif

putvarchr MEMORY_FILE 0x100 0
log MEMORY_FILE 0 0x100

for
   get FOFFSET threebyte MEMORY_FILE2
   get NAME_POS byte MEMORY_FILE2
   get NAME_SIZE byte MEMORY_FILE2
   get DUMMY34 short MEMORY_FILE2
   get FSIZE long MEMORY_FILE2
   
   if ARCHIVE_TYPE == "SceeWhPC"
      get NAME_CRC long MEMORY_FILE2
   endif
   
   if FOFFSET == 0
   if NAME_POS == 0
   if NAME_SIZE == 0
   if DUMMY34 == 0
   if FSIZE == 0
      break
   endif
   endif
   endif
   endif
   endif
   
   math FOFFSET * 0x800
   
   savepos TMP2 MEMORY_FILE2
   savepos NAME_TMP1 MEMORY_FILE2
   math NAME_TMP1 + NAME_SIZE
   math NAME_TMP1 - 1
   goto NAME_TMP1 MEMORY_FILE2
   get EXT_IDX byte MEMORY_FILE2
   if EXT_IDX <= 0x20
      xmath FULL_NAME_SIZE "(NAME_POS + NAME_SIZE) - 1"
      xmath EXT_OFF "(EXT_IDX * 4) + 0x110"
      goto EXT_OFF
      getdstring EXT1 4
      math NAME_SIZE - 1
      goto TMP2 MEMORY_FILE2
      getdstring NAME NAME_SIZE MEMORY_FILE2
      get EXT_IDX2 byte MEMORY_FILE2
   else
      xmath FULL_NAME_SIZE "NAME_POS + NAME_SIZE"
      goto TMP2 MEMORY_FILE2
      getdstring NAME NAME_SIZE MEMORY_FILE2
      set EXT1 extension NAME
   endif
   
   if NAME_POS != 0
      savepos MTMP1 MEMORY_FILE
      goto NAME_POS MEMORY_FILE
      putct NAME string -1 MEMORY_FILE
      goto MTMP1 MEMORY_FILE
   else
      goto 0 MEMORY_FILE
      putct NAME string -1 MEMORY_FILE
   endif
   
   goto 0 MEMORY_FILE
   getdstring FULL_NAME FULL_NAME_SIZE MEMORY_FILE
   
   if EXT_IDX <= 0x20
      string FNAME p "%s.%s" FULL_NAME EXT1
   else
      string FNAME p "%s" FULL_NAME
   endif
   
   log FNAME FOFFSET FSIZE
next
the PAK format was too damn easy in the end i couldn't even bother with it anymore...
TheMarkopoloShow
Posts: 1
Joined: Sat Oct 19, 2019 3:45 am

Re: The Getaway

Post by TheMarkopoloShow »

AnonBaiter wrote:well, my job here is done...

Code: Select all

math INFO_OFF1 == 0x190

getdstring ARCHIVE_TYPE 8
if ARCHIVE_TYPE != "SceeWhPC" && ARCHIVE_TYPE != "SceeWhPk"
   break
endif
getdstring TIMESTAMP 20
get TABLE_SIZE long
get TOTAL_FILES long
getdstring RANDOM 0x80
for t1 = 0 < 28
   get DUMMY03 long
next t1

goto INFO_OFF1
get FOLDERS1 long
get SIZE1 long
if FOLDERS1 != 0 && SIZE1 != 0
   # copy-pasted straight from aluigi's getaway.bms script
   savepos INFO_OFF2
   xmath FOLDERS2 "FOLDERS1 * 0x74"
   xmath INFO_OFF2 "INFO_OFF2 + FOLDERS2"

    for FOLDER = 0 < FOLDERS1

        getdstring EXT2 4
        getdstring NAME2 0x60
        get ENTRIES1 long
        get ENTRIES2 long
        get ENTRIES3 long
        get OFFSET2 long

        savepos TMP1
        math OFFSET2 + INFO_OFF2
        goto OFFSET2
      
      if ENTRIES2 == 0 || ENTRIES2 == 1
         if ENTRIES1 > ENTRIES3
            math ENTRIES == ENTRIES1
         elif ENTRIES1 < ENTRIES3
            math ENTRIES == ENTRIES3
         elif ENTRIES1 == ENTRIES3
            math ENTRIES == ENTRIES3
         endif
      else
         xmath ENTRIES "(ENTRIES3 - ENTRIES2) + 1"
      endif

        string NAME2 + \
      math i2 = 0
        for i = 0 < ENTRIES
            get FSIZE2 long
            get FOFFSET2 long
            if ARCHIVE_TYPE == "SceeWhPC"
                get NAME_CRC2 long
            endif
         math i2 + 1
         
            math FOFFSET2 * 0x800
            if FSIZE2 != 0
            string NAME3 p "%s%d.%s" NAME2 i2 EXT2
                if FSIZE2 & 0xc0000000 # 0x40000000 and 0x80000000
               savepos TMP2
               goto FOFFSET2
               get FZSIZE1 long
               goto TMP2
                    math FSIZE2 & 0x3fffffff
               string TMP_NAME2 p "%s[compressed_0x%08x]" NAME3 FZSIZE1
                    log TMP_NAME2 FOFFSET2 FSIZE2
                else
                    log NAME3 FOFFSET2 FSIZE2
                endif
            endif
        next i

        goto TMP1

    next FOLDER
   
   xmath INFO_OFF3 "INFO_OFF2 + SIZE1"
   log MEMORY_FILE2 INFO_OFF3 TABLE_SIZE
else
   xmath INFO_OFF4 "INFO_OFF1 + 8"
   log MEMORY_FILE2 INFO_OFF4 TABLE_SIZE
endif

putvarchr MEMORY_FILE 0x100 0
log MEMORY_FILE 0 0x100

for
   get FOFFSET threebyte MEMORY_FILE2
   get NAME_POS byte MEMORY_FILE2
   get NAME_SIZE byte MEMORY_FILE2
   get DUMMY34 short MEMORY_FILE2
   get FSIZE long MEMORY_FILE2
   
   if ARCHIVE_TYPE == "SceeWhPC"
      get NAME_CRC long MEMORY_FILE2
   endif
   
   if FOFFSET == 0
   if NAME_POS == 0
   if NAME_SIZE == 0
   if DUMMY34 == 0
   if FSIZE == 0
      break
   endif
   endif
   endif
   endif
   endif
   
   math FOFFSET * 0x800
   
   savepos TMP2 MEMORY_FILE2
   savepos NAME_TMP1 MEMORY_FILE2
   math NAME_TMP1 + NAME_SIZE
   math NAME_TMP1 - 1
   goto NAME_TMP1 MEMORY_FILE2
   get EXT_IDX byte MEMORY_FILE2
   if EXT_IDX <= 0x20
      xmath FULL_NAME_SIZE "(NAME_POS + NAME_SIZE) - 1"
      xmath EXT_OFF "(EXT_IDX * 4) + 0x110"
      goto EXT_OFF
      getdstring EXT1 4
      math NAME_SIZE - 1
      goto TMP2 MEMORY_FILE2
      getdstring NAME NAME_SIZE MEMORY_FILE2
      get EXT_IDX2 byte MEMORY_FILE2
   else
      xmath FULL_NAME_SIZE "NAME_POS + NAME_SIZE"
      goto TMP2 MEMORY_FILE2
      getdstring NAME NAME_SIZE MEMORY_FILE2
      set EXT1 extension NAME
   endif
   
   if NAME_POS != 0
      savepos MTMP1 MEMORY_FILE
      goto NAME_POS MEMORY_FILE
      putct NAME string -1 MEMORY_FILE
      goto MTMP1 MEMORY_FILE
   else
      goto 0 MEMORY_FILE
      putct NAME string -1 MEMORY_FILE
   endif
   
   goto 0 MEMORY_FILE
   getdstring FULL_NAME FULL_NAME_SIZE MEMORY_FILE
   
   if EXT_IDX <= 0x20
      string FNAME p "%s.%s" FULL_NAME EXT1
   else
      string FNAME p "%s" FULL_NAME
   endif
   
   log FNAME FOFFSET FSIZE
next
the PAK format was too damn easy in the end i couldn't even bother with it anymore...


Hey, do you know if all the files are being extracted? I'm trying to locate the soundtrack in Aiding and abetting when escorting Jake to the warehouse. I believe a few others are also missing.