用EXEinfo PE查壳后拖入IDA打开, 进入DialogFunc函数查看。
看到if ( strlen(String) == 8 )时开始进行一系列操作,所以flag长度应该为8。进入sub_4010F0函数查看,发现该函数是将DialogFunc函数内的v7数组传入,对v7数组内的数据进行加密,要得到加密后的数据则需要将该函数代码换为c程序运行得到加密数据。
*(_DWORD *)是汇编代码的表示,在c程序中删掉即可。(4 * i + a1)是数组的寻址方式,这个就代表int型数组的第i个数据,4是int型数据所占字节。将该代码转为c程序需要一些修改。只需将(4 * i + a1)此种类型改为c程序的数组数据表示方法即可。运行后得到加密数据:51 67 83 74 78 83 97 90 69 103 110
#include<stdio.h>
int sub_4010F0(int* a1, int a2, int a3)
{
int result; // eax 对传进的数组v7进行操作
int i; // esi
int v5; // ecx
int v6; // edx
result = a3; // v7[10]
for ( i = a2; i <= a3; a2 = i )
{
v5 = i;
v6 = a1[i]; // a1就是传进的数组v7
if ( a2 < result && i < result )
{
do
{
if ( v6 > a1[result])// a1 + 4 * result数组寻址方式,即v7[result]
{
if ( i >= result )
break;
++i;
a1[v5] = a1[result];
if ( i >= result )
break;
while ( a1[i] <= v6 )
{
if ( ++i >= result )
goto LABEL_13;
}
if ( i >= result )
break;
v5 = 4 * i;
a1[result] = a1[i];
}
--result;
}
while ( i < result );
}
LABEL_13:
a1[result] = v6;
sub_4010F0(a1, a2, i - 1);
result = a3;
++i;
}
return result;
}
int main()
{
int a1[]={90,74,83,69,67,97,78,72,51,110,103};
sub_4010F0(a1,0,10);
for(int i=0;i<11;i++)
{
printf("%d ",a1[i]);
}
return 0;
}
之后退出此函数往下看,发现有同样的v4/v5 = sub_401000((int)v18, strlen(v18));
点进查看,发现byte_407830,继续点进查看,发现base64加密。
退出查看下面的if代码,可以确认v4和v5的数据是经过加密后的数据,在进行base64解密后得到正确的数据为:base64加密后v4=ak1w,v5=V1Ax。解密后v4=jMp,v5=WP1。
分析if函数内的代码,String[0] == v7[0] + 34,v7[0]在是数组的第一个元素,比照加密后的数据,v7[0]=51,所以string[0]=51+34=85,对照ASCII码表,85对应大写字母U,所以这就是flag的第一个数据,下面的同理。
String[0]=U,strinh[1]=J,string[2]=W,string[3]=P,v4=jMp,v5=WP1,可以看到string[2]=W,string[3]=P,所以v5应该是在v4的前面,组合一下得到flag{UJWP1jMp}