总结:
1.第一道题是把flag藏在压缩包中的做法,即在压缩包的数据流中直接粘贴进去一段base64加密后的字段,这样的方法会在解压时提示压缩包损坏(因为其中有一段是没压缩过的直接加进去的),做这种题还是要熟悉文件头;
2.第二道是一道逆向的题,需要注意的有:
①做逆向的题可以先shift+F12查找字符串,在通过X显示字符串都出现在哪里,最后F5反编译开始做;
②在题中可以右键添加注释;
③IDA中绿色是常量;
④strcpy是复制字符串,strlen是取字符串的长度;
⑤for循环中若没有条件即本循环只能通过break终止循环;
⑥*(_BYTE *)(a1 + 9 * a2 + a3)是二维数组的取值方法,byte是取一个字节的数据;
⑦下次做这种题可以写个程序把地图画出来;
⑧int是4个字节,char是1个。
下面是题:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@3
size_t v4; // ebx@5
size_t v5; // eax@6
char v6; // [sp+4h] [bp-50h]@1
char v7[50]; // [sp+13h] [bp-41h]@1
char v8[4]; // [sp+45h] [bp-Fh]@1
char v9; // [sp+4Bh] [bp-9h]@1
size_t i; // [sp+4Ch] [bp-8h]@1
sub_40D870();
sub_47C370((int)&dword_487F00, v7);
strcpy(v8, "xman{"); // xman是答案的开头
v9 = 125; // 125的ASCII码为}
for ( i = 0; ; ++i )
{
v4 = i;
if ( v4 >= strlen(v8) )
break;
if ( v7[i] != v8[i] ) // v4是我的输入值
{
sub_401500((int)"違うよ\n", v6);
return 0;
}
}
v5 = strlen(v7); // v2是v4的长度
if ( v7[v5 - 1] == v9 )
{
v7[strlen(v7) - 1] = 0;
sub_4015F3(&v7[5]);
result = 0;
}
else
{
sub_401500((int)"違うよ\n", v6);
result = 0;
}
return result;
}
// a1可能是我输入的值中的数字
int __cdecl sub_4015F3(char *a1)
{
signed int v1; // eax@2
size_t v2; // ebx@17
int result; // eax@19
char v4; // [sp+4h] [bp-64h]@0
int v5; // [sp+1Ah] [bp-4Eh]@1
int v6; // [sp+1Eh] [bp-4Ah]@1
char v7; // [sp+22h] [bp-46h]@1
int v8; // [sp+23h] [bp-45h]@1
int v9; // [sp+27h] [bp-41h]@1
char v10; // [sp+2Bh] [bp-3Dh]@1
int v11; // [sp+2Ch] [bp-3Ch]@1
int v12; // [sp+30h] [bp-38h]@1
char v13; // [sp+34h] [bp-34h]@1
int v14; // [sp+35h] [bp-33h]@1
int v15; // [sp+39h] [bp-2Fh]@1
char v16; // [sp+3Dh] [bp-2Bh]@1
int v17; // [sp+3Eh] [bp-2Ah]@1
int v18; // [sp+42h] [bp-26h]@1
char v19; // [sp+46h] [bp-22h]@1
int v20; // [sp+47h] [bp-21h]@1
int v21; // [sp+4Bh] [bp-1Dh]@1
char v22; // [sp+4Fh] [bp-19h]@1
int v23; // [sp+50h] [bp-18h]@1
int v24; // [sp+54h] [bp-14h]@1
size_t i; // [sp+58h] [bp-10h]@1
char v26; // [sp+5Fh] [bp-9h]@1
v5 = 0x5202020;
v6 = 0x20202020;
v7 = 0; // char
v8 = 0x5200520;
v9 = 0x20050520;
v10 = 0; // char
v11 = 0x20050520;
v12 = 0x20200520; // char
v13 = 0;
v14 = 0x20200520;
v15 = 0x20052020;
v16 = 0; // char
v17 = 0x5200520;
v18 = 0x5050520;
v19 = 0; // char
v20 = 0x5202020;
v21 = 0x20202020;
v22 = 0; // char
v24 = 0;
v23 = 0;
v26 = 1;
for ( i = 0; ; ++i )
{
v2 = i;
if ( v2 >= strlen(a1) ) // strlen是取字符串的长度
break;
v1 = a1[i]; // 把a的第一个值给v1
if ( v1 == '2' )
{
v26 = sub_40157C((int)&v24, &v23); // 23=7? ++ v23<=6
goto LABEL_14;
}
if ( v1 > 50 )
{
if ( v1 == '3' )
{
v26 = sub_4015A4(&v24); // v24=0? -- v24>=1
goto LABEL_14;
}
if ( v1 == '4' )
{
v26 = sub_4015CB(&v24); // v24=7? 24++
goto LABEL_14;
}
}
else if ( v1 == '1' )
{
v26 = sub_401555((int)&v24, &v23); // 23=0? 23--
goto LABEL_14;
}
v26 = 0;
LABEL_14:
if ( (unsigned __int8)sub_401529((int)&v5, v24, v23) ^ 1 )// v24=3,v23=1或4
{
v26 = 0;
break;
}
}
if ( v26 == 1 ) // 如果v26不等于1,就会出现痛···
{
if ( v24 != 5 || v23 != 7 )
{
result = sub_401500((int)&unk_489033, v4);
}
else if ( strlen(a1) <= '\x10' )
{
result = sub_401500((int)"本当に 本当に よかった\n", v4);
}
else
{
result = sub_401500((int)&"ああ..疲れた....\n", v4);
}
}
else
{
result = sub_401500((int)"痛いQAQ\n", v4);
}
return result;
}