ZenHAX

Free Game Research Forum | Official QuickBMS support | twitter @zenhax | SSL HTTPS://zenhax.com
It is currently Wed Jun 23, 2021 7:42 am

All times are UTC




Post new topic  Reply to topic  [ 9 posts ] 
Author Message
PostPosted: Thu Apr 08, 2021 12:11 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
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:
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



Attachments:
gacha_cash_2017_0701.7z [339.02 KiB]
Downloaded 24 times


Last edited by chrrox on Thu Apr 08, 2021 2:38 pm, edited 1 time in total.
Top
   
PostPosted: Thu Apr 08, 2021 2:38 pm 

Joined: Sat Aug 09, 2014 2:34 pm
Posts: 1199
you can make a simple function for decryption, like this one

Code:
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.

Top
   
PostPosted: Thu Apr 08, 2021 2:41 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
s_uEncryptionKey is a bunch of unsigned integers.
no need to combine them first in c++ before xoring?


Top
   
PostPosted: Thu Apr 08, 2021 2:48 pm 

Joined: Sat Aug 09, 2014 2:34 pm
Posts: 1199
in this case you can do xor data by DWORD like this:

Code:
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;
   }
}


Top
   
PostPosted: Thu Apr 08, 2021 3:23 pm 

Joined: Sat Aug 09, 2014 2:34 pm
Posts: 1199
Code:
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


Top
   
PostPosted: Thu Apr 08, 2021 3:40 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
what am doing wrong i get.
Quote:
<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:
get SIZE asize
log MEMORY_FILE 0 SIZE
calldll MEMORY_FILE10 DecryptCCZ tcc RET MEMORY_FILE SIZE
log "DECRYPTED.dat" 0 SIZE MEMORY_FILE


Top
   
PostPosted: Thu Apr 08, 2021 4:25 pm 

Joined: Sat Aug 09, 2014 2:34 pm
Posts: 1199
it's weird


Top
   
PostPosted: Thu Apr 08, 2021 4:26 pm 

Joined: Thu Aug 07, 2014 10:28 pm
Posts: 379
This works

Code:
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


Top
   
PostPosted: Thu Apr 08, 2021 4:31 pm 

Joined: Sat Aug 09, 2014 2:34 pm
Posts: 1199
Ok. Problem with "defines" I suppose :D


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 9 posts ] 

All times are UTC


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Limited