Star Ocean 5

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

Star Ocean 5

Post by chrrox »

They changed their slz format.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Star Ocean 5

Post by chrrox »

it seems if the file size is over 0x10000 it splits the compressed chunks so that each chunk never uncompresses to more then that size.
COMP_RLEW seems to produce the closest results to the correct output. some sections look ok output with this.
more info
http://forum.xentax.com/viewtopic.php?f=10&t=4618
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Star Ocean 5

Post by aluigi »

That RLEW has been taken from the game AIM Racing. I doubt that it's the correct algorithm but it's interesting if it's not much far from the expected original uncompressed data :)
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Star Ocean 5

Post by chrrox »

I got slz_02 working perfect in quickbms.
I can get slz_03 working for single sections.
In another game from the developers that used this same archive format with slz05 type
They split the files into 0x10000 (uncompressed size) chunks.
This would seem to match the format here.
Using some old ps2 tools I am able to extract some of the chunks if i create the old header the tool is looking for
but doing the same thing in quickbms I get a crash.
ill send a sample
0041.slz is from ps2 game and works fin in quickbms and in the old tool.
in the asf file
the 3rd and 4th slz sections extract fine in quickbms
53 4C 5A 03 05 04 00 25 00 00 16 86 00 00 2C E0 00 00 00 00 00 26 07 A8 01 40 00 80 00 00 00 00
53 4C 5A 02 06 04 00 25 00 00 13 86 00 00 30 44 00 00 00 00 00 26 1E 10 01 40 00 80 00 00 00 00

When I try the first section
53 4C 5A 03 00 04 00 25 00 00 6A F8 00 01 81 B0 00 00 00 00 00 00 00 80 65 40 00 10 00 00 00 00

53 4C 5A 03 - SLZ Magic
00 - chunk start
04 00 25 - version?
00 00 6A F8 -compressed chunk total size
00 01 81 B0 -uncompressed size
00 00 00 00 00 00 00 80 - chunk start based on slz header offset
65 40 00 10
00 00 00 00

Now if i go to 0x80
it starts with 0x48 FA
this is the chunk size
so i read that may bytes after it
i end up at 0x497C
then i read the 2nd chunk size
0x21 FA

This should be all for this chunk
the old tools I can get some data to extract correctly with the modified header but I cant get anything with quickbms.

r4125393126.7z is the new game using 0x5 slz type so you can see its the same layout.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Star Ocean 5

Post by aluigi »

Script 0.2.1
I don't know how to make it compatible with ce200_f01a.asf without making it even more complicated than how it's already now.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Star Ocean 5

Post by chrrox »

I am fine with not changing the script I am saying the decompression is crashing when i manually try to set it in the script.
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Star Ocean 5

Post by aluigi »

No idea
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Star Ocean 5

Post by chrrox »

I tested some more it seems the original slz_03 code posted is not correct and that is why it is failing.
El Duderino
Posts: 14
Joined: Fri Aug 08, 2014 12:30 am

Re: Star Ocean 5

Post by El Duderino »

I completely forgot about this game.

Image
akderebur
Posts: 68
Joined: Wed Nov 15, 2017 1:54 pm

Re: Star Ocean 5

Post by akderebur »

I got the new type 3 code by disassembling Resonance of Fate on pc. It seems to work fine for SO5 files too. It can probably be simplified a lot, but it works for me as is. Just wanted to post here incase you want to put it to use in quickbms.

Code: Select all

