首页
社区
课程
招聘
[原创] 看雪 2023 KCTF 年度赛 第七题 智能联盟计划
2023-9-17 07:12 9950

[原创] 看雪 2023 KCTF 年度赛 第七题 智能联盟计划

2023-9-17 07:12
9950

(印象中这题之前好像放在第八题的位置上,是因为赶上周末所以把难题调整顺序了?)


第七题
Archaia
方案二

众多熟悉的因素叠加

writeup正文开始前,先看一个有关Archaia战队的合订本。

战队名称:Archaia
战队签名&战队介绍:武汉科锐学员队
注册时间:2019-06-08

(以上信息来自 https://ctf.kanxue.com/team-myctf-101159.htm)

从注册时间往后看,最早能追溯到2019看雪CTF晋级赛Q2

Archaia战队第一次防守方出的题,思路颇有特色。
但从第二次开始(至少直到上次),所有题目的思路高度雷同(甚至有的题目算法都相同):windows程序+方案二+一些计算算法检查序列号+混淆&|加壳+从不公开混淆&加壳程序的源代码+官方题解从未给出过自动化去混淆脚本

2019看雪CTF晋级赛Q2 第八题:迷雾中的琴声:输入作为shellcode执行,目标是弹框Win+通过crc校验,无壳,多解。
2019看雪CTF晋级赛Q3 第十题:传家之宝:2880层自解密自复制蜗牛壳,每层都包含核心逻辑的少量分片,程序正常运行都需要若干秒才能结束。序列号的检查逻辑是魔改AES算法
2019看雪CTF总决赛 第六题:三道八佛:1401层smc,只在最后一层有核心逻辑;上次的脱壳脚本可以复用。序列号的检查逻辑是一个自定义数据算法。与2019Q3的题混淆/加壳相同,算法改变了。
看雪.深信服 2021 KCTF 春季赛 第七题 千里寻根:2021层smc,每层的蜗牛壳代码都不一样(重中之重,这一个小改动导致攻破此题的三个攻击方都没有像先前的题一样做到完美抠出核心逻辑的指令交给IDA,而是更多的依赖调试和看汇编,体力活更大了;另外,赛后出题人在题解里轻飘飘的说了句 “脚本log出来的数据需要自己提取出有用的"肉代码". 可以人肉搞定, 或者找到规律后写脚本一通字符串操作也能搞定.这里给出前几层肉代码的分析, 后面层的同理.”(链接),但等了两年出题人却迟迟没有公开这个脚本,合理质疑下出题人真的验证过这样的简单性吗?又或许每层壳虽然代码不同但只有有限种组合,那么出题人是不是应该公开加壳处理的代码证明一下这一点呢?)。算法部分与2019Q4类似,只做了小改动。
看雪.众安 2021 KCTF 秋季赛 第九题 万事俱备:还是代码混淆,语言换成了python字节码。算法也是2021H1的老算法+微小修改。解释器改opcode是常规但对于攻击方而言除了徒增工作量以外毫无学习意义;而字节码混淆,出题人说“只要攻击方能击破代码混淆, 就是看"源码"写逆算法的活了”(链接),不过读几位攻击方大佬的writeup,实际处理起来似乎并没有这么轻松;同样,出题人没有公开自己的处理脚本,合理质疑下出题人验题真的尝试正面破解过自己的代码混淆吗?
看雪 2022·KCTF 春季赛 第五题 危机四伏:基于2021H1题目继续加难,蜗牛壳没了,但每层的垃圾指令混淆还在。三个公开的攻击方writeup全是非预期(算法几乎完全没变,只改了异或常量),而出题人的预期仍然说的非常轻松:想办法处理xxx、找出xxx的规律、根据特征xxx、写脚本将垃圾指令除去、等(链接)。但是,具体用什么办法?规律和特征是怎样的?脚本怎么写?出题人仍然什么都没公开。
看雪 2022·KCTF 秋季赛 第十一题 衣锦昼行:这次终于换了算法,但不变的还是代码混淆+出题人对于具体怎么去混淆只字未谈(所以,题目发布前是怎么验题的?)。另外序列号在程序计算过程中暴露,导致题目被迅速非预期。

结合2022H1-2021H1-2019Q4-2019Q3题目的延续性,以及2022H2的题目被非预期,当Archaia出现在今年的防守方列表时,就有预感大概率是把2022H2的题目修了非预期再出。

正文开始


IDA打开,看到main函数立刻证明了这就是基于2022H2题目修改而来。下载2022H2题目出题人公开的源代码(链接),对照main函数,把所有变量和函数重命名并修正类型。

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
// bad sp value at call has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int v4; // eax
  char szInput_encrypted[256]; // [esp+0h] [ebp-1140h] BYREF
  char szKeySerialConcat[500]; // [esp+100h] [ebp-1040h] BYREF
  _BYTE szKeySerialConcat_[50][8]; // [esp+2F4h] [ebp-E4Ch] BYREF
  char szInput[256]; // [esp+4E8h] [ebp-C58h] BYREF
  char szAllHash[50][8]; // [esp+5E8h] [ebp-B58h] BYREF
  char White_message[50]; // [esp+778h] [ebp-9C8h] BYREF
  char szKeySerial[50][9]; // [esp+7ACh] [ebp-994h] BYREF
  char Black_message10[16]; // [esp+970h] [ebp-7D0h] BYREF
  char Black_message6[16]; // [esp+980h] [ebp-7C0h] BYREF
  char Black_message5[16]; // [esp+990h] [ebp-7B0h] BYREF
  char Black_message4[16]; // [esp+9A0h] [ebp-7A0h] BYREF
  char Black_message48[16]; // [esp+9B0h] [ebp-790h] BYREF
  char Black_message47[16]; // [esp+9C0h] [ebp-780h] BYREF
  char Black_message46[16]; // [esp+9D0h] [ebp-770h] BYREF
  char Black_message42[16]; // [esp+9E0h] [ebp-760h] BYREF
  char Black_message41[16]; // [esp+9F0h] [ebp-750h] BYREF
  char Black_message40[16]; // [esp+A00h] [ebp-740h] BYREF
  char Black_message36[16]; // [esp+A10h] [ebp-730h] BYREF
  char Black_message35[16]; // [esp+A20h] [ebp-720h] BYREF
  char Black_message34[16]; // [esp+A30h] [ebp-710h] BYREF
  char Black_message30[16]; // [esp+A40h] [ebp-700h] BYREF
  char Black_message29[16]; // [esp+A50h] [ebp-6F0h] BYREF
  char Black_message28[16]; // [esp+A60h] [ebp-6E0h] BYREF
  char Black_message24[16]; // [esp+A70h] [ebp-6D0h] BYREF
  char Black_message23[16]; // [esp+A80h] [ebp-6C0h] BYREF
  char Black_message22[16]; // [esp+A90h] [ebp-6B0h] BYREF
  char Black_message18[16]; // [esp+AA0h] [ebp-6A0h] BYREF
  char Black_message17[16]; // [esp+AB0h] [ebp-690h] BYREF
  char Black_message16[16]; // [esp+AC0h] [ebp-680h] BYREF
  char Black_message12[16]; // [esp+AD0h] [ebp-670h] BYREF
  char Black_message11[16]; // [esp+AE0h] [ebp-660h] BYREF
  char My_key33[8]; // [esp+AF0h] [ebp-650h] BYREF
  char My_key34[8]; // [esp+AF8h] [ebp-648h] BYREF
  char My_key35[8]; // [esp+B00h] [ebp-640h] BYREF
  char My_key36[8]; // [esp+B08h] [ebp-638h] BYREF
  char Black_message45[16]; // [esp+B10h] [ebp-630h] BYREF
  char Black_message44[16]; // [esp+B20h] [ebp-620h] BYREF
  char Black_message43[16]; // [esp+B30h] [ebp-610h] BYREF
  char Black_message39[16]; // [esp+B40h] [ebp-600h] BYREF
  char Black_message38[16]; // [esp+B50h] [ebp-5F0h] BYREF
  char Black_message37[16]; // [esp+B60h] [ebp-5E0h] BYREF
  char Black_message33[16]; // [esp+B70h] [ebp-5D0h] BYREF
  char Black_message32[16]; // [esp+B80h] [ebp-5C0h] BYREF
  char Black_message31[16]; // [esp+B90h] [ebp-5B0h] BYREF
  char Black_message27[16]; // [esp+BA0h] [ebp-5A0h] BYREF
  char Black_message26[16]; // [esp+BB0h] [ebp-590h] BYREF
  char Black_message25[16]; // [esp+BC0h] [ebp-580h] BYREF
  char Black_message21[16]; // [esp+BD0h] [ebp-570h] BYREF
  char Black_message20[16]; // [esp+BE0h] [ebp-560h] BYREF
  char Black_message19[16]; // [esp+BF0h] [ebp-550h] BYREF
  char Black_message15[16]; // [esp+C00h] [ebp-540h] BYREF
  char Black_message14[16]; // [esp+C10h] [ebp-530h] BYREF
  char Black_message13[16]; // [esp+C20h] [ebp-520h] BYREF
  char Black_message9[16]; // [esp+C30h] [ebp-510h] BYREF
  char Black_message8[16]; // [esp+C40h] [ebp-500h] BYREF
  char Black_message7[16]; // [esp+C50h] [ebp-4F0h] BYREF
  char Black_message3[16]; // [esp+C60h] [ebp-4E0h] BYREF
  char Black_message2[16]; // [esp+C70h] [ebp-4D0h] BYREF
  char Black_message1[16]; // [esp+C80h] [ebp-4C0h] BYREF
  char My_key37[8]; // [esp+C90h] [ebp-4B0h] BYREF
  char My_key38[8]; // [esp+C98h] [ebp-4A8h] BYREF
  char My_key43[8]; // [esp+CA0h] [ebp-4A0h] BYREF
  char My_key45[8]; // [esp+CA8h] [ebp-498h] BYREF
  char My_key46[8]; // [esp+CB0h] [ebp-490h] BYREF
  char My_key47[8]; // [esp+CB8h] [ebp-488h] BYREF
  char My_key48[8]; // [esp+CC0h] [ebp-480h] BYREF
  char My_key39[8]; // [esp+CC8h] [ebp-478h] BYREF
  char My_key40[8]; // [esp+CD0h] [ebp-470h] BYREF
  char My_key41[8]; // [esp+CD8h] [ebp-468h] BYREF
  char My_key42[8]; // [esp+CE0h] [ebp-460h] BYREF
  char My_key44[8]; // [esp+CE8h] [ebp-458h] BYREF
  char My_key32[8]; // [esp+CF0h] [ebp-450h] BYREF
  char My_key31[8]; // [esp+CF8h] [ebp-448h] BYREF
  char My_key30[8]; // [esp+D00h] [ebp-440h] BYREF
  char My_key29[8]; // [esp+D08h] [ebp-438h] BYREF
  char My_key28[8]; // [esp+D10h] [ebp-430h] BYREF
  char My_key27[8]; // [esp+D18h] [ebp-428h] BYREF
  char My_key26[8]; // [esp+D20h] [ebp-420h] BYREF
  char My_key25[8]; // [esp+D28h] [ebp-418h] BYREF
  char My_key24[8]; // [esp+D30h] [ebp-410h] BYREF
  char My_key23[8]; // [esp+D38h] [ebp-408h] BYREF
  char My_key22[8]; // [esp+D40h] [ebp-400h] BYREF
  char My_key21[8]; // [esp+D48h] [ebp-3F8h] BYREF
  char My_key20[8]; // [esp+D50h] [ebp-3F0h] BYREF
  char My_key19[8]; // [esp+D58h] [ebp-3E8h] BYREF
  char My_key18[8]; // [esp+D60h] [ebp-3E0h] BYREF
  char My_key17[8]; // [esp+D68h] [ebp-3D8h] BYREF
  char My_key16[8]; // [esp+D70h] [ebp-3D0h] BYREF
  char My_key15[8]; // [esp+D78h] [ebp-3C8h] BYREF
  char My_key14[8]; // [esp+D80h] [ebp-3C0h] BYREF
  char My_key13[8]; // [esp+D88h] [ebp-3B8h] BYREF
  char My_key12[8]; // [esp+D90h] [ebp-3B0h] BYREF
  char My_key11[8]; // [esp+D98h] [ebp-3A8h] BYREF
  char My_key10[8]; // [esp+DA0h] [ebp-3A0h] BYREF
  char My_key9[8]; // [esp+DA8h] [ebp-398h] BYREF
  char My_key8[8]; // [esp+DB0h] [ebp-390h] BYREF
  char My_key7[8]; // [esp+DB8h] [ebp-388h] BYREF
  char My_key6[8]; // [esp+DC0h] [ebp-380h] BYREF
  char My_key5[8]; // [esp+DC8h] [ebp-378h] BYREF
  char My_key4[8]; // [esp+DD0h] [ebp-370h] BYREF
  char My_key3[8]; // [esp+DD8h] [ebp-368h] BYREF
  char My_key2[8]; // [esp+DE0h] [ebp-360h] BYREF
  char My_key1[8]; // [esp+DE8h] [ebp-358h] BYREF
  char RSHashResult34[9]; // [esp+DF0h] [ebp-350h] BYREF
  char RSHashResult30[9]; // [esp+DFCh] [ebp-344h] BYREF
  char RSHashResult28[9]; // [esp+E08h] [ebp-338h] BYREF
  char RSHashResult24[9]; // [esp+E14h] [ebp-32Ch] BYREF
  char RSHashResult23[9]; // [esp+E20h] [ebp-320h] BYREF
  char RSHashResult22[9]; // [esp+E2Ch] [ebp-314h] BYREF
  char RSHashResult18[9]; // [esp+E38h] [ebp-308h] BYREF
  char RSHashResult17[9]; // [esp+E44h] [ebp-2FCh] BYREF
  char RSHashResult16[9]; // [esp+E50h] [ebp-2F0h] BYREF
  char RSHashResult12[9]; // [esp+E5Ch] [ebp-2E4h] BYREF
  char RSHashResult11[9]; // [esp+E68h] [ebp-2D8h] BYREF
  char RSHashResult10[9]; // [esp+E74h] [ebp-2CCh] BYREF
  char RSHashResult6[9]; // [esp+E80h] [ebp-2C0h] BYREF
  char RSHashResult5[9]; // [esp+E8Ch] [ebp-2B4h] BYREF
  char RSHashResult4[9]; // [esp+E98h] [ebp-2A8h] BYREF
  char RSHashResult29[9]; // [esp+EA4h] [ebp-29Ch] BYREF
  char RSHashResult48[9]; // [esp+EB0h] [ebp-290h] BYREF
  char RSHashResult47[9]; // [esp+EBCh] [ebp-284h] BYREF
  char RSHashResult46[9]; // [esp+EC8h] [ebp-278h] BYREF
  char RSHashResult42[9]; // [esp+ED4h] [ebp-26Ch] BYREF
  char RSHashResult41[9]; // [esp+EE0h] [ebp-260h] BYREF
  char RSHashResult40[9]; // [esp+EECh] [ebp-254h] BYREF
  char RSHashResult36[9]; // [esp+EF8h] [ebp-248h] BYREF
  char RSHashResult35[9]; // [esp+F04h] [ebp-23Ch] BYREF
  HANDLE (__stdcall *CreateThread)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD); // [esp+F10h] [ebp-230h]
  char *szInput_hexdecoded; // [esp+F14h] [ebp-22Ch]
  int nInput; // [esp+F18h] [ebp-228h]
  char RSHashResult15[9]; // [esp+F1Ch] [ebp-224h] BYREF
  char RSHashResult27[9]; // [esp+F28h] [ebp-218h] BYREF
  char RSHashResult26[9]; // [esp+F34h] [ebp-20Ch] BYREF
  char RSHashResult25[9]; // [esp+F40h] [ebp-200h] BYREF
  char RSHashResult21[9]; // [esp+F4Ch] [ebp-1F4h] BYREF
  char RSHashResult20[9]; // [esp+F58h] [ebp-1E8h] BYREF
  char RSHashResult19[9]; // [esp+F64h] [ebp-1DCh] BYREF
  char RSHashResult2[9]; // [esp+F70h] [ebp-1D0h] BYREF
  char RSHashResult14[9]; // [esp+F7Ch] [ebp-1C4h] BYREF
  char RSHashResult13[9]; // [esp+F88h] [ebp-1B8h] BYREF
  char RSHashResult9[9]; // [esp+F94h] [ebp-1ACh] BYREF
  char RSHashResult8[9]; // [esp+FA0h] [ebp-1A0h] BYREF
  char RSHashResult7[9]; // [esp+FACh] [ebp-194h] BYREF
  char RSHashResult3[9]; // [esp+FB8h] [ebp-188h] BYREF
  char RSHashResult1[9]; // [esp+FC4h] [ebp-17Ch] BYREF
  char RSHashResult32[9]; // [esp+FD0h] [ebp-170h] BYREF
  char RSHashResult33[9]; // [esp+FDCh] [ebp-164h] BYREF
  char RSHashResult37[9]; // [esp+FE8h] [ebp-158h] BYREF
  char RSHashResult38[9]; // [esp+FF4h] [ebp-14Ch] BYREF
  char RSHashResult39[9]; // [esp+1000h] [ebp-140h] BYREF
  char RSHashResult31[9]; // [esp+100Ch] [ebp-134h] BYREF
  char RSHashResult43[9]; // [esp+1018h] [ebp-128h] BYREF
  char RSHashResult44[9]; // [esp+1024h] [ebp-11Ch] BYREF
  char RSHashResult45[9]; // [esp+1030h] [ebp-110h] BYREF
  char szHash2Hash_[12]; // [esp+103Ch] [ebp-104h] BYREF
  char szDecCurrent_[12]; // [esp+1048h] [ebp-F8h] BYREF
  void *pSerial_Rest21; // [esp+1054h] [ebp-ECh]
  HMODULE hModule; // [esp+1058h] [ebp-E8h]
  void *pSerial_Rest2; // [esp+105Ch] [ebp-E4h]
  void *pSerial_Rest1; // [esp+1060h] [ebp-E0h]
  void *pSerial_Rest3; // [esp+1064h] [ebp-DCh]
  void *pSerial_Rest4; // [esp+1068h] [ebp-D8h]
  void *pSerial_Rest5; // [esp+106Ch] [ebp-D4h]
  void *pSerial_Rest6; // [esp+1070h] [ebp-D0h]
  void *pSerial_Rest7; // [esp+1074h] [ebp-CCh]
  void *pSerial_Rest8; // [esp+1078h] [ebp-C8h]
  void *pSerial_Rest9; // [esp+107Ch] [ebp-C4h]
  void *pSerial_Rest10; // [esp+1080h] [ebp-C0h]
  void *pSerial_Rest11; // [esp+1084h] [ebp-BCh]
  void *pSerial_Rest12; // [esp+1088h] [ebp-B8h]
  void *pSerial_Rest13; // [esp+108Ch] [ebp-B4h]
  void *pSerial_Rest14; // [esp+1090h] [ebp-B0h]
  void *pSerial_Rest15; // [esp+1094h] [ebp-ACh]
  void *pSerial_Rest16; // [esp+1098h] [ebp-A8h]
  void *pSerial_Rest17; // [esp+109Ch] [ebp-A4h]
  void *pSerial_Rest18; // [esp+10A0h] [ebp-A0h]
  void *pSerial_Rest19; // [esp+10A4h] [ebp-9Ch]
  void *pSerial_Rest20; // [esp+10A8h] [ebp-98h]
  char szHash2Hash[9]; // [esp+10ACh] [ebp-94h] BYREF
  char Format[12]; // [esp+10B8h] [ebp-88h] BYREF
  char v186[4]; // [esp+10C4h] [ebp-7Ch] BYREF
  char v187[10]; // [esp+10C8h] [ebp-78h] BYREF
  char v188[4]; // [esp+10D2h] [ebp-6Eh] BYREF
  int m; // [esp+10D8h] [ebp-68h]
  int i; // [esp+10DCh] [ebp-64h]
  size_t k; // [esp+10E0h] [ebp-60h]
  int j; // [esp+10E4h] [ebp-5Ch]
  char szDecCurrent[17]; // [esp+10E8h] [ebp-58h] BYREF
  char szSerialNum_Real[17]; // [esp+10FCh] [ebp-44h] BYREF
  char szDecResult[17]; // [esp+1110h] [ebp-30h] BYREF
  char szCurrentSer[17]; // [esp+1124h] [ebp-1Ch] BYREF
  char White_message_8[8]; // [esp+1138h] [ebp-8h] BYREF
 
  memset(szKeySerial, 0, sizeof(szKeySerial));
  memset(szAllHash, 0, sizeof(szAllHash));
  qmemcpy(My_key1, "qrstuvwx", sizeof(My_key1));
  memset(White_message, 0, sizeof(White_message));
  memset(White_message_8, 0, sizeof(White_message_8));
  memset(Black_message1, 0, sizeof(Black_message1));
  memset(RSHashResult1, 0, sizeof(RSHashResult1));
  Format[0] = 0xC7;
  Format[1] = 0xEB;
  Format[2] = 0xCA;
  Format[3] = 0xE4;
  Format[4] = 0xC8;
  Format[5] = 0xEB;
  Format[6] = 0xD3;
  Format[7] = 0xC3;
  Format[8] = 0xBB;
  Format[9] = 0xA7;
  Format[10] = 0xC3;
  Format[11] = 0xFB;
  strcpy(v186, ":\n");
  printf(Format);    // 请输入用户名:
  gets_s(White_message, 50u);
  v3 = strlen(White_message);
  nInput = RSHash(White_message, v3);
  itoa(nInput, White_message_8, 16);
  Encode_1(My_key1, White_message_8, Black_message1, RSHashResult1);
  memcpy(szKeySerial, Black_message1, 8u);
  memcpy(szAllHash, RSHashResult1, 8u);
  qmemcpy(My_key2, "abcdefgh", sizeof(My_key2));
  memset(Black_message2, 0, sizeof(Black_message2));
  memset(RSHashResult2, 0, sizeof(RSHashResult2));
  Encode_2(My_key2, White_message_8, Black_message2, RSHashResult2);
  memcpy(szKeySerial[1], Black_message2, 8u);
  memcpy(szAllHash[1], RSHashResult2, sizeof(char[8]));
  qmemcpy(My_key3, "ijklmnop", sizeof(My_key3));
  memset(Black_message3, 0, sizeof(Black_message3));
  memset(RSHashResult3, 0, sizeof(RSHashResult3));
  Encode_2(My_key3, White_message_8, Black_message3, RSHashResult3);
  memcpy(szKeySerial[2], Black_message3, 8u);
  memcpy(szAllHash[2], RSHashResult3, sizeof(char[8]));
  qmemcpy(My_key4, "qrstuvwx", sizeof(My_key4));
  memset(Black_message4, 0, sizeof(Black_message4));
  memset(RSHashResult4, 0, sizeof(RSHashResult4));
  Encode_4(My_key4, White_message_8, Black_message4, RSHashResult4);
  qmemcpy(My_key5, "abcdefgh", sizeof(My_key5));
  memset(Black_message5, 0, sizeof(Black_message5));
  memset(RSHashResult5, 0, sizeof(RSHashResult5));
  Encode_5(My_key5, White_message_8, Black_message5, RSHashResult5);
  qmemcpy(My_key6, "ijklmnop", sizeof(My_key6));
  memset(Black_message6, 0, sizeof(Black_message6));
  memset(RSHashResult6, 0, sizeof(RSHashResult6));
  Encode_6(My_key6, White_message_8, Black_message6, RSHashResult6);
  qmemcpy(My_key7, "qrstuvwx", sizeof(My_key7));
  memset(Black_message7, 0, sizeof(Black_message7));
  memset(RSHashResult7, 0, sizeof(RSHashResult7));
  Encode_7(My_key7, White_message_8, Black_message7, RSHashResult7);
  memcpy(szKeySerial[3], Black_message7, 8u);
  memcpy(szAllHash[3], RSHashResult7, sizeof(char[8]));
  qmemcpy(My_key8, "abcdefgh", sizeof(My_key8));
  memset(Black_message8, 0, sizeof(Black_message8));
  memset(RSHashResult8, 0, sizeof(RSHashResult8));
  Encode_8(My_key8, White_message_8, Black_message8, RSHashResult8);
  memcpy(szKeySerial[4], Black_message8, 8u);
  memcpy(szAllHash[4], RSHashResult8, sizeof(char[8]));
  qmemcpy(My_key9, "ijklmnop", sizeof(My_key9));
  memset(Black_message9, 0, sizeof(Black_message9));
  memset(RSHashResult9, 0, sizeof(RSHashResult9));
  Encode_9(My_key9, White_message_8, Black_message9, RSHashResult9);
  memcpy(szKeySerial[4], Black_message9, 8u);
  memcpy(szAllHash[4], RSHashResult9, sizeof(char[8]));
  qmemcpy(My_key10, "qrstuvwx", sizeof(My_key10));
  memset(Black_message10, 0, sizeof(Black_message10));
  memset(RSHashResult10, 0, sizeof(RSHashResult10));
  Encode_10(My_key10, White_message_8, Black_message10, RSHashResult10);
  qmemcpy(My_key11, "abcdefgh", sizeof(My_key11));
  memset(Black_message11, 0, sizeof(Black_message11));
  memset(RSHashResult11, 0, sizeof(RSHashResult11));
  Encode_11(My_key11, White_message_8, Black_message11, RSHashResult11);
  qmemcpy(My_key12, "ijklmnop", sizeof(My_key12));
  memset(Black_message12, 0, sizeof(Black_message12));
  memset(RSHashResult12, 0, sizeof(RSHashResult12));
  Encode_12(My_key12, White_message_8, Black_message12, RSHashResult12);
  qmemcpy(My_key13, "qrstuvwx", sizeof(My_key13));
  memset(Black_message13, 0, sizeof(Black_message13));
  memset(RSHashResult13, 0, sizeof(RSHashResult13));
  Encode_13(My_key13, White_message_8, Black_message13, RSHashResult13);
  memcpy(szKeySerial[6], Black_message13, 8u);
  memcpy(szAllHash[6], RSHashResult13, sizeof(char[8]));
  qmemcpy(My_key14, "abcdefgh", sizeof(My_key14));
  memset(Black_message14, 0, sizeof(Black_message14));
  memset(RSHashResult14, 0, sizeof(RSHashResult14));
  Encode_14(My_key14, White_message_8, Black_message14, RSHashResult14);
  memcpy(szKeySerial[7], Black_message14, 8u);
  memcpy(szAllHash[7], RSHashResult14, sizeof(char[8]));
  qmemcpy(My_key15, "ijklmnop", sizeof(My_key15));
  memset(Black_message15, 0, sizeof(Black_message15));
  memset(RSHashResult15, 0, sizeof(RSHashResult15));
  Encode_15(My_key15, White_message_8, Black_message15, RSHashResult15);
  memcpy(szKeySerial[8], Black_message15, 8u);
  memcpy(szAllHash[8], RSHashResult15, sizeof(char[8]));
  qmemcpy(My_key16, "qrstuvwx", sizeof(My_key16));
  memset(Black_message16, 0, sizeof(Black_message16));
  memset(RSHashResult16, 0, sizeof(RSHashResult16));
  Encode_16(My_key16, White_message_8, Black_message16, RSHashResult16);
  qmemcpy(My_key17, "abcdefgh", sizeof(My_key17));
  memset(Black_message17, 0, sizeof(Black_message17));
  memset(RSHashResult17, 0, sizeof(RSHashResult17));
  Encode_17(My_key17, White_message_8, Black_message17, RSHashResult17);
  qmemcpy(My_key18, "ijklmnop", sizeof(My_key18));
  memset(Black_message18, 0, sizeof(Black_message18));
  memset(RSHashResult18, 0, sizeof(RSHashResult18));
  Encode_18(My_key18, White_message_8, Black_message18, RSHashResult18);
  qmemcpy(My_key19, "qrstuvwx", sizeof(My_key19));
  memset(Black_message19, 0, sizeof(Black_message19));
  memset(RSHashResult19, 0, sizeof(RSHashResult19));
  Encode_19(My_key19, White_message_8, Black_message19, RSHashResult19);
  memcpy(szKeySerial[9], Black_message19, 8u);
  memcpy(szAllHash[9], RSHashResult19, sizeof(char[8]));
  qmemcpy(My_key20, "abcdefgh", sizeof(My_key20));
  memset(Black_message20, 0, sizeof(Black_message20));
  memset(RSHashResult20, 0, sizeof(RSHashResult20));
  Encode_20(My_key20, White_message_8, Black_message20, RSHashResult20);
  memcpy(szKeySerial[10], Black_message20, 8u);
  memcpy(szAllHash[10], RSHashResult20, sizeof(char[8]));
  qmemcpy(My_key21, "ijklmnop", sizeof(My_key21));
  memset(Black_message21, 0, sizeof(Black_message21));
  memset(RSHashResult21, 0, sizeof(RSHashResult21));
  Encode_21(My_key21, White_message_8, Black_message21, RSHashResult21);
  memcpy(szKeySerial[11], Black_message21, 8u);
  memcpy(szAllHash[11], RSHashResult21, sizeof(char[8]));
  qmemcpy(My_key22, "qrstuvwx", sizeof(My_key22));
  memset(Black_message22, 0, sizeof(Black_message22));
  memset(RSHashResult22, 0, sizeof(RSHashResult22));
  Encode_22(My_key22, White_message_8, Black_message22, RSHashResult22);
  qmemcpy(My_key23, "abcdefgh", sizeof(My_key23));
  memset(Black_message23, 0, sizeof(Black_message23));
  memset(RSHashResult23, 0, sizeof(RSHashResult23));
  Encode_23(My_key23, White_message_8, Black_message23, RSHashResult23);
  qmemcpy(My_key24, "ijklmnop", sizeof(My_key24));
  memset(Black_message24, 0, sizeof(Black_message24));
  memset(RSHashResult24, 0, sizeof(RSHashResult24));
  Encode_24(My_key24, White_message_8, Black_message24, RSHashResult24);
  qmemcpy(My_key25, "qrstuvwx", sizeof(My_key25));
  memset(Black_message25, 0, sizeof(Black_message25));
  memset(RSHashResult25, 0, sizeof(RSHashResult25));
  Encode_25(My_key25, White_message_8, Black_message25, RSHashResult25);
  memcpy(szKeySerial[12], Black_message25, 8u);
  memcpy(szAllHash[12], RSHashResult25, sizeof(char[8]));
  qmemcpy(My_key26, "abcdefgh", sizeof(My_key26));
  memset(Black_message26, 0, sizeof(Black_message26));
  memset(RSHashResult26, 0, sizeof(RSHashResult26));
  Encode_26(My_key26, White_message_8, Black_message26, RSHashResult26);
  memcpy(szKeySerial[13], Black_message26, 8u);
  memcpy(szAllHash[13], RSHashResult26, sizeof(char[8]));
  qmemcpy(My_key27, "ijklmnop", sizeof(My_key27));
  memset(Black_message27, 0, sizeof(Black_message27));
  memset(RSHashResult27, 0, sizeof(RSHashResult27));
  Encode_27(My_key27, White_message_8, Black_message27, RSHashResult27);
  memcpy(szKeySerial[14], Black_message27, 8u);
  memcpy(szAllHash[14], RSHashResult27, sizeof(char[8]));
  qmemcpy(My_key28, "qrstuvwx", sizeof(My_key28));
  memset(Black_message28, 0, sizeof(Black_message28));
  memset(RSHashResult28, 0, sizeof(RSHashResult28));
  Encode_28(My_key28, White_message_8, Black_message28, RSHashResult28);
  qmemcpy(My_key29, "abcdefgh", sizeof(My_key29));
  memset(Black_message29, 0, sizeof(Black_message29));
  memset(RSHashResult29, 0, sizeof(RSHashResult29));
  Encode_29(My_key29, White_message_8, Black_message29, RSHashResult29);
  qmemcpy(My_key30, "ijklmnop", sizeof(My_key30));
  memset(Black_message30, 0, sizeof(Black_message30));
  memset(RSHashResult30, 0, sizeof(RSHashResult30));
  Encode_30(My_key30, White_message_8, Black_message30, RSHashResult30);
  qmemcpy(My_key31, "qrstuvwx", sizeof(My_key31));
  memset(Black_message31, 0, sizeof(Black_message31));
  memset(RSHashResult31, 0, sizeof(RSHashResult31));
  Encode_31(My_key31, White_message_8, Black_message31, RSHashResult31);
  memcpy(szKeySerial[15], Black_message31, 8u);
  memcpy(szAllHash[15], RSHashResult31, sizeof(char[8]));
  qmemcpy(My_key32, "abcdefgh", sizeof(My_key32));
  memset(Black_message32, 0, sizeof(Black_message32));
  memset(RSHashResult32, 0, sizeof(RSHashResult32));
  Encode_32(My_key32, White_message_8, Black_message32, RSHashResult32);
  memcpy(szKeySerial[16], Black_message32, 8u);
  memcpy(szAllHash[16], RSHashResult32, sizeof(char[8]));
  qmemcpy(My_key33, "ijklmnop", sizeof(My_key33));
  memset(Black_message33, 0, sizeof(Black_message33));
  memset(RSHashResult33, 0, sizeof(RSHashResult33));
  Encode_33(My_key33, White_message_8, Black_message33, RSHashResult33);
  memcpy(szKeySerial[17], Black_message33, 8u);
  memcpy(szAllHash[17], RSHashResult33, sizeof(char[8]));
  qmemcpy(My_key34, "qrstuvwx", sizeof(My_key34));
  memset(Black_message34, 0, sizeof(Black_message34));
  memset(RSHashResult34, 0, sizeof(RSHashResult34));
  Encode_34(My_key34, White_message_8, Black_message34, RSHashResult34);
  qmemcpy(My_key35, "abcdefgh", sizeof(My_key35));
  memset(Black_message35, 0, sizeof(Black_message35));
  memset(RSHashResult35, 0, sizeof(RSHashResult35));
  Encode_35(My_key35, White_message_8, Black_message35, RSHashResult35);
  qmemcpy(My_key36, "ijklmnop", sizeof(My_key36));
  memset(Black_message36, 0, sizeof(Black_message36));
  memset(RSHashResult36, 0, sizeof(RSHashResult36));
  Encode_36(My_key36, White_message_8, Black_message36, RSHashResult36);
  qmemcpy(My_key37, "qrstuvwx", sizeof(My_key37));
  memset(Black_message37, 0, sizeof(Black_message37));
  memset(RSHashResult37, 0, sizeof(RSHashResult37));
  Encode_37(My_key37, White_message_8, Black_message37, RSHashResult37);
  memcpy(szKeySerial[18], Black_message37, 8u);
  memcpy(szAllHash[18], RSHashResult37, sizeof(char[8]));
  qmemcpy(My_key38, "abcdefgh", sizeof(My_key38));
  memset(Black_message38, 0, sizeof(Black_message38));
  memset(RSHashResult38, 0, sizeof(RSHashResult38));
  Encode_38(My_key38, White_message_8, Black_message38, RSHashResult38);
  memcpy(szKeySerial[19], Black_message38, 8u);
  memcpy(szAllHash[19], RSHashResult38, sizeof(char[8]));
  qmemcpy(My_key39, "ijklmnop", sizeof(My_key39));
  memset(Black_message39, 0, sizeof(Black_message39));
  memset(RSHashResult39, 0, sizeof(RSHashResult39));
  Encode_39(My_key39, White_message_8, Black_message39, RSHashResult39);
  memcpy(szKeySerial[20], Black_message39, 8u);
  memcpy(szAllHash[20], RSHashResult39, sizeof(char[8]));
  qmemcpy(My_key40, "qrstuvwx", sizeof(My_key40));
  memset(Black_message40, 0, sizeof(Black_message40));
  memset(RSHashResult40, 0, sizeof(RSHashResult40));
  Encode_40(My_key40, White_message_8, Black_message40, RSHashResult40);
  qmemcpy(My_key41, "abcdefgh", sizeof(My_key41));
  memset(Black_message41, 0, sizeof(Black_message41));
  memset(RSHashResult41, 0, sizeof(RSHashResult41));
  Encode_41(My_key41, White_message_8, Black_message41, RSHashResult41);
  qmemcpy(My_key42, "ijklmnop", sizeof(My_key42));
  memset(Black_message42, 0, sizeof(Black_message42));
  memset(RSHashResult42, 0, sizeof(RSHashResult42));
  Encode_42(My_key42, White_message_8, Black_message42, RSHashResult42);
  qmemcpy(My_key43, "qrstuvwx", sizeof(My_key43));
  memset(Black_message43, 0, sizeof(Black_message43));
  memset(RSHashResult43, 0, sizeof(RSHashResult43));
  Encode_43(My_key43, White_message_8, Black_message43, RSHashResult43);
  memcpy(szKeySerial[21], Black_message43, 8u);
  memcpy(szAllHash[21], RSHashResult43, sizeof(char[8]));
  qmemcpy(My_key44, "abcdefgh", sizeof(My_key44));
  memset(Black_message44, 0, sizeof(Black_message44));
  memset(RSHashResult44, 0, sizeof(RSHashResult44));
  Encode_44(My_key44, White_message_8, Black_message44, RSHashResult44);
  memcpy(szKeySerial[22], Black_message44, 8u);
  memcpy(szAllHash[22], RSHashResult44, sizeof(char[8]));
  qmemcpy(My_key45, "ijklmnop", sizeof(My_key45));
  memset(Black_message45, 0, sizeof(Black_message45));
  memset(RSHashResult45, 0, sizeof(RSHashResult45));
  Encode_45(My_key45, White_message_8, Black_message45, RSHashResult45);
  memcpy(szKeySerial[23], Black_message45, 8u);
  memcpy(szAllHash[23], RSHashResult45, sizeof(char[8]));
  qmemcpy(My_key46, "qrstuvwx", sizeof(My_key46));
  memset(Black_message46, 0, sizeof(Black_message46));
  memset(RSHashResult46, 0, sizeof(RSHashResult46));
  Encode_46(My_key46, White_message_8, Black_message46, RSHashResult46);
  qmemcpy(My_key47, "abcdefgh", sizeof(My_key47));
  memset(Black_message47, 0, sizeof(Black_message47));
  memset(RSHashResult47, 0, sizeof(RSHashResult47));
  Encode_47(My_key47, White_message_8, Black_message47, RSHashResult47);
  qmemcpy(My_key48, "ijklmnop", sizeof(My_key48));
  memset(Black_message48, 0, sizeof(Black_message48));
  memset(RSHashResult48, 0, sizeof(RSHashResult48));
  Encode_48(My_key48, White_message_8, Black_message48, RSHashResult48);
  memset(szHash2Hash, 0, sizeof(szHash2Hash));
  memset(szHash2Hash_, 0, 9);
  v4 = RSHash(szAllHash[0], 192);
  sprintf_s(szHash2Hash, 9u, "%08x", v4);
  memcpy(szHash2Hash_, szHash2Hash, 9u);
  memset(szKeySerialConcat, 0, sizeof(szKeySerialConcat));
  memset(szKeySerialConcat_, 0, 500u);
  for ( i = 0; i < 50; ++i )
    strcat_s(szKeySerialConcat, 0x400u, szKeySerial[i]);
  memmove(szKeySerialConcat_, szKeySerialConcat, 500u);
  sub_40F9AF(szHash2Hash, szKeySerialConcat_[0], 0);// sub_40F9AF: first arg is key, second arg is value
  for ( j = 0; j < 50; ++j )
    memmove(szKeySerial[j], szKeySerialConcat_[j], 8u);
  sub_40F9AF(szKeySerialConcat_[0], szHash2Hash, 0);
  memset(szCurrentSer, 0, sizeof(szCurrentSer));
  memset(szSerialNum_Real, 0, sizeof(szSerialNum_Real));
  Encode_For_Serial(szKeySerial[0], szHash2Hash, szCurrentSer);
  pSerial_Rest1 = malloc(8u);
  memcpy(pSerial_Rest1, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[1], szCurrentSer, szSerialNum_Real);
  pSerial_Rest2 = malloc(8u);
  memcpy(pSerial_Rest2, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[2], szSerialNum_Real, szCurrentSer);
  pSerial_Rest3 = malloc(8u);
  memcpy(pSerial_Rest3, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[3], szCurrentSer, szSerialNum_Real);
  pSerial_Rest4 = malloc(8u);
  memcpy(pSerial_Rest4, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[4], szSerialNum_Real, szCurrentSer);
  pSerial_Rest5 = malloc(8u);
  memcpy(pSerial_Rest5, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[5], szCurrentSer, szSerialNum_Real);
  pSerial_Rest6 = malloc(8u);
  memcpy(pSerial_Rest6, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[6], szSerialNum_Real, szCurrentSer);
  pSerial_Rest7 = malloc(8u);
  memcpy(pSerial_Rest7, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[7], szCurrentSer, szSerialNum_Real);
  pSerial_Rest8 = malloc(8u);
  memcpy(pSerial_Rest8, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[8], szSerialNum_Real, szCurrentSer);
  pSerial_Rest9 = malloc(8u);
  memcpy(pSerial_Rest9, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[9], szCurrentSer, szSerialNum_Real);
  pSerial_Rest10 = malloc(8u);
  memcpy(pSerial_Rest10, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[10], szSerialNum_Real, szCurrentSer);
  pSerial_Rest11 = malloc(8u);
  memcpy(pSerial_Rest11, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[11], szCurrentSer, szSerialNum_Real);
  pSerial_Rest12 = malloc(8u);
  memcpy(pSerial_Rest12, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[12], szSerialNum_Real, szCurrentSer);
  pSerial_Rest13 = malloc(8u);
  memcpy(pSerial_Rest13, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[13], szCurrentSer, szSerialNum_Real);
  pSerial_Rest14 = malloc(8u);
  memcpy(pSerial_Rest14, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[14], szSerialNum_Real, szCurrentSer);
  pSerial_Rest15 = malloc(8u);
  memcpy(pSerial_Rest15, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[15], szCurrentSer, szSerialNum_Real);
  pSerial_Rest16 = malloc(8u);
  memcpy(pSerial_Rest16, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[16], szSerialNum_Real, szCurrentSer);
  pSerial_Rest17 = malloc(8u);
  memcpy(pSerial_Rest17, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[17], szCurrentSer, szSerialNum_Real);
  pSerial_Rest18 = malloc(8u);
  memcpy(pSerial_Rest18, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[18], szSerialNum_Real, szCurrentSer);
  pSerial_Rest19 = malloc(8u);
  memcpy(pSerial_Rest19, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[19], szCurrentSer, szSerialNum_Real);
  pSerial_Rest20 = malloc(8u);
  memcpy(pSerial_Rest20, &szSerialNum_Real[8], 8u);
  Encode_For_Serial(szKeySerial[20], szSerialNum_Real, szCurrentSer);
  pSerial_Rest21 = malloc(8u);
  memcpy(pSerial_Rest21, &szCurrentSer[8], 8u);
  Encode_For_Serial(szKeySerial[21], szCurrentSer, szSerialNum_Real);
  hModule = LoadLibraryA(LibFileName);
  if ( hModule )
  {
    CreateThread = (HANDLE (__stdcall *)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD))GetProcAddress(hModule, ProcName);
    ((void (__cdecl *)(HANDLE (__stdcall *)(LPSECURITY_ATTRIBUTES, SIZE_T, LPTHREAD_START_ROUTINE, LPVOID, DWORD, LPDWORD)))loc_409DE1)(CreateThread);
  }
  memset(szInput, 0, sizeof(szInput));
  v187[0] = 0xCA;
  v187[1] = 0xE4;
  v187[2] = 0xC8;
  v187[3] = 0xEB;
  v187[4] = 0xD0;
  v187[5] = 0xF2;
  v187[6] = 0xC1;
  v187[7] = 0xD0;
  v187[8] = 0xBA;
  v187[9] = 0xC5;
  strcpy(v188, ":\n");
  printf(v187);    // 输入序列号:
  gets_s(szInput, 0x100u);
  if ( strlen(szInput) >= 0x21 )
    goto LABEL_20;
  for ( k = 0; k < strlen(szInput); ++k )
  {
    if ( szInput[k] >= 'a' && szInput[k] <= 'z' )
      goto LABEL_20;
  }
  szInput_hexdecoded = hexdecode(szInput, 32);
  memset(szInput_encrypted, 0, sizeof(szInput_encrypted));
  sub_403ACA(szInput_hexdecoded, szCurrentSer, szInput_encrypted);
  Encode_For_Serial(szKeySerial[21], szCurrentSer, szSerialNum_Real);
  memset(szDecResult, 0, sizeof(szDecResult));
  memset(szDecCurrent, 0, sizeof(szDecCurrent));
  Decode_For_Serial(szKeySerial[21], szDecResult, szInput_encrypted);
  memcpy(&szDecResult[8], pSerial_Rest21, 8u);
  Decode_For_Serial(szKeySerial[20], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest20, 8u);
  Decode_For_Serial(szKeySerial[19], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest19, 8u);
  Decode_For_Serial(szKeySerial[18], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest18, 8u);
  Decode_For_Serial(szKeySerial[17], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest17, 8u);
  Decode_For_Serial(szKeySerial[16], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest16, 8u);
  Decode_For_Serial(szKeySerial[15], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest15, 8u);
  Decode_For_Serial(szKeySerial[14], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest14, 8u);
  Decode_For_Serial(szKeySerial[13], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest13, 8u);
  Decode_For_Serial(szKeySerial[12], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest12, 8u);
  Decode_For_Serial(szKeySerial[11], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest11, 8u);
  Decode_For_Serial(szKeySerial[10], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest10, 8u);
  Decode_For_Serial(szKeySerial[9], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest9, 8u);
  Decode_For_Serial(szKeySerial[8], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest8, 8u);
  Decode_For_Serial(szKeySerial[7], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest7, 8u);
  Decode_For_Serial(szKeySerial[6], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest6, 8u);
  Decode_For_Serial(szKeySerial[5], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest5, 8u);
  Decode_For_Serial(szKeySerial[4], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest4, 8u);
  Decode_For_Serial(szKeySerial[3], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest3, 8u);
  Decode_For_Serial(szKeySerial[2], szDecCurrent, szDecResult);
  memcpy(&szDecCurrent[8], pSerial_Rest2, 8u);
  Decode_For_Serial(szKeySerial[1], szDecResult, szDecCurrent);
  memcpy(&szDecResult[8], pSerial_Rest1, 8u);
  Decode_For_Serial(szKeySerial[0], szDecCurrent, szDecResult);
  szDecCurrent_[8] = 0;
  memcpy(szDecCurrent_, szDecCurrent, 8u);
  memset(szKeySerialConcat, 0, sizeof(szKeySerialConcat));
  for ( m = 0; m < 50; strcat_s(szKeySerialConcat, 0x400u, szKeySerial[m++]) )
    ;
  memmove(szKeySerialConcat_, szKeySerialConcat, 500u);
  sub_40F9AF(szKeySerialConcat_[0], szDecCurrent_, 1);
  if ( !strcmp(szHash2Hash_, szDecCurrent_) )
    MessageBoxA(0, Text, Caption, 0);
  else
