BUUCTF Reverse/[2019红帽杯]xx
先看下文件信息:没有加壳、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就是它的秘钥,然后再变换位置