首页
论坛
课程
招聘
[Reverse] [原创]2021美团CTF-Re-100mazes
2021-5-26 01:55 2478

[Reverse] [原创]2021美团CTF-Re-100mazes

2021-5-26 01:55
2478

100mazes

0

 

开头就先总结一下这篇文章学到了什么吧

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
总结:
一. 使用capstone对二进制文件进行指令解析
"""
先以rb形式打开文件,然后.read()读取赋值给变量
然后binary = data[addr: addr+0x666]这种指令是取出要解析的那一段代码的机器码
md = Cs(CS_ARCH_X86, CS_MODE_64)   设置解析模式为X86架构下的64位
 
for i in md.disasm(binary, addr):
# 第一个参数是机器码Byte数据,第二个参数是这段代码的"基地址".
该函数为反汇编到一条错误的指令为止
 
解析出指令:ins = "0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str)       
# 地址信息、助记符、操作数字符串
 
然后接下来就是匹配指令,比如:(获取到自己想要的那些指令,操作数等)
if 'mov    byte ptr [rbp' in ins:
    pass
if 'mov    dword ptr [rbp' in ins:
  pass
...
 
二.数据结构-图;图的遍历算法BFS,DFS(仅此肯定是不够的,之后还得加深)
 
三.使用DFS算法自动走迷宫的python脚本写法:(一般情况的思路)
solve(map, startX, startY, direct, path):
#传入的参数有map,开始位置的坐标,控制方向的字符,和走过的path字符串(path是为了返回的)
 
if len(path) == 15:
    return True, path
#通过走过的路径长度来判断是否返回
 
然后外面还必须有个checkValid来检测走到的位置是否合法
def checkValid(map, x, y):       # 检测某个坐标是否合法
    if x < 0 or y < 0 or x > 24 or y > 24:
        return False
    return map[y * 25 + x] == ord('.')
 
使用checkValid的方法
几个if条件进行判断(也就是查找每一个邻接结点)
根据对应的移动来+-坐标,然后作为参数传入checkValid进行检测,如果这个点合法
就将按照这种移动方法移动的下一个点的坐标和这种移动方法的操作字符都append下来
例:all_dir.append((startX - 1, startY, direct[2]))
 
之后for i in all_dir
逐渐取出所有的可能走的方向,然后进行递归
for dir in all_dir:                         # 这个循环存在的意义是为了避免可以有多条路线
    result = solve(map, dir[0], dir[1], direct, path + dir[2])   
# 递归到下一个点,并将上一个点的方向控制符加到路线中
 
"""

一:分析

1. 逻辑分析

拿到之后打开发现就是100张地图,然后将走出来的总长度为1500的路线md5得到flag

 

查看发现基本上100个maze的大体流程基本都是相同的

 

我们先分析其中一个就可以

 