LABEL_20:
    MessageBoxA(0, aFail_0, aFail, 0);
  return 0;
}

注意这些被调用函数的调用约定都是"__cdecl",需要先手动修正过来,否则IDA对栈上临时变量的识别会出问题。

调用的Encode_{X}、RSHash、sub_40F9AF、Encode_For_Serial、sub_403ACA、Decode_For_Serial函数都加了混淆,主要是花指令+垃圾指令+控制流跳转混淆。(例如,jz xxx ; jnz xxx 两个相邻且条件相反的条件跳转指令,等价于一条绝对跳转。)

大概看了一下,感觉模式匹配或许能处理一部分;或者,不处理混淆,动态调试单步执行硬跟的复杂度也能接受。

在此之前,main函数没有混淆,先梳理一下name和serial的数据流。

name输入后,先经过48个Encode_{X}函数运算,再经过RSHash运算,得到szHash2Hash_,作为最后strcmp的第一个参数参与比较。
然后对szHash2Hash先做两次sub_40F9AF_0(以0作为第三个参数调用sub_40F9AF)运算再做21次Encode_For_Serial运算可得到szCurrentSer。
serial输入后,先hexdecode,再与szCurrentSer一起做sub_403ACA运算,然后是22次Decode_For_Serial运算,最后是sub_40F9AF_1(以1作为第三个参数调用sub_40F9AF)运算,得到szDecCurrent_,作为最后strcmp的第二个参数参与比较,如果与szHash2Hash_相等则通过校验。

