xxtea

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

xxtea

Post by chrrox »

What would i need to log from this function to get the xxtea key.
I am assuming this is xxtea encryption.
https://pastebin.com/FNcm2vev
this is what the game calls to decrypt the files.
The game also has a function called xxtea_decrypt and that looks almost identical.
https://pastebin.com/WyEwcrEY

attached decrypted and encrypted samples.


example output from gamedc calls.

"a0": "0x7051923006", - encrypted data
"a1": "0x1e38", - data size
"a2": "0x6fe5b8c008", --always this value unk_154A7F0
"a3": "0x6fe230f370" - data size



What should be the key but it is not plain text?

Code: Select all

void *__fastcall gameex(size_t *a1, unsigned __int8 *a2)
{
  size_t *v2; // r4
  void *v3; // r5
  int v4; // r0
  bool v5; // zf
  int v6; // r0
  bool v7; // zf
  int v8; // r0
  bool v9; // zf
  unsigned int *v10; // r0
  unsigned int *v11; // r8
  int v12; // r5
  size_t v13; // r6
  void *v14; // r7
  int v15; // r0
  size_t v16; // r6
  size_t byte_count; // [sp+4h] [bp-24h]
  int v19; // [sp+8h] [bp-20h]

  v2 = a1;
  v3 = a2;
  v4 = *a2;
  v5 = v4 == 12;
  if ( v4 == 12 )
    v5 = a2[1] == 7;
  if ( v5 )
  {
    v6 = a2[2];
    v7 = v6 == 8;
    if ( v6 == 8 )
      v7 = a2[3] == 13;
    if ( v7 )
    {
      v8 = a2[4];
      v9 = v8 == 11;
      if ( v8 == 11 )
        v9 = a2[5] == 9;
      if ( v9 )
      {
        v10 = j_gamedc((int)(a2 + 6), *v2 - 6, (int)&unk_154A7F0, (int)&v19);
        v11 = v10;
        v12 = (int)v10 + 1;
        v13 = *(unsigned __int8 *)v10 << 15;
        v14 = malloc(*(unsigned __int8 *)v10 << 15);
        byte_count = v13;
        v15 = j_uncompress((int)v14, (int *)&byte_count, v12, v19 - 1);
        if ( !v14 || v15 )
        {
          free(v14);
          free(v11);
          v3 = 0;
        }
        else
        {
          v16 = byte_count;
          v3 = malloc(byte_count);
          qmemcpy(v3, v14, v16);
          free(v14);
          free(v11);
          *v2 = byte_count;
        }
      }
    }
  }
  return v3;
}


unk_154A7F0 =

Code: Select all

24 fa 49 9b 10 8d 62 59 29 26 81 67 4b f7 91 eb 36 1f 78 07 49 ca 35 a2 37 d7 b0 a6 49 d3 31 d5 9a 5b 46 86 14 ff 21 cb bc 63 ba 1c 49 fc 94 2f  f8 35 d9 46 1f 15 2b 2f 37 54 9d cc 44 d9 77 c4


data in the samples has first 6 magic bytes removed.
Last edited by chrrox on Wed Mar 24, 2021 2:36 pm, edited 1 time in total.
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: xxtea

Post by chrrox »

Ghidra version of the code.
https://pastebin.com/nkC6LvbE
https://pastebin.com/Hq8VH4kR

https://pastebin.com/jWsGfT1X

Code: Select all

                             BYTE_ARRAY_01977008                             XREF[2]:     ass:00e82bfc(*), 
                                                                                          gameex:00e83268(*) 
        01977008 24 fa 49        db[64]
                 9b 10 8d
                 62 59 29
           01977008 [0]            24h, FAh, 49h, 9Bh
           0197700c [4]            10h, 8Dh, 62h, 59h
           01977010 [8]            29h, 26h, 81h, 67h
           01977014 [12]           4Bh, F7h, 91h, EBh
           01977018 [16]           36h, 1Fh, 78h, 07h
           0197701c [20]           49h, CAh, 35h, A2h
           01977020 [24]           37h, D7h, B0h, A6h
           01977024 [28]           49h, D3h, 31h, D5h
           01977028 [32]           9Ah, 5Bh, 46h, 86h
           0197702c [36]           14h, FFh, 21h, CBh
           01977030 [40]           BCh, 63h, BAh, 1Ch
           01977034 [44]           49h, FCh, 94h, 2Fh
           01977038 [48]           F8h, 35h, D9h, 46h
           0197703c [52]           1Fh, 15h, 2Bh, 2Fh
           01977040 [56]           37h, 54h, 9Dh, CCh
           01977044 [60]           44h, D9h, 77h, C4h
chrrox
Posts: 388
Joined: Thu Aug 07, 2014 10:28 pm

Re: xxtea

Post by chrrox »

its only using the first 16 byes of the key this script works.

Code: Select all

set KEY binary "\x24\xfa\x49\x9b\x10\x8d\x62\x59\x29\x26\x81\x67\x4b\xf7\x91\xeb"
encryption xxtea KEY "0x9e3779b9 0" 0 16    # cocos2d

idstring "\x0C\x07\x08\x0D\x0B\x09"
savepos OFFSET
get SIZE asize
math SIZE - OFFSET
get NAME filename
log MEMORY_FILE OFFSET SIZE
encryption xor ""
log NAME 0 SIZE MEMORY_FILE