用die查壳
无壳,且为32位模式
拖入ida
shifit+f12找字符串
找到关键字段
点进去,按ctrl+x交叉引用
再按f5反汇编
发现主函数
__main();
v6 = 0;
memset(v5, 0, 4 * (((Str - v5 + 64) & 0xFFFFFFFC) >> 2));
Str[0] = 67;
Str[1] = -33;
Str[2] = 20;
v5[0] = 3;
v5[1] = 13;
v5[2] = 44;
v5[3] = 9;
v5[4] = 1;
v5[5] = 23;
v5[6] = 23;
v5[7] = 8;
v5[8] = -4;
v5[9] = 43;
v5[10] = -6;
v5[11] = 20;
v5[12] = 23;
v5[13] = -7;
v5[14] = 37;
v5[15] = -11;
v5[16] = 34;
v5[17] = 61;
v5[18] = -50;
v5[19] = 24;
v5[20] = 22;
v5[21] = 10;
qmemcpy(v8, "REVERSE", sizeof(v8));
v9 = strlen(Str);
printf(&Format);
scanf("%s", v7);
mix(v7, v8, v9);
for ( i = 0; i < v9; ++i )
{
if ( v7[i] != Str[i] )
{
puts(Buffer);
return 0;
}
}
puts(aFlag);
return 0;
}
这里猜测,str和v5的地址是连在一起的,要不然最后的str只有三个数字,这是不可能的
查看地址空间也证实了这一猜想
函数很简单,就是把输入的v7进行mix操作,最后要与str相等
点进mix函数
for ( i = 0; i < a3; ++i )
a1[i] -= 64;
for ( j = 0; j < a3; ++j )
a1[j] -= a1[j + 1];
for ( k = 0; k < strlen(Str); ++k )
Str[k] %= 64;
for ( l = 0; l < a3; ++l )
a1[l] += Str[l % 7];
for ( m = 0; a3 / 2 > m; ++m )
{
v5 = a1[m];
a1[m] = a1[a3 - m - 1];
a1[a3 - m - 1] = v5;
}
for ( n = 0; ; ++n )
{
result = n;
if ( n >= a3 )
break;
if ( (Str[n % 7] & 1) != 0 )
v3 = a1[n] + 2;
else
v3 = a1[n] + 1;
a1[n] = v3;
}
return result;
}
代码也很简单,直接写脚本爆破
不过有一点需要注意,我刚开始也没想明白,
for ( j = 0; j < a3; ++j )
a1[j] -= a1[j + 1];
这段函数一看就溢出了
只能猜测ida会自动不管溢出的函数了
所以a1的最后一位没变
写脚本
s=[67,-33,20,3,13,44,9,1,23,23,8,-4,43,-6,20,23,-7,37,-11,34,61,-50,24,22,10]
v8 = "REVERSE"
v81=[]
v9 = len(s) #v9=25
flag=[]
for i in range(len(v8)):
k = ord(v8[i])%64
v81.append(k)
for c in range(v9):
for i in range(-127,127):
i1=i
if (v81[c%7]&1) !=0:
v3 = i+2
else:
v3 = i+1
i = v3
if i == s[c]:
flag.append(i1)
for i in range(13):
v5 = flag[i]
flag[i]=flag[v9-i-1]
flag[v9-i-1]=v5
for i in range(v9):
flag[i]-=v81[i%7]
#flag[v9-1]+=flag[0]
for i in range(v9-2,-1,-1):
flag[i]+=flag[i+1]
for i in range(v9):
flag[i]+=64
for i in range(v9):
print(chr(flag[i]),end="")
得到结果ISCC{REVERSE_IS_NOT_HARD}