但是,如果在输入serial之前最后一个调用的Encode_For_Serial和输入serial之后第一个调用的Decode_For_Serial下断点,可以发现它们的参数是互逆的。这表明,从szHash2Hash出发,依次做 2次sub_40F9AF_0 -> 22次Encode_For_Serial -> 22次Decode_For_Serial -> 1次sub_40F9AF_1,会得到与szHash2Hash相等的值,而已知Encode_For_Serial与Decode_For_Serial互逆,所以 2次sub_40F9AF_0 与 1次sub_40F9AF_0 互逆,这几个函数混淆后的代码都无需关注。

所以,现在只有sub_403ACA的逻辑未知且找不到它的逆函数。动态调试发现它的前两个参数是输入,第三个参数是输出。

当已知name时,沿着数据流可以正向得到szCurrentSer作为sub_403ACA的第二个参数,同时可以正向得到szHash2Hash,经判等转到szDecCurrent_,再逆向 1次sub_40F9AF_1+22次Decode_For_Serial可得到sub_403ACA的第三个参数 (前面验证了这个逆向的过程等同于 2次sub_40F9AF_0+22次Encode_For_Serial,所以直接在0x40347A,即最后一个Encode_For_Serial的位置下断点看此时栈上的参数即可获得具体值) 。

总结下来,在已知name时,sub_403ACA的第二个参数和第三个参数都可以获得,而第一个参数是待求的serial,所以只需要逆向这一个函数即可。


