强网杯初赛 2025 RE tradre

butterfly

AI直接秒了

  • 要求输入/输出文件各一个参数,然后把输入文件完整读进内存。
  • 追加 2 字节把原始长度写在缓冲区末尾(但这些额外字节不会写出)。
  • 以 8 字节为一块做“编码”:
    • 先与常量 MMXEncod 做字节级 XOR;
    • 把每个 16 位的两个字节互换;
    • 把 64 位视作整数左旋 1 bit;
    • 再加回同一个常量(字节级加法,模 256)。
      这样剩余的零头(不足 8 字节)保持原样。
  • 写到输出文件,同时生成 %s.key 文件,只包含文案 “MMXEncode2024 coding file: %s\n”——并没有保存任何真正的密钥。
  • 输出里看见的 encode.dat 就是转过一遍的结果。
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
#!/usr/bin/env python3
"""Recover the original plaintext from the challenge encoder output."""

from pathlib import Path
from typing import Iterable


KEY = b"MMXEncod" # first 8 bytes of the hard-coded encoder tag


def _swap_bytes_in_words(block: bytearray) -> None:
"""Swap the two bytes inside every 16-bit word (operation is its own inverse)."""
for i in range(0, 8, 2):
block[i], block[i + 1] = block[i + 1], block[i]


def _rotr64(value: int, bits: int) -> int:
"""Rotate a 64-bit integer right by the requested amount."""
mask = (1 << 64) - 1
bits %= 64
return ((value >> bits) | ((value << (64 - bits)) & mask)) & mask


def decode_blocks(data: Iterable[int]) -> bytes:
buf = bytearray(data)
full_blocks = len(buf) // 8
for block_index in range(full_blocks):
start = block_index * 8
end = start + 8
block = bytearray((buf[pos] - KEY[pos - start]) & 0xFF for pos in range(start, end))
rotated = _rotr64(int.from_bytes(block, "little"), 1).to_bytes(8, "little")
block = bytearray(rotated)
_swap_bytes_in_words(block)
for i in range(8):
block[i] ^= KEY[i]
buf[start:end] = block
return bytes(buf)


def main() -> None:
encoded_path = Path("encode.dat")
encoded = encoded_path.read_bytes()
decoded = decode_blocks(encoded)
try:
print(decoded.decode("utf-8"))
except UnicodeDecodeError:
print(decoded.hex())


if __name__ == "__main__":
main()

flag{butter_fly_mmx_encode_7778167}

这里记录下

lumina

Lumina 是 IDA Pro 引入的一项协作技术,用于在全球用户之间共享函数签名、反编译结果和命名信息。 它允许用户上传分析过的函数名称和原型,并从服务器自动同步他人上传的符号信息,从而显著提升逆向工程效率。

强网杯S9初赛Reverse writeup | xia0ji233’s blog

里面有,这里我自己的服务器过期了没续,下次用到了再说吧

tradre [复现]

做了很久,这道题怎么会有80个解的 😂

基于异常的虚拟机,并且父进程子进程交互,导致动调变得很困难。

写个IDApython脚本(找不到了,问AI应该很简单)dump一下所有的状态

image-20251030220904087

写个脚本去分析

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
#!/usr/bin/env python3
"""
Parse the VM node dump (dump.txt) and reconstruct each 0x20-byte node.

Each node layout, starting at base address B, is assumed to be:
B + 0x00: default branch pointer
B + 0x08: alternate branch pointer
B + 0x10: handler function pointer
B + 0x18: RIP target written into the traced child

The script prints a human-readable summary and writes a JSON file with
the structured information for downstream processing.
"""

from __future__ import annotations

import argparse
import json
import pathlib
from collections import defaultdict
from typing import Dict, Iterable, List, Tuple

Node = Dict[str, int]


def parse_dump_lines(lines: Iterable[str]) -> List[Tuple[int, int]]:
"""Parse "(0xADDR, 0xVALUE)" tuples into integer pairs."""
pairs: List[Tuple[int, int]] = []
for raw in lines:
line = raw.strip()
if not line or line.startswith("data") or line.startswith("]"):
continue
if line.endswith(","):
line = line[:-1]
if not (line.startswith("(") and line.endswith(")")):
continue
addr_str, value_str = line[1:-1].split(",", 1)
address = int(addr_str.strip(), 16)
value = int(value_str.strip(), 16)
pairs.append((address, value))
return pairs


def build_nodes(pairs: Iterable[Tuple[int, int]]) -> Dict[int, Node]:
"""Group 0x20-byte nodes and return a dict keyed by base address."""
grouped: Dict[int, Dict[int, int]] = defaultdict(dict)
for address, value in pairs:
base = address & ~0x1F # align down to 0x20-byte boundary
offset = address - base
grouped[base][offset] = value

nodes: Dict[int, Node] = {}
for base, fields in grouped.items():
node = {
"default": fields.get(0x00, 0),
"alternate": fields.get(0x08, 0),
"handler": fields.get(0x10, 0),
"rip": fields.get(0x18, 0),
}
nodes[base] = node
return dict(sorted(nodes.items()))


def fmt64(value: int) -> str:
"""Format 64-bit value as 0x-prefixed, zero-padded hex string."""
return f"0x{value:016x}"


def main() -> None:
parser = argparse.ArgumentParser(description="Parse VM node dump")
parser.add_argument(
"--input",
type=pathlib.Path,
default=pathlib.Path("dump.txt"),
help="path to dump file (default: dump.txt)",
)
parser.add_argument(
"--json",
type=pathlib.Path,
default=pathlib.Path("vm_nodes.json"),
help="where to store the parsed nodes as JSON",
)
parser.add_argument(
"--limit",
type=int,
default=10,
help="print only the first N nodes (0 to disable, default: 10)",
)
args = parser.parse_args()

pairs = parse_dump_lines(args.input.read_text().splitlines())
if not pairs:
raise SystemExit("No (address, value) tuples parsed – check input file.")

nodes = build_nodes(pairs)

# Prepare JSON with hexadecimal strings (more convenient for RE work).
json_friendly = {
fmt64(base): {
field: fmt64(value)
for field, value in node.items()
}
for base, node in nodes.items()
}
args.json.write_text(json.dumps(json_friendly, indent=2))

print(f"[+] Parsed {len(nodes)} nodes from {args.input}")
print(f"[+] JSON written to {args.json}")

if args.limit != 0:
print("[+] Preview:")
for idx, (base, node) in enumerate(nodes.items()):
if args.limit > 0 and idx >= args.limit:
break
default = node["default"]
alternate = node["alternate"]
handler = node["handler"]
rip = node["rip"]
print(
f" base={base:#010x} "
f"default={default:#018x} "
f"alt={alternate:#018x} "
f"handler={handler:#018x} "
f"rip={rip:#018x}"
)


