cocos2d Texture Packer CCZ decrypt

Doubts, help and support about QuickBMS and other game research tools
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

cocos2d Texture Packer CCZ decrypt

Post by chrrox »

I got this code working outside quickbms but I can't figure out how to make t into a call dll script.
s_uEncryptionKey is 1024 uint values.
should be combined into 4096 byte xor key.
that xores the file starting at offset 12

Code: Select all

set MEMORY_FILE10 string "
typedef unsigned int u32;

u32 s_uEncryptedPvrKeyParts [4];
u32 s_uEncryptionKey [1024];


u32 MX(u32 z, u32 y, u32 p, u32 e, u32 sum) {
    return (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (s_uEncryptedPvrKeyParts[(p & 3) ^ e] ^ z)));
}

void SetKey(u32 key1, u32 key2, u32 key3, u32 key4) {
    s_uEncryptedPvrKeyParts[0] = key1;
    s_uEncryptedPvrKeyParts[1] = key2;
    s_uEncryptedPvrKeyParts[2] = key3;
    s_uEncryptedPvrKeyParts[3] = key4;
}

void InitializeKey() {
    unsigned int enclen = 1024;

    unsigned int y, p, e;
    unsigned int rounds = 6;
    unsigned int sum = 0;
    unsigned int z = s_uEncryptionKey[enclen - 1];

    do
    {
        unsigned int DELTA = 0x9e3779b9;

        sum += DELTA;
        e = (sum >> 2) & 3;

        for (p = 0; p < enclen - 1; p++)
        {
            y = s_uEncryptionKey[p + 1];
        z = s_uEncryptionKey[p] += MX(z, y, p, e, sum);
        }

        y = s_uEncryptionKey[0];
        z = s_uEncryptionKey[enclen - 1] += MX(z, y, p, e, sum);

        } while (--rounds > 0);

}

void decrypt(unsigned char *buff, int size, u32 key1, u32 key2, u32 key3, u32 key4) {
    SetKey(key1, key2, key3, key4);
    InitializeKey();
    //int i;
    //for(i = 0; i < size; i++) {
    //    buff[i] ^= RandXor128();
    //}
}
"


get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 decrypt tcc RET MEMORY_FILE SIZE 0xF68C6273 0x07C32116 0x4AF4F1AC 0xBF0988A6
log "dump.dat" 0 SIZE MEMORY_FILE

Last edited by chrrox on Thu Apr 08, 2021 2:38 pm, edited 1 time in total.
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by Ekey »

you can make a simple function for decryption, like this one

Code: Select all

set MEMORY_FILE10 string "

unsigned int s_uEncryptedPvrKeyParts[4];
unsigned int s_uEncryptionKey[1024];

void SetKey(unsigned int key1, unsigned int key2, unsigned int key3, unsigned int key4)
{
   s_uEncryptedPvrKeyParts[0] = key1;
   s_uEncryptedPvrKeyParts[1] = key2;
   s_uEncryptedPvrKeyParts[2] = key3;
   s_uEncryptedPvrKeyParts[3] = key4;
}
     
unsigned int MX(unsigned int z, unsigned int y, unsigned int p, unsigned int e, unsigned int sum)
{
   return (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (s_uEncryptedPvrKeyParts[(p & 3) ^ e] ^ z)));
}

void InitializeKey()
{
   int enclen = 1024;

   unsigned int y, p, e;
   unsigned int rounds = 6;
   unsigned int sum = 0;
   unsigned int z = s_uEncryptionKey[enclen - 1];

   do
   {
      unsigned int DELTA = 0x9e3779b9;

      sum += DELTA;
      e = (sum >> 2) & 3;

      for (p = 0; p < enclen - 1; p++)
      {
         y = s_uEncryptionKey[p + 1];
         z = s_uEncryptionKey[p] += MX(z, y, p, e, sum);
      }

            y = s_uEncryptionKey[0];
            z = s_uEncryptionKey[enclen - 1] += MX(z, y, p, e, sum);

   } while (--rounds > 0);
}

void Decrypt(unsigned char* lpBuffer, int dwSize)
{
  SetKey(0xF68C6273, 0x07C32116, 0x4AF4F1AC, 0xBF0988A6);
  InitializeKey();
  for (int i = 0; i < dwSize; i++)
  {
     lpBuffer[i] ^= s_uEncryptionKey[i % 4096];
  }
}
"

get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 "Decrypt" "tcc" RET MEMORY_FILE SIZE
log "DECRYPTED.dat" 0 SIZE MEMORY_FILE


not tested but in theory it should work :)
Last edited by Ekey on Thu Apr 08, 2021 2:41 pm, edited 1 time in total.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by chrrox »

s_uEncryptionKey is a bunch of unsigned integers.
no need to combine them first in c++ before xoring?
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by Ekey »

in this case you can do xor data by DWORD like this:

Code: Select all

void DecryptByDWORD(void* lpBuffer, DWORD dwSize)
{
   dwSize >>= 2;
   LPDWORD dwBlock = (LPDWORD)lpBuffer;

   SetKey(0xF68C6273, 0x07C32116, 0x4AF4F1AC, 0xBF0988A6);
   InitializeKey();

   DWORD ch;

   for (int i = 0; i < dwSize; i++)
   {
      ch  = *dwBlock ^ s_uEncryptionKey[i % 1024];
      *dwBlock++ = ch;
   }
}
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by Ekey »