静态逆向?代码混淆着实非常讨厌,这里从动态调试入手分析。

动态调试观察到sub_403ACA函数的三个参数,每个长度都是16字节,且前两个参数即使改一个bit第三个参数的输出也会完全改变,所以这很可能是某种16字节的块加密算法。

对前两个参数所在的内存下硬件数据读写断点,在经历一次数据复制后到达了栈上19EDB4的位置,此后的数据访问都发生在这里。
实测发现,需要对第一个参数(即serial)的4个四字节都下上硬件读写断点,如果偷懒只下一个或两个程序有可能会闪退。具体原因未深究,但是注意到main函数有启动一个新的线程,且如果patch掉这块代码,程序会在sub_403ACA闪退,所以这里可能有特殊的检测。代码混淆太恶心了,不想去碰。

初始:name和serial分别输入题目提供的值:CCFE84316BD02C02和D532E41AFE55A4265D7789C84BF40384

对第二个参数下好4个断点,逐步按F9并跟随数据复制修改断点位置,发现代码在逐渐填充19ECF0到19EDAF之间的数据,填充数量合计11*4个四字节。

1
2
3
4
5
6
7
8
9
10
11
12
13
0019ECE4  00 00 00 00 FE FF FF FF 01 00 00 00 30 45 39 41  ....þÿÿÿ....0E9A 
0019ECF4  DA 9F A6 E7 58 C7 61 86 38 FF 9E 18 60 9F 01 19  Ú.¦çXÇa.8ÿ..`... 
0019ED04  53 CC CD D4 9D 51 9C 48 17 46 DA 92 D1 97 4D DF  SÌÍÔ.Q.H.FÚ.Ñ.Mß 
0019ED14  E6 71 3C E3 6B 1A 26 C5 45 34 41 45 B4 80 C1 84  æq<ãk.&ÅE4AE´.Á. 
0019ED24  E9 69 A8 2C 06 6F C7 EB DB B4 73 98 E0 54 27 BF  éi¨,.oÇëÛ´s.àT'¿ 
0019ED34  47 13 34 8B F0 E3 D7 5C 28 CB 1C 40 65 AE B2 F2  G.4.ðã×\(Ë.@e®²ò 
0019ED44  39 97 25 D7 33 37 37 34 69 5E 69 5D 5F 01 68 35  9.%×3774i^i]_.h5 
0019ED54  BB BA D2 E7 3F 85 57 B0 BF 3A 6D DD 67 5D 30 ED  »ºÒç?.W°¿:mÝg]0í 
0019ED64  E5 B8 88 65 F3 4B C3 A6 0F 44 87 21 EF AB 2C 0D  å¸.eóKæ.D.!ï«,. 
0019ED74  39 45 37 43 FA BF 88 CB 27 98 10 DB 83 1B 0B D0  9E7Cú¿.Ë'..Û...Р
0019ED84  44 5F 54 84 EA B5 E1 65 E9 5C BD D8 55 09 B4 6C  D_T.êµáeé\½ØU.´l 
0019ED94  62 6B DF B3 3C 57 88 3B BA ED 65 5E 30 45 39 41  bkß³<W.;ºíe^0E9A 
0019EDA4  45 34 41 45 33 37 37 34 39 45 37 43 00 00 00 00  E4AE37749E7C.... 

对第一个参数下好4个断点,同样按F9并跟随数据复制修改断点位置,观察到19EDB4数据的变化,发现有逐单字节改变和逐四字节改变的交替

重新开始单步调试,观察到这里数据的变化有几个阶段:

初始:
19EDB4的数据清零;堆区有分配的serial值(注意8BD8D8这个地址不是固定的)

1
008BD8D8  D5 32 E4 1A FE 55 A4 26 5D 77 89 C8 4B F4 03 84  Õ2ä.þU¤&]w.ÈKô.. 

第一步:把serial值复制到19EDB4处,复制时以4为间隔步长(另一个角度理解,相当于4*4矩阵的转置)
新的数值:

1
0019EDB4  D5 FE 5D 4B 32 55 77 F4 E4 A4 89 03 1A 26 C8 84

第二步:19EDB4开始的4个四字节,分别与19ECF8、19ED24、19ED50、19ED7C的4个四字节异或
待异或的值:

1
58 C7 61 86 E9 69 A8 2C 5F 01 68 35 27 98 10 DB

异或之后的值:

1
0019EDB4  8D 39 3C CD DB 3C DF D8 BB A5 E1 36 3D BE D8 5F  .9<ÍÛ<ßØ»¥á6=¾Ø_ 

第三步:19EDB4位置,4个字节一组,第一组不变,第二组循环左移1字节,第三组循环左移3字节,第四组循环左移2字节
变化之后的值:

1
0019EDB4  8D 39 3C CD 3C DF D8 DB 36 BB A5 E1 D8 5F 3D BE  .9<Í<ßØÛ6»¥áØ_=¾ 

第四步:19EDB4的每个字节做一次查表变换,表在0x62C700,位于程序的.rdata段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
0062C700
    0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F
0  28 C2 E8 57 48 24 97 C5  18 8C 9B 72 F7 99 DE D3
1  85 58 7A 0B 44 D1 B0 47  C7 AE F0 6D 53 E1 60 B4
2  4B 5C 10 52 01 39 B9 90  AB 00 D4 73 64 32 9F A1
3  6A 1C 6B 21 F1 EF 3F 67  95 F2 79 E0 0C D0 66 7F
4  2C C3 12 5A 34 EB 15 A6  BC 7D A0 B8 55 49 C1 FB
5  E9 08 3C E2 56 2F 30 9E  0E CB 25 E3 46 5D EC 4C
6  09 BE 87 04 89 D8 19 3D  71 40 7E 5F 16 7B 3A 27
7  43 76 45 8A 35 96 F9 07  8F 0F 54 CF BA 38 83 CE
8  2A AC 68 F4 80 31 A4 FE  93 B3 7C CA B6 75 DA A8
9  D7 B1 37 C4 6C 6F D5 4F  23 14 98 AA DC 65 74 42
A  C8 41 8D A5 22 EA 4D B5  17 02 1E 88 91 33 C6 78
3B 2D D9 FC 1B 9A CD E6  1F ED 92 29 4A FA 1A EE
0D E7 63 8E FF 06 3E 1D  F8 AD E5 36 05 70 A2 69
84 BF A9 8B 03 D6 26 2E  82 62 81 E4 94 A7 AF 5E
9D D2 B2 86 2B 51 CC DD  13 F5 77 50 C0 B7 0A 59
4E C9 BB 11 A3 6E DB F6  61 9C 20 DF FD BD 5B F3

变换之后:

1
0019EDB4  75 F2 0C 70 0C 5E 82 E4 3F 29 EA D2 82 4C D0 1A  uò.p.^.ä?)êÒ.LÐ. 

至此,数据的变换已经出现了明显的AES特征。第二、三、四步分别可能对应addroundkey、shiftrows/invshiftrows、subbytes/invsubbytes。

回顾一下10轮AES-128加密和解密的步骤:

加密:

1
2
3
4
5
6
7
8
9
addroundkey roundkey_0
for i = 1..9:
    subbytes
    shiftrows
    mixcolumns
    addroundkey roundkey_i
subbytes
shiftrows
addroundkey roundkey_10

解密:

1
2
3
4
5
6
7
8
9
addroundkey roundkey_10
invshiftrows
invsubbytes
for i = 9..1:
    addroundkey roundkey_i
    invmixcolumns
    invshiftrows
    invsubbytes
addroundkey roundkey_0

目前的第二、三、四步,与加密的前三步不同,与解密的前三步能对应上,且能够确认的是invshiftrows有魔改(每行移位的数量与标准算法不同)、invsbox有修改。

按照AES解密的逻辑,下一个步骤应该是invmixcolumns。先前找到了魔改过的invsbox在全局变量byte_62C700,而它附近的byte_62C800恰好是对应的sbox,且在.text段有交叉引用(这或许预示着sub_403ACA的逆函数就在程序里,但那又有什么用呢,代码混淆解开之前根本找不到入口点在哪里);再看附近的内存,byte_62C900 (02 03 01 01 01 02 03 01 01 01 02 03 03 01 01 02) 和byte_62C910分别是mixcolumns和invmixcolumns矩阵的标准形式,所以invmixcolumns应该没有经过魔改。继续单步调试,数据变换与标准的invmixcolumns计算结果相同,证明确实如此。

最后是addroundkey使用的轮密钥,调试发现是19ECF0到19EDAF之间填充的值,但每轮并不是按顺序取值。在这块区域下数据访问断点,多调试几轮,可以找出具体顺序。


基于以上分析,写出aes_dec复现sub_403ACA的逻辑,动态调试验证结果正确后改写为aes_enc,得到serial生成脚本如下:

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
import phoenixAES    # pip install phoenixAES
 
sbox = bytes.fromhex("""
29 24 A9 D4 63 CC C5 77  51 60 EE 13 3C C0 58 79
22 F3 42 E8 99 46 6C A8  08 66 BE B4 31 C7 AA B8
FA 33 A4 98 05 5A D6 6F  00 BB 80 E4 40 B1 D7 55
56 85 2D AD 44 74 CB 92  7D 25 6E B0 52 67 C6 36
69 A1 9F 70 14 72 5C 17  04 4D BC 20 5F A6 F0 97
EB E5 23 1C 7A 4C 54 03  11 EF 43 FE 21 5D DF 6B
1E F8 D9 C2 2C 9D 3E 37  82 CF 30 32 94 1B F5 95
CD 68 0B 2B 9E 8D 71 EA  AF 3A 12 6D 8A 49 6A 3F
84 DA D8 7E D0 10 E3 62  AB 64 73 D3 09 A2 C3 78
27 AC BA 88 DC 38 75 06  9A 0D B5 0A F9 E0 57 2E
4A 2F CE F4 86 A3 47 DD  8F D2 9B 28 81 C9 19 DE
16 91 E2 89 1F A7 8C ED  4B 26 7C F2 48 FD 61 D1
EC 4E 01 41 93 07 AE 18  A0 F1 8B 59 E6 B6 7F 7B
3D 15 E1 0F 2A 96 D5 90  65 B2 8E F6 9C E7 0E FB
3B 1D 53 5B DB CA B7 C1  02 50 A5 45 5E B9 BF 35
1A 34 39 FF 83 E9 F7 0C  C8 76 BD 4F B3 FC 87 C4
""")
 
invsbox = bytes.fromhex("""
28 C2 E8 57 48 24 97 C5  18 8C 9B 72 F7 99 DE D3
85 58 7A 0B 44 D1 B0 47  C7 AE F0 6D 53 E1 60 B4
4B 5C 10 52 01 39 B9 90  AB 00 D4 73 64 32 9F A1
6A 1C 6B 21 F1 EF 3F 67  95 F2 79 E0 0C D0 66 7F
2C C3 12 5A 34 EB 15 A6  BC 7D A0 B8 55 49 C1 FB
E9 08 3C E2 56 2F 30 9E  0E CB 25 E3 46 5D EC 4C
09 BE 87 04 89 D8 19 3D  71 40 7E 5F 16 7B 3A 27
43 76 45 8A 35 96 F9 07  8F 0F 54 CF BA 38 83 CE
2A AC 68 F4 80 31 A4 FE  93 B3 7C CA B6 75 DA A8
D7 B1 37 C4 6C 6F D5 4F  23 14 98 AA DC 65 74 42
C8 41 8D A5 22 EA 4D B5  17 02 1E 88 91 33 C6 78
3B 2D D9 FC 1B 9A CD E6  1F ED 92 29 4A FA 1A EE
0D E7 63 8E FF 06 3E 1D  F8 AD E5 36 05 70 A2 69
84 BF A9 8B 03 D6 26 2E  82 62 81 E4 94 A7 AF 5E
9D D2 B2 86 2B 51 CC DD  13 F5 77 50 C0 B7 0A 59
4E C9 BB 11 A3 6E DB F6  61 9C 20 DF FD BD 5B F3
""")
 
def transpose(state):
    return bytearray([state[0], state[4], state[8], state[12],
                      state[1], state[5], state[9], state[13],
                      state[2], state[6], state[10], state[14],
                      state[3], state[7], state[11], state[15]])
 
def addroundkey(state, key):
    return phoenixAES.xor(state, key)
 
def subbytes(state):
    return bytearray([sbox[x] for x in state])
 
def invsubbytes(state):
    return bytearray([invsbox[x] for x in state])
 
def shiftrows(state):
    return bytearray([state[0], state[1], state[2], state[3],
                      state[7], state[4], state[5], state[6],
                      state[9], state[10], state[11], state[8],
                      state[14], state[15], state[12], state[13]])
 
def invshiftrows(state):
    return bytearray([state[0], state[1], state[2], state[3],
                      state[5], state[6], state[7], state[4],
                      state[11], state[8], state[9], state[10],
                      state[14], state[15], state[12], state[13]])
 
def mixcolumns(state):
    return transpose(phoenixAES.MC(transpose(state)))
 
def invmixcolumns(state):
    return transpose(phoenixAES.InvMC(transpose(state)))
 
def aes_enc_internal(state, keys):
    state = addroundkey(state, keys[0])
    for i in range(1, 10):
        state = subbytes(state)
        state = shiftrows(state)
        state = mixcolumns(state)
        state = addroundkey(state, keys[i])
    state = subbytes(state)
    state = shiftrows(state)
    state = addroundkey(state, keys[10])
    return state
 
def aes_dec_internal(state, keys):
    state = addroundkey(state, keys[10])
    state = invshiftrows(state)
    state = invsubbytes(state)
    for i in range(9, 0, -1):
        state = addroundkey(state, keys[i])
        state = invmixcolumns(state)
        state = invshiftrows(state)
        state = invsubbytes(state)
    state = addroundkey(state, keys[0])
    return state
 
def aes_enc(plaintext, keys):
    state = transpose(plaintext)
    state = aes_enc_internal(state, keys)
    ciphertext = transpose(state)
    return ciphertext
 
def aes_dec(ciphertext, keys):
    state = transpose(ciphertext)
    state = aes_dec_internal(state, keys)
    plaintext = transpose(state)
    return plaintext
 
def parse_keys(buf):
    keys = [None for _ in range(11)]
    for i in range(11):
        group = 0 if i == 0 else ( 2*i-1 if i<=5 else 22-2*i )
        offset = group*4
        key = []
        for j in range(4):
            key += buf[offset+11*4*j:offset+11*4*j+4]
        keys[i] = key
    return keys
 
 
keys = parse_keys(bytes.fromhex("""
34 31 41 43 C4 F5 B4 F7 76 83 37 C0 63 E0 D7 17 
8D 6D BA AD DE B3 09 A4 1F AC A5 01 B8 14 B1 B0 
2A 3E 8F 3F 85 BB 34 0B 3D 86 B2 B9 30 41 34 34 
57 16 22 16 D1 C7 E5 F3 66 A1 44 B7 22 83 C7 70 
29 AA 6D 1D 1B B1 DC C1 EE 5F 83 42 81 DE 5D 1F 
5F 81 DC C3 F1 70 AC 6F 30 33 42 37 A5 96 D4 E3 
4C DA 0E ED 2D F7 F9 14 09 FE 07 13 C7 39 3E 2D 
C3 FA C4 E9 42 B8 7C 95 5F E7 9B 0E 6B 8C 17 19 
38 B4 A3 BA 34 36 30 38 6E 58 68 50 98 C0 A8 F8 
95 55 FD 05 D2 87 7A 7F E1 66 1C 63 C3 A5 B9 DA 
01 A4 1D C7 3A 9E 83 44 45 DB 58 1C 37 EC B4 A8 
"""))    # input name is KCTF, dumped from 0019ECF0 when breakpoint at 0x40347A
 
plaintext = b"914760739524BCD5"    # input name is KCTF, dumped from [esp+8] when breakpoint at 0x40347A
 
r = aes_enc(plaintext, keys)
print("serial: ", r.hex().upper())    # 8BCBB6979E174CB7ECAEACDA104522CA

最终答案:

1
2
name: KCTF
serial: 8BCBB6979E174CB7ECAEACDA104522CA

多解:
hexdecode之前只检查了不出现小写字母,但调试发现如果输入的字符不在[0-9A-F]会视为0,所以serial中的0可以替换为几乎所有字符,例如:
8BCBB6979E174CB7ECAEACDA1G4522CA
(题目过滤小写字母大概是想避免2022H2的大小写多解,但是,基于黑名单的过滤总是容易出现意外惊喜;既然做了字符过滤,换成白名单,限制只允许[0-9A-F]即可轻松解决(用哈希虽然也能限制多解,但是缺了灵魂))


正文结束

最后,作为对攻击方“在最终成绩公布前请在【答案提交区】发表解题分析文章、所用工具、源代码等材料,且文章有理有据能够详细完成说明自己获得答案的整个过程”的对等要求,在此恳请组委会,要求此题防守方能公开此题做混淆处理过程的源代码(注意这不同于crackme混淆前的源代码)(ref:看雪·2023 KCTF 年度赛【防守方】规则 方案二,“所提交的壳或VM或其他手工处理的方法将在赛后向广大会员公开”,https://bbs.kanxue.com/thread-276642.htm,这里是不是应该理解为用出题人公开的源代码按照出题人公开的方法要能够生成最终的二进制文件?另外.obj文件显然并不等同于源代码),以及,验题时出题人/验题人以攻击者视角做题时的具体去混淆方法和处理代码(这里 描述的破解思路,显然过于简洁,并不满足“有理有据能够详细完成说明自己获得答案的整个过程”的(虽然这是对攻击方的要求,但防守方自己出的题,达成同样的要求会更简单);或者说,出题人给出的题解,至少要充分详细到让一个完全没有做过这道题的人照着抄答案能够破解掉题目,对于加了混淆的题目,详细且可复现的去混淆方法当然是必备的)。


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2023-9-18 21:34 被mb_mgodlfyn编辑 ,原因:
收藏
点赞3
打赏
分享
最新回复 (5)
雪    币: 8283
活跃值: (4811)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
v0id_ 2023-9-17 13:15
2
0
哈哈哈,《当Archaia出现在今年的防守方列表时,就有预感大概率是把2022H2的题目修了非预期再出。》
雪    币: 7
活跃值: (42)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
ThisCha 2023-9-17 14:42
3
0
这个,由于混淆模式是固定的,通过调试识别相应的混淆代码,手工查找替换或者编写脚本就能反混淆,本身也是没有对调试是没有限制的
雪    币: 3507
活跃值: (17964)
能力值: ( LV12,RANK:277 )
在线值:
发帖
回帖
粉丝
0x指纹 5 2023-9-18 08:44
4
0
感谢分享,很精彩
雪    币: 19410
活跃值: (29069)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋狝 2023-9-18 08:45
5
1
感谢分享
雪    币: 1954
活跃值: (3653)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
method 2023-9-18 11:54
6
0
确实,出题方管杀不管埋
游客
登录 | 注册 方可回帖
返回