ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

攻防世界-Reverse区WP--maze

2022-01-13 17:59:14  阅读:182  来源: 互联网

标签:__ Reverse -- LABEL a1 v1 v4 WP v9


   疫情当下,都已经耍了半个月了,都不知道干啥了,无聊中,那就写了Reverse解题记录吧。

图片

maze

根据题目描述可知这是一道迷宫题。用IDA64打开,F5将主函数main反编译成C伪代码: 

__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) != '}' )
  {                                             // flag长度为24 并且由nctf{}包裹
LABEL_22:
    puts("Wrong flag!");
    exit(-1);
  }
  v3 = 5LL;
  if ( strlen(&s1) - 1 > 5 )
  {
    while ( 1 )
    {
      v4 = *(&s1 + v3);                         // 从flag花括号内的第一个字符开始比对
      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)] != '#' ) //循环结束判断 是否到达迷宫终点'#'
    goto LABEL_20;
  v7 = "Congratulations!";
LABEL_21:
  puts(v7);
  return 0LL;
}

其中 SHIDWORD(v9)即 &v9 + 1 ,迷宫字符串asc_601060[]如下,长度为64:

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

 根据以下代码能够判断出 &v9 为纵坐标(所在行), &v9+1为横坐标(所在列),迷宫是8*8规格的。

if ( asc_601060[8 * (signed int)v9 + SHIDWORD(v9)] != '#' )    //判断是否到达迷宫终点'#'

 其中逻辑为:


当前位置 = 8(迷宫横长) * 当前纵坐标(所在行) + 当前纵坐标(所在列)

 其中横纵坐标由0开始算。又根据伪代码中四个 if判断中的函数判断移动四个方向:

bool __fastcall sub_400650(_DWORD *a1)     // a1为 &v9+1(横坐标)
{            // v4 = 'O'
  int v1; 
  v1 = (*a1)--;      // 横坐标-1 向左移动
  return v1 > 0;    // 是否超出边界
}

bool __fastcall sub_400660(int *a1)      // a1为 &v9+1
{            // v4 = 'o'
  int v1; 
  v1 = *a1 + 1;      // 横坐标+1 向右移动
  *a1 = v1;
  return v1 < 8;
}

bool __fastcall sub_400670(_DWORD *a1)    // a1为 v9(纵坐标)
{            // v4 = '.'
  int v1;
  v1 = (*a1)--;      // 纵坐标-1 向上移动
  return v1 > 0;    // 超界判断
}

bool __fastcall sub_400680(int *a1)      // a1为 v9
{
  int v1;         // v4 = '0'
  v1 = *a1 + 1;      // 纵坐标+1 向下移动
  *a1 = v1;
  return v1 < 8;
}

 将迷宫字符串以8*8格式打印出来(起点在左上角,终点为#)


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

 走出迷宫方式为:右下右右下下左下下下右右右右上上左左 对应flag字符串:o0oo00O000oooo…OO 字符串长度刚好也对应为程序开头的判断(18+6=24) 在Linux虚拟机内运行验证也正确。

 我们的公众号

作者微信:CSJH2209

标签:__,Reverse,--,LABEL,a1,v1,v4,WP,v9
来源: https://blog.csdn.net/qq_46939030/article/details/122476140

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有