zoukankan      html  css  js  c++  java
  • 记一次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}

  • 相关阅读:
    memento模式
    observe模式
    state模式
    Trie树的简单介绍和应用
    strategy模式
    全组和问题
    SRM 551 DIV2
    全排列问题
    TSE中关于分词的算法的改写最少切分
    template模式
  • 原文地址:https://www.cnblogs.com/lex-shoukaku/p/13257712.html
Copyright © 2011-2022 走看看