HelloTalk 加密算法分析

StringUtils.hmacSha256 is called: str=fe0629ad30d48b5bf1e82865404694fe8525200575f5c4339debf5e8ff571c6e, str2=3082035930820241a003020102020461e4cac1300d06092a864886f70d01010b0500305c310b300906035504061302434e31123010060355040813096775616e67646f6e673111300f060355040713087368656e7a68656e310b3009060355040a13026a79310b3009060355040b13026a79310c300a06035504031303776c683020170d3132313031363032303033365a180f32303637303732303032303033365a305c310b300906035504061302434e31123010060355040813096775616e67646f6e673111300f060355040713087368656e7a68656e310b3009060355040a13026a79310b3009060355040b13026a79310c300a060355017159277085.5.70(7311,china)4031303776c6830820122300d06092a864886f70d01010105000382010f003082010a0282010100947e44daa5fe6b440513b2f206196f9a535da8a2a83841bfb430218322e95b513a5ae62bcea16330027e78557b701cc51ca6a02de45820592444244f456182fe6f7acf2283a085fb2258a445c9a3080ce236112bcbaeef77d4cf7fd4fa0e788799c2a372ed71b8805c20ed313333599f4db298ea10992e976d96157b642686b357b57dbca4d5ffcae60e8c5e3a77ba6b441e2f04194b6209275153199dca2b24845787f6bf777fc274c0b6cfaec2ba73ed84b910334d046234cb31bb094245d6bd00b6371025b216b26aef2348dce9c4f90bd2f00d625b253d1fbe78a9e28a1f6b89
StringUtils.hmacSha256 result=ae1f63bcd8f14ad4c2bf86ed2f12b8d5e46f1b1a9a948b5a3b394993b547b118
TeaUtils.xConnInfo result=ae1f63bcd8f14ad4c2bf86ed2f12b8d5e46f1b1a9a948b5a3b394993b547b1181715927708
DeviceVQHelper.generateDVId = d2f00d625b253d1fbe78a9e28a1f6b89

StringUtils.hmacSha256 is called: str=fe0629ad30d48b5bf1e82865404694fe8525200575f5c4339debf5e8ff571c6e, str2=3082035930820241a003020102020461e4cac1300d06092a864886f70d01010b0500305c310b300906035504061302434e31123010060355040813096775616e67646f6e673111300f060355040713087368656e7a68656e310b3009060355040a13026a79310b3009060355040b13026a79310c300a06035504031303776c683020170d3132313031363032303033365a180f32303637303732303032303033365a305c310b300906035504061302434e31123010060355040813096775616e67646f6e673111300f060355040713087368656e7a68656e310b3009060355040a13026a79310b3009060355040b13026a79310c300a060355017159273065.5.70(7311,china)4031303776c6830820122300d06092a864886f70d01010105000382010f003082010a0282010100947e44daa5fe6b440513b2f206196f9a535da8a2a83841bfb430218322e95b513a5ae62bcea16330027e78557b701cc51ca6a02de45820592444244f456182fe6f7acf2283a085fb2258a445c9a3080ce236112bcbaeef77d4cf7fd4fa0e788799c2a372ed71b8805c20ed313333599f4db298ea10992e976d96157b642686b357b57dbca4d5ffcae60e8c5e3a77ba6b441e2f04194b6209275153199dca2b24845787f6bf777fc274c0b6cfaec2ba73ed84b910334d046234cb31bb094245d6bd00b6371025b216b26aef2348dce9c4f90bd2f00d625b253d1fbe78a9e28a1f6b89
StringUtils.hmacSha256 result=84c718204c2587ce8c5fa24b66659e85e01784096a14d284347767fc25c692e2
TeaUtils.xConnInfo result=84c718204c2587ce8c5fa24b66659e85e01784096a14d284347767fc25c692e21715927306
DeviceVQHelper.generateDVId = d2f00d625b253d1fbe78a9e28a1f6b89
copy success
1
2
3
4
5
6
7
8
9

20240510193535_image.png

