先看下文件信息:没有加壳、64位程序
看别人wp时候发现个好东东,就是这个findcrypt插件,可以看加密算法的,具体安装可以看这个IDA7.5安装findcrypt3插件
可以看到这是tea加密
先一点点分析代码,输入flag,flag的长度必须为19
sub_7FF7A98718C0(std::cin, argv, flag); // 输入flag
v3 = -1i64;
v4 = -1i64;
do
++v4;
while ( *((_BYTE *)flag + v4) );
if ( v4 != 19 ) // 长度为19
{
sub_7FF7A9871620(std::cout, "error\n");
_exit((int)flag);
这里给v6赋值为qwertyuiopasdfghjklzxcvbnm1234567890
这行代码看上去挺麻烦的,一眼唬住,但是仔细看下,前面有个v9 = v5,后面又减去了个v5,所以这行代码就变成了v10 = *flag
v10 = *((_BYTE *)v9 + (char *)flag - (char *)v5);
这段代码比较的是输入的flag的前四个字符是否在qwertyuiopasdfghjklzxcvbnm1234567890之间,顺便把flag的前四个字符赋值给v5
v5 = (__int128 *)operator new(5ui64);
v6 = *(_QWORD *)&Code;
v7 = v5;
v8 = 0;
v9 = v5;
do
{
v10 = *((_BYTE *)v9 + (char *)flag - (char *)v5);
v11 = 0;
*(_BYTE *)v9 = v10;
v12 = 0i64;
v13 = -1i64;
do
++v13;
while ( *(_BYTE *)(v6 + v13) );
if ( v13 )
{
do
{
if ( v10 == *(_BYTE *)(v6 + v12) )
break;
++v11;
++v12;
}
while ( v11 < v13 );
}
v14 = -1i64;
do
++v14;
while ( *(_BYTE *)(v6 + v14) );
if ( v11 == v14 )
_exit(v6);
v9 = (__int128 *)((char *)v9 + 1);
}
while ( (char *)v9 - (char *)v5 < 4 );
将v5扩展成16位,不足补0,前四位应该是 ‘flag’,补完后就是 ‘flag000000000000’
v30 = *v7;
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 < 0x10; ++i )
*((_BYTE *)&v30 + i) = 0;
这一段就是给输入的flag进行xxtea加密,前面扩展的v5就是它的秘钥,然后再变换位置
v17 = sub_7FF7A9871AB0((__int64)flag, v3, (unsigned __int8 *)&v30, &Size);// tea加密
v18 = Size;
v19 = 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];
xxtea里面还有一段拆分的代码,将32位的数拆分成4个8位的数
if ( v40 )
{
do
{
v42[v13] = v11[v13 >> 2] >> (8 * (v13 & 3));
++v13;
}
while ( v13 < v40 );
}
异或
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;
}
变换后的字符串要等于v30中的字符串
*(_QWORD *)&v30 = 0xC0953A7C6B40BCCEui64;
v25 = v20 - (_BYTE *)&v30;
*((_QWORD *)&v30 + 1) = 0x3502F79120209BEFi64;
v26 = 0i64;
v31 = 0xC8021823;
v32 = 0xFA5656E7;
do
{
if ( *((_BYTE *)&v30 + v26) != *((_BYTE *)&v30 + v26 + v25) )
_exit(v8 * v8);
++v8;
++v26;
}
while ( v26 < 24 );
梳理下:
输入flag->取前四位扩展成16位作秘钥-> xxtea加密->拆分 ->移位 ->异或
然后写脚本挨个逆就行,先异或
int v20[] = { 0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B,
0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8,
0xE7, 0x56, 0x56, 0xFA};
for(int v22 = 23,v21 = 23; v21 >= 1; v22--)
{
int v23 = 0;
if( v21 / 3 > 0)
{
//int v24 = v20[v22];
do
{
//v24 ^= v20[v23 ++];
//v20[v22] = v24;
v20[v22] ^= v20[v23++];
}
while(v23 < v21 / 3);
}
--v21;
}
移位
int v19[25] = {0};
v19[0] = v20[1];
v19[2] = v20[0];
v19[3] = v20[2];
v19[1] = v20[3];
v19[6] = v20[4];
v19[4] = v20[5];
v19[7] = v20[6];
v19[5] = v20[7];
v19[10] = v20[8];
v19[8] = v20[9];
v19[11] = v20[10];
v19[9] = v20[11];
v19[14] = v20[12];
v19[12] = v20[13];
v19[15] = v20[14];
v19[13] = v20[15];
v19[18] = v20[16];
v19[16] = v20[17];
v19[19] = v20[18];
v19[17] = v20[19];
v19[22] = v20[20];
v19[20] = v20[21];
v19[23] = v20[22];
v19[21] = v20[23];
合并
unsigned int flag[10] = {0};
for(int i = 0 ; i < 0x18 ; i++)
{
//printf("%d, %d\n",i , 4 * (i / 4 + 1) - (i % 4) - 1);
flag[i >>2] <<= 8;
flag[i >> 2] += v19[4 * (i / 4 + 1) - i % 4 - 1];
}
xxtea解密
xxtea秘钥是4个32位数,小端排序
#define MX ((y ^ sum) + (z ^ key[e ^ (p & 3)])) ^ (((4 * y) ^ (z >> 5)) + ((y >> 3) ^ (16 * z)))
#define DELTA 0x61C88647
int key[5] = {0x67616c66,0x00,0x00,0x00};
unsigned int sum = 0 , n = 6;
int rounds = 52 / n + 6;
int i,j,k;
unsigned int z,y,e,p;
rounds = 6 + 52/n;
sum = rounds * DELTA * (-1);
y = flag[0];
do
{
// if(rounds < 0) break;
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = flag[p-1];
//y = v2[p] -= ((y ^ sum) + (z ^ key[e ^ (p & 3)])) ^ (((4 * y) ^ (z >> 5)) + ((y >> 3) ^ (16 * z)));
y = flag[p] -= MX;
printf("p = %d\n",p);
}
z = flag[n-1];
//y = v2[0] -= ((v2[0] ^ sum) + (z ^ key[e ^ (p & 3)])) ^ (((4 * v2[0]) ^ (z >> 5)) + ((v2[0] >> 3) ^ (16 * z)));
y = flag[0] -= MX;
sum += DELTA;
printf("rounds = %d\n",rounds);
}
while(--rounds);
总代码
#include
#include
#include
#include
#define MX ((y ^ sum) + (z ^ key[e ^ (p & 3)])) ^ (((4 * y) ^ (z >> 5)) + ((y >> 3) ^ (16 * z)))
#define DELTA 0x61C88647
int main()
{
int v20[] = { 0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B,
0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8,
0xE7, 0x56, 0x56, 0xFA};
int key[5] = {0x67616c66,0x00,0x00,0x00};
for(int v22 = 23,v21 = 23; v21 >= 1; v22--)
{
int v23 = 0;
if( v21 / 3 > 0)
{
do
{
v20[v22] ^= v20[v23++];
}
while(v23 < v21 / 3);
}
--v21;
}
int v19[25] = {0};
v19[0] = v20[1];
v19[2] = v20[0];
v19[3] = v20[2];
v19[1] = v20[3];
v19[6] = v20[4];
v19[4] = v20[5];
v19[7] = v20[6];
v19[5] = v20[7];
v19[10] = v20[8];
v19[8] = v20[9];
v19[11] = v20[10];
v19[9] = v20[11];
v19[14] = v20[12];
v19[12] = v20[13];
v19[15] = v20[14];
v19[13] = v20[15];
v19[18] = v20[16];
v19[16] = v20[17];
v19[19] = v20[18];
v19[17] = v20[19];
v19[22] = v20[20];
v19[20] = v20[21];
v19[23] = v20[22];
v19[21] = v20[23];
unsigned int flag[10] = {0};
for(int i = 0 ; i < 0x18 ; i++)
{
//printf("%d, %d\n",i , 4 * (i / 4 + 1) - (i % 4) - 1);
flag[i >>2] <<= 8;
flag[i >> 2] += v19[4 * (i / 4 + 1) - i % 4 - 1];
}
unsigned int sum = 0 , n = 6;
int rounds = 52 / n + 6;
int i,j,k;
unsigned int z,y,e,p;
//xxtea
rounds = 6 + 52/n;
sum = rounds * DELTA * (-1);
y = flag[0];
do
{
// if(rounds < 0) break;
e = (sum >> 2) & 3;
for (p=n-1; p>0; p--)
{
z = flag[p-1];
y = flag[p] -= MX;
}
z = flag[n-1];
y = flag[0] -= MX;
sum += DELTA;
}
while(--rounds);
//输出
char *tmp = flag;
for(int i = 0 ; i < 19 ; i++)
{
printf("%c",*tmp++);
}
return 0;
}
输出
最终flag:flag{CXX_and_++tea}