
没有加壳,主函数也很简洁
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v5[512]; // [rsp+20h] [rbp-60h] BYREF
char v6[512]; // [rsp+220h] [rbp+1A0h] BYREF
sub_401AC0(argc, argv, envp);
memset(v6, 0, sizeof(v6));
memset(v5, 0, sizeof(v5));
puts("Help Me Out!!!!!!!!");
sub_40AE30("%200s", v6);
if ( sub_401757(v6) && (unsigned __int8)sub_40161A((__int64)&v6[6]) )
puts("Yes! Escaped!");
else
puts("No way!");
return 0;
}
一个验证flag格式
_BOOL8 __fastcall sub_401757(const char *a1)
{
return !strncmp(a1, "unctf{", 6ui64) && a1[strlen(a1) - 1] == '}';
}
另一个判断路径
__int64 __fastcall sub_40161A(__int64 a1)
{
int v1; // eax
int v3; // [rsp+24h] [rbp-Ch]
int v4; // [rsp+28h] [rbp-8h]
int v5; // [rsp+2Ch] [rbp-4h]
v5 = 0;
v4 = 0;
v3 = 0;
while ( 1 )
{
v1 = *(char *)(a1 + v5);
if ( v1 == 100 )
{
++v4;
}
else if ( v1 > 100 )
{
if ( v1 == 115 )
{
++v3;
}
else
{
if ( v1 != 119 )
return 0i64;
--v3;
}
}
else
{
if ( v1 != 97 )
return 0i64;
--v4;
}
if ( v4 < 0
|| v3 < 0
|| *((_BYTE *)qword_40F030 + 10 * v3 + v4) == 68
|| *((_BYTE *)qword_40F030 + 10 * v3 + v4) == 48 )
{
return 0i64;
}
if ( v4 > 9 || v3 > 9 )
return 0i64;
if ( *((_BYTE *)qword_40F030 + 10 * v3 + v4) == 83 )
break;
if ( (unsigned __int8)sub_4019F4() )
{
puts("I See YOU!");
exit(2);
}
++v5;
}
return 1i64;
}
这里是判断是否走到终点 qword_40F030中存的就是地图数据
if ( v4 < 0
|| v3 < 0
|| *((_BYTE *)qword_40F030 + 10 * v3 + v4) == 'D'
|| *((_BYTE *)qword_40F030 + 10 * v3 + v4) == '0')
{
return 0i64;
}
if ( v4 > 9 || v3 > 9 )
return 0i64;
if ( *((_BYTE *)qword_40F030 + 10 * v3 + v4) == 'S' )
break;
if ( (unsigned __int8)sub_4019F4() ) // 检测debug
{
puts("I See YOU!");
exit(2);
}
按x交叉引用找到给其赋值的地方

char *sub_4017AA()
{
_QWORD *v0; // rax
char *result; // rax
__int64 v2[14]; // [rsp+20h] [rbp-70h] BYREF
qmemcpy(
v2,
"Oo00oD00SD0oooo0Doooo0D0oD0o00ooooo00o00oD0D0oooooo00o0o0o0ooDoooooDDDo00o00oooooD0D0000oDoooooooooD",
100);
qword_40F030 = malloc(0x80ui64);
memset(qword_40F030, 0, 0x80ui64);
v0 = qword_40F030;
*(_QWORD *)qword_40F030 = v2[0];
v0[1] = v2[1];
v0[2] = v2[2];
v0[3] = v2[3];
v0[4] = v2[4];
v0[5] = v2[5];
v0[6] = v2[6];
v0[7] = v2[7];
v0[8] = v2[8];
v0[9] = v2[9];
v0[10] = v2[10];
v0[11] = v2[11];
*((_DWORD *)v0 + 24) = v2[12];
result = (char *)qword_40F030 + 100;
*((_BYTE *)qword_40F030 + 100) = 0;
return result;
}
分析下,ws上下,ad左右,左上角是起始点,S是终点 o是可以走的路径
Oo00oD00SD
0oooo0Dooo
o0D0oD0o00
ooooo00o00
oD0D0ooooo
o00o0o0o0o
oDoooooDDD
o00o00oooo
oD0D0000oD
oooooooooD
手动走一下:dsdddssaaaassssssddddddddwwaawawwddwwwdw
最终flag: unctf{dsdddssaaaassssssddddddddwwaawawwddwwwdw}