if __name__ == "__main__":
main()

可以得到这样的json

image-20251030220958818

举个例子

1
2
3
4
5
g_vm_node_array(0x606AC0) 是虚拟机图的表头节点。该节点的四个槽:
+0(0x607160) 记录“返回后要走的节点”;
+8(0x607FE0) 指向真正的第一个业务节点;
+16(0x401EB4=vm_action_call) 告诉调度器把这个节点按“CALL”语义处理;
+24(0x4009F7) 是子进程当前的真实 RIP,对应 child_vm_payload 起点,也是第一条 int3。调度循环遇到这个节点时,会把 0x607160 压入自建调用栈,然后切到 0x607FE0,开始执行首个功能块。

那我们实际看看

image-20251031153814648

首先是第一个块执行的是4009F7,会一直执行到这里的int3

image-20251031153937148

下一个块是607fe0,实际的rip是4018ce

image-20251031154342900

image-20251031155225456

那么很简单我们只要根据我们导出来的这个表去把这个块的代码打印出来即可恢复逻辑(到int 3为止)

有两种方案

  1. 把这些代码复制出来,写个识别脚本
  2. 写个IDApython代码,去自动去做这个

我们可以写个IDApython

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
import ida_ua
import ida_lines
import ida_bytes
import idc

VM_NODE_BASE = 0x606AC0

VM_ACTION_RET = 0x401E96
VM_ACTION_JUMP = 0x401EA5
VM_ACTION_CALL = 0x401EB4

def read_node(ea):
ea = int(ea)
vals = []
for off in (0x0, 0x8, 0x10, 0x18):
q = idc.get_qword(ea + off)
vals.append(0 if q == idc.BADADDR else q)
return tuple(vals)

def dump_until_int3(start_ea):
ea = int(start_ea)
insn = ida_ua.insn_t()
while ida_ua.decode_insn(insn, ea) > 0:
if ida_bytes.get_byte(ea) == 0xCC:
break
line = ida_lines.generate_disasm_line(ea, ida_lines.GENDSM_REMOVE_TAGS)
if not line:
line = ida_lines.tag_remove(ida_lines.generate_disasm_line(ea, 0))
print(f"{ea:#x}: {line}")
ea += insn.size

def traverse_vm_blocks(start_node):
stack = [int(start_node)]
visited_nodes = set()
printed_blocks = set()
block_index = 0

while stack:
node_ea = stack.pop()
if not node_ea or node_ea in visited_nodes:
continue
visited_nodes.add(node_ea)

fallthrough, branch, handler, resume_rip = read_node(node_ea)

if resume_rip and resume_rip not in printed_blocks:
printed_blocks.add(resume_rip)
block_index += 1
print(f"\n== block #{block_index} @ {resume_rip:#x} ==")
dump_until_int3(resume_rip)

if handler not in (VM_ACTION_CALL, VM_ACTION_JUMP):
if branch:
stack.append(branch)
if fallthrough:
stack.append(fallthrough)
else:
if fallthrough:
stack.append(fallthrough)
if branch:
stack.append(branch)

# 执行遍历
traverse_vm_blocks(VM_NODE_BASE)

跑出来的结果有点问题,可以加个字典

image-20251101232035886

1
funcdict={0x400810:'_puts',0x400820:'__stack_chk_fail_ptr',0x400830:'_printf',0x400840:'_memset',0x400850:'_alarm',0x400860:'_read',0x400870:'_srand',0x400880:'_signal',0x400890:'_ptrace',0x4008A0:'_setvbuf',0x4008B0:'_perror',0x4008C0:'_atoi',0x4008D0:'_exit',0x4008E0:'_wait',0x4008F0:'_fork',0x400900:'_rand'}
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
import ida_ua
import ida_lines
import ida_bytes
import idc

VM_NODE_BASE = 0x606AC0

VM_ACTION_RET = 0x401E96
VM_ACTION_JUMP = 0x401EA5
VM_ACTION_CALL = 0x401EB4

FUNC_NAMES = {
0x400810: "_puts",
0x400820: "__stack_chk_fail",
0x400830: "_printf",
0x400840: "_memset",
0x400850: "_alarm",
0x400860: "_read",
0x400870: "_srand",
0x400880: "_signal",
0x400890: "_ptrace",
0x4008A0: "_setvbuf",
0x4008B0: "_perror",
0x4008C0: "_atoi",
0x4008D0: "_exit",
0x4008E0: "_wait",
0x4008F0: "_fork",
0x400900: "_rand",
}

COND_NAMES = {
0x401BC4: "if carry==1",
0x401C31: "if signed < 0",
0x401CA6: "if signed <= 0",
0x401D22: "if zf==0",
0x401D5B: "if zf==1",
0x401D94: "if sf==1",
0x401DCD: "if sf==0",
0x401E06: "if above",
0x401E4E: "if below-or-equal",
0x401F0C: "if signed > 0",
}

def fmt_ptr(addr):
if not addr:
return "0"
name = FUNC_NAMES.get(addr)
return name if name else f"{addr:#x}"

def read_node(ea):
ea = int(ea)
vals = []
for off in (0x0, 0x8, 0x10, 0x18):
q = idc.get_qword(ea + off)
vals.append(0 if q == idc.BADADDR else q)
return tuple(vals)

def dump_until_int3(start_ea):
ea = int(start_ea)
insn = ida_ua.insn_t()
while ida_ua.decode_insn(insn, ea) > 0:
if ida_bytes.get_byte(ea) == 0xCC:
break
line = ida_lines.generate_disasm_line(ea, ida_lines.GENDSM_REMOVE_TAGS)
if not line:
line = ida_lines.tag_remove(ida_lines.generate_disasm_line(ea, 0))
print(f" {ea:#x}: {line}")
ea += insn.size

def describe_handler(handler, fallthrough, branch):
if handler == VM_ACTION_RET:
print(f" ret -> {fmt_ptr(fallthrough)}")
elif handler == VM_ACTION_JUMP:
print(f" call {fmt_ptr(branch)}")
elif handler == VM_ACTION_CALL:
print(f" call {fmt_ptr(branch)})")
elif handler in COND_NAMES:
print(f" handler={handler:#x} {COND_NAMES[handler]}: false -> {fmt_ptr(fallthrough)}, true -> {fmt_ptr(branch)}")
elif handler:
print(f" handler={handler:#x}")
else:
# 没有 handler:按默认 next 走
pass

def traverse_vm_blocks(start_node):
stack = [int(start_node)]
visited_nodes = set()
printed_blocks = set()
block_index = 0

