首页
社区
课程
招聘
[原创]2021 KCTF 春季赛 第二题 南冥神功
2021-5-11 16:05 4116

[原创]2021 KCTF 春季赛 第二题 南冥神功

2021-5-11 16:05
4116

反编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
sub_40AD70();
  sub_4AF840((int)&dword_4B8860, "Input your code: ");
  sub_4B0AB0((int)&dword_4B8680, ipt);
  if ( strlen(ipt) <= 48 )
  {
    p = ipt[0];
    if ( ipt[0] )
    {
      ii = 0;
      yy = 0;
      xx_ = 0;
      is36 = ::is36;
      is0 = c0_z[0];
LOOP:
      if ( is36 > 0 )
      {
        jj = 0;
        if ( is0 == p )
        {
LABEL_11:
          v7 = (ii + jj / 6) % 6;
          ii_jj = jj + ii;
          xx = xx_;
          sw2 = v7;
          sw = 5 - ii_jj % 6;
          for ( i = 0; ; i = 1 )
          {
            switch ( sw )
            {
              case 1:
                ++xx;
                break;
              case 2:
                v17 = (yy++ & 1) == 0;          // 当前y是偶数则
                                                // x++ y++
                                                // 否则 y++
                xx += v17;
                break;
              case 3:
                v12 = (yy++ & 1) != 0;          // 当前y是奇数则
                                                // x-- y++
                                                // 否则 y++
                xx -= v12;
                break;
              case 4:
                --xx;
                break;
              case 5:
                v19 = (yy-- & 1) != 0;          // 当前y是奇数则
                                                // x-- y--
                                                // 否则 y--
                xx -= v19;
                break;
              default:
                v18 = (yy-- & 1) == 0;          // 当前y是偶数数则
                                                // x++ y--
                                                // 否则 y--
                xx += v18;
                break;
            }
            if ( xx > 9 )
              break;
            if ( yy > 8 )
              break;
            v13 = &pz[yy][xx];                  // 一定要为0
            if ( *v13 )
              break;
            *v13 = 1;
            if ( i == 1 )
            {
              ++ii;
              xx_ = xx;
              p = ipt[ii];
              if ( p )
                goto LOOP;
              goto END;
            }
            sw = sw2;
          }
        }
        else
        {
          while ( is36 != ++jj )
          {
            if ( c0_z[jj] == p )
              goto LABEL_11;
          }
        }
      }
    }
    else
    {
END:
      tst = pz;
      cc = 0;
      do
      {
        v16 = tst + 1;                          // tst 90 个都为1
        do
        {
          cc += *(_BYTE *)tst == 0;
          tst = (char (*)[10])((char *)tst + 1);
        }
        while ( v16 != tst );
      }
      while ( &pz_end != (_UNKNOWN *)v16 );
      if ( !cc )
      {
        sub_4ABF30(&dword_4B8860, "Good job!", 9);
        sub_4AD980(&dword_4B8860);
        return 0;
      }
    }
  }
  sub_4ABF30(&dword_4B8860, "Try again...", 12);
  sub_4AD980(&dword_4B8860);

流程

  1. 有个 9*10 迷宫
    1
    2
    3
    4
    5
    6
    7
    8
    9
    0: S010010011
    1: 1100100100
    0: 0010111110
    1: 0110100100
    0: 0010010011
    1: 1101110101
    0: 0011110101
    1: 0110010101
    0: 0001001100
    S 为起点,左边标记了0为偶数行,1为奇数行,目的是不能碰到1的走过所有0
  2. 读入长度小于48字节的字符 ipt
  3. 令 i 为 ipt 下标,从 0 开始
  4. 令 j 为 ipt[i] 在 0-9A-Z 的序号
  5. 令 a = 5 - (i + j) % 6,b = (i + j/6) % 6,a、b 为运动连续两步运动
  6. 运动方向对应图
    1
    2
    3
    5(1行)    ↑0(1行)/5(0行)    ↗0(0行)
    4                            1
    3(1行)    ↓2(1行)/3(0行)    ↘2(0行)
    括号内是行动所在行的限定

解法

  1. 先人肉出运动描述:1234321234321101210050543450501210121234322321,推测出输入有23位

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
r = "1234321234321101210050543450501210121234322321"
z = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
s = ""
for i in xrange(23):
    a = ord(r[i*2]) -ord('0')
    b = ord(r[i*2+1]) -ord('0')
    t = False
 
    for j in xrange(36):
        if a == 5 - (i + j) % 6 and b == (i + j/6) % 6:
            assert not t # 测试唯一解
            t = True
            s += z[j]
print s

[培训]《安卓高级研修班(网课)》月薪三万计划

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回