void SLZ3_Decode(unsigned char* in, char* out_buffer) {
      int v3 = 0; // ebp
      unsigned __int8 *v5 = nullptr; // r13
      int i = 0; // edx
      bool v160 = false; // zf
      unsigned __int8 *DataS = nullptr; // rbx
      signed __int64 v1217 = 0; // r12
      int v1218 = 0; // er15
      int v1238 = 0; // eax
      int v1239 = 0; // er13
      int v1240 = 0; // eax
      int v1241 = 0; // er12
      int v1242 = 0; // ecx
      int v1243 = 0; // eax
      char *v1244 = nullptr; // rbx
      signed __int64 v1245 = 0;  // rsi
      size_t v1246 = 0; // r14
      _WORD *outPtr = nullptr; // rcx
      _WORD *v1259 = nullptr; // rdi
                 //char *v1259; // rdi
      int v1260 = 0; // er9
      signed int v1261 = 0; // er11
      unsigned int v1262 = 0; // eax
      unsigned int v1263 = 0; // edx
      unsigned int v1264 = 0; // eax
      unsigned int v1265 = 0; // er10
      signed __int64 v1266 = 0; // rax
      __int64 writeC = 0; // rdx
      char *Dst = nullptr; // [rsp+38h] [rbp-3C0h]
      int v1276 = 0; // [rsp+48h] [rbp-3B0h]

      v5 = in;
      Dst = out_buffer;

      DataS = (unsigned __int8 *)(v5 + *(unsigned int *)(v5 + 20));
      v1217 = *(signed int *)(v5 + 12);
      v1218 = *(unsigned __int8 *)(v5 + 25) << 10;
      if (v1218)
      {
         v1238 = (v1218 + (signed int)v1217 - 1) / v1218;
         v1239 = v1238;
         v1276 = (v1218 + (signed int)v1217 - 1) / v1218;
         v1240 = v1238 - 1;
         v1241 = v1217 - v1218 * v1240;
         if (v1239 <= 0)
            return;
         while (1)
         {
            v160 = v3 == v1240;
            v1242 = v1218;
            v1243 = *(unsigned __int16 *)DataS;
            if (v160)
               v1242 = v1241;
            v1244 = (char *)(DataS + 2);
            v1245 = v1242;
            if ((_WORD)v1243)
               v1242 = v1243;
            v1246 = v1242;
            outPtr = (WORD*)Dst;
            if (v1246 == v1245)
            {
               if (Dst >= v1244 || (char *)Dst + v1246 <= v1244)
                  memcpy(Dst, v1244, v1245);
               else
                  memmove(Dst, v1244, v1245);
            }
            else if (Dst >= v1244 || (char *)Dst + v1245 <= v1244)
            {
               v1259 = (WORD*)v1244;
               v1260 = 0;
               v1261 = 1;
               while (1)
               {
                  while (1)
                  {
                     if (--v1261)
                     {
                        v1260 >>= 1;
                     }
                     else
                     {
                        v1260 = (unsigned __int16)*v1259;
                        v1261 = 16;
                        v1259++;
                     }
                     //LOWORD(v1262) = *v1259;
                     v1262 = *v1259;
                     if (!(v1260 & 1))
                        break;
                     *outPtr = v1262;
                     ++outPtr;
                     ++v1259;
                  }
                  v1262 = (unsigned __int16)v1262;
                  v1263 = v1262 & 0xFFF;
                  if (!(v1262 & 0xFFF))
                     break;
                  v1264 = v1262 >> 12;
                  v1265 = v1264 + 2;
                  if (v1264 != -2)
                  {
                     v1266 = -(signed __int64)v1263;
                     writeC = v1265;
                     do
                     {
                        *outPtr = outPtr[v1266];
                        ++outPtr;
                        --writeC;
                     } while (writeC);
                  }
                  ++v1259;
               }
            }
            else
            {
               if (v1245 > 0x10000)
                  return;
               
            }

            Dst = (char *)Dst + v1245;
            DataS = (unsigned __int8 *)&v1244[v1246];
            //SwitchToThread();
            ++v3;
            v1240 = v1239 - 1;
            if (v3 >= v1239)
            {
               return;
            }
         }
      }
   }
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Star Ocean 5

Post by aluigi »

Very good.
Now the real problem is... how should I call it in quickbms? :D
slz_03 is already taken, maybe slz_03b?
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: Star Ocean 5

Post by chrrox »

sounds good to me.
Rainx
Posts: 21
Joined: Sat Feb 24, 2018 7:24 am

Re: Star Ocean 5

Post by Rainx »

Hello, aluigi.
Can you add support for attached file (*slz*)?

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

Re: Star Ocean 5

Post by aluigi »

It's a type 3.
As far as I know there is no compression supported for this type because if there was any I would have already implemented it.
Chrrox?
Rainx
Posts: 21
Joined: Sat Feb 24, 2018 7:24 am

Re: Star Ocean 5

Post by Rainx »

Yeah.
BattleCollection_Status - type 3.
CommonText22 - type 2.

Code: Select all

Error: incomplete input file 0: D:\BattleCollection_Status.slz
       Can't read 185232503 bytes from offset 00000b2c.
       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   100%   2866       2860       . offset 00000b2c

Last script line before the error or that produced the error:
  138 log MEMORY_FILE2 OFFSET CHUNKS_SIZE

Code: Select all

-------------------
*EXCEPTION HANDLER*
-------------------
An error or crash occurred:

*EH* ExceptionCode      c0000005 access violation
*EH* ExceptionFlags     00000000
*EH* ExceptionAddress   77C311C5
                        77C00000 + 000311c5 msvcrt.dll
*EH* NumberParameters   00000002
*EH*                    00000001
*EH*                    00000000

Last script line before the error or that produced the error:
  138 log MEMORY_FILE2 OFFSET CHUNKS_SIZE


Hm. What about akderebur's code?
aluigi
Site Admin
Posts: 12984
Joined: Wed Jul 30, 2014 9:32 pm

Re: Star Ocean 5

Post by aluigi »

Ah right, I wrongly used triace.bms instead of slz.bms
Ok so slz.bms already implements everything including type 3: 1, 2, 3, 4, 5 and 7.

The error reading "incomplete input" is an headache.
The script includes tons of checks and work-arounds for supporing multiple variants so it's quite complicated to fix something.