前言
好多題解writeup直接說這個題目是個迷宮題,說的好像一眼就能看出來似的。但是實際上不提前看答案或者研究透徹這個題目的話,根本想不出來這是個迷宮。
下面說一下我的思路吧。
題目
不一樣的flag
是不是做習慣了正常的逆向題目?試試這道題,看你在能不能在程式中找到真正的flag!注意:flag并非是flag{XXX}形式,就是一個’字元串‘,考驗眼力的時候到了! 注意:得到的 flag 請包上 flag{} 送出
思路
首先是反編譯:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
_BYTE v_5x5_4[29]; // [esp+17h] [ebp-35h] BYREF
int v4; // [esp+34h] [ebp-18h]
int input; // [esp+38h] [ebp-14h] BYREF
int i; // [esp+3Ch] [ebp-10h]
_BYTE v7[12]; // [esp+40h] [ebp-Ch] BYREF
__main();
v_5x5_4[26] = 0;
*(_WORD *)&v_5x5_4[27] = 0;
v4 = 0;
strcpy(v_5x5_4, "*11110100001010000101111#");
while ( 1 )
{
puts("you can choose one action to execute");
puts("1 up");
puts("2 down");
puts("3 left");
printf("4 right\n:");
scanf("%d", &input);
if ( input == 2 ) // 下
{
++*(_DWORD *)&v_5x5_4[25];
}
else if ( input > 2 )
{
if ( input == 3 ) // 左
{
--v4;
}
else
{
if ( input != 4 )
LABEL_13:
exit(1);
++v4; // 右
}
}
else
{
if ( input != 1 )
goto LABEL_13;
--*(_DWORD *)&v_5x5_4[25]; // 上
}
for ( i = 0; i <= 1; ++i )
{
if ( *(int *)&v_5x5_4[4 * i + 25] < 0 || *(int *)&v_5x5_4[4 * i + 25] > 4 )// 超出邊界退出。25是上下位置,29超出數組了,指針指向到v4的位置,為左右位置
exit(1);
}
if ( v7[5 * *(_DWORD *)&v_5x5_4[25] - 41 + v4] == '1' )
exit(1);
if ( v7[5 * *(_DWORD *)&v_5x5_4[25] - 41 + v4] == '#' )
{
puts("\nok, the order you enter is the flag!");
exit(0);
}
}
}
我在代碼上加上注釋了。
這個代碼的核心之處就是,迷宮是個_BYTE v_5x5_4[29]變量,前面25位是迷宮地圖,第26位是上下坐标的位置,v4變量是左右坐标的位置。左上角*号為(0,0)坐标,向右向下為第一象限。
下面一個2次的for循環,利用指針越界判斷上下左右坐标。25是上下位置,29超出數組了,指針指向到v4的位置,為左右位置,超出迷宮範圍則越界。
最後一段,就是碰牆退出,碰#号出迷宮。迷宮地圖為:
"*1111"
"01000"
"01010"
"00010"
"1111#"
是以,最後的答案才是迷宮的路徑,“下下下右右上上右右下下下”,即flag{222441144222}