maze1:

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
unsigned __int64 maze_1(void)
{
  char v321[624]; // [rsp+6h] [rbp-C6Ah] BYREF
  char direction[5]; // [rsp+276h] [rbp-9FAh] BYREF
  char input_char; // [rsp+27Bh] [rbp-9F5h]
  int col; // [rsp+27Ch] [rbp-9F4h]
  int line; // [rsp+280h] [rbp-9F0h]
  int v326; // [rsp+284h] [rbp-9ECh]
  int v327; // [rsp+288h] [rbp-9E8h]
  int i; // [rsp+28Ch] [rbp-9E4h]
  int v329; // [rsp+290h] [rbp-9E0h]
  int v330; // [rsp+294h] [rbp-9DCh]
  char *table1; // [rsp+298h] [rbp-9D8h]
  int table2[626]; // [rsp+2A0h] [rbp-9D0h] BYREF
  unsigned __int64 v333; // [rsp+C68h] [rbp-8h]
 
  v333 = __readfsqword(0x28u);
  v321[0] = 0xB0;
  v321[1] = 0x70;
  v321[20x8D;
  .............此处省略一些赋值的代码
  __asm { rdrand  rax }
  v321[605] = -127;
  v321[606] = 126;
  v321[607] = 96;
  v321[608] = -110;
  v321[609] = 12;
  v321[610] = 32;
  __asm { rdrand  rax }
  v321[611] = -65;
  __asm { rdrand  rax }
  v321[612] = -95;
  __asm { rdrand  rax }
  v321[613] = 62;
  __asm { rdrand  rax }
  v321[614] = -19;
  __asm { rdrand  rax }
  v321[615] = 6;
  v321[616] = 13;
  v321[617] = 95;
  __asm { rdrand  rax }
  v321[618] = -13;
  v321[619] = 44;
  __asm { rdrand  rax }
  v321[620] = 58;
  __asm { rdrand  rax }
  v321[621] = 93;
  v321[622] = 53;
  v321[623] = -9;
  qmemcpy(direction, "kgMp9", sizeof(direction));
  qmemcpy(table2, dword_A7420, 0x9C0uLL);
  table2[624] = 65;
  table1 = v321;
  col = 4;
  line = 24;
  v326 = 4;
  v327 = 24;
  for ( i = 0; i <= 14; ++i )                   // 循环15
  {
    v329 = col;
    v330 = line;
    input_char = getchar();                     // 读入单个字符
    if ( input_char == direction[1] )           // g 上移
    {
      --line;
    }
    else if ( input_char == direction[2] )      // M 下移
    {
      ++line;
    }
    else if ( input_char == direction[3] )      // p 左移
    {
      --col;
    }
    else
    {
      if ( input_char != direction[4] )         // 9 右移
        exit(0);
      ++col;
    }
    if ( col < 0
      || line < 0
      || col > 24
      || line > 24                              // 行列的下标最多24,说明这是一个25*25的maze
      || ((unsigned __int8)table1[25 * line + col] ^ table2[25 * line + col]) != '.'// 两个表异或得到真正的表,这里是在检测走的路不是'.'
      || col == v326 && line == v327 )          // 判断是否还在起点
    {
      exit(0);
    }
    v326 = v329;
    v327 = v330;
  }
  return __readfsqword(0x28u) ^ v333;
}

主要的逻辑就是,前面先mov给table1进行赋值,然后赋我们的"方向盘",然后赋我们的table2

 

之后用循环来走15次,说明每个迷宫走出来的字符串都是长度为15,最后加了个if条件将table1和table2异或之后来进行判断,说明将两个table异或之后才能得到真正的maze

 

逻辑不难,但是由于是100个迷宫,提取数据和解析等人工难以解决

 

下面我们先分析每个函数的汇编指令有些什么相似之处

2. 指令分析

思路:先分析函数的共同点,用capstone来解析指令并自动提取出我们的数据

 

首先我们发现,table1的赋值都是这种指令:

1
2
3
4
5
6
7
8
.text:0000000000001CFE                 mov     [rbp+var_A54], 4Ah ; 'J'
.text:0000000000001D05                 mov     [rbp+var_A53], 0ACh
.text:0000000000001D0C                 mov     [rbp+var_A52], 0DFh
.text:0000000000001D13                 mov     [rbp+var_A51], 0ABh
.text:0000000000001D1A                 mov     [rbp+var_A50], 0ADh
.text:0000000000001D21                 mov     [rbp+var_A4F], 0A1h
.text:0000000000001D28                 mov     [rbp+var_A4E], 0ABh
.text:0000000000001D2F                 mov     [rbp+var_A4D], 1Ah

共625条

 

赋完table1之后,紧接着之后又发现了几条同样的指令,这几个指令就是赋我们的"方向盘"的

1
2
3
4
.text:0000000000002069                 mov     [rbp+var_9F9], 67h ; 'g'
.text:0000000000002070                 mov     [rbp+var_9F8], 4Dh ; 'M'
.text:0000000000002077                 mov     [rbp+var_9F7], 70h ; 'p'
.text:000000000000207E                 mov     [rbp+var_9F6], 39h ; '9'

table2的解析:

 

发现 table2 有一条 lea 指令用来传址,并且是相对 eip 的寻址

1
0xa4e6c:    lea    rax, [rip + 0x3ed6d]

map2 的地址为 0xa4e6c(当前地址)+7(指令长度)+ 0x3ed6d, 直接解析 625 个 int 即可

 

然后继续分析,发现两条mov dword ptr [rbp + xxx], xxx 赋值起点坐标

3. 使用capstone解析地图数据的函数decode

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
# _*_ coding:utf-8 _*_
# @功能描述:
# @程序作者:SYJ
# @版权信息:Reversed By SYJ
# @版本信息:0.0.0
 
from capstone import *
import struct
 
def decode(offset):
    data_bin = open('E:\\SYJ\\COMPETITIONS\\2021美团\\100mazes\\100mazes', 'rb').read()
    data = data_bin[offset: offset + 0x2010]               # 获取到要分析的那一段
    md = Cs(CS_ARCH_X86, CS_MODE_64)                       # X86_64
    inscnt = 0
    inscnt2 = 0
    map1 = []
    map2 = []
    start_position = []
    for i in md.disasm(data, offset):      # 第一个参数是机器码Byte数据,第二个参数是这段代码的"基地址".该函数为反汇编到一条错误的指令为止
        ins = "0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str)        # 地址信息、助记符、操作数字符串
        if 'mov    byte ptr [rbp' in ins:     # 匹配向table1传数据的指令 和 向初始位置赋值的指令
            if inscnt < 629:
                map1.append(int(i.op_str.split(', ')[1], 16))            # 取操作数['byte ptr [rbp..', '0xC4']列表的第二个
            inscnt += 1
 
        if 'mov    dword ptr [rbp' in ins:    # 匹配start_position位置的赋值指令
            if inscnt2 < 2:
                start_position.append(int(i.op_str.split(', ')[1], 16))
            inscnt2 += 1
 
        if 'lea    rax, [rip +' in ins:
            off1 = i.op_str[11:-1]         # 取到和rip的偏移
            off1 = int(off1, 16) + i.address + 7     # 取到table2的地址,i.address是取到当前rip的地址,7是当前指令的长度
            map2_data = data_bin[off1: off1 + 4 * 625]   # 625个dword数据
            for j in range(625):
                # 将b'\x0f\x00\x00\x00'这种bytes类型数据解包成unsigned_int的数据
                map2.append(struct.unpack("I", map2_data[j * 4: j * 4 + 4])[0])     # 解包成unsigned_int数据的元组后[0]取出元素
 
    real_map = []
    for i in range(625):
        real_map.append(map1[i] ^ map2[i])
    return real_map, bytearray(map1[-4:]), start_position
    # 返回异或得到的真正的地图,table1的最后四个元素的bytes形式(就是控制方向的四个元素),和开始位置的坐标

4. 使用dfs自动地图寻路

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
def checkValid(map, x, y):       # 检测某个坐标是否合法
    if x < 0 or y < 0 or x > 24 or y > 24:
        return False
    return map[y * 25 + x] == ord('.')
 
def solve(map, startX, startY, direct, path):
    map[startY * 25 + startX] = ord('*')     # 每次走一步就将其走过位置填为'*'(maze的墙的构成元素)
    if len(path) == 15:          # 每次递归调用之后判断是否已经走了15步,每个迷宫只走15步
        return True, path
 
    all_dir = []
    i = 0
    if checkValid(map, startX, startY - 1):              # 查找每一个邻接结点
        all_dir.append((startX, startY - 1, direct[0]))
    if checkValid(map, startX, startY + 1):
        all_dir.append((startX, startY + 1, direct[1]))
    if checkValid(map, startX - 1, startY):
        all_dir.append((startX - 1, startY, direct[2]))
    if checkValid(map, startX + 1, startY):
        all_dir.append((startX + 1, startY, direct[3]))    # 将checkValid的坐标和行进的字符append到all_dir
 
    for dir in all_dir:                         # 这个循环存在的意义是为了避免可以有多条路线
        result = solve(map, dir[0], dir[1], direct, path + dir[2])    # 递归到下一个点,并将上一个点的方向控制符加到路线中
        if result[0] == True:
            return result
    return False, ''

二:完整脚本

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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# _*_ coding:utf-8 _*_
# @功能描述:
# @程序作者:SYJ
# @版权信息:Reversed By SYJ
# @版本信息:0.0.0
 
from capstone import *
import struct
 
def decode(offset):
    data_bin = open('E:\\SYJ\\COMPETITIONS\\2021美团\\100mazes\\100mazes', 'rb').read()
    data = data_bin[offset: offset + 0x2010]               # 获取到要分析的那一段
    md = Cs(CS_ARCH_X86, CS_MODE_64)                       # X86_64
    inscnt = 0
    inscnt2 = 0
    map1 = []
    map2 = []
    start_position = []
    for i in md.disasm(data, offset):      # 第一个参数是机器码Byte数据,第二个参数是这段代码的"基地址".该函数为反汇编到一条错误的指令为止
        ins = "0x%x:\t%s\t%s" % (i.address, i.mnemonic, i.op_str)        # 地址信息、助记符、操作数字符串
        if 'mov    byte ptr [rbp' in ins:     # 匹配向table1传数据的指令 和 向初始位置赋值的指令
            if inscnt < 629:
                map1.append(int(i.op_str.split(', ')[1], 16))            # 取操作数['byte ptr [rbp..', '0xC4']列表的第二个
            inscnt += 1
 
        if 'mov    dword ptr [rbp' in ins:    # 匹配start_position位置的赋值指令
            if inscnt2 < 2:
                start_position.append(int(i.op_str.split(', ')[1], 16))
            inscnt2 += 1
 
        if 'lea    rax, [rip +' in ins:
            off1 = i.op_str[11:-1]         # 取到和rip的偏移
            off1 = int(off1, 16) + i.address + 7     # 取到table2的地址,i.address是取到当前rip的地址,7是当前指令的长度
            map2_data = data_bin[off1: off1 + 4 * 625]   # 625个dword数据
            for j in range(625):
                # 将b'\x0f\x00\x00\x00'这种bytes类型数据解包成unsigned_int的数据
                map2.append(struct.unpack("I", map2_data[j * 4: j * 4 + 4])[0])     # 解包成unsigned_int数据的元组后[0]取出元素
 
    real_map = []
    for i in range(625):
        real_map.append(map1[i] ^ map2[i])
    return real_map, bytearray(map1[-4:]), start_position
    # 返回异或得到的真正的地图,table1的最后四个元素的bytes形式(就是控制方向的四个元素),和开始位置的坐标
 
def checkValid(map, x, y):       # 检测某个坐标是否合法
    if x < 0 or y < 0 or x > 24 or y > 24:
        return False
    return map[y * 25 + x] == ord('.')
 
def solve(map, startX, startY, direct, path):
    map[startY * 25 + startX] = ord('*')     # 每次走一步就将其走过位置填为'*'(maze的墙的构成元素)
    if len(path) == 15:          # 每次递归调用之后判断是否已经走了15步,每个迷宫只走15步
        return True, path
 
    all_dir = []
    i = 0
    if checkValid(map, startX, startY - 1):              # 查找每一个邻接结点
        all_dir.append((startX, startY - 1, direct[0]))
    if checkValid(map, startX, startY + 1):
        all_dir.append((startX, startY + 1, direct[1]))
    if checkValid(map, startX - 1, startY):
        all_dir.append((startX - 1, startY, direct[2]))
    if checkValid(map, startX + 1, startY):
        all_dir.append((startX + 1, startY, direct[3]))    # 将checkValid的坐标和行进的字符append到all_dir
 
    for dir in all_dir:                         # 这个循环存在的意义是为了避免可以有多条路线
        result = solve(map, dir[0], dir[1], direct, path + dir[2])    # 递归到下一个点,并将上一个点的方向控制符加到路线中
        if result[0] == True:
            return result
    return False, ''
 
def printMap(map):
    for i in range(25):
        line = ''
        for j in range(25):
            line += chr(map[i * 25 + j])
        print(line)
 
# 这一段数据是从ida的函数窗口直接复制出来的
funcs = """maze_1(void)    .text    000000000000078A    00001AC5    00000C78    00000000    R    .    .    .    .    B    T    .
maze_2(void)    .text    000000000000224F    00001A8F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_3(void)    .text    0000000000003CDE    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_4(void)    .text    000000000000574F    00001A2F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_5(void)    .text    000000000000717E    00001A53    00000C78    00000000    R    .    .    .    .    B    T    .
maze_6(void)    .text    0000000000008BD1    00001A59    00000C78    00000000    R    .    .    .    .    B    T    .
maze_7(void)    .text    000000000000A62A    00001A2F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_8(void)    .text    000000000000C059    00001B25    00000C78    00000000    R    .    .    .    .    B    T    .
maze_9(void)    .text    000000000000DB7E    00001A23    00000C78    00000000    R    .    .    .    .    B    T    .
maze_10(void)    .text    000000000000F5A1    00001A83    00000C78    00000000    R    .    .    .    .    B    T    .
maze_11(void)    .text    0000000000011024    000019B1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_12(void)    .text    00000000000129D5    00001A47    00000C78    00000000    R    .    .    .    .    B    T    .
maze_13(void)    .text    000000000001441C    00001A83    00000C78    00000000    R    .    .    .    .    B    T    .
maze_14(void)    .text    0000000000015E9F    00001A6B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_15(void)    .text    000000000001790A    00001A7D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_16(void)    .text    0000000000019387    00001AD7    00000C78    00000000    R    .    .    .    .    B    T    .
maze_17(void)    .text    000000000001AE5E    00001A9B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_18(void)    .text    000000000001C8F9    00001AB3    00000C78    00000000    R    .    .    .    .    B    T    .
maze_19(void)    .text    000000000001E3AC    00001AAD    00000C78    00000000    R    .    .    .    .    B    T    .
maze_20(void)    .text    000000000001FE59    00001B2B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_21(void)    .text    0000000000021984    00001A9B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_22(void)    .text    000000000002341F    00001A9B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_23(void)    .text    0000000000024EBA    00001ADD    00000C78    00000000    R    .    .    .    .    B    T    .
maze_24(void)    .text    0000000000026997    00001A59    00000C78    00000000    R    .    .    .    .    B    T    .
maze_25(void)    .text    00000000000283F0    00001A35    00000C78    00000000    R    .    .    .    .    B    T    .
maze_26(void)    .text    0000000000029E25    00001A83    00000C78    00000000    R    .    .    .    .    B    T    .
maze_27(void)    .text    000000000002B8A8    00001A47    00000C78    00000000    R    .    .    .    .    B    T    .
maze_28(void)    .text    000000000002D2EF    00001AB9    00000C78    00000000    R    .    .    .    .    B    T    .
maze_29(void)    .text    000000000002EDA8    00001AB3    00000C78    00000000    R    .    .    .    .    B    T    .
maze_30(void)    .text    000000000003085B    00001AA1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_31(void)    .text    00000000000322FC    00001A89    00000C78    00000000    R    .    .    .    .    B    T    .
maze_32(void)    .text    0000000000033D85    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_33(void)    .text    000000000003581A    00001A7D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_34(void)    .text    0000000000037297    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_35(void)    .text    0000000000038D2C    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_36(void)    .text    000000000003A79D    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_37(void)    .text    000000000003C232    00001A7D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_38(void)    .text    000000000003DCAF    00001A8F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_39(void)    .text    000000000003F73E    00001A77    00000C78    00000000    R    .    .    .    .    B    T    .
maze_40(void)    .text    00000000000411B5    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_41(void)    .text    0000000000042C4A    00001AA1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_42(void)    .text    00000000000446EB    00001A53    00000C78    00000000    R    .    .    .    .    B    T    .
maze_43(void)    .text    000000000004613E    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_44(void)    .text    0000000000047BD3    00001A6B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_45(void)    .text    000000000004963E    00001B4F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_46(void)    .text    000000000004B18D    00001A53    00000C78    00000000    R    .    .    .    .    B    T    .
maze_47(void)    .text    000000000004CBE0    00001A65    00000C78    00000000    R    .    .    .    .    B    T    .
maze_48(void)    .text    000000000004E645    00001A83    00000C78    00000000    R    .    .    .    .    B    T    .
maze_49(void)    .text    00000000000500C8    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_50(void)    .text    0000000000051B5D    00001B0D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_51(void)    .text    000000000005366A    00001A6B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_52(void)    .text    00000000000550D5    00001ABF    00000C78    00000000    R    .    .    .    .    B    T    .
maze_53(void)    .text    0000000000056B94    00001AE9    00000C78    00000000    R    .    .    .    .    B    T    .
maze_54(void)    .text    000000000005867D    00001A3B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_55(void)    .text    000000000005A0B8    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_56(void)    .text    000000000005BB4D    00001A59    00000C78    00000000    R    .    .    .    .    B    T    .
maze_57(void)    .text    000000000005D5A6    00001AD1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_58(void)    .text    000000000005F077    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_59(void)    .text    0000000000060AE8    00001A35    00000C78    00000000    R    .    .    .    .    B    T    .
maze_60(void)    .text    000000000006251D    00001A59    00000C78    00000000    R    .    .    .    .    B    T    .
maze_61(void)    .text    0000000000063F76    00001A4D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_62(void)    .text    00000000000659C3    00001AD7    00000C78    00000000    R    .    .    .    .    B    T    .
maze_63(void)    .text    000000000006749A    00001AD7    00000C78    00000000    R    .    .    .    .    B    T    .
maze_64(void)    .text    0000000000068F71    00001AA1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_65(void)    .text    000000000006AA12    00001AD1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_66(void)    .text    000000000006C4E3    00001B25    00000C78    00000000    R    .    .    .    .    B    T    .
maze_67(void)    .text    000000000006E008    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_68(void)    .text    000000000006FA9D    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_69(void)    .text    000000000007150E    00001AD7    00000C78    00000000    R    .    .    .    .    B    T    .
maze_70(void)    .text    0000000000072FE5    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_71(void)    .text    0000000000074A56    00001AD7    00000C78    00000000    R    .    .    .    .    B    T    .
maze_72(void)    .text    000000000007652D    00001AF5    00000C78    00000000    R    .    .    .    .    B    T    .
maze_73(void)    .text    0000000000078022    00001AFB    00000C78    00000000    R    .    .    .    .    B    T    .
maze_74(void)    .text    0000000000079B1D    00001AB9    00000C78    00000000    R    .    .    .    .    B    T    .
maze_75(void)    .text    000000000007B5D6    00001AB9    00000C78    00000000    R    .    .    .    .    B    T    .
maze_76(void)    .text    000000000007D08F    00001AF5    00000C78    00000000    R    .    .    .    .    B    T    .
maze_77(void)    .text    000000000007EB84    00001A47    00000C78    00000000    R    .    .    .    .    B    T    .
maze_78(void)    .text    00000000000805CB    000019FF    00000C78    00000000    R    .    .    .    .    B    T    .
maze_79(void)    .text    0000000000081FCA    00001AF5    00000C78    00000000    R    .    .    .    .    B    T    .
maze_80(void)    .text    0000000000083ABF    00001ACB    00000C78    00000000    R    .    .    .    .    B    T    .
maze_81(void)    .text    000000000008558A    00001A8F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_82(void)    .text    0000000000087019    00001AAD    00000C78    00000000    R    .    .    .    .    B    T    .
maze_83(void)    .text    0000000000088AC6    00001ABF    00000C78    00000000    R    .    .    .    .    B    T    .
maze_84(void)    .text    000000000008A585    00001A3B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_85(void)    .text    000000000008BFC0    00001A77    00000C78    00000000    R    .    .    .    .    B    T    .
maze_86(void)    .text    000000000008DA37    00001AD1    00000C78    00000000    R    .    .    .    .    B    T    .
maze_87(void)    .text    000000000008F508    00001ACB    00000C78    00000000    R    .    .    .    .    B    T    .
maze_88(void)    .text    0000000000090FD3    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_89(void)    .text    0000000000092A68    00001B0D    00000C78    00000000    R    .    .    .    .    B    T    .
maze_90(void)    .text    0000000000094575    00001ABF    00000C78    00000000    R    .    .    .    .    B    T    .
maze_91(void)    .text    0000000000096034    00001A71    00000C78    00000000    R    .    .    .    .    B    T    .
maze_92(void)    .text    0000000000097AA5    00001ACB    00000C78    00000000    R    .    .    .    .    B    T    .
maze_93(void)    .text    0000000000099570    00001A11    00000C78    00000000    R    .    .    .    .    B    T    .
maze_94(void)    .text    000000000009AF81    00001A9B    00000C78    00000000    R    .    .    .    .    B    T    .
maze_95(void)    .text    000000000009CA1C    00001B07    00000C78    00000000    R    .    .    .    .    B    T    .
maze_96(void)    .text    000000000009E523    00001A95    00000C78    00000000    R    .    .    .    .    B    T    .
maze_97(void)    .text    000000000009FFB8    00001AAD    00000C78    00000000    R    .    .    .    .    B    T    .
maze_98(void)    .text    00000000000A1A65    00001AF5    00000C78    00000000    R    .    .    .    .    B    T    .
maze_99(void)    .text    00000000000A355A    00001B1F    00000C78    00000000    R    .    .    .    .    B    T    .
maze_100(void)    .text    00000000000A5079    00001A2F    00000C78    00000000    R    .    .    .    .    B    T    ."""
 
total = ''
for ll in funcs.splitlines():
    ll = ll.split("    ")
    addr = int(ll[2], 16)                        # 获取函数的起始地址
    realmap, dirs, start_point = decode(addr)    # dirs是table1的最后四个值,也就是操作字符的bytes形式
    print("process:" + hex(addr))
    rr = solve(realmap, start_point[0], start_point[1], dirs.decode('utf-8'), '')
    # 第一个参数是真正的maze,二三个参数是起始坐标,第四个是移动操作的字符
    total += rr[1]
 
import hashlib
mm = hashlib.md5(total.encode('utf-8')).hexdigest()
 
print(total)
print(len(total))
d = mm
print("flag{%s-%s-%s-%s-%s}" % (d[0:8], d[8:12], d[12:16], d[16:20], d[20:32]))

运行结果:

1
2
3
4
5
6
...............
process:0xa355a
process:0xa5079
99g99M9999ggggpCSSSOOlOllOlOOOrrrnnnnrnntttntTmm44m44K444m44DDJJxJJDJJDDDDStjtjjttPtPPPtPPQvQQyQQQyQQQvvc11KKDKDDAADDDAA4444jjjYjYYY99YQQQxxQQxxnxnnxn66A6AANNWNNWNNWY1YYY1Y11QQQQ1QBBxxhhhhhhxhxhxPyPPVVVPPPyyPPVpzzzzpzzhhhhhzhuuggguururrr00rssXX3X3X33t3t3tqKqqKKEEKEEEwEw1zzjzjjojojoojomKmmmKKXXXKKXKXQQFFQFFQQ8Q88QQllRRlljjllllRlRo666o6oooommQmQJJRJJJSJSJSJSJJBFFBFBFBBFBFFkFCCGGCCXCCXXvvXXxEEGGGWGWWGGWWx4464644QQQ44Q44HyyHHhHHHyyHHHyeFFFFeFFuuuuuukTbTTFTFTFF55555LfffLffffoooonnXXPPGPPGPGGGGPPBooBoBB4BBB44B4TkTTkkkGG0GG00GZZdZddAdAAAAAAW8d88HHHHHnnHnnHJJNJNJNJJJYYIYYNN00ppppQpQpppQzTTTzTzTTTTZZfZUppppeppUUpUUmUVMVVlVlVVVMVMVVL9L99O99999O9OOBQBQQSSSSSSSSgSjgjgjgggguggjggvpvppp88p8pppppojojjooooojojjjTcTTTTuTTcTTTTTmnnDnDDSDDnDnDn3C3C3C3C333jjhjxxZZxZxZxxxxxxxWWUUWWUUUWWEWEEo00o000EE00E000KKEKEKEEEEKKEE9viiviiivvggggg200V000VVeVV0VVVvvuu1u1u1u111NNCkCCCkkk55I5555zFzz9z99eeeeeFe5BBBBppBppppFppMMMMMMaaanannna4gggg4ggtttssssfHfHHDDHDDDDHDDcqcqqqqqqtqqccIppzpzzppzppzzUzrvvrvrrtrtrrvrrCppZppCppCCQCCQOkOkOOSSOSS66SSZvvvvOOTTTOOOTOvvKKvvGvvvGGaaaYddMMdMdMMjMjMMQOQOO555LL5LLLQvvBvBBfBBfffBBvdzdzdzdzzfzfzffzXXXhXhXhXhhhhXADAAAAffHHffAfAKQKQQKKpppKpKKphhJJhJhJhJJJPPqoooHHHoHoHooDoDC3333CC6CC666C6LOLOLOLOLOOLOOOxexxee3ee33eeeerrvrrrrvvYYYYYYvvvvvGGGGGwGwGGJnJJnnnnwwwywwnncccncnccUcUUUdOrOOOrOrrYYYNYYW0WW00W00WWWFWFzzQzQQzzaaasaazbGbGGLLYLYLYYbYsfssfffffmmfmfmWWKKVKKVKKWKKVKVsVsVsVVVsVVtVtZ4Z4444MMMMMjjZddnddaaddnnddaaIIIIhIIIIIiiiiW3ffff88ff3f3ff8FfFFfFfFFSFFfFFkkrrrsrsrrsssppiMiiWiiMMiiMiMi
1500
flag{60e92557-3e0c-3123-6eb1-c57005fc0655}

[注意] 招人!base上海,课程运营、市场多个坑位等你投递!

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