攻防世界re:maze

1.查壳
攻防世界re:maze_第1张图片64位ELF文件
2.拖入IDA
找到main函数F5反编译
在这里插入图片描述

__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) != '}' )
  {
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(asc_601060, HIDWORD(v9), (unsigned int)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)] != '#' )
    goto LABEL_20;
  v7 = "Congratulations!";
LABEL_21:
  puts(v7);
  return 0LL;
}

这段代码一出来还有点懵,不过还是习惯性地把能转成字符串的转换好
沉思有一段时间后,参考题目说是走迷宫,又看到代码中有O,o,0,.这四个字符,于是猜测可能对应上下左右四个方向,而迷宫应该是个二维数组
分析代码,发现了四个函数

bool __fastcall sub_400650(_DWORD *a1)//(_DWORD *)&v9 + 1 'O'
{
  int v1; // eax

  v1 = (*a1)--;
  return v1 > 0;
}

bool __fastcall sub_400660(int *a1)//(int *)&v9 + 1 'o'
{
  int v1; // eax

  v1 = *a1 + 1;
  *a1 = v1;
  return v1 < 8;
}

bool __fastcall sub_400670(_DWORD *a1)//&v9 '.'
{
  int v1; // eax

  v1 = (*a1)--;
  return v1 > 0;
}

bool __fastcall sub_400680(int *a1)//&v9 '0'
{
  int v1; // eax

  v1 = *a1 + 1;
  *a1 = v1;
  return v1 < 8;
}

分别与O,o,.,0相对应
根据二维数组的性质,可以判断出
O对应左
o对应右
.对应上
0对应下
而这些函数传入的参数v9应该就是迷宫了
所以要找到迷宫

 asc_601060      db '  *******   *  **** * ****  * ***  *#  *** *** ***     *********',0

这些就是迷宫,需要把它还原
asc_601060是个char[65]的字符串,除去一个空字符,所以猜测应该是个8
8的迷宫

  ******
*   *  *
*** * **
**  * **
**  * **
*  *#  *
** *** *
**     *
********

我们的终点是迷宫中心的那个#,起点是左上角顶点,所以走迷宫就能得到flag
再加上程序开头提示的

if ( strlen(&s1) != 24 || strncmp(&s1, "nctf{", 5uLL) || *(&byte_6010BF + 24) != '}' )

我们就能得出flag为

nctf{o0oo00O000oooo…OO}

你可能感兴趣的:(CTF)