TEA

因为网上大多tea加密都是用的c

所以我这里也用C

2023.11.8做了一个新题

加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+4h] [rbp-3Ch]
_QWORD input[6]; // [rsp+10h] [rbp-30h] BYREF

input[5] = __readfsqword(0x28u);
puts("plz input u fl4g:");
__isoc99_scanf("%32s", input);//输入
sub_400763();
for ( i = 0; i <= 3; ++i )//实现加密
sub_400696(&input[i], &dword_601080);//dword_601080这个里面是key
if ( !memcmp(input, &dword_6010A0, 0x20uLL) )//dword_6010A0这个里面就是加密后的数据
puts("yeh~");
else
puts("oh,no");
return 0LL;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
__int64 __fastcall sub_400696(unsigned int *a1, _DWORD *k)
{
__int64 result; // rax
unsigned int v3; // [rsp+10h] [rbp-10h]
unsigned int v4; // [rsp+14h] [rbp-Ch]
int v5; // [rsp+18h] [rbp-8h]
unsigned int i; // [rsp+1Ch] [rbp-4h]

v3 = *a1; // a1[0]
v4 = a1[1];
v5 = 0;
for ( i = 0; i <= 0x1F; ++i )
{
v5 -= 1640531527;
v3 += (v4 + v5) ^ (16 * v4 + *k) ^ ((v4 >> 5) + k[1]);
v4 += (v3 + v5) ^ (16 * v3 + k[2]) ^ ((v3 >> 5) + k[3]);
}
*a1 = v3;
result = v4;
a1[1] = v4;
return result;
}

解密:

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
#include <cstdio>
#include <stdint.h>
#include <stdlib.h>
void decrypt(unsigned int* v, const unsigned int* k)
{
//必须得使用 uint32_t 不能用int
uint32_t v3 = v[0];
uint32_t v4 = v[1];
//因为原式子中最开始是0每次都 -1640531527 了这么多【32次】
//所以在逆向的时候首先先定义 (-1640531527) * 32 然后每次 + 1640531527
uint32_t v5 = ((-1640531527) * 32 ) & 0xFFFFFFFF;//这里报错了,所以就 &0xffffffff

for (int i = 0; i <= 31; ++i)
{
//这里就是加密原理
v4 -= (v3 + v5) ^ (16 * v3 + k[2]) ^ ((v3 >> 5) + k[3]);
v3 -= (v4 + v5) ^ (16 * v4 + k[0]) ^ ((v4 >> 5) + k[1]);
v5 += 1640531527;
}

v[0] = v3;
v[1] = v4;
}
int main()
{
unsigned int v[8] = {
0x0DB8F2569,0x40CD83E3,0xA033E680,0xFFF7A644,
0x690C3A17,0x0B621B866,0x34E7E2A7,0xAD10A692
};//这里是加密数据,每次的加密数据不一样。可以有更多
unsigned int k[4] = { 0x01234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210 };//这里是密钥。每次都是k[4]

for (int i = 0; i < 8; i += 2)//这个8是因为加密后的数据有8个。在加密的时候必须得是+=2
{
decrypt(v + i, k);
}
for (int i = 0; i < 8; i++)//这里是将解密后的数据打印出来
{
printf("%xh\n", v[i]);//这里打印出来后,可能大小端绪的问题就需要用后面的代码
}

//下面是将8个32位的数据转化成32个8位的数据。并且用小端序存放
//将给定的十六进制数据按小端序存放,并将其转化为8位数据存储在名为flag的32个元素的数组中:
unsigned char flag[32];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
flag[i * 4 + j] = (v[i] >> (j * 8)) & 0xFF;
}
}

// Print the result
printf("flag[32] = {");
for (int i = 0; i < 32; i++) {
printf("0x%02X", flag[i]);
if (i < 31) {
printf(", ");
}
}
printf("}\n");

//最后转化出来的数据打出来
for (int i = 0; i < 32; i++)
{
printf("%c", flag[i]);
}

}


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
#include <cstdio>

void decrypt(unsigned int* v, const unsigned int* k)
{
int v6 = v[0];
int v5 = v[1];
int v4 = 0xC6EF3720;
for (int i = 0; i <= 31; ++i)
{
v4 -= 0x61C88647;
v6 += (v5 + v4) ^ (k[0] + 16 * v5) ^ ((v5 >> 5) + k[1]);
v5 += (v6 + v4) ^ (k[2] + 16 * v6) ^ ((v6 >> 5) + k[3]);
}
v[0] = v6;
v[1] = v5;
}
int main()
{
unsigned int v[] = {
0x6B046D5E, 0x0F38A133E, 0x4F6144D9, 0x5A22624B, 0x600DD811, 0x3A15D5A5, 0x1A9C6DBF, 0x0F6C94ADD,
0x0F99AFF46,0x0CE3C1008, 0x92CA6FEC, 0x4C98D1D0, 0x6F0AB52C, 0x1C4EE3F1, 0x0B5B5650D, 0x0EBCC67DE
};
unsigned int k[4] = { 0x1145, 0x5140, 0x5140, 0x8100 };

for (int i = 0; i <= 15; i += 2)
{
decrypt(v+i, k);

}

for (int i = 0; i <= 15; i++)
{
printf("%Xh ", v[i]);
}
}
//D19126B2h 413CC158h 27BB2614h E3F0F324h 3DCECEF0h F3DFF92Eh E359E61Fh 73798691h 3BF7541Ah 83761649h 71DF9953h B47BEF89h F23F33E1h 15B45D38h D4C6DFDFh BBB8E555h
//0xD19126B2 0x413CC158 0x27BB2614 0xE3F0F324 0x3DCECEF0 0xF3DFF92E 0xE359E61F 0x73798691 0x3BF7541A 0x83761649 0x71DF9953 0xB47BEF89 0xF23F33E1 0x15B45D38 0xD4C6DFDF 0xBBB8E555

XXTEA

当这个遇到base64的时候就可以用在线网站解开:

image-20231025215426513