https://pan.baidu.com/s/1i5gLzIt
下下来是一个linux程序,运行起来看看
…直接扔IDA64打开吧。下面是main函数的代码:
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
signed __int64 v3; // rbx
signed int v4; // eax
bool v5; // bp
bool v6; // al
const char *v7; // rdi
__int64 v9; // [rsp+0h] [rbp-28h]
v9 = 0LL;
puts("Input flag:");
scanf("%s", &s1, 0LL);
if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + 24) != 125 )
{
LABEL_22:
puts("Wrong flag!");
exit(-1);
}
v3 = 5LL;
if ( strlen(&s1) - 1 > 5 )
{
while ( 1 )
{
v4 = *(&s1 + v3);
v5 = '\0';
if ( v4 > 'N' )
{
v4 = (unsigned __int8)v4;
if ( (unsigned __int8)v4 == 'O' )
{
v6 = sub_400650((_DWORD *)&v9 + 1); // ///
goto LABEL_14;
}
if ( v4 == 'o' )
{
v6 = sub_400660((int *)&v9 + 1); // ///
goto LABEL_14;
}
}
else
{
v4 = (unsigned __int8)v4;
if ( (unsigned __int8)v4 == '.' ) // ///
{
v6 = sub_400670(&v9);
goto LABEL_14;
}
if ( v4 == '0' ) // ///
{
v6 = sub_400680((int *)&v9);
LABEL_14:
v5 = v6;
goto LABEL_15;
}
}
LABEL_15:
if ( !(unsigned __int8)sub_400690((__int64)asc_601060, SHIDWORD(v9), v9) )
goto LABEL_22;
if ( ++v3 >= strlen(&s1) - 1 )
{
if ( v5 )
break;
LABEL_20:
v7 = "Wrong flag!";
goto LABEL_21;
}
}
}
if ( asc_601060[8 * (signed int)v9 + SHIDWORD(v9)] != 35 )
goto LABEL_20;
v7 = "Congratulations!";
LABEL_21:
puts(v7);
return 0LL;
}
第一眼感觉好复杂,先看看它有什么字符串常量吧。
看到下面的一堆星星,结合题目名字,这应该是一个逆向的迷宫题。
先把这一堆星星复制出来。(最好用IDA里面的保存到文件功能复制,这样导出来的字符串是完整的。
这一堆星星就是我们的迷宫地图了。
再回到main代码里面看过程。迷宫题一般会让你走迷宫,既然是走迷宫,那迷宫一定会有长和宽。
在main代码里面没有很明显的坐标移动的代码,所以进到那些函数里面看看。
看到这个东西,这个函数传入了一个指针,然后用间值的方式改变main那边变量的值。
最后那个return非常疑似边界判定的操作
(那个O是要按R转换成字符才会出现的)这个GOTO太恶心了,代码很难看,不过在四个if处都发现了可以转换成字符的数字。这个非常像走迷宫的控制系统。在那四个IF里面都有功能相似的函数,判断是控制移动的代码。
最后那个函数肯定是控制左移或者上移的,因为走迷宫的初始坐标是0,0。往下增加,往右也增加。往左往上减少。
上面两个函数感觉一个是控制右移,一个是下移的。不过具体是控制什么的看不出来。反正到时候多试试就好了。从上面可以看出来迷宫地图是8*8的。把地图数据整到辅助工具里。
用光标走完,得到路径数据(小人的位置在光标前面一格哦)
然后把题目中说的控制方向的字符打到对应的方向键上。再按替换文本
打开那个程序试试答案对不对(记得带上nctf{})
……那 那就换个方向试试吧
嘎嘎嘎拿到flag了
nctf{o0oo00O000oooo..OO}