R3CTF 2025 Reverse-Neon Deceit WriteUp

3.1k 词

程序本身不管是否附加调试器运行都只会输出hello world,text中有一段被塞入了长达200KB的nop指令,且系统函数貌似全都被替换成了不正常的函数名称。

经过观察发现了被塞入nop指令的函数行为很可疑,尝试不包含nop部分进行反编译发现不成功,仔细研究后发现是一个混淆系统函数verrx无法被ida正确理解导致其后的函数产生截断,重新反编译后认为地址0x55555556C597开始的函数是一个整体,一直到main的上方。

此外程序多次调用了一个字符串=>866>83>;).(;9?6.(;9?(;>;(?h(h并xor了0x5A,异或后发现是各种调试器的名称,因此这是一个基于名称查找的反调试,可以patch这个字符串进行反反调试。

main中的exit也是用于混淆的函数,实际并不会退出,更可靠的方式还是观察retn指令:

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
.text:00005555555AD6D8 sub_5555555AD6D8 proc near              ; DATA XREF: start+18↑o
.text:00005555555AD6D8
.text:00005555555AD6D8 var_4= dword ptr -4
.text:00005555555AD6D8
.text:00005555555AD6D8 ; __unwind { // 555555554000
.text:00005555555AD6D8 endbr64
.text:00005555555AD6DC push rbp
.text:00005555555AD6DD mov rbp, rsp
.text:00005555555AD6E0 sub rsp, 10h
.text:00005555555AD6E4 mov [rbp+var_4], edi
.text:00005555555AD6E7 lea rax, ptr ; "hello world"
.text:00005555555AD6EE mov rdi, rax ; s
.text:00005555555AD6F1 call _puts
.text:00005555555AD6F6 mov edi, 0 ; status
.text:00005555555AD6FB call _exit
.text:00005555555AD700 ; ---------------------------------------------------------------------------
.text:00005555555AD700 cmp [rbp+var_4], 7
.text:00005555555AD704 jnz short loc_5555555AD712
.text:00005555555AD706 mov eax, 0
.text:00005555555AD70B call sub_55555556C597
.text:00005555555AD710 ; ---------------------------------------------------------------------------
.text:00005555555AD710 jmp short loc_5555555AD72B
.text:00005555555AD712 ; ---------------------------------------------------------------------------
.text:00005555555AD712
.text:00005555555AD712 loc_5555555AD712: ; CODE XREF: sub_5555555AD6D8+2C↑j
.text:00005555555AD712 lea rax, ptr ; "hello world"
.text:00005555555AD719 mov rdi, rax ; ptr
.text:00005555555AD71C call _realloc
.text:00005555555AD721 mov edi, 0 ; utmpx
.text:00005555555AD726 call _pututxline
.text:00005555555AD72B
.text:00005555555AD72B loc_5555555AD72B: ; CODE XREF: sub_5555555AD6D8+38↑j
.text:00005555555AD72B mov eax, 0
.text:00005555555AD730 leave
.text:00005555555AD731 retn
.text:00005555555AD731 ; } // starts at 5555555AD6D8
.text:00005555555AD731 sub_5555555AD6D8 endp
.text:00005555555AD731
.text:00005555555AD731 _text ends
.text:00005555555AD731

这里main中有一个cmp [rbp+var_4], 7比较了输入参数的个数,当个数为6时进入下面的sub_55555556C597执行正确逻辑,可以patch jnz为jz方便运行,接下来对sub_55555556C597进行分析:

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
.text:000055555556C597 endbr64
.text:000055555556C59B push rbp
.text:000055555556C59C mov rbp, rsp
.text:000055555556C59F lea r11, [rsp+var_6000]
.text:000055555556C5A7
.text:000055555556C5A7 loc_55555556C5A7: ; CODE XREF: sub_55555556C597+1F↓j
.text:000055555556C5A7 sub rsp, 1000h
.text:000055555556C5AE or [rsp+1000h+var_1000], 0
.text:000055555556C5B3 cmp rsp, r11
.text:000055555556C5B6 jnz short loc_55555556C5A7
.text:000055555556C5B8 sub rsp, 0A50h
.text:000055555556C5BF mov rax, fs:28h
.text:000055555556C5C8 mov [rbp+var_8], rax
.text:000055555556C5CC xor eax, eax
.text:000055555556C5CE mov ecx, 0
.text:000055555556C5D3 mov edx, 1 ; arg
.text:000055555556C5D8 mov esi, 0 ; format
.text:000055555556C5DD mov edi, 0 ; s
.text:000055555556C5E2 mov eax, 0
.text:000055555556C5E7 call _vfwprintf
.text:000055555556C5EC test rax, rax
.text:000055555556C5EF jns short loc_55555556C605
.text:000055555556C5F1 mov esi, 2 ; modes
.text:000055555556C5F6 lea rax, dirp
.text:000055555556C5FD mov rdi, rax
.text:000055555556C600 call _cimag
.text:000055555556C605
.text:000055555556C605 loc_55555556C605: ; CODE XREF: sub_55555556C597+58↑j
.text:000055555556C605 nop
.text:000055555556C606 mov qword ptr [rbp+format], 0
...

经过调试发现这里call _vfwprintf是一个反调试,下面的jns用于判断,实际观察后发现这个函数中大部分用于退出函数(也就是不满足条件或者检测到调试器等)的结构都形如这个部分:

1
2
3
4
5
6
.text:000055555556C5EC test    rax, rax
.text:000055555556C5EF jns short loc_55555556C605
.text:000055555556C5F1 mov esi, 2 ; modes
.text:000055555556C5F6 lea rax, dirp
.text:000055555556C5FD mov rdi, rax
.text:000055555556C600 call _cimag

猜测cimag是exit,可以根据这个结构推断哪些地方可能有检验,这里把jns patch成jnz,继续执行,发现下面有一个迷宫地图生成和验证逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.text:000055555556CA3F mov     eax, [rbp+pid]
.text:000055555556CA45 mov dword ptr [rbp+termios_p], eax
.text:000055555556CA4B mov eax, dword ptr [rbp+termios_p]
.text:000055555556CA51 mov edi, eax ; termios_p
.text:000055555556CA53 call _cfsetispeed
.text:000055555556CA58 lea rax, [rbp+loadavg]
.text:000055555556CA5F mov rdi, rax
.text:000055555556CA62 call sub_55555556B712
.text:000055555556CA67 lea rax, [rbp+loadavg]
.text:000055555556CA6E mov rdi, rax ; loadavg
.text:000055555556CA71 call sub_55555556BA5F
.text:000055555556CA76 mov [rbp+var_6A48], eax
.text:000055555556CA7C mov [rbp+var_672D], 20h ; ' '
.text:000055555556CA83 mov [rbp+var_6365], 20h ; ' '
.text:000055555556CA8A call _wordexp
.text:000055555556CA8F call _getloadavg
.text:000055555556CA94 call _sqrtl
.text:000055555556CA99 mov edi, 0
.text:000055555556CA9E call _nexttoward
.text:000055555556CAA3 lea rax, dirp
.text:000055555556CAAA mov rdi, rax
.text:000055555556CAAD call _rintl

生成的地图为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
###################################################
# # # # #
# ##### ### # # # ####### # # # ####### # ### # # #
# # # # # # # # # # # # # #
# ### ### # # # ########### # # # # # ########### #
# # # # # # # # # # # # # # # #
# # # # # # # ### # # # # # ##### # # ### ##### # #
# # # # # # # # # # # # # # # # # #
# # ### # # # # ##### # ### # ########### ####### #
# # # # # # # # # # # # # # # # # # # # # #
######################### # # # # # # # # # # # # #
# # # # #
####### ############# ##### # # # ### # ### ### # #
# # # # # # # # # # #
# # # # # ############# ###########################
# # # # # # #
# ### # # # # ### # # # # # # # # # # ### ### ### #
# # # # # # # # # # # # # # # # # # # # #
# # ##### # # # # ##### # # # # # ### # # # # # # #
# # # # # # # # # # # # # # # # # # # #
###################################################

其中左上角应该是入口,右下角应该是出口,路径为:dddddddddddddddddddddddddssddssssssssaaaaaassddssddddddddddddddddddddddddddssssd (长度为80)

继续查看后续的逻辑,之后打印了整体界面然后等待输入:

1
2
.text:000055555556CF94 call    _drem
.text:000055555556CF99 call _sqrtl

这里_drem是读取输入,接下来就进入了最关键的路径判定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.text:000055555556D211 loc_55555556D211:                       ; CODE XREF: sub_55555556C597+C77↑j
.text:000055555556D211 lea rax, [rbp+loadavg]
.text:000055555556D218 mov [rbp+var_6980], rax
.text:000055555556D21F lea rax, [rbp+modes]
.text:000055555556D226 mov [rbp+buffer], rax
.text:000055555556D22D mov eax, [rbp+var_6A48]
.text:000055555556D233 mov [rbp+var_6A28], eax
.text:000055555556D239 mov rax, [rbp+buffer]
.text:000055555556D240 mov rdi, rax ; buffer
.text:000055555556D243 call _getutent_r
.text:000055555556D248 mov [rbp+var_6970], rax
.text:000055555556D24F cmp [rbp+var_6970], 0
.text:000055555556D257 jz short loc_55555556D268
.text:000055555556D259 mov rax, [rbp+var_6970]
.text:000055555556D260 and eax, 1
.text:000055555556D263 test rax, rax
.text:000055555556D266 jz short loc_55555556D27C
.text:000055555556D268
.text:000055555556D268 loc_55555556D268: ; CODE XREF: sub_55555556C597+CC0↑j
.text:000055555556D268 mov esi, 1
.text:000055555556D26D lea rax, dirp
.text:000055555556D274 mov rdi, rax
.text:000055555556D277 call _cimag
.text:000055555556D27C

这里buffer是输入的内容,_getutent_r貌似是求长度,rax中是目标长度0x50(80)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.text:000055555556D27C loc_55555556D27C:                       ; CODE XREF: sub_55555556C597+CCF↑j
.text:000055555556D27C mov rax, [rbp+var_6970]
.text:000055555556D283 shr rax, 1
.text:000055555556D286 mov [rbp+var_6968], rax
.text:000055555556D28D mov rax, [rbp+var_6968]
.text:000055555556D294 shl rax, 2
.text:000055555556D298 mov [rbp+var_6960], rax
.text:000055555556D29F mov eax, [rbp+var_6A28]
.text:000055555556D2A5 cdqe
.text:000055555556D2A7 cmp [rbp+var_6960], rax
.text:000055555556D2AE jb short loc_55555556D2C8
.text:000055555556D2B0 mov eax, [rbp+var_6A28]
.text:000055555556D2B6 cdqe
.text:000055555556D2B8 mov rdx, [rbp+var_6960]
.text:000055555556D2BF sub rdx, 4
.text:000055555556D2C3 cmp rax, rdx
.text:000055555556D2C6 ja short loc_55555556D2DC
.text:000055555556D2C8
.text:000055555556D2C8 loc_55555556D2C8: ; CODE XREF: sub_55555556C597+D17↑j
.text:000055555556D2C8 mov esi, 1
.text:000055555556D2CD lea rax, dirp
.text:000055555556D2D4 mov rdi, rax
.text:000055555556D2D7 call _cimag
.text:000055555556D2DC

这里比较了长度,[rbp+var_6960]中的值是输入的值的长度的2倍,所以实际上需要输入的是40字节,带入40个字节后发现成功通过,继续分析:

1
2
3
4
5
6
7
8
9
10
11
12
.text:000055555556D2DC loc_55555556D2DC:                       ; CODE XREF: sub_55555556C597+D2F↑j
.text:000055555556D2DC mov rax, [rbp+var_6968]
.text:000055555556D2E3 mov rdi, rax
.text:000055555556D2E6 call _nextafterl
.text:000055555556D2EB mov [rbp+var_6958], rax
.text:000055555556D2F2 cmp [rbp+var_6958], 0
.text:000055555556D2FA jnz short loc_55555556D310
.text:000055555556D2FC mov esi, 1
.text:000055555556D301 lea rax, dirp
.text:000055555556D308 mov rdi, rax
.text:000055555556D30B call _cimag
.text:000055555556D310

这里貌似在确认路径长度不为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
.text:000055555556D310 loc_55555556D310:                       ; CODE XREF: sub_55555556C597+D63↑j
.text:000055555556D310 mov [rbp+var_6950], 0
.text:000055555556D31B jmp short loc_55555556D38A
.text:000055555556D31D ; ---------------------------------------------------------------------------
.text:000055555556D31D
.text:000055555556D31D loc_55555556D31D: ; CODE XREF: sub_55555556C597+E01↓j
.text:000055555556D31D mov rdx, [rbp+var_6958]
.text:000055555556D324 mov rax, [rbp+var_6950]
.text:000055555556D32B add rdx, rax ; optname
.text:000055555556D32E mov rax, [rbp+var_6950]
.text:000055555556D335 lea rcx, [rax+rax]
.text:000055555556D339 mov rax, [rbp+buffer]
.text:000055555556D340 add rax, rcx
.text:000055555556D343 lea rcx, level ; "%2hhx"
.text:000055555556D34A mov rsi, rcx ; level
.text:000055555556D34D mov rdi, rax ; fd
.text:000055555556D350 mov eax, 0
.text:000055555556D355 call _getsockopt
.text:000055555556D35A cmp eax, 1
.text:000055555556D35D jz short loc_55555556D382
.text:000055555556D35F mov rax, [rbp+var_6958]
.text:000055555556D366 mov rdi, rax
.text:000055555556D369 call _nextup
.text:000055555556D36E mov esi, 1
.text:000055555556D373 lea rax, dirp
.text:000055555556D37A mov rdi, rax
.text:000055555556D37D call _cimag
.text:000055555556D382
.text:000055555556D382 loc_55555556D382: ; CODE XREF: sub_55555556C597+DC6↑j
.text:000055555556D382 add [rbp+var_6950], 1
.text:000055555556D38A
.text:000055555556D38A loc_55555556D38A: ; CODE XREF: sub_55555556C597+D84↑j
.text:000055555556D38A mov rax, [rbp+var_6968]
.text:000055555556D391 cmp rax, [rbp+var_6950]
.text:000055555556D398 ja short loc_55555556D31D

这里进行了0x14(20)次循环,按2字符合并为一个字节的十六进制进行读取,继续分析:

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
.text:000055555556D39A lea     rdx, [rbp+var_6330]
.text:000055555556D3A1 mov eax, 0
.text:000055555556D3A6 mov ecx, 85h
.text:000055555556D3AB mov rdi, rdx
.text:000055555556D3AE rep stosq
.text:000055555556D3B1 mov rdx, rdi
.text:000055555556D3B4 mov [rdx], eax
.text:000055555556D3B6 add rdx, 4
.text:000055555556D3BA mov [rdx], ax
.text:000055555556D3BD add rdx, 2
.text:000055555556D3C1 mov [rdx], al
.text:000055555556D3C3 add rdx, 1
.text:000055555556D3C7 mov dword ptr [rbp+var_6940], 1
.text:000055555556D3D1 mov dword ptr [rbp+var_6940+4], 0
.text:000055555556D3DB mov eax, dword ptr [rbp+var_6940]
.text:000055555556D3E1 mov edx, dword ptr [rbp+var_6940+4]
.text:000055555556D3E7 movsxd rcx, edx
.text:000055555556D3EA movsxd rdx, eax
.text:000055555556D3ED mov rax, rdx
.text:000055555556D3F0 add rax, rax
.text:000055555556D3F3 add rax, rdx
.text:000055555556D3F6 mov rdx, rax
.text:000055555556D3F9 shl rdx, 4
.text:000055555556D3FD add rax, rdx
.text:000055555556D400 add rax, rbp
.text:000055555556D403 add rax, rcx
.text:000055555556D406 sub rax, 6330h
.text:000055555556D40C mov byte ptr [rax], 1
.text:000055555556D40F mov [rbp+var_6A24], 0
.text:000055555556D419 mov [rbp+var_6948], 0
.text:000055555556D424 jmp loc_55555556D64C
...
.text:000055555556D64C loc_55555556D64C: ; CODE XREF: sub_55555556C597+E8D↑j
.text:000055555556D64C mov rax, [rbp+var_6968]
.text:000055555556D653 cmp rax, [rbp+var_6948]
.text:000055555556D65A ja loc_55555556D429

这里又是一个20次循环,进入了真正的走迷宫的逻辑:

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
.text:000055555556D429 ; ---------------------------------------------------------------------------
.text:000055555556D429
.text:000055555556D429 loc_55555556D429: ; CODE XREF: sub_55555556C597+10C3↓j
.text:000055555556D429 mov [rbp+var_6A20], 0 ;对于每个字节处理4次
.text:000055555556D433 jmp loc_55555556D634
...
.text:000055555556D634
.text:000055555556D634 loc_55555556D634: ; CODE XREF: sub_55555556C597+E9C↑j
.text:000055555556D634 cmp [rbp+var_6A20], 3 ;达到4次后jmp出去
.text:000055555556D63B jle loc_55555556D438 ;进入每个字节的处理逻辑
.text:000055555556D641 jmp short loc_55555556D644

.text:000055555556D438 ; ---------------------------------------------------------------------------
.text:000055555556D438
.text:000055555556D438 loc_55555556D438: ; CODE XREF: sub_55555556C597+10A4↓j
.text:000055555556D438 mov eax, [rbp+var_6A28]
.text:000055555556D43E cmp eax, [rbp+var_6A24]
.text:000055555556D444 jle loc_55555556D643
.text:000055555556D44A mov rdx, [rbp+var_6958]
.text:000055555556D451 mov rax, [rbp+var_6948]
.text:000055555556D458 add rax, rdx
.text:000055555556D45B movzx eax, byte ptr [rax]
.text:000055555556D45E movzx edx, al ;edx就是输入的字节
.text:000055555556D461 mov eax, 3
.text:000055555556D466 sub eax, [rbp+var_6A20]
.text:000055555556D46C add eax, eax
.text:000055555556D46E mov ecx, eax
.text:000055555556D470 sar edx, cl ;第一次是右移6
.text:000055555556D472 mov eax, edx
.text:000055555556D474 and eax, 3 ;取2位
.text:000055555556D477 mov [rbp+var_6A1C], eax
.text:000055555556D47D mov rax, [rbp+var_6940]
.text:000055555556D484 mov [rbp+var_6938], rax ;这里进入一系列cmp比较
.text:000055555556D48B cmp [rbp+var_6A1C], 3
.text:000055555556D492 jz short loc_55555556D4F6
.text:000055555556D494 cmp [rbp+var_6A1C], 3
.text:000055555556D49B jg short loc_55555556D506
.text:000055555556D49D cmp [rbp+var_6A1C], 2
.text:000055555556D4A4 jz short loc_55555556D4E5
.text:000055555556D4A6 cmp [rbp+var_6A1C], 2
.text:000055555556D4AD jg short loc_55555556D506
.text:000055555556D4AF cmp [rbp+var_6A1C], 0
.text:000055555556D4B6 jz short loc_55555556D4C3
.text:000055555556D4B8 cmp [rbp+var_6A1C], 1
.text:000055555556D4BF jz short loc_55555556D4D4
.text:000055555556D4C1 jmp short loc_55555556D506
.text:000055555556D4C3 ; ---------------------------------------------------------------------------
.text:000055555556D4C3
.text:000055555556D4C3 loc_55555556D4C3: ; CODE XREF: sub_55555556C597+F1F↑j
.text:000055555556D4C3 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D4C9 sub eax, 1
.text:000055555556D4CC mov dword ptr [rbp+var_6938], eax
.text:000055555556D4D2 jmp short loc_55555556D506
.text:000055555556D4D4 ; ---------------------------------------------------------------------------
.text:000055555556D4D4
.text:000055555556D4D4 loc_55555556D4D4: ; CODE XREF: sub_55555556C597+F28↑j
.text:000055555556D4D4 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D4DA add eax, 1
.text:000055555556D4DD mov dword ptr [rbp+var_6938], eax
.text:000055555556D4E3 jmp short loc_55555556D506
.text:000055555556D4E5 ; ---------------------------------------------------------------------------
.text:000055555556D4E5
.text:000055555556D4E5 loc_55555556D4E5: ; CODE XREF: sub_55555556C597+F0D↑j
.text:000055555556D4E5 mov eax, dword ptr [rbp+var_6938+4]
.text:000055555556D4EB sub eax, 1
.text:000055555556D4EE mov dword ptr [rbp+var_6938+4], eax
.text:000055555556D4F4 jmp short loc_55555556D506
.text:000055555556D4F6 ; ---------------------------------------------------------------------------
.text:000055555556D4F6
.text:000055555556D4F6 loc_55555556D4F6: ; CODE XREF: sub_55555556C597+EFB↑j
.text:000055555556D4F6 mov eax, dword ptr [rbp+var_6938+4]
.text:000055555556D4FC add eax, 1
.text:000055555556D4FF mov dword ptr [rbp+var_6938+4], eax
.text:000055555556D505 nop
.text:000055555556D506
.text:000055555556D506 loc_55555556D506: ; CODE XREF: sub_55555556C597+F04↑j
.text:000055555556D506 ; sub_55555556C597+F16↑j ...
.text:000055555556D506 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D50C test eax, eax
.text:000055555556D50E js short loc_55555556D566
.text:000055555556D510 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D516 cmp eax, 14h
.text:000055555556D519 jg short loc_55555556D566
.text:000055555556D51B mov eax, dword ptr [rbp+var_6938+4]
.text:000055555556D521 test eax, eax
.text:000055555556D523 js short loc_55555556D566
.text:000055555556D525 mov eax, dword ptr [rbp+var_6938+4]
.text:000055555556D52B cmp eax, 32h ; '2'
.text:000055555556D52E jg short loc_55555556D566
.text:000055555556D530 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D536 movsxd rdx, eax
.text:000055555556D539 mov rax, rdx
.text:000055555556D53C add rax, rax
.text:000055555556D53F add rax, rdx
.text:000055555556D542 mov rdx, rax
.text:000055555556D545 shl rdx, 4
.text:000055555556D549 add rdx, rax
.text:000055555556D54C mov rax, [rbp+var_6980]
.text:000055555556D553 add rdx, rax
.text:000055555556D556 mov eax, dword ptr [rbp+var_6938+4]
.text:000055555556D55C cdqe
.text:000055555556D55E movzx eax, byte ptr [rdx+rax]
.text:000055555556D562 cmp al, 23h ; '#'
.text:000055555556D564 jnz short loc_55555556D589
.text:000055555556D566
.text:000055555556D566 loc_55555556D566: ; CODE XREF: sub_55555556C597+F77↑j
.text:000055555556D566 ; sub_55555556C597+F82↑j ...
.text:000055555556D566 mov rax, [rbp+var_6958]
.text:000055555556D56D mov rdi, rax
.text:000055555556D570 call _nextup
.text:000055555556D575 mov esi, 1
.text:000055555556D57A lea rax, dirp
.text:000055555556D581 mov rdi, rax
.text:000055555556D584 call _cimag
.text:000055555556D589
.text:000055555556D589 loc_55555556D589: ; CODE XREF: sub_55555556C597+FCD↑j
.text:000055555556D589 mov eax, dword ptr [rbp+var_6938]
.text:000055555556D58F mov edx, dword ptr [rbp+var_6938+4]
.text:000055555556D595 movsxd rcx, edx
.text:000055555556D598 movsxd rdx, eax
.text:000055555556D59B mov rax, rdx
.text:000055555556D59E add rax, rax
.text:000055555556D5A1 add rax, rdx
.text:000055555556D5A4 mov rdx, rax
.text:000055555556D5A7 shl rdx, 4
.text:000055555556D5AB add rax, rdx
.text:000055555556D5AE add rax, rbp
.text:000055555556D5B1 add rax, rcx
.text:000055555556D5B4 sub rax, 6330h
.text:000055555556D5BA movzx eax, byte ptr [rax]
.text:000055555556D5BD test al, al
.text:000055555556D5BF jz short loc_55555556D5E4
.text:000055555556D5C1 mov rax, [rbp+var_6958]
.text:000055555556D5C8 mov rdi, rax
.text:000055555556D5CB call _nextup
.text:000055555556D5D0 mov esi, 1
.text:000055555556D5D5 lea rax, dirp
.text:000055555556D5DC mov rdi, rax
.text:000055555556D5DF call _cimag
.text:000055555556D5E4
.text:000055555556D5E4 loc_55555556D5E4: ; CODE XREF: sub_55555556C597+1028↑j
.text:000055555556D5E4 mov rax, [rbp+var_6938]
.text:000055555556D5EB mov [rbp+var_6940], rax
.text:000055555556D5F2 mov eax, dword ptr [rbp+var_6940]
.text:000055555556D5F8 mov edx, dword ptr [rbp+var_6940+4]
.text:000055555556D5FE movsxd rcx, edx
.text:000055555556D601 movsxd rdx, eax
.text:000055555556D604 mov rax, rdx
.text:000055555556D607 add rax, rax
.text:000055555556D60A add rax, rdx
.text:000055555556D60D mov rdx, rax
.text:000055555556D610 shl rdx, 4
.text:000055555556D614 add rax, rdx
.text:000055555556D617 add rax, rbp
.text:000055555556D61A add rax, rcx
.text:000055555556D61D sub rax, 6330h
.text:000055555556D623 mov byte ptr [rax], 1
.text:000055555556D626 add [rbp+var_6A24], 1
.text:000055555556D62D add [rbp+var_6A20], 1

.text:000055555556D643 ; ---------------------------------------------------------------------------
.text:000055555556D643
.text:000055555556D643 loc_55555556D643: ; CODE XREF: sub_55555556C597+EAD↑j
.text:000055555556D643 nop
.text:000055555556D644
.text:000055555556D644 loc_55555556D644: ; CODE XREF: sub_55555556C597+10AA↑j
.text:000055555556D644 add [rbp+var_6948], 1 ;加一次外层循环的值
.text:000055555556D64C
.text:000055555556D64C loc_55555556D64C: ; CODE XREF: sub_55555556C597+E8D↑j
.text:000055555556D64C mov rax, [rbp+var_6968]
.text:000055555556D653 cmp rax, [rbp+var_6948]
.text:000055555556D65A ja loc_55555556D429 ;20次处理

发现这里是如下逻辑:带入的每个字节被拆分成4个2位bit,按大端序排列,每个2位bit控制迷宫走向,00为w,01为s,10为a,11为d,var_6938为当前Y轴,var_6938+4为当前X轴

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
.text:000055555556D660 mov     rax, [rbp+var_6958]
.text:000055555556D667 mov rdi, rax
.text:000055555556D66A call _nextup
.text:000055555556D66F mov eax, dword ptr [rbp+var_6940]
.text:000055555556D675 cmp eax, 19
.text:000055555556D678 jnz short loc_55555556D685
.text:000055555556D67A mov eax, dword ptr [rbp+var_6940+4]
.text:000055555556D680 cmp eax, 50
.text:000055555556D683 jz short loc_55555556D699
.text:000055555556D685
.text:000055555556D685 loc_55555556D685: ; CODE XREF: sub_55555556C597+10E1↑j
.text:000055555556D685 mov esi, 1
.text:000055555556D68A lea rax, dirp
.text:000055555556D691 mov rdi, rax
.text:000055555556D694 call _cimag
.text:000055555556D699
.text:000055555556D699 loc_55555556D699: ; CODE XREF: sub_55555556C597+10EC↑j
.text:000055555556D699 nop
.text:000055555556D69A call _frexpf
.text:000055555556D69F lea rax, [rbp+modes]
.text:000055555556D6A6 mov rsi, rax ; n
.text:000055555556D6A9 lea rax, fd ; "R3CTF{%s}\n"
.text:000055555556D6B0 mov rdi, rax ; fd
.text:000055555556D6B3 mov eax, 0
.text:000055555556D6B8 call _listen

最终要达到的位置是19(20)的Y轴(var_6940)和50(51)的X轴(var_6940+4),根据之前的迷宫路径得到要输入的内容是ffffffffffffd7d5556aa97d7ffffffffffffd57,则flag为R3CTF{ffffffffffffd7d5556aa97d7ffffffffffffd57}.