while stack:
node_ea = stack.pop()
if not node_ea or node_ea in visited_nodes:
continue
visited_nodes.add(node_ea)

fallthrough, branch, handler, resume_rip = read_node(node_ea)

if resume_rip and resume_rip not in printed_blocks:
printed_blocks.add(resume_rip)
block_index += 1
dump_until_int3(resume_rip)

describe_handler(handler, fallthrough, branch)

# 只要保留原先 DFS 逻辑即可;若 branch 是外部函数就不再深入
branch_is_external = branch in FUNC_NAMES
if handler not in (VM_ACTION_CALL, VM_ACTION_JUMP):
if branch and not branch_is_external:
stack.append(branch)
if fallthrough:
stack.append(fallthrough)
else:
if fallthrough:
stack.append(fallthrough)
if branch and not branch_is_external:
stack.append(branch)

# 执行遍历
traverse_vm_blocks(VM_NODE_BASE)

dump出是:

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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
0x4009f7: push    rbp; 核心 VM 负载:在大量自插入 int3 的混淆代码中执行真实逻辑,交由父进程调度。
0x4009f8: mov rbp, rsp
0x4009fb: push rbx
0x4009fc: sub rsp, 1E8h
0x400a03: mov rax, fs:28h
0x400a0c: mov [rbp+var_18], rax
0x400a10: xor eax, eax
0x400a12: mov [rbp+var_160], 0E2h
0x400a19: mov [rbp+var_15F], 8Bh
0x400a20: mov [rbp+var_15E], 55h ; 'U'
0x400a27: mov [rbp+var_15D], 38h ; '8'
0x400a2e: mov [rbp+var_15C], 69h ; 'i'
0x400a35: mov [rbp+var_15B], 0FAh
0x400a3c: mov [rbp+var_15A], 80h ; '€'
0x400a43: mov [rbp+var_159], 0C2h
0x400a4a: mov [rbp+var_158], 64h ; 'd'
0x400a51: mov [rbp+var_157], 4Eh ; 'N'
0x400a58: mov [rbp+var_156], 7Fh
0x400a5f: mov [rbp+var_155], 0E7h
0x400a66: mov [rbp+var_154], 13h
0x400a6d: mov [rbp+var_153], 6
0x400a74: mov [rbp+var_152], 14h
0x400a7b: mov [rbp+var_151], 0C5h
0x400a82: mov [rbp+var_150], 0C0h
0x400a89: mov [rbp+var_14F], 13h
0x400a90: mov [rbp+var_14E], 0D3h
0x400a97: mov [rbp+var_14D], 12h
0x400a9e: mov [rbp+var_14C], 6Bh ; 'k'
0x400aa5: mov [rbp+var_14B], 0BDh
0x400aac: mov [rbp+var_14A], 0F2h
0x400ab3: mov [rbp+var_149], 0C7h
0x400aba: mov [rbp+var_148], 88h
0x400ac1: mov [rbp+var_147], 44h ; 'D'
0x400ac8: mov [rbp+var_146], 3Eh ; '>'
0x400acf: mov [rbp+var_145], 9
0x400ad6: mov [rbp+var_144], 0E8h
0x400add: mov [rbp+var_143], 0A3h
0x400ae4: mov [rbp+var_142], 83h
0x400aeb: mov [rbp+var_141], 30h ; '0'
0x400af2: lea rax, [rbp+var_160]
0x400af9: mov rdi, rax
call 0x607fe0)
0x4018ce: push rbp
0x4018cf: mov rbp, rsp
0x4018d2: sub rsp, 20h
0x4018d6: mov [rbp+var_18], rdi
0x4018da: lea rdi, aOooooooooooooO; "ooooooooooooo "...
call _puts
0x401254: lea rdi, a88888888888Y88; "8' 888 `8 "...
call _puts
0x4012aa: lea rdi, a888OoooD8bOooo; " 888 oooo d8b .oooo. .oooo"...
call _puts
0x4012e7: lea rdi, a8888888pP88bD8; " 888 `888\"\"8P `P )88b d88'"...
call _puts
0x400e55: lea rdi, a888888Op888888; " 888 888 .oP\"888 888 "...
call _puts
0x400d45: lea rdi, a888888D8888888; " 888 888 d8( 888 888 "...
call _puts
0x400fc1: lea rdi, aO888oD888bY888; " o888o d888b `Y888\"\"8o `Y8b"...
call _puts
0x400bf8: mov edi, 10000h
call _srand
0x400fee: mov dword ptr [rbp+var_8], 0
0x400b7c: cmp dword ptr [rbp+var_8], 7
handler=0x401ca6 if signed <= 0: false -> 0x608000, true -> 0x607460
0x4018e2: nop
0x4018e3: leave
ret -> 0
0x4012b8: mov dword ptr [rbp+var_8+4], 0
0x4014d5: cmp dword ptr [rbp+var_8+4], 1Fh
handler=0x401ca6 if signed <= 0: false -> 0x607240, true -> 0x607da0
0x40117f: add dword ptr [rbp+var_8], 1
0x401726: mov eax, dword ptr [rbp+var_8]; 双层 S 盒与异或:对 32 字节状态数组做逐字节白盒运算
0x401729: shl eax, 5
0x40172c: mov edx, eax
0x40172e: mov eax, dword ptr [rbp+var_8+4]
0x401731: add eax, edx
0x401733: movsxd rdx, eax
0x401736: lea rax, g_sbox_forward
0x40173d: movzx esi, byte ptr [rdx+rax]
0x401741: mov eax, dword ptr [rbp+var_8+4]
0x401744: movsxd rdx, eax
0x401747: mov rax, [rbp+var_18]
0x40174b: add rax, rdx
0x40174e: movzx ecx, byte ptr [rax]
0x401751: mov eax, dword ptr [rbp+var_8]
0x401754: shl eax, 5
0x401757: mov edx, eax
0x401759: mov eax, dword ptr [rbp+var_8+4]
0x40175c: add eax, edx
0x40175e: xor ecx, esi
0x401760: movsxd rdx, eax
0x401763: lea rax, g_sbox_forward
0x40176a: mov [rdx+rax], cl
0x40176d: mov eax, dword ptr [rbp+var_8]
0x401770: shl eax, 5
0x401773: mov edx, eax
0x401775: mov eax, dword ptr [rbp+var_8+4]
0x401778: add eax, edx
0x40177a: movsxd rdx, eax
0x40177d: lea rax, g_sbox_inverse
0x401784: movzx esi, byte ptr [rdx+rax]
0x401788: mov eax, dword ptr [rbp+var_8+4]
0x40178b: movsxd rdx, eax
0x40178e: mov rax, [rbp+var_18]
0x401792: add rax, rdx
0x401795: movzx ecx, byte ptr [rax]
0x401798: mov eax, dword ptr [rbp+var_8]
0x40179b: shl eax, 5
0x40179e: mov edx, eax
0x4017a0: mov eax, dword ptr [rbp+var_8+4]
0x4017a3: add eax, edx
0x4017a5: xor ecx, esi
0x4017a7: movsxd rdx, eax
0x4017aa: lea rax, g_sbox_inverse
0x4017b1: mov [rdx+rax], cl
0x4017b4: add dword ptr [rbp+var_8+4], 1
0x401018: mov rax, cs:stdin
0x40101f: mov ecx, 0
0x401024: mov edx, 2
0x401029: mov esi, 0
0x40102e: mov rdi, rax
call _setvbuf
0x401184: mov rax, cs:stdout
0x40118b: mov ecx, 0
0x401190: mov edx, 2
0x401195: mov esi, 0
0x40119a: mov rdi, rax
call _setvbuf
0x40163e: mov rax, cs:stderr
0x401645: mov ecx, 0
0x40164a: mov edx, 2
0x40164f: mov esi, 0
0x401654: mov rdi, rax
call _setvbuf
0x400beb: lea rdi, aInputYourFlag; 准备输出提示字符串 "Input your flag"(调用路径由父进程调度触发)
0x400bf2: mov eax, 0
call _printf
0x4014ad: lea rax, [rbp+var_140]
0x4014b4: mov esi, 21h ; '!'
0x4014b9: mov rdi, rax
call 0x606dc0)
0x400d1f: push rbp
0x400d20: mov rbp, rsp
0x400d23: sub rsp, 30h
0x400d27: mov [rbp+var_28], rdi
0x400d2b: mov [rbp+var_2C], esi
0x400d2e: mov rax, fs:28h
0x400d37: mov [rbp+var_8], rax
0x400d3b: xor eax, eax
0x400d3d: mov [rbp+var_10], 0
0x4019a2: mov eax, [rbp+var_2C]
0x4019a5: sub eax, 1
0x4019a8: cmp [rbp+var_10], eax
handler=0x401c31 if signed < 0: false -> 0x607300, true -> 0x607740
0x401612: mov eax, [rbp+var_10]; 末尾补 0,构造最终字符串用于校验/输出
0x401615: movsxd rdx, eax
0x401618: mov rax, [rbp+var_28]
0x40161c: add rax, rdx
0x40161f: mov byte ptr [rax], 0
0x401622: mov eax, [rbp+var_10]
0x401625: mov rcx, [rbp+var_8]
0x401629: xor rcx, fs:28h
handler=0x401d5b if zf==1: false -> 0x607aa0, true -> 0x6070e0
call __stack_chk_fail
0x400ff9: leave
ret -> 0
0x40142f: lea rax, [rbp+var_18+7]
0x401433: mov edx, 1
0x401438: mov rsi, rax
0x40143b: mov edi, 0
call _read
0x401407: mov [rbp+var_C], eax
0x40140a: cmp [rbp+var_C], 0
handler=0x401f0c if signed > 0: false -> 0x606ae0, true -> 0x607540
0x400afd: mov edi, 0FFFFFFFFh
call _exit
0x401312: movzx eax, byte ptr [rbp+var_18+7]
0x401316: cmp al, 0Ah
handler=0x401d5b if zf==1: false -> 0x606f20, true -> 0x6074a0
0x400e22: mov eax, [rbp+var_10]
0x400e25: movsxd rdx, eax
0x400e28: mov rax, [rbp+var_28]
0x400e2c: add rdx, rax
0x400e2f: movzx eax, byte ptr [rbp+var_18+7]
0x400e33: mov [rdx], al
0x400e35: add [rbp+var_10], 1
0x4012c1: nop
0x40137f: mov [rbp+var_1E0], 0
0x400c7c: cmp [rbp+var_1E0], 0Fh
handler=0x401ca6 if signed <= 0: false -> 0x6072c0, true -> 0x607a80
0x4011c4: lea rax, [rbp+var_180]
0x4011cb: mov [rbp+var_198], rax
0x4011d2: lea rax, [rbp+var_110]
0x4011d9: mov [rbp+var_190], rax
0x4011e0: mov [rbp+var_1C8], 4
0x4011ea: mov [rbp+var_1C4], 0Ah
0x4011f4: mov [rbp+var_1C0], 0
0x401566: mov eax, [rbp+var_1C8]
0x40156c: shl eax, 2
0x40156f: cmp [rbp+var_1C0], eax
handler=0x401c31 if signed < 0: false -> 0x607200, true -> 0x607640
0x401073: mov eax, [rbp+var_1C8]
0x401079: mov [rbp+var_1C0], eax
0x4019b7: db 8Bh
0x4019bd: dq 1C083FFFFFE3C85h, 0FFFE40853902E0C1h
0x4019c0: dq 1C083FFFFFE3C85h, 0FFFE40853902E0C1h
0x4019c3: dq 1C083FFFFFE3C85h, 0FFFE40853902E0C1h
handler=0x401c31 if signed < 0: false -> 0x606da0, true -> 0x608080
0x400cdf: lea rax, [rbp+var_140]
0x400ce6: mov [rbp+var_1A8], rax
0x400ced: lea rax, [rbp+var_110]
0x400cf4: mov [rbp+var_1A0], rax
0x400cfb: mov [rbp+var_1D0], 0Ah
0x400d05: mov rcx, [rbp+var_1A0]
0x400d0c: mov rax, [rbp+var_1A8]
0x400d13: mov edx, 0
0x400d18: mov rsi, rcx
0x400d1b: mov rdi, rax
call 0x608060)
0x40193c: push rbp
0x40193d: mov rbp, rsp
0x401940: mov [rbp+var_18], rdi
0x401944: mov [rbp+var_20], rsi
0x401948: mov dword ptr [rbp+var_28+4], edx
0x40194b: mov dword ptr [rbp+var_8+4], 0
0x40148b: cmp dword ptr [rbp+var_8+4], 0Fh
handler=0x401ca6 if signed <= 0: false -> 0x606e20, true -> 0x6075c0
0x400d58: nop
0x400d59: pop rbp
ret -> 0
0x40133d: mov eax, dword ptr [rbp+var_8+4]
0x401340: movsxd rdx, eax
0x401343: mov rax, [rbp+var_18]
0x401347: add rax, rdx
0x40134a: movzx esi, byte ptr [rax]
0x40134d: mov eax, dword ptr [rbp+var_28+4]
0x401350: shl eax, 4
0x401353: mov edx, eax
0x401355: mov eax, dword ptr [rbp+var_8+4]
0x401358: add eax, edx
0x40135a: movsxd rdx, eax
0x40135d: mov rax, [rbp+var_20]
0x401361: add rax, rdx
0x401364: movzx ecx, byte ptr [rax]
0x401367: mov eax, dword ptr [rbp+var_8+4]
0x40136a: movsxd rdx, eax
0x40136d: mov rax, [rbp+var_18]
0x401371: add rax, rdx
0x401374: xor esi, ecx
0x401376: mov edx, esi
0x401378: mov [rax], dl
0x40137a: add dword ptr [rbp+var_8+4], 1
0x40151a: mov [rbp+var_1CC], 1
0x4018bc: mov eax, [rbp+var_1D0]
0x4018c2: sub eax, 1
0x4018c5: cmp [rbp+var_1CC], eax
handler=0x401ca6 if signed <= 0: false -> 0x6073a0, true -> 0x606e00
0x401249: mov rax, [rbp+var_1A8]
0x401250: mov rdi, rax
call 0x607e00)
0x4017d1: push rbp
0x4017d2: mov rbp, rsp
0x4017d5: mov [rbp+var_18], rdi
0x4017d9: mov dword ptr [rbp+var_8+4], 0
0x40138b: cmp dword ptr [rbp+var_8+4], 0Fh
handler=0x401ca6 if signed <= 0: false -> 0x6070c0, true -> 0x606e40
0x400ff6: nop
0x400ff7: pop rbp
ret -> 0
0x400d5b: mov eax, dword ptr [rbp+var_8+4]
0x400d5e: movsxd rdx, eax
0x400d61: mov rax, [rbp+var_18]
0x400d65: add rax, rdx
0x400d68: movzx eax, byte ptr [rax]
0x400d6b: movzx eax, al
0x400d6e: mov edx, dword ptr [rbp+var_8+4]
0x400d71: movsxd rcx, edx
0x400d74: mov rdx, [rbp+var_18]
0x400d78: add rcx, rdx
0x400d7b: movsxd rdx, eax
0x400d7e: lea rax, g_sbox_forward
0x400d85: movzx eax, byte ptr [rdx+rax]
0x400d89: mov [rcx], al
0x400d8b: add dword ptr [rbp+var_8+4], 1
0x40129f: mov rax, [rbp+var_1A8]
0x4012a6: mov rdi, rax
call 0x607220)
0x401080: push rbp
0x401081: mov rbp, rsp
0x401084: mov [rbp+var_18], rdi
0x401088: mov rax, [rbp+var_18]
0x40108c: movzx eax, byte ptr [rax+1]
0x401090: mov byte ptr [rbp+var_8+7], al
0x401093: mov rax, [rbp+var_18]
0x401097: lea rdx, [rax+1]
0x40109b: mov rax, [rbp+var_18]
0x40109f: movzx eax, byte ptr [rax+5]
0x4010a3: mov [rdx], al
0x4010a5: mov rax, [rbp+var_18]
0x4010a9: lea rdx, [rax+5]
0x4010ad: mov rax, [rbp+var_18]
0x4010b1: movzx eax, byte ptr [rax+9]
0x4010b5: mov [rdx], al
0x4010b7: mov rax, [rbp+var_18]
0x4010bb: lea rdx, [rax+9]
0x4010bf: mov rax, [rbp+var_18]
0x4010c3: movzx eax, byte ptr [rax+0Dh]
0x4010c7: mov [rdx], al
0x4010c9: mov rax, [rbp+var_18]
0x4010cd: lea rdx, [rax+0Dh]
0x4010d1: movzx eax, byte ptr [rbp+var_8+7]
0x4010d5: mov [rdx], al
0x4010d7: mov rax, [rbp+var_18]
0x4010db: movzx eax, byte ptr [rax+2]
0x4010df: mov byte ptr [rbp+var_8+7], al
0x4010e2: mov rax, [rbp+var_18]
0x4010e6: lea rdx, [rax+2]
0x4010ea: mov rax, [rbp+var_18]
0x4010ee: movzx eax, byte ptr [rax+0Ah]
0x4010f2: mov [rdx], al
0x4010f4: mov rax, [rbp+var_18]
0x4010f8: lea rdx, [rax+0Ah]
0x4010fc: movzx eax, byte ptr [rbp+var_8+7]
0x401100: mov [rdx], al
0x401102: mov rax, [rbp+var_18]
0x401106: movzx eax, byte ptr [rax+6]
0x40110a: mov byte ptr [rbp+var_8+7], al
0x40110d: mov rax, [rbp+var_18]
0x401111: lea rdx, [rax+6]
0x401115: mov rax, [rbp+var_18]
0x401119: movzx eax, byte ptr [rax+0Eh]
0x40111d: mov [rdx], al
0x40111f: mov rax, [rbp+var_18]
0x401123: lea rdx, [rax+0Eh]
0x401127: movzx eax, byte ptr [rbp+var_8+7]
0x40112b: mov [rdx], al
0x40112d: mov rax, [rbp+var_18]
0x401131: movzx eax, byte ptr [rax+0Fh]
0x401135: mov byte ptr [rbp+var_8+7], al
0x401138: mov rax, [rbp+var_18]
0x40113c: lea rdx, [rax+0Fh]
0x401140: mov rax, [rbp+var_18]
0x401144: movzx eax, byte ptr [rax+0Bh]
0x401148: mov [rdx], al
0x40114a: mov rax, [rbp+var_18]
0x40114e: lea rdx, [rax+0Bh]
0x401152: mov rax, [rbp+var_18]
0x401156: movzx eax, byte ptr [rax+7]
0x40115a: mov [rdx], al
0x40115c: mov rax, [rbp+var_18]
0x401160: lea rdx, [rax+7]
0x401164: mov rax, [rbp+var_18]
0x401168: movzx eax, byte ptr [rax+3]
0x40116c: mov [rdx], al
0x40116e: mov rax, [rbp+var_18]
0x401172: lea rdx, [rax+3]
0x401176: movzx eax, byte ptr [rbp+var_8+7]
0x40117a: mov [rdx], al
0x40117c: nop
0x40117d: pop rbp
ret -> 0
0x4012ef: mov edx, [rbp+var_1D0]
0x4012f5: mov rcx, [rbp+var_1A0]
0x4012fc: mov rax, [rbp+var_1A8]
0x401303: mov rsi, rcx
0x401306: mov rdi, rax
call 0x608060)
0x40195e: lea rax, [rbp+var_140]
0x401965: add rax, 10h
0x401969: mov [rbp+var_1B8], rax
0x401970: lea rax, [rbp+var_110]
0x401977: mov [rbp+var_1B0], rax
0x40197e: mov [rbp+var_1D8], 0Ah
0x401988: mov rcx, [rbp+var_1B0]
0x40198f: mov rax, [rbp+var_1B8]
0x401996: mov edx, 0
0x40199b: mov rsi, rcx
0x40199e: mov rdi, rax
call 0x608060)
0x401843: mov [rbp+var_1D4], 1
0x400fb1: mov eax, [rbp+var_1D8]
0x400fb7: sub eax, 1
0x400fba: cmp [rbp+var_1D4], eax
handler=0x401ca6 if signed <= 0: false -> 0x606b20, true -> 0x6080e0
0x400b6e: mov rax, [rbp+var_1B8]
0x400b75: mov rdi, rax
call 0x607e00)
0x4017b9: mov rax, [rbp+var_1B8]
0x4017c0: mov rdi, rax
call 0x607220)
0x40122e: mov edx, [rbp+var_1D8]
0x401234: mov rcx, [rbp+var_1B0]
0x40123b: mov rax, [rbp+var_1B8]
0x401242: mov rsi, rcx
0x401245: mov rdi, rax
call 0x608060)
call _rand
0x400b79: mov edi, eax
call _srand
0x4014dc: mov [rbp+var_1DC], 0
0x4014e6: mov [rbp+var_1E0], 0
0x401713: cmp [rbp+var_1E0], 0Fh
handler=0x401ca6 if signed <= 0: false -> 0x6072e0, true -> 0x606cc0
0x4011ff: mov [rbp+var_1E0], 0
0x400c74: cmp [rbp+var_1E0], 0Fh
handler=0x401ca6 if signed <= 0: false -> 0x607b60, true -> 0x606ee0
0x4015b2: cmp [rbp+var_1DC], 1Fh
handler=0x401ca6 if signed <= 0: false -> 0x607660, true -> 0x607e60
0x4013c3: mov rax, cs:g_validation_lut
0x4013ca: mov rdi, rax
call _puts
0x400f5c: mov rax, [rbp+var_18]
0x400f60: xor rax, fs:28h
handler=0x401d5b if zf==1: false -> 0x607100, true -> 0x606d40
call __stack_chk_fail
0x400c8c: add rsp, 1E8h
0x400c93: pop rbx
0x400c94: pop rbp
ret -> 0
0x401802: mov rax, cs:g_ascii_banner_table
0x401809: mov rdi, rax
call _puts
0x4018cc: nop
0x400def: mov eax, [rbp+var_1E0]
0x400df5: add eax, 10h
0x400df8: cdqe
0x400dfa: movzx edx, [rbp+rax+var_140]
0x400e02: mov eax, [rbp+var_1E0]
0x400e08: add eax, 10h
0x400e0b: cdqe
0x400e0d: movzx eax, [rbp+rax+var_160]
0x400e15: xor eax, edx
0x400e17: mov ebx, eax
call _rand
0x400bbe: xor eax, ebx
0x400bc0: mov [rbp+var_1E2], al
0x400bc6: movzx edx, [rbp+var_1E2]
0x400bcd: mov rcx, cs:g_validation_lut
0x400bd4: mov eax, [rbp+var_1E0]
0x400bda: add eax, 11h
0x400bdd: cdqe
0x400bdf: add rax, rcx
0x400be2: movzx eax, byte ptr [rax]
0x400be5: movsx eax, al
0x400be8: cmp edx, eax
handler=0x401d22 if zf==0: false -> 0x607140, true -> 0x608120
0x401010: add [rbp+var_1DC], 1
0x4019ca: dw 8583h, 0FE20h, 0FFFFh
0x400c4f: mov eax, [rbp+var_1E0]
0x400c55: cdqe
0x400c57: movzx edx, [rbp+rax+var_140]
0x400c5f: mov eax, [rbp+var_1E0]
0x400c65: cdqe
0x400c67: movzx eax, [rbp+rax+var_160]
0x400c6f: xor eax, edx
0x400c71: mov ebx, eax
call _rand
0x400b81: xor eax, ebx
0x400b83: mov [rbp+var_1E2], al
0x400b89: movzx edx, [rbp+var_1E2]
0x400b90: mov rcx, cs:g_validation_lut
0x400b97: mov eax, [rbp+var_1E0]
0x400b9d: cdqe
0x400b9f: add rax, rcx
0x400ba2: movzx eax, byte ptr [rax]
0x400ba5: movsx eax, al
0x400ba8: cmp edx, eax
handler=0x401d22 if zf==0: false -> 0x6077c0, true -> 0x607ea0
0x401490: add [rbp+var_1DC], 1
0x401831: add [rbp+var_1E0], 1
0x4019ac: dd 48858B48h
0x4019b3: db 0FEh, 0FFh, 0FFh, 48h, 89h, 0C7h, 0CCh
call 0x607e00)
0x40171b: mov rax, [rbp+var_1B8]
0x401722: mov rdi, rax
call 0x607220)
0x401633: mov rax, [rbp+var_1B8]
0x40163a: mov rdi, rax
call 0x607e80)
0x40180d: push rbp
0x40180e: mov rbp, rsp
0x401811: push rbx
0x401812: sub rsp, 28h
0x401816: mov [rbp+var_28], rdi
0x40181a: mov rax, fs:28h
0x401823: mov [rbp+var_18], rax
0x401827: xor eax, eax
0x401829: mov dword ptr [rbp+var_20], 0
0x4018b7: cmp dword ptr [rbp+var_20], 3
handler=0x401ca6 if signed <= 0: false -> 0x606c60, true -> 0x607de0
0x400c25: nop
0x400c26: mov rax, [rbp+var_18]
0x400c2a: xor rax, fs:28h
handler=0x401d5b if zf==1: false -> 0x607600, true -> 0x607d20
call __stack_chk_fail
0x401703: add rsp, 28h
0x401707: pop rbx
0x401708: pop rbp
ret -> 0
0x4017c4: mov rax, [rbp+var_28]
0x4017c8: movzx eax, byte ptr [rax]
0x4017cb: movzx eax, al
0x4017ce: mov edi, eax
call 0x606fc0)
0x400f6a: push rbp
0x400f6b: mov rbp, rsp
0x400f6e: mov eax, edi
0x400f70: mov byte ptr [rbp+var_8+4], al
0x400f73: movzx eax, byte ptr [rbp+var_8+4]
0x400f77: test al, al
handler=0x401dcd if sf==0: false -> 0x607ec0, true -> 0x607860
0x401839: movzx eax, byte ptr [rbp+var_8+4]
0x40183d: add eax, eax
0x40183f: xor eax, 1Bh
0x4014da: pop rbp
ret -> 0
0x4014bd: movzx eax, byte ptr [rbp+var_8+4]
0x4014c1: add eax, eax
0x400d90: mov ebx, eax
0x400d92: mov rax, [rbp+var_28]
0x400d96: add rax, 1
0x400d9a: movzx eax, byte ptr [rax]
0x400d9d: movzx eax, al
0x400da0: mov edi, eax
call 0x607120)
0x400ffc: push rbp
0x400ffd: mov rbp, rsp
0x401000: sub rsp, 8
0x401004: mov eax, edi
0x401006: mov byte ptr [rbp+var_8+4], al
0x401009: movzx eax, byte ptr [rbp+var_8+4]
0x40100d: mov edi, eax
call 0x606fc0)
0x4015ad: xor al, byte ptr [rbp+var_8+4]
0x4015b0: leave
ret -> 0
0x400c96: xor ebx, eax
0x400c98: mov edx, ebx
0x400c9a: mov rax, [rbp+var_28]
0x400c9e: add rax, 2
0x400ca2: movzx eax, byte ptr [rax]
0x400ca5: xor edx, eax
0x400ca7: mov rax, [rbp+var_28]
0x400cab: add rax, 3
0x400caf: movzx eax, byte ptr [rax]
0x400cb2: xor eax, edx
0x400cb4: mov byte ptr [rbp+var_20+4], al
0x400cb7: mov rax, [rbp+var_28]
0x400cbb: movzx ebx, byte ptr [rax]
0x400cbe: mov rax, [rbp+var_28]
0x400cc2: add rax, 1
0x400cc6: movzx eax, byte ptr [rax]
0x400cc9: movzx eax, al
0x400ccc: mov edi, eax
call 0x606fc0)
0x40119e: xor ebx, eax
0x4011a0: mov rax, [rbp+var_28]
0x4011a4: add rax, 2
0x4011a8: movzx eax, byte ptr [rax]
0x4011ab: movzx eax, al
0x4011ae: mov edi, eax
call 0x607120)
0x401684: xor ebx, eax
0x401686: mov edx, ebx
0x401688: mov rax, [rbp+var_28]
0x40168c: add rax, 3
0x401690: movzx eax, byte ptr [rax]
0x401693: xor eax, edx
0x401695: mov byte ptr [rbp+var_20+5], al
0x401698: mov rax, [rbp+var_28]
0x40169c: movzx edx, byte ptr [rax]
0x40169f: mov rax, [rbp+var_28]
0x4016a3: add rax, 1
0x4016a7: movzx eax, byte ptr [rax]
0x4016aa: mov ebx, edx
0x4016ac: xor ebx, eax
0x4016ae: mov rax, [rbp+var_28]
0x4016b2: add rax, 2
0x4016b6: movzx eax, byte ptr [rax]
0x4016b9: movzx eax, al
0x4016bc: mov edi, eax
call 0x606fc0)
0x401576: xor ebx, eax
0x401578: mov rax, [rbp+var_28]
0x40157c: add rax, 3
0x401580: movzx eax, byte ptr [rax]
0x401583: movzx eax, al
0x401586: mov edi, eax
call 0x607120)
0x400bfe: xor eax, ebx
0x400c00: mov byte ptr [rbp+var_20+6], al
0x400c03: mov rax, [rbp+var_28]
0x400c07: movzx eax, byte ptr [rax]
0x400c0a: movzx eax, al
0x400c0d: mov edi, eax
call 0x607120)
0x4015e3: mov edx, eax
0x4015e5: mov rax, [rbp+var_28]
0x4015e9: add rax, 1
0x4015ed: movzx eax, byte ptr [rax]
0x4015f0: xor edx, eax
0x4015f2: mov rax, [rbp+var_28]
0x4015f6: add rax, 2
0x4015fa: movzx eax, byte ptr [rax]
0x4015fd: xor edx, eax
0x4015ff: mov ebx, edx
0x401601: mov rax, [rbp+var_28]
0x401605: add rax, 3
0x401609: movzx eax, byte ptr [rax]
0x40160c: movzx eax, al
0x40160f: mov edi, eax
call 0x606fc0)
0x40125c: xor eax, ebx; 将经过多轮 XOR/替换的 4 字节块写回输出缓冲区
0x40125e: mov byte ptr [rbp+var_20+7], al
0x401261: movzx edx, byte ptr [rbp+var_20+4]
0x401265: mov rax, [rbp+var_28]
0x401269: mov [rax], dl
0x40126b: mov rax, [rbp+var_28]
0x40126f: lea rdx, [rax+1]
0x401273: movzx eax, byte ptr [rbp+var_20+5]
0x401277: mov [rdx], al
0x401279: mov rax, [rbp+var_28]
0x40127d: lea rdx, [rax+2]
0x401281: movzx eax, byte ptr [rbp+var_20+6]
0x401285: mov [rdx], al
0x401287: mov rax, [rbp+var_28]
0x40128b: lea rdx, [rax+3]
0x40128f: movzx eax, byte ptr [rbp+var_20+7]
0x401293: mov [rdx], al
0x401295: add dword ptr [rbp+var_20], 1
0x401299: add [rbp+var_28], 4
0x401213: mov edx, [rbp+var_1D4]
0x401219: mov rcx, [rbp+var_1B0]
0x401220: mov rax, [rbp+var_1B8]
0x401227: mov rsi, rcx
0x40122a: mov rdi, rax
call 0x608060)
0x4014cd: add [rbp+var_1D4], 1
0x400d4d: mov rax, [rbp+var_1A8]
0x400d54: mov rdi, rax
call 0x607e00)
0x4018e5: mov rax, [rbp+var_1A8]
0x4018ec: mov rdi, rax
call 0x607220)
0x401319: mov rax, [rbp+var_1A8]
0x401320: mov rdi, rax
call 0x607e80)
0x400e3a: mov edx, [rbp+var_1CC]
0x400e40: mov rcx, [rbp+var_1A0]
0x400e47: mov rax, [rbp+var_1A8]
0x400e4e: mov rsi, rcx
0x400e51: mov rdi, rax
call 0x608060)
0x401498: add [rbp+var_1CC], 1
0x401953: mov [rbp+var_1BC], 0
0x400c84: cmp [rbp+var_1BC], 3
handler=0x401ca6 if signed <= 0: false -> 0x607ca0, true -> 0x607f40
0x401672: mov eax, [rbp+var_1C0]
0x401678: cdq
0x401679: idiv [rbp+var_1C8]
0x40167f: mov eax, edx
0x401681: test eax, eax
handler=0x401d22 if zf==0: false -> 0x608040, true -> 0x607960
0x4018f0: movzx eax, [rbp+var_184]
0x4018f7: mov [rbp+var_1E1], al
0x4018fd: movzx eax, [rbp+var_183]
0x401904: mov [rbp+var_184], al
0x40190a: movzx eax, [rbp+var_182]
0x401911: mov [rbp+var_183], al
0x401917: movzx eax, [rbp+var_181]
0x40191e: mov [rbp+var_182], al
0x401924: movzx eax, [rbp+var_1E1]
0x40192b: mov [rbp+var_181], al
0x401931: mov [rbp+var_1BC], 0
0x40130a: cmp [rbp+var_1BC], 3
handler=0x401ca6 if signed <= 0: false -> 0x607000, true -> 0x606e80
0x400f83: movzx ecx, [rbp+var_184]
0x400f8a: mov eax, [rbp+var_1C0]
0x400f90: cdq
0x400f91: idiv [rbp+var_1C8]
0x400f97: sub eax, 1
0x400f9a: movsxd rdx, eax
0x400f9d: lea rax, g_round_mask
0x400fa4: movzx eax, byte ptr [rdx+rax]
0x400fa8: xor eax, ecx
0x400faa: mov [rbp+var_184], al
0x4014fa: mov [rbp+var_1BC], 0
0x400e1a: cmp [rbp+var_1BC], 3
handler=0x401ca6 if signed <= 0: false -> 0x606ca0, true -> 0x606b00
0x400c47: add [rbp+var_1C0], 1
0x400b03: mov eax, [rbp+var_1C0]
0x400b09: sub eax, [rbp+var_1C8]
0x400b0f: lea edx, ds:0[rax*4]
0x400b16: mov eax, [rbp+var_1BC]
0x400b1c: add eax, edx
0x400b1e: movsxd rdx, eax
0x400b21: mov rax, [rbp+var_190]
0x400b28: add rax, rdx
0x400b2b: movzx esi, byte ptr [rax]
0x400b2e: mov eax, [rbp+var_1BC]
0x400b34: cdqe
0x400b36: movzx ecx, [rbp+rax+var_184]
0x400b3e: mov eax, [rbp+var_1C0]
0x400b44: lea edx, ds:0[rax*4]
0x400b4b: mov eax, [rbp+var_1BC]
0x400b51: add eax, edx
0x400b53: movsxd rdx, eax
0x400b56: mov rax, [rbp+var_190]
0x400b5d: add rax, rdx
0x400b60: xor esi, ecx
0x400b62: mov edx, esi
0x400b64: mov [rax], dl
0x400b66: add [rbp+var_1BC], 1
0x400da3: mov eax, [rbp+var_1BC]
0x400da9: cdqe
0x400dab: movzx eax, [rbp+rax+var_184]
0x400db3: movzx eax, al
0x400db6: movsxd rdx, eax
0x400db9: lea rax, g_sbox_forward
0x400dc0: movzx edx, byte ptr [rdx+rax]
0x400dc4: mov eax, [rbp+var_1BC]
0x400dca: cdqe
0x400dcc: mov [rbp+rax+var_184], dl
0x400dd3: add [rbp+var_1BC], 1
0x401864: mov eax, [rbp+var_1C0]; 从 g_sbox_forward 中取值混淆局部数组,形成非线性变换
0x40186a: sub eax, 1
0x40186d: lea edx, ds:0[rax*4]
0x401874: mov eax, [rbp+var_1BC]
0x40187a: add eax, edx
0x40187c: movsxd rdx, eax
0x40187f: mov rax, [rbp+var_190]
0x401886: add rax, rdx
0x401889: movzx edx, byte ptr [rax]
0x40188c: mov eax, [rbp+var_1BC]
0x401892: cdqe
0x401894: mov [rbp+rax+var_184], dl
0x40189b: add [rbp+var_1BC], 1
0x401390: mov eax, [rbp+var_1C0]
0x401396: movsxd rdx, eax
0x401399: mov rax, [rbp+var_198]
0x4013a0: add rax, rdx
0x4013a3: mov edx, [rbp+var_1C0]
0x4013a9: movsxd rcx, edx
0x4013ac: mov rdx, [rbp+var_190]
0x4013b3: add rdx, rcx
0x4013b6: movzx eax, byte ptr [rax]
0x4013b9: mov [rdx], al
0x4013bb: add [rbp+var_1C0], 1
call _rand
0x401034: mov edx, eax
0x401036: mov eax, [rbp+var_1E0]
0x40103c: cdqe
0x40103e: mov [rbp+rax+var_180], dl
0x401045: add [rbp+var_1E0], 1

