-1

I recently found a function using IDA within a game that creates a CRC from a string. I don't understand much of the code or how the game takes in the string as data.

__int64 __fastcall ITF::StrToCRC_Template<1u>(unsigned __int8 *a1, unsigned int a2)
{
  unsigned int v2; // w8
  int v3; // w10
  unsigned int v4; // w11
  int v5; // w9
  int v6; // w12
  int v7; // w13
  int v8; // w14
  unsigned int v9; // w12
  int v10; // w13
  int v11; // w15
  unsigned int v12; // w12
  int v13; // w14
  int v14; // w12
  int v15; // w13
  int v16; // w9
  int v17; // w12
  int v18; // w15
  unsigned int v19; // w14
  int v20; // w15
  unsigned int v21; // w14
  int v22; // w13
  int v23; // w14
  int v24; // w15
  int v25; // w8
  int v26; // w9
  unsigned int v27; // w12
  unsigned __int8 v28; // w13
  int v29; // w15
  unsigned int v30; // w12
  unsigned __int8 v31; // w13
  unsigned int v32; // w10
  int v33; // w9
  unsigned int v34; // w8
  unsigned int v35; // w10
  int v36; // w9
  unsigned int v37; // w8
  unsigned int v38; // w10
  unsigned int v39; // w10
  int v40; // w11
  int v41; // w11
  int v42; // w11
  int v43; // w11
  int v44; // w11
  int v45; // w11
  int v46; // w11
  int v47; // w11
  int v48; // w11
  int v49; // w11
  int v50; // w11
  int v51; // w9
  unsigned int v52; // w8
  unsigned int v53; // w10
  int v54; // w9
  unsigned int v55; // w8
  unsigned int v56; // w10
  int v57; // w9

  v2 = -1640531527;
  v3 = 0;
  v4 = a2;
  v5 = -1640531527;
  if ( a2 >= 0xC )
  {
    do
    {
      v6 = *a1;
      v7 = a1[1];
      if ( (unsigned int)(v6 - 97) <= 0x19 )
        v6 += 224;
      v8 = a1[2];
      if ( (unsigned int)(v7 - 97) <= 0x19 )
        LOBYTE(v7) = v7 - 32;
      v9 = v6 & 0xFFFF00FF | ((unsigned __int8)v7 << 8);
      v10 = a1[3];
      if ( (unsigned int)(v8 - 97) <= 0x19 )
        LOBYTE(v8) = v8 - 32;
      if ( (unsigned int)(v10 - 97) <= 0x19 )
        LOBYTE(v10) = v10 - 32;
      v11 = a1[4];
      v12 = v9 & 0xFF00FFFF | ((unsigned __int8)v8 << 16);
      v13 = v11 + 224;
      v14 = v12 & 0xFFFFFF | ((unsigned __int8)v10 << 24);
      v15 = a1[6];
      v16 = v14 + v5;
      v17 = a1[8];
      if ( (unsigned int)(v11 - 97) > 0x19 )
        v13 = a1[4];
      v18 = a1[5];
      if ( (unsigned int)(v18 - 97) <= 0x19 )
        LOBYTE(v18) = v18 - 32;
      v19 = v13 & 0xFFFF00FF | ((unsigned __int8)v18 << 8);
      if ( (unsigned int)(v15 - 97) <= 0x19 )
        LOBYTE(v15) = v15 - 32;
      v20 = a1[7];
      v21 = v19 & 0xFF00FFFF | ((unsigned __int8)v15 << 16);
      if ( (unsigned int)(v20 - 97) <= 0x19 )
        LOBYTE(v20) = v20 - 32;
      if ( (unsigned int)(v17 - 97) <= 0x19 )
        v17 += 224;
      v22 = a1[9];
      v23 = v21 & 0xFFFFFF | ((unsigned __int8)v20 << 24);
      v24 = a1[10];
      v25 = v23 + v2;
      v26 = v16 - v25;
      if ( (unsigned int)(v22 - 97) <= 0x19 )
        LOBYTE(v22) = v22 - 32;
      v27 = v17 & 0xFFFF00FF | ((unsigned __int8)v22 << 8);
      v28 = v24 - 32;
      if ( (unsigned int)(v24 - 97) > 0x19 )
        v28 = a1[10];
      v29 = a1[11];
      a1 += 12;
      v30 = v27 & 0xFF00FFFF | (v28 << 16);
      if ( (unsigned int)(v29 - 97) <= 0x19 )
        v31 = v29 - 32;
      else
        v31 = v29;
      v32 = (v30 & 0xFFFFFF | (v31 << 24)) + v3;
      v33 = (v26 - v32) ^ (v32 >> 13);
      v34 = (v25 - v32 - v33) ^ (v33 << 8);
      v35 = (v32 - v33 - v34) ^ (v34 >> 13);
      v36 = (v33 - v34 - v35) ^ (v35 >> 12);
      v37 = (v34 - v35 - v36) ^ (v36 << 16);
      v38 = (v35 - v36 - v37) ^ (v37 >> 5);
      v5 = (v36 - v37 - v38) ^ (v38 >> 3);
      v2 = (v37 - v38 - v5) ^ (v5 << 10);
      v3 = (v38 - v5 - v2) ^ (v2 >> 15);
      v4 -= 12;
    }
    while ( v4 > 0xB );
  }
  v39 = v3 + a2;
  switch ( v4 )
  {
    case 1u:
      goto LABEL_59;
    case 2u:
      goto LABEL_56;
    case 3u:
      goto LABEL_53;
    case 4u:
      goto LABEL_50;
    case 5u:
      goto LABEL_47;
    case 6u:
      goto LABEL_44;
    case 7u:
      goto LABEL_41;
    case 8u:
      goto LABEL_38;
    case 9u:
      goto LABEL_35;
    case 0xAu:
      goto LABEL_32;
    case 0xBu:
      v40 = a1[10];
      if ( (unsigned int)(v40 - 97) <= 0x19 )
        v40 += 224;
      v39 += v40 << 24;
LABEL_32:
      v41 = a1[9];
      if ( (unsigned int)(v41 - 97) <= 0x19 )
        LOBYTE(v41) = v41 - 32;
      v39 += (unsigned __int8)v41 << 16;
LABEL_35:
      v42 = a1[8];
      if ( (unsigned int)(v42 - 97) <= 0x19 )
        LOBYTE(v42) = v42 - 32;
      v39 += (unsigned __int8)v42 << 8;
LABEL_38:
      v43 = a1[7];
      if ( (unsigned int)(v43 - 97) <= 0x19 )
        v43 += 224;
      v2 += v43 << 24;
LABEL_41:
      v44 = a1[6];
      if ( (unsigned int)(v44 - 97) <= 0x19 )
        LOBYTE(v44) = v44 - 32;
      v2 += (unsigned __int8)v44 << 16;
LABEL_44:
      v45 = a1[5];
      if ( (unsigned int)(v45 - 97) <= 0x19 )
        LOBYTE(v45) = v45 - 32;
      v2 += (unsigned __int8)v45 << 8;
LABEL_47:
      v46 = a1[4];
      if ( (unsigned int)(v46 - 97) <= 0x19 )
        LOBYTE(v46) = v46 - 32;
      v2 += (unsigned __int8)v46;
LABEL_50:
      v47 = a1[3];
      if ( (unsigned int)(v47 - 97) <= 0x19 )
        v47 += 224;
      v5 += v47 << 24;
LABEL_53:
      v48 = a1[2];
      if ( (unsigned int)(v48 - 97) <= 0x19 )
        LOBYTE(v48) = v48 - 32;
      v5 += (unsigned __int8)v48 << 16;
LABEL_56:
      v49 = a1[1];
      if ( (unsigned int)(v49 - 97) <= 0x19 )
        LOBYTE(v49) = v49 - 32;
      v5 += (unsigned __int8)v49 << 8;
LABEL_59:
      v50 = *a1;
      if ( (unsigned int)(v50 - 97) <= 0x19 )
        LOBYTE(v50) = v50 - 32;
      v5 += (unsigned __int8)v50;
      break;
    default:
      break;
  }
  v51 = (v5 - v2 - v39) ^ (v39 >> 13);
  v52 = (v2 - v39 - v51) ^ (v51 << 8);
  v53 = (v39 - v51 - v52) ^ (v52 >> 13);
  v54 = (v51 - v52 - v53) ^ (v53 >> 12);
  v55 = (v52 - v53 - v54) ^ (v54 << 16);
  v56 = (v53 - v54 - v55) ^ (v55 >> 5);
  v57 = (v54 - v55 - v56) ^ (v56 >> 3);
  return (v56 - v57 - ((v55 - v56 - v57) ^ (v57 << 10))) ^ (((v55 - v56 - v57) ^ (v57 << 10)) >> 15);
}

This is the code, I am trying to convert this to a Python function so I can integrate it into a program I am making. Could anyone help me start converting this? Or make the code more understandable?

  • Hi and welcome to RE.SE. How about renaming some of the variables to make the code more readable? Unless Hexrays has lost that functionality, that should be easily doable. It's the inherited interactive trait from the acronym IDA. – 0xC0000022L Aug 20 at 8:58
2

v2 = -1640531527;

C:>python -c "print hex(0x100000000-1640531527)" 0x9e3779b9L

google 0x9e3779b9L

first hit TEA algorithm

google python tea

first hit pytea quoting from the site below

from pytea import TEA
key = os.urandom(16)
print('key is', key)
content = 'Hello, 你好'
tea = TEA(key)
e = tea.encrypt(content.encode())
print('encrypt hex:', e.hex())
d = tea.decrypt(e)
print('decrypt:', d.decode())

i would suggest check pytea output with the functions output before moving further to understand if the algo is modified or used differently

  • I believe they modified the function because the value that comes out of the function is normally a 32 bit integer. TEA encrypts the whole message and because of this the value doesn't match. – mzkoops56 Aug 20 at 13:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.