main函数一大串,只能一点点慢慢分析
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rax
__int128 *v5; // rax
__int64 v6; // r11
__int128 *v7; // r14
int v8; // edi
__int128 *v9; // rsi
char v10; // r10
int v11; // edx
__int64 v12; // r8
unsigned __int64 v13; // rcx
__int64 v14; // rcx
unsigned __int64 v15; // rax
unsigned __int64 i; // rax
__int64 v17; // rax
size_t v18; // rsi
_BYTE *v19; // rbx
_BYTE *v20; // r9
int v21; // r11d
char *v22; // r8
__int64 v23; // rcx
char v24; // al
__int64 v25; // r9
__int64 v26; // rdx
__int64 v27; // rax
size_t Size; // [rsp+20h] [rbp-48h] BYREF
__int128 v30; // [rsp+28h] [rbp-40h] BYREF
int v31; // [rsp+38h] [rbp-30h]
int v32; // [rsp+3Ch] [rbp-2Ch]
int Code[4]; // [rsp+40h] [rbp-28h] BYREF
int v34; // [rsp+50h] [rbp-18h]
*(_OWORD *)Code = 0i64;
v34 = 0;
sub_7FF60F2818C0(std::cin, argv, Code); // 读取用户输入到Code
v3 = -1i64;
v4 = -1i64;
do
++v4;
while ( *((_BYTE *)Code + v4) ); // v4=len(Code)=19
if ( v4 != 19 )
{
print(std::cout, "error\n");
_exit((int)Code);
}
v5 = (__int128 *)operator new(5ui64); // v5里存放了一个空间为5的地址
v6 = *(_QWORD *)&::Code; // v6=qwertyuiopasdfghjklzxcvbnm1234567890
v7 = v5;
v8 = 0;
v9 = v5;
do
{
v10 = *((_BYTE *)v9 + (char *)Code - (char *)v5);// v10=Code
v11 = 0;
*(_BYTE *)v9 = v10;
v12 = 0i64;
v13 = -1i64;
do
++v13;
while ( *(_BYTE *)(v6 + v13) );
if ( v13 )
{
do
{
if ( v10 == *(_BYTE *)(v6 + v12) ) // input字符在qw..0中
break;
++v11;
++v12;
}
while ( v11 < v13 );
}
v14 = -1i64;
do
++v14;
while ( *(_BYTE *)(v6 + v14) ); // v14=36
if ( v11 == v14 )
_exit(v6);
v9 = (__int128 *)((char *)v9 + 1);
}
while ( (char *)v9 - (char *)v5 < 4 ); // *v5=flag\x00
*((_BYTE *)v5 + 4) = 0; // 执行4次,flag{}-->v10=flag
do
++v3;
while ( *((_BYTE *)Code + v3) ); // v3=36
v15 = 0i64;
v30 = *v7; // v30=v7=v5=v9=malloc(5)
while ( *((_BYTE *)&v30 + v15) )
{
if ( !*((_BYTE *)&v30 + v15 + 1) )
{
++v15;
break;
}
if ( !*((_BYTE *)&v30 + v15 + 2) )
{
v15 += 2i64;
break;
}
if ( !*((_BYTE *)&v30 + v15 + 3) )
{
v15 += 3i64;
break;
}
v15 += 4i64;
if ( v15 >= 0x10 )
break;
}
for ( i = v15 + 1; i < 16; ++i ) // 四位扩展为16位,是TEA的key
*((_BYTE *)&v30 + i) = 0;
v17 = (__int64)XXTEA((__int64)Code, v3, (unsigned __int8 *)&v30, &Size);// XXTEA
v18 = Size;
v19 = (_BYTE *)v17;
v20 = operator new(Size);
v21 = 1;
*v20 = v19[2];
v22 = v20 + 1;
v20[1] = *v19;
v20[2] = v19[3];
v20[3] = v19[1];
v20[4] = v19[6];
v20[5] = v19[4];
v20[6] = v19[7];
v20[7] = v19[5];
v20[8] = v19[10];
v20[9] = v19[8];
v20[10] = v19[11]; // 打乱顺序
v20[11] = v19[9];
v20[12] = v19[14];
v20[13] = v19[12];
v20[14] = v19[15];
v20[15] = v19[13];
v20[16] = v19[18];
v20[17] = v19[16];
v20[18] = v19[19];
v20[19] = v19[17];
v20[20] = v19[22];
v20[21] = v19[20];
v20[22] = v19[23];
for ( v20[23] = v19[21]; v21 < v18; ++v22 )
{
v23 = 0i64;
if ( v21 / 3 > 0 )
{
v24 = *v22;
do
{
v24 ^= v20[v23++]; // 迭代异或
*v22 = v24;
}
while ( v23 < v21 / 3 );
}
++v21;
}
*(_QWORD *)&v30 = 0xC0953A7C6B40BCCEui64;
v25 = v20 - (_BYTE *)&v30;
*((_QWORD *)&v30 + 1) = 0x3502F79120209BEFi64;
v26 = 0i64;
v31 = 0xC8021823; // v30,v30+1,v31,v32一起的
v32 = 0xFA5656E7;
do
{
if ( *((_BYTE *)&v30 + v26) != *((_BYTE *)&v30 + v26 + v25) )
_exit(v8 * v8); // 比较已有数据与解密后结果
++v8; // 由于小端序,最后相比较的字符串是CEBC406B7C3A95COEF9B202091F70235231802C8E75656FA
++v26;
}
while ( v26 < 24 );
v27 = print(std::cout, "You win!");
std::ostream::operator<<(v27, sub_7FF60F2817F0);
return 0;
}
差不多就是;
1.用户输入19位字符串
2.取前四位扩展作为XXTEA加密密钥
3.XXTEA加密
4.将加密后字符串打乱顺序
5.进行异或
6.与存储数据进行对比
这个异或太多变量了,不好分析
enc=b'CEBC406B7C3A95C0EF9B202091F70235231802C8E75656FA'
ant=[]
for i in range(0,len(enc),2):
ant.append(int(enc[i:i+2],16))
print(ant)
print(len(ant))
for v21 in range(len(ant)-1,-1,-1):
k=v21//3
if k>0:
for i in range(k):
ant[v21]^=ant[i]
print(ant)
str=[0]*len(ant)
order=[2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]
print(len(order))
for i in range(len(ant)):
str[order[i]]=ant[i]
print(str)
# [206, 188, 64, 107, 124, 58, 149, 192, 239, 155, 32, 32, 145, 247, 2, 53, 35, 24, 2, 200, 231, 86, 86, 250]
# 24
# [206, 188, 64, 165, 178, 244, 231, 178, 157, 169, 18, 18, 200, 174, 91, 16, 6, 61, 29, 215, 248, 220, 220, 112]
# 24
# [188, 165, 206, 64, 244, 178, 178, 231, 169, 18, 157, 18, 174, 16, 200, 91, 61, 215, 6, 29, 220, 112, 248, 220]
然后就是XXTEA的解密了
TEA、XTEA、XXTEA加密解密算法_xxtea.dll下载-CSDN博客
XXTEA 加解密 as3 和 Python 分别实现_python xxtea.encrypt(data, key, signature)-CSDN博客
import xxtea
result = 'CE BC 40 6B 7C 3A 95 C0 EF 9B 20 20 91 F7 02 35 23 18 02 C8 E7 56 56 FA'.split(" ")
res = [int(i,16) for i in result]
for i in range(7,-1,-1):
t = 0
for n in range(0,i):
if t == 0 :
t = res[0]
else :
t ^= res[n]
for j in range(3) :
res[i*3+j] ^= t
box = [1,3,0,2,5,7,4,6,9,11,8,10,13,15,12,14,17,19,16,18,21,23,20,22]
m = []
for i in range(len(box)):
m.append(res[box[i]])
key = 'flag'+'\x00'*12
print(xxtea.decrypt(bytes(m),key,padding=False))
得到flag。