记一次CTF_1

记一次CTF的题。

CTF和平时破解的题不一样,需要从题目中的一些提示寻找突破口,有时还需要脑洞。

首先我们打开程序:

看到一个上下左右的提示,然后我们输入试着输入不同的值,发现输入1、3、4,都会弹出窗口,而输入2,则会继续这个循环。

在对程序有一个大概的了解之后,我们用IAD打开,查看一下伪代码:

main函数很好找,直接能看到:

void main()
{
  char v0; // [sp+17h] [bp-35h]@1
  int y; // [sp+30h] [bp-1Ch]@1
  int x; // [sp+34h] [bp-18h]@1
  signed int input; // [sp+38h] [bp-14h]@2
  signed int i; // [sp+3Ch] [bp-10h]@14
  int v5; // [sp+40h] [bp-Ch]@20

  __main();                                     // 初始化
  y = 0;
  x = 0;                                        // x,y为坐标
  qmemcpy(&v0, _data_start__, 0x19u);           // v0=*11110100001010000101111#
  while ( 1 )
  {
    puts("you can choose one action to execute");
    puts("1 up");
    puts("2 down");                         // 1.上 2.下 3.左 4.右
    puts("3 left");
    printf("4 right
:");
    scanf("%d", &input);
    if ( input == 2 )                           // input=2
    {
      ++y;                                      // y坐标增加1
    }
    else if ( input > 2 )
    {                                           // input=3
      if ( input == 3 )
      {
        --x;                                    // x坐标减少1
      }
      else
      {
        if ( input != 4 )                       // input =4
LABEL_13:
          exit(1);
        ++x;                                    // x坐标增加1
      }
    }
    else
    {
      if ( input != 1 )                         // input=1
        goto LABEL_13;
      --y;                                      // y坐标减少1
    }
    for ( i = 0; i <= 1; ++i )
    {
      if ( *(&y + i) < 0 || *(&y + i) > 4 )     // 判断v1是否在0-4,否则退出
        exit(1);
    }
    if ( *((_BYTE *)&v5 + 5 * y + x - 41) == '1' )// 判断坐标是否为墙
      exit(1);
    if ( *((_BYTE *)&v5 + 5 * y + x - 41) == '#' )// 判断坐标是否为终点
    {
      puts("
ok, the order you enter is the flag!");
      exit(0);
    }
  }
}

图中已经将伪代码的逻辑进行了标注,我们已经可以比较清晰的看到,这是一个迷宫的地图,因此找到迷宫,有了上下左右,题目自然就解出来了。

那么地图在哪里呢。

在师傅的指点下,我找到了。

我们先看到这个

这里是判断坐标是否为墙和终点,我们来看看这里的逻辑:首先是(v5的地址+y*5+x-41),我们知道y于x是坐标,所以这个式子就可以变成

(v5的地址-41+坐标)

我们可以想:如果要判断是否为墙,那么一定要把坐标放在地图上比较,所以,这个v5的地址-41,一定是地图的地址。

而经过计算,我们发现v5的地址,其实就是前面v0的地址,所以地图就是

地图就是

*1111

01000

01010

00010

1111#

那么flag就是{222441144222}

原文地址:https://www.cnblogs.com/lex-shoukaku/p/13257712.html