Code: Select all

set MEMORY_FILE10 string "

unsigned int s_uEncryptedPvrKeyParts[4] = {0xF68C6273, 0x07C32116, 0x4AF4F1AC, 0xBF0988A6};
unsigned int s_uEncryptionKey[1024];

void decodeEncodedPvr(unsigned int *data, size_t len)
{
    const int enclen = 1024;
    const int securelen = 512;
    const int distance = 64;
   
    // create long key
    unsigned int y, p, e;
    unsigned int rounds = 6;
    unsigned int sum = 0;
    unsigned int z = s_uEncryptionKey[enclen-1];
       
    do
    {
      #define DELTA 0x9e3779b9
      #define MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (s_uEncryptedPvrKeyParts[(p & 3) ^ e] ^ z)))
           
        sum += DELTA;
        e = (sum >> 2) & 3;
           
        for (p = 0; p < enclen - 1; p++)
        {
           y = s_uEncryptionKey[p + 1];
           z = s_uEncryptionKey[p] += MX;
        }
           
           y = s_uEncryptionKey[0];
           z = s_uEncryptionKey[enclen - 1] += MX;
           
    } while (--rounds);
   
    int b = 0;
    int i = 0;
   
    // decrypt first part completely
    for(; i < len && i < securelen; i++)
    {
        data[i] ^= s_uEncryptionKey[b++];
       
        if(b >= enclen)
        {
            b = 0;
        }
    }
   
    // decrypt second section partially
    for(; i < len; i += distance)
    {
        data[i] ^= s_uEncryptionKey[b++];
       
        if(b >= enclen)
        {
            b = 0;
        }
    }
}

void DecryptCCZ(unsigned char *lpBuffer, int dwSize)
{
   unsigned int* lpData = (unsigned int*)(lpBuffer + 12);
   size_t dwEncryptedSize = (dwSize - 12) / 4;

   decodeEncodedPvr(lpData, dwEncryptedSize);
}
"


here is the working code :)

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

Re: cocos2d Texture Packer CCZ decrypt

Post by chrrox »

what am doing wrong i get.
<string>:3: error: invalid type

Last script line before the error or that produced the error:
74 calldll MEMORY_FILE10 DecryptCCZ tcc RET MEMORY_FILE SIZE


Code: Select all

get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 DecryptCCZ tcc RET MEMORY_FILE SIZE
log "DECRYPTED.dat" 0 SIZE MEMORY_FILE
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by Ekey »

it's weird
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by chrrox »

This works

Code: Select all

set MEMORY_FILE10 string "
typedef unsigned int u32;
unsigned int s_uEncryptedPvrKeyParts[4] = {0xF68C6273, 0x07C32116, 0x4AF4F1AC, 0xBF0988A6};
unsigned int s_uEncryptionKey[1024];

u32 MX(u32 z, u32 y, u32 p, u32 e, u32 sum) {
    return (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (s_uEncryptedPvrKeyParts[(p & 3) ^ e] ^ z)));
}

void decodeEncodedPvr(unsigned int *data, unsigned int len)
{
    const int enclen = 1024;
    const int securelen = 512;
    const int distance = 64;
   
    // create long key
    unsigned int y, p, e;
    unsigned int rounds = 6;
    unsigned int sum = 0;
    unsigned int z = s_uEncryptionKey[enclen-1];
       


    do
    {
        unsigned int DELTA = 0x9e3779b9;

        sum += DELTA;
        e = (sum >> 2) & 3;

        for (p = 0; p < enclen - 1; p++)
        {
            y = s_uEncryptionKey[p + 1];
        z = s_uEncryptionKey[p] += MX(z, y, p, e, sum);
        }

        y = s_uEncryptionKey[0];
        z = s_uEncryptionKey[enclen - 1] += MX(z, y, p, e, sum);

        } while (--rounds > 0);
   
    int b = 0;
    int i = 0;
   
    // decrypt first part completely
    for(; i < len && i < securelen; i++)
    {
        data[i] ^= s_uEncryptionKey[b++];
       
        if(b >= enclen)
        {
            b = 0;
        }
    }
   
    // decrypt second section partially
    for(; i < len; i += distance)
    {
        data[i] ^= s_uEncryptionKey[b++];
       
        if(b >= enclen)
        {
            b = 0;
        }
    }
}

void DecryptCCZ(unsigned char *lpBuffer, int dwSize)
{
   unsigned int* lpData = (unsigned int*)(lpBuffer + 12);
   unsigned int dwEncryptedSize = (dwSize - 12) / 4;

   decodeEncodedPvr(lpData, dwEncryptedSize);
}
"

get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 DecryptCCZ tcc RET MEMORY_FILE SIZE
log "DECRYPTED.dat" 0 SIZE MEMORY_FILE
Ekey
Posts: 1383
Joined: Sat Aug 09, 2014 2:34 pm

Re: cocos2d Texture Packer CCZ decrypt

Post by Ekey »

Ok. Problem with "defines" I suppose :D