问了GPT其实ai还是不太能够判断是否是aes

不过有些其它ai还是能看有点看运气

这里还有一种方法就是我们下断点自动跑,把所有的执行流打印出来,跑一次很长时间

跑出来的结果有几万行,不过包括一个256次初始化盒,能去掉很多,很多重复片段,我们可以写代码处理下这里提供调试代码

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
import idc

# 在调试暂停状态下执行
g_node_addr = idc.get_name_ea_simple("g_current_vm_node")
current_node = idc.get_qword(g_node_addr)

if current_node == 0:
print("g_current_vm_node 当前为 0,可能还未初始化。")
else:
next_node = idc.get_qword(current_node)
branch_node = idc.get_qword(current_node + 0x8)
handler_ptr = idc.get_qword(current_node + 0x10)
resume_rip = idc.get_qword(current_node + 0x18)


def fmt(ea):
if ea == 0:
return "0"
name = idc.get_name(ea, idc.GN_VISIBLE)
return f"{name} ({ea:#x})" if name else f"{ea:#x}"


print(f"current node : {current_node:#x}")
print(f" next : {fmt(next_node)}")
print(f" branch : {fmt(branch_node)}")
print(f" handler : {fmt(handler_ptr)}")
print(f" resume_rip : {fmt(resume_rip)}")

可以看到这里最后是跑到了pop的

image-20251103110349284

image-20251103110320439

我们可以再写个idapython代码把它详细的反汇编打印出来,首先需要处理掉重复片段,再喂给AI就能识别出AES了

这里大家自己调一下

image-20251103110529859

最后的解密代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from ctypes import *
from Crypto.Cipher import AES

def xor(a,b):
return bytes([i^j for i,j in zip(a,b)])
libc = cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
libc.srand(0x10000)
aeskey=[]
for i in range(16):
aeskey.append(libc.rand()&0xff)
libc.srand(libc.rand())
randstr=[]
for i in range(32):
x=libc.rand()
randstr.append(x&0xff)
cipher=AES.new(bytes(aeskey),AES.MODE_ECB)
pt=cipher.decrypt(xor(xor(bytes.fromhex('E28B553869FA80C2644E7FE7130614C5C013D3126BBDF2C788443E09E8A38330'),bytes(randstr)),b'Congratulations!This is the correct flag!'))
print(f'flag{{{pt.decode()}}}')