TeaUtils.xTEADecryptWithKey is called: bArr=580cbaa6b87e6f0f1dc55c6315ebba887752776845b0e35acdf122ba7d42827bd89edd88db022705f05185293f61abe6de17b013b584b7e096f5d4f69f43f33b7bf04f6ff9f26ad013e196f5331367ba784f011da32ae245f8cdedeb55bd33132adf7f6f8d15f9a97d0563266e577b8b1bbadd83bbbefa454ca232fb2d62a696f5d8818cddfea7f2aaed923342cfa4856276d6c7470c40edf1d3bdcc808e6b682a42313a955783139d7ef55961d4560bc122495409c71599, bArr2=f393ab1926a5b8be7c821ff288dd7d74

解密 data: 0x7c3aa8b000 dataLen: 0xb8 580cbaa6b87e6f0f1dc55c6315ebba887752776845b0e35acdf122ba7d42827bd89edd88db022705f05185293f61abe6de17b013b584b7e096f5d4f69f43f33b7bf04f6ff9f26ad013e196f5331367ba784f011da32ae245f8cdedeb55bd33132adf7f6f8d15f9a97d0563266e577b8b1bbadd83bbbefa454ca232fb2d62a696f5d8818cddfea7f2aaed923342cfa4856276d6c7470c40edf1d3bdcc808e6b682a42313a955783139d7ef55961d4560bc122495409c71599
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c3aa8b000  58 0c ba a6 b8 7e 6f 0f 1d c5 5c 63 15 eb ba 88  X....~o...\c....
7c3aa8b010  77 52 77 68 45 b0 e3 5a cd f1 22 ba 7d 42 82 7b  wRwhE..Z..".}B.{
7c3aa8b020  d8 9e dd 88 db 02 27 05 f0 51 85 29 3f 61 ab e6  ......'..Q.)?a..
7c3aa8b030  de 17 b0 13 b5 84 b7 e0 96 f5 d4 f6 9f 43 f3 3b  .............C.;
7c3aa8b040  7b f0 4f 6f f9 f2 6a d0 13 e1 96 f5 33 13 67 ba  {.Oo..j.....3.g.
7c3aa8b050  78 4f 01 1d a3 2a e2 45 f8 cd ed eb 55 bd 33 13  xO...*.E....U.3.
7c3aa8b060  2a df 7f 6f 8d 15 f9 a9 7d 05 63 26 6e 57 7b 8b  *..o....}.c&nW{.
7c3aa8b070  1b ba dd 83 bb be fa 45 4c a2 32 fb 2d 62 a6 96  .......EL.2.-b..
7c3aa8b080  f5 d8 81 8c dd fe a7 f2 aa ed 92 33 42 cf a4 85  ...........3B...
7c3aa8b090  62 76 d6 c7 47 0c 40 ed f1 d3 bd cc 80 8e 6b 68  [email protected]
7c3aa8b0a0  2a 42 31 3a 95 57 83 13 9d 7e f5 59 61 d4 56 0b  *B1:.W...~.Ya.V.
7c3aa8b0b0  c1 22 49 54 09 c7 15 99                          ."IT....
key: 0x7c009f9d20 f393ab1926a5b8be7c821ff288dd7d74
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c009f9d20  f3 93 ab 19 26 a5 b8 be 7c 82 1f f2 88 dd 7d 74  ....&...|.....}t
result: 0x7c03c131e0 {"data":{"email_verify":1,"phone":"46726414232","need_verify_phone":0,"bind_info":[1,10],"email":"[email protected]","show_reward_notify":false},"msg":"success","status":0}
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c03c131e0  7b 22 64 61 74 61 22 3a 7b 22 65 6d 61 69 6c 5f  {"data":{"email_
7c03c131f0  76 65 72 69 66 79 22 3a 31 2c 22 70 68 6f 6e 65  verify":1,"phone
7c03c13200  22 3a 22 34 36 37 32 36 34 31 34 32 33 32 22 2c  ":"46726414232",
7c03c13210  22 6e 65 65 64 5f 76 65 72 69 66 79 5f 70 68 6f  "need_verify_pho
7c03c13220  6e 65 22 3a 30 2c 22 62 69 6e 64 5f 69 6e 66 6f  ne":0,"bind_info
7c03c13230  22 3a 5b 31 2c 31 30 5d 2c 22 65 6d 61 69 6c 22  ":[1,10],"email"
7c03c13240  3a 22 71 73 69 72 31 37 40 76 6b 6e 6f 74 65 2e  :"qsir17@vknote.
7c03c13250  63 6f 6d 22 2c 22 73 68 6f 77 5f 72 65 77 61 72  com","show_rewar
7c03c13260  64 5f 6e 6f 74 69 66 79 22 3a 66 61 6c 73 65 7d  d_notify":false}
7c03c13270  2c 22 6d 73 67 22 3a 22 73 75 63 63 65 73 73 22  ,"msg":"success"
7c03c13280  2c 22 73 74 61 74 75 73 22 3a 30 7d              ,"status":0}
a5: 0x7bef9b9cc4 172
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7bef9b9cc4  ac 00 00 00 4a ec 26 14 05 32 c4 95 a0 14 62 fb  ....J.&..2....b.
retval 0x1
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

20240510135122_image.png

data: 0x7c3aa52460 dataLen: 0x69 {"uid":135464904,"os":1,"version":"5.5.60","area_code":"CN","session":"K6D3j6UJT4upgYYjne3NdARd1MlV065V"}
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c3aa52460  7b 22 75 69 64 22 3a 31 33 35 34 36 34 39 30 34  {"uid":135464904
7c3aa52470  2c 22 6f 73 22 3a 31 2c 22 76 65 72 73 69 6f 6e  ,"os":1,"version
7c3aa52480  22 3a 22 35 2e 35 2e 36 30 22 2c 22 61 72 65 61  ":"5.5.60","area
7c3aa52490  5f 63 6f 64 65 22 3a 22 43 4e 22 2c 22 73 65 73  _code":"CN","ses
7c3aa524a0  73 69 6f 6e 22 3a 22 4b 36 44 33 6a 36 55 4a 54  sion":"K6D3j6UJT
7c3aa524b0  34 75 70 67 59 59 6a 6e 65 33 4e 64 41 52 64 31  4upgYYjne3NdARd1
7c3aa524c0  4d 6c 56 30 36 35 56 22 7d                       MlV065V"}
key: 0x7c1a545860 323068656c6c6f54434a54414c4b3230
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c1a545860  32 30 68 65 6c 6c 6f 54 43 4a 54 41 4c 4b 32 30  20helloTCJTALK20
result: 0x7c3aa7a300 70ac3d224306a1cb5f84eb0d5fef074bbe7b62eb405e83b33d0dfe44fbba2fb91f0487543d484b9a7afb3428779683ac7ac3cc3d2ac9e877169daac845ef50be004ab4ec4867962ab1223f1786e1078a0c6071b39feb306e14de4c888f8fa7f213c938918bfd8802d600b2ec19e5286e85eedeb13d14651e
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c3aa7a300  70 ac 3d 22 43 06 a1 cb 5f 84 eb 0d 5f ef 07 4b  p.="C..._..._..K
7c3aa7a310  be 7b 62 eb 40 5e 83 b3 3d 0d fe 44 fb ba 2f b9  .{b.@^..=..D../.
7c3aa7a320  1f 04 87 54 3d 48 4b 9a 7a fb 34 28 77 96 83 ac  ...T=HK.z.4(w...
7c3aa7a330  7a c3 cc 3d 2a c9 e8 77 16 9d aa c8 45 ef 50 be  z..=*..w....E.P.
7c3aa7a340  00 4a b4 ec 48 67 96 2a b1 22 3f 17 86 e1 07 8a  .J..Hg.*."?.....
7c3aa7a350  0c 60 71 b3 9f eb 30 6e 14 de 4c 88 8f 8f a7 f2  .`q...0n..L.....
7c3aa7a360  13 c9 38 91 8b fd 88 02 d6 00 b2 ec 19 e5 28 6e  ..8...........(n
7c3aa7a370  85 ee de b1 3d 14 65 1e 00                       ....=.e..
a5: 0x7c1a545874
             0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
7c1a545874  78 00 00 00 4a ec 26 14 05 32 c4 95 38 93 6a 13  x...J.&..2..8.j.
retval 0x1
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
memory read &v35
memory read v16 -c 120
po/tx v18

copy success
1
2
3
4
signed __int64 __fastcall xTEAEncryptWithKey(__int64 a1, unsigned int a2, int *a3, __int64 a4, signed int *a5)
{
  unsigned __int64 v5; // x25
  __int64 v6; // x22
  signed __int64 result; // x0
  int *v8; // x21
  __int64 v9; // x19
  unsigned int v10; // w23
  __int64 v11; // x24
  signed int v12; // w26
  __int64 v13; // x8
  __int64 v14; // x27
  signed __int64 v15; // x0
  _BYTE *v16; // x20
  signed __int64 v17; // x24
  _DWORD *v18; // x8
  int v19; // w9
  int v20; // w10
  int v21; // w11
  int v22; // w12
  __int64 v23; // x8
  int v24; // w1
  int v25; // w2
  int v26; // w15
  int v27; // w14
  int *v28; // x16
  int v29; // w0
  int v30; // w17
  signed int v31; // w1
  signed int v32; // w3
  unsigned int v33; // w4
  unsigned int v34; // w2
  signed __int64 v35; // [xsp-78h] [xbp-78h]
  char v36; // [xsp-70h] [xbp-70h]
  __int64 v37; // [xsp-68h] [xbp-68h]

  v5 = _ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2));
  v6 = a1;
  result = 0LL;
  v37 = *(_QWORD *)(v5 + 40);
  if ( v6 )
  {
    v8 = a3;
    if ( a3 )
    {
      v9 = a4;
      if ( a4 )
      {
        v10 = a2;
        v35 = -5931894172722287187LL;
        v36 = -83;
        if ( a2 )
        {
          if ( (a2 + 2) & 7 )  //求8的余数
            v11 = 8 - ((a2 + 2) & 7); //补齐 8 的倍数
          else
            v11 = 0LL;
          v12 = a2 + v11 + 10;  //加密后数据总长度 保证是 8 的倍数 // 105 + 5 + 10 = 120
          LODWORD(v13) = a2 + v11 + 13; // 取低32位 因为变量是64位
          if ( v12 >= 0 )  //如果计算结果有效
            v13 = (unsigned int)v12;     // 120
          else
            v13 = (unsigned int)v13;    
          v14 = v13 << 32 >> 34;  // 120 / 4 = 30
          if ( (unsigned __int64)v14 >> 62 )   
            v15 = 1LL;
          else
            v15 = (signed __int64)((unsigned __int64)(unsigned int)((signed int)v13 >> 2) << 32) >> 30; //120
          *a5 = v12;
          v16 = (_BYTE *)operator new[](v15);
          *v16 = v11 | 0xA8;
          memcpy(v16 + 1, &v35, (unsigned int)(v11 + 2));
          v17 = (signed __int64)&v16[v11 + 3];
          memcpy(v17, v6, v10);
          v18 = (_DWORD *)(v17 + v10);
          *v18 = 0;
          *(_DWORD *)((char *)v18 + 3) = 0;
          if ( v12 >= 4 )
          {
            v19 = *v8;
            v20 = v8[1];
            v21 = v8[2];
            v22 = v8[3];
            v23 = 0LL;
            v24 = 0;
            v25 = 0;
            v26 = 0;
            v27 = 0;
            do
            {
              v28 = (int *)&v16[4 * v23];
              v29 = *v28 ^ v24;
              v30 = v28[1] ^ v25;
              v31 = 16;
              v32 = -1640531527;
              v33 = v29;
              v34 = v28[1] ^ v25;
              do
              {
                v33 += (v19 + 16 * v34) ^ (v34 + v32) ^ (v20 + (v34 >> 5));
                --v31;
                v34 += (v21 + 16 * v33) ^ (v32 + v33) ^ (v22 + (v33 >> 5));
                v32 -= 1640531527;
              }
              while ( v31 );
              v23 += 2LL;
              v24 = v33 ^ v26;
              v25 = v34 ^ v27;
              v26 = v29;
              v27 = v30;
              *v28 = v24;
              v28[1] = v25;
            }
            while ( v23 < v14 );
          }
          memcpy(v9, v16, v12);
          operator delete[](v16);
          result = 1LL;
        }
        else
        {
          result = 0LL;
        }
      }
    }
  }
  *(_QWORD *)(v5 + 40);
  return result;
}
copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// XTEA加密函数声明
signed long long xTEAEncryptWithKey(long long a1, unsigned int a2, int *a3, long long a4, signed int *a5);

int main() {
    // 待加密的数据
    char data[] = "{\"uid\":135464904,\"os\":1,\"version\":\"5.5.60\",\"area_code\":\"CN\",\"session\":\"K6D3j6UJT4upgYYjne3NdARd1MlV065V\"}";
    // 待加密数据的长度
    unsigned int data_length = 0x69;
    // 加密密钥
    char key[] = "20helloTCJTALK20";
    
    // 计算加密后的数据长度
    signed int encrypted_length;
    signed long long result;
    xTEAEncryptWithKey((long long)data, data_length, (int *)key, 0, &encrypted_length);
    
    // 分配内存存放加密后的数据
    unsigned char *encrypted_data = (unsigned char *)malloc(encrypted_length);
    
    // 加密数据
    result = xTEAEncryptWithKey((long long)data, data_length, (int *)key, (long long)encrypted_data, &encrypted_length);
    
    // 输出加密结果
    printf("Encrypted data:\n");
    for (int i = 0; i < encrypted_length; ++i) {
        printf("%02X ", encrypted_data[i]);
    }
    printf("\n");
    
    // 释放内存
    free(encrypted_data);
    
    return 0;
}

// XTEA加密函数定义
signed long long xTEAEncryptWithKey(long long a1, unsigned int a2, int *a3, long long a4, signed int *a5) {
    long long v6;
    signed long long result;
    int *v8;
    long long v9;
    unsigned int v10;
    long long v11;
    signed int v12;
    long long v13;
    long long v14;
    signed long long v15;
    char *v16;
    signed long long v17;
    unsigned int *v18;
    int v19;
    int v20;
    int v21;
    int v22;
    long long v23;
    int v24;
    int v25;
    int v26;
    int v27;
    int *v28;
    int v29;
    int v30;
    signed int v31;
    signed int v32;
    unsigned int v33;
    unsigned int v34;
    signed long long v35;
    char v36;

    v6 = a1;
    result = 0LL;
    if (v6) {
        v8 = a3;
        if (a3) {
            v9 = a4;
            if (a4) {
                v10 = a2;
                v35 = -5931894172722287187LL;
                v36 = -83;
                if (a2) {
                    if ((a2 + 2) & 7)
                        v11 = 8 - ((a2 + 2) & 7);
                    else
                        v11 = 0LL;
                    v12 = a2 + v11 + 10;
                    if (v12 >= 0)
                        v13 = (unsigned int)v12;
                    else
                        v13 = (unsigned int)v13;
                    v14 = v13 << 32 >> 34;
                    if ((unsigned long long)v14 >> 62)
                        v15 = 1LL;
                    else
                        v15 = (signed long long)((unsigned long long)(unsigned int)((signed int)v13 >> 2) << 32) >> 30;
                    *a5 = v12;
                    v16 = (char *)malloc(v15);
                    *v16 = v11 | 0xA8;
                    memcpy(v16 + 1, &v35, (unsigned int)(v11 + 2));
                    v17 = (signed long long)&v16[v11 + 3];
                    memcpy(v17, (const void *)v6, v10);
                    
                    // 将v18设置为v17 + v10的地址,将v18解释为一个无符号整数指针
                    v18 = (unsigned int *)(v17 + v10);
                    // 在v18指向的地址处存储值0
                    *v18 = 0;
                    // 在v18指向的地址的偏移3处(即v18后面的3个字节处)存储值0
                    *(v18 + 1) = 0;
                    
                    if (v12 >= 4) {
                        v19 = *v8;
                        v20 = v8[1];
                        v21 = v8[2];
                        v22 = v8[3];
                        v23 = 0LL;
                        v24 = 0;
                        v25 = 0;
                        v26 = 0;
                        v27 = 0;
                        do {
                            v28 = (int *)&v16[4 * v23];
                            v29 = *v28 ^ v24;
                            v30 = v28[1] ^ v25;
                            v31 = 16;
                            v32 = -1640531527;
                            v33 = v29;
                            v34 = v28[1] ^ v25;
                            do {
                                v33 += (v19 + 16 * v34) ^ (v34 + v32) ^ (v20 + (v34 >> 5));
                                --v31;
                                v34 += (v21 + 16 * v33) ^ (v32 + v33) ^ (v22 + (v33 >> 5));
                                v32 -= 1640531527;
                            } while (v31);
                            v23 += 2LL;
                            v24 = v33 ^ v26;
                            v25 = v34 ^ v27;
                            v26 = v29;
                            v27 = v30;
                            *v28 = v24;
                            v28[1] = v25;
                        } while (v23 < v14);
                    }
                    memcpy((void *)v9, v16, v12);
                    free(v16);
                    result = 1LL;
                } else {
                    result = 0LL;
                }
            }
        }
    }
    return result;
}


copy success
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158