最近和学长们打了一些大比赛,看了下来发现 VMP 有点多哈 😅。总不能每次见到就投降吧。

什么是 VMP

VMP 全称是 “基于虚拟机的代码保护技术” (Virtual Machine-Based Protection)。当然,和各位可能听到过的 VMWare 等不太一样,程序保护中的 “虚拟机” 更多像 “解释器”:虚拟机先将原始代码翻译成其自己的专有字节码(这个过程称为虚拟化),然后在运行时解释并执行字节码对应语句。

专业点说,就是使用自己的一套指令集架构(指令、内存、寄存器、权限……)作为中间层,隐藏实际的通用架构指令。

这种保护技术的特点是,我们不能直接看到自己可能熟悉的原始指令;我们必须首先分析解释器,然后使用所获得的自定义指令集知识将专有字节码转换为我们熟悉的标准指令。

最基础的 VM

用 C 的 switch-case 语句就能构建一个非常简单的 VM:

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
#include <stdio.h>

int vm(int* opcode, int opleng)
{
  int pc = 0;
  if(opleng <= 0)
  {
    printf("Invaild length of opcode array\n");
    return 1;
  }
  else
  {
    while(pc != opleng)
    {
      switch(opcode[pc])
      {
        // ...
        default:
          printf("Invalid opcode: 0x%x at position %d\n", opcode[pc], pc);
          return 2;
      }
      pc++;
    }
  }
  return 0;
}

int main(void)
{
  int opcode[] = {...};
  int opleng = sizeof(opcode) / sizeof(opcode[0]);

  vm(opcode, opleng);
  return 0;
}

这个 VM 会按顺序执行 opcode[] 定义的的字节码,通过 switch(opcode[pc]) 指定如何解释字节码行为,还有基本的错误处理功能。

当然,这个 VM 是禁不住考验的:对于防守方,opcode 的复用性差劲,没有完全实现 “解释器” 功能;对于攻击方,整个架构太简单,VM 本身也变得需要保护。

从计组讲起

指令执行的五个阶段分为取指 (Fetch)、译码 (Decode)、执行 (Execute)、访存、写回。VM 就是要部分模拟这个过程,一般是取指、译码、分发 (Dispatch)、执行。其中分发环节是 VM 设计的重点。

我们上面给出的简单 VM 就演示了 switch-case dispatch 这种分发方式。

以一道 CTF 题目为基础

L3HCTF 2025 easyvm

视频:【星盟安全】L3HCTF 逆向方向 easyvm 讲解

字符串定位主函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
sub_140005940();
v2 = std::operator<<<std::char_traits<char>>(a1, a2, "Welcome to L3HCTF2025!!!Do you love cpp and vm?", &std::cout);
std::ostream::operator<<(a1, a2, &std::endl<char,std::char_traits<char>>, v2);
sub_140011D30(a1, a2, v3, v29, v4, v5);
sub_140017DF0(a1, a2, &unk_140022040, v28, v6, v7);
sub_140010700(a1, a2, v28, v29, v8, v9);
v10 = std::operator<<<std::char_traits<char>>(a1, a2, "Explore this virtual machine and have fun!", &std::cout);
std::ostream::operator<<(a1, a2, &std::endl<char,std::char_traits<char>>, v10);
v11 = std::operator<<<std::char_traits<char>>(a1, a2, "Plz show me flag:", &std::cout);
std::ostream::operator<<(a1, a2, &std::endl<char,std::char_traits<char>>, v11);
sub_140011C40(a1, a2, v12, v29, v13, v14);
sub_140011AB0(a1, a2, v15, v29, v16, v17);
sub_140011AE0(a1, a2, v18, v29, v19, v20);
sub_140017FC0(a1, a2, v21, v28, v22, v23);
sub_140011DE0(a1, a2, v24, v29, v25, v26);

我们主要看提示输入 flag 后的这 4 个函数。

sub_140011C40 里面有一个格式化字符串 %s,猜测作用是读取输入的 flag。

sub_140011AB0 内的 sub_1400107E0 里有着大量的 switch-case 结构:

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
__int64 __fastcall sub_1400107E0(void *Ix, int a2, int a3, __int64 a4, int a5, int a6)
{
  unsigned __int64 v6; // rbx
  int v7; // r8d
  int v8; // r9d
  int v11; // edx
  int v12; // r8d
  int v13; // r9d
  unsigned __int8 n2; // al
  int v15; // edx
  int v16; // r8d
  int v17; // r9d
  int v18; // edx
  int v19; // r8d
  int v20; // r9d
  int v21; // r8d
  int v22; // r9d
  int v23; // edx
  int v24; // r8d
  int v25; // r9d
  int v26; // edx
  int v27; // r8d
  int v28; // r9d
  int v29; // edx
  int v30; // r8d
  int v31; // r9d
  int v32; // edx
  int v33; // r8d
  int v34; // r9d
  int v35; // r8d
  int v36; // r9d
  int v37; // r8d
  int v38; // r9d
  int v39; // edx
  int v40; // r8d
  int v41; // r9d
  int v42; // edx
  int v43; // r8d
  int v44; // r9d
  int v45; // edx
  int v46; // r8d
  int v47; // r9d
  int v48; // edx
  int v49; // r8d
  int v50; // r9d
  int v51; // r8d
  int v52; // r9d
  int v53; // edx
  int v54; // r8d
  int v55; // r9d
  int v56; // edx
  int v57; // r8d
  int v58; // r9d
  int v59; // edx
  int v60; // r8d
  int v61; // r9d
  int v62; // edx
  int v63; // r8d
  int v64; // r9d
  int v65; // r8d
  int v66; // r9d
  int v67; // edx
  int v68; // r8d
  int v69; // r9d
  int v70; // edx
  int v71; // r8d
  int v72; // r9d
  int v73; // edx
  int v74; // r8d
  int v75; // r9d
  int v76; // edx
  int v77; // r8d
  int v78; // r9d
  int v79; // r8d
  int v80; // r9d
  int v81; // edx
  int v82; // r8d
  int v83; // r9d
  int v84; // edx
  int v85; // r8d
  int v86; // r9d
  int v87; // edx
  int v88; // r8d
  int v89; // r9d
  int v90; // edx
  int v91; // r8d
  int v92; // r9d
  int v93; // r8d
  int v94; // r9d
  int v95; // edx
  int v96; // r8d
  int v97; // r9d
  int v98; // edx
  int v99; // r8d
  int v100; // r9d
  int v101; // edx
  int v102; // r8d
  int v103; // r9d
  int v104; // edx
  int v105; // r8d
  int v106; // r9d
  int v107; // r8d
  int v108; // r9d
  int v109; // edx
  int v110; // r8d
  int v111; // r9d
  int v112; // edx
  int v113; // r8d
  int v114; // r9d
  int v115; // r8d
  int v116; // r9d
  int v117; // edx
  int v118; // r8d
  int v119; // r9d
  int v120; // edx
  int v121; // r8d
  int v122; // r9d
  int v123; // edx
  int v124; // r8d
  int v125; // r9d
  int v126; // edx
  int v127; // r8d
  int v128; // r9d
  int v129; // r8d
  int v130; // r9d
  int v131; // edx
  int v132; // r8d
  int v133; // r9d
  int v134; // edx
  int v135; // r8d
  int v136; // r9d
  int v137; // edx
  int v138; // r8d
  int v139; // r9d
  int v140; // edx
  int v141; // r8d
  int v142; // r9d
  int v143; // r8d
  int v144; // r9d
  int v145; // edx
  int v146; // r8d
  int v147; // r9d
  int v148; // edx
  int v149; // r8d
  int v150; // r9d
  int v151; // edx
  int v152; // r8d
  int v153; // r9d
  int v154; // edx
  int v155; // r8d
  int v156; // r9d
  int v157; // r8d
  int v158; // r9d
  int v159; // edx
  int v160; // r8d
  int v161; // r9d
  int v162; // edx
  int v163; // r8d
  int v164; // r9d
  int v165; // edx
  int v166; // r8d
  int v167; // r9d
  int v168; // edx
  int v169; // r8d
  int v170; // r9d
  int v171; // r8d
  int v172; // r9d
  int v173; // edx
  int v174; // r8d
  int v175; // r9d
  int v176; // edx
  int v177; // r8d
  int v178; // r9d
  int v179; // edx
  int v180; // r8d
  int v181; // r9d
  int v182; // edx
  int v183; // r8d
  int v184; // r9d
  int v185; // r8d
  int v186; // r9d
  int v187; // edx
  int v188; // r8d
  int v189; // r9d
  int v190; // edx
  int v191; // r8d
  int v192; // r9d
  int v193; // edx
  int v194; // r8d
  int v195; // r9d
  int v196; // edx
  int v197; // r8d
  int v198; // r9d
  int v199; // r8d
  int v200; // r9d
  int v201; // edx
  int v202; // r8d
  int v203; // r9d
  int v204; // edx
  int v205; // r8d
  int v206; // r9d
  int v207; // edx
  int v208; // r8d
  int v209; // r9d
  int v210; // edx
  int v211; // r8d
  int v212; // r9d
  int v213; // r8d
  int v214; // r9d
  BOOL v215; // eax
  int v216; // edx
  int v217; // r8d
  int v218; // r9d
  int v219; // edx
  int v220; // r8d
  int v221; // r9d
  int v222; // edx
  int v223; // r8d
  int v224; // r9d
  int v225; // edx
  int v226; // r8d
  int v227; // r9d
  int v228; // r8d
  int v229; // r9d
  BOOL v230; // eax
  int v231; // edx
  int v232; // r8d
  int v233; // r9d
  int v234; // edx
  int v235; // r8d
  int v236; // r9d
  int v237; // r8d
  int v238; // r9d
  int v239; // edx
  int v240; // r8d
  int v241; // r9d
  int v242; // edx
  int v243; // r8d
  int v244; // r9d
  int v245; // edx
  int v246; // r8d
  int v247; // r9d
  int v248; // edx
  int v249; // r8d
  int v250; // r9d
  int v251; // r9d
  int v252; // edx
  int v253; // r8d
  int v254; // r9d
  int v255; // edx
  int v256; // r8d
  int v257; // r9d
  int v258; // edx
  int v259; // r8d
  int v260; // r9d
  int v261; // edx
  int v262; // r8d
  int v263; // r9d
  int v264; // r9d
  int v265; // edx
  int v266; // r8d
  int v267; // r9d
  int v268; // edx
  int v269; // r8d
  int v270; // r9d
  int v271; // r8d
  int v272; // r9d
  int v273; // eax
  int v274; // r8d
  int v275; // r9d
  int v276; // edx
  int v277; // r8d
  int v278; // r9d
  int v279; // edx
  int v280; // r8d
  int v281; // r9d
  int v282; // edx
  int v283; // r8d
  int v284; // r9d
  int v285; // edx
  int v286; // r8d
  int v287; // r9d
  int v288; // ebx
  int v289; // r8d
  int v290; // r9d
  int v291; // edx
  int v292; // r8d
  int v293; // r9d
  int v294; // edx
  int v295; // r8d
  int v296; // r9d
  int v297; // edx
  int v298; // r8d
  int v299; // r9d
  int v300; // edx
  int v301; // r8d
  int v302; // r9d
  int v303; // edx
  int v304; // r8d
  int v305; // r9d
  int v306; // edx
  int v307; // r8d
  int v308; // r9d
  int v309; // edx
  int v310; // r8d
  int v311; // r9d
  int v312; // edx
  int v313; // r8d
  int v314; // r9d
  int v315; // r8d
  int v316; // r9d
  int v317; // edx
  int v318; // r8d
  int v319; // r9d
  __int64 *v320; // rax
  __int64 v321; // rdx
  int v322; // r8d
  int v323; // r9d
  __int64 v324; // [rsp+0h] [rbp-80h]
  __int64 v325; // [rsp+0h] [rbp-80h]
  __int64 v326; // [rsp+0h] [rbp-80h]
  __int64 v327; // [rsp+8h] [rbp-78h]
  int v328; // [rsp+28h] [rbp-58h] BYREF
  int v329; // [rsp+2Ch] [rbp-54h] BYREF
  int v330; // [rsp+30h] [rbp-50h] BYREF
  int v331; // [rsp+34h] [rbp-4Ch] BYREF
  int v332; // [rsp+38h] [rbp-48h] BYREF
  int v333; // [rsp+3Ch] [rbp-44h] BYREF
  int v334; // [rsp+40h] [rbp-40h] BYREF
  int v335; // [rsp+44h] [rbp-3Ch] BYREF
  int v336; // [rsp+48h] [rbp-38h] BYREF
  int v337; // [rsp+4Ch] [rbp-34h] BYREF
  BOOL v338; // [rsp+50h] [rbp-30h] BYREF
  BOOL v339; // [rsp+54h] [rbp-2Ch] BYREF
  BOOL v340; // [rsp+58h] [rbp-28h] BYREF
  BOOL v341; // [rsp+5Ch] [rbp-24h] BYREF
  BOOL v342; // [rsp+60h] [rbp-20h] BYREF
  BOOL v343; // [rsp+64h] [rbp-1Ch] BYREF
  BOOL v344; // [rsp+68h] [rbp-18h] BYREF
  BOOL v345; // [rsp+6Ch] [rbp-14h] BYREF
  BOOL v346; // [rsp+70h] [rbp-10h] BYREF
  int v347; // [rsp+74h] [rbp-Ch] BYREF
  unsigned int v348; // [rsp+78h] [rbp-8h] BYREF
  unsigned int v349; // [rsp+7Ch] [rbp-4h] BYREF
  unsigned int v350; // [rsp+80h] [rbp+0h] BYREF
  int v351; // [rsp+84h] [rbp+4h] BYREF
  __int64 v352; // [rsp+88h] [rbp+8h] BYREF
  int v353; // [rsp+90h] [rbp+10h]
  int v354; // [rsp+94h] [rbp+14h]
  int v355; // [rsp+98h] [rbp+18h]
  int v356; // [rsp+9Ch] [rbp+1Ch]
  int v357; // [rsp+A0h] [rbp+20h]
  int v358; // [rsp+A4h] [rbp+24h]
  unsigned int v359; // [rsp+A8h] [rbp+28h]
  unsigned int v360; // [rsp+ACh] [rbp+2Ch]
  unsigned int v361; // [rsp+B0h] [rbp+30h]
  unsigned int v362; // [rsp+B4h] [rbp+34h]
  int v363; // [rsp+B8h] [rbp+38h]
  int v364; // [rsp+BCh] [rbp+3Ch]
  unsigned int v365; // [rsp+C0h] [rbp+40h]
  int v366; // [rsp+C4h] [rbp+44h]
  int v367; // [rsp+C8h] [rbp+48h]
  int v368; // [rsp+CCh] [rbp+4Ch]
  int v369; // [rsp+D0h] [rbp+50h]
  int v370; // [rsp+D4h] [rbp+54h]
  int v371; // [rsp+D8h] [rbp+58h]
  int v372; // [rsp+DCh] [rbp+5Ch]
  unsigned int v373; // [rsp+E0h] [rbp+60h]
  unsigned int v374; // [rsp+E4h] [rbp+64h]
  unsigned int v375; // [rsp+E8h] [rbp+68h]
  unsigned int v376; // [rsp+ECh] [rbp+6Ch]
  unsigned int v377; // [rsp+F0h] [rbp+70h]
  unsigned int v378; // [rsp+F4h] [rbp+74h]
  unsigned int v379; // [rsp+F8h] [rbp+78h]
  unsigned int v380; // [rsp+FCh] [rbp+7Ch]
  int v381; // [rsp+100h] [rbp+80h]
  int v382; // [rsp+104h] [rbp+84h]
  int v383; // [rsp+108h] [rbp+88h]
  int v384; // [rsp+10Ch] [rbp+8Ch]
  int v385; // [rsp+110h] [rbp+90h]
  unsigned int v386; // [rsp+114h] [rbp+94h]
  int v387; // [rsp+118h] [rbp+98h]
  unsigned int v388; // [rsp+11Ch] [rbp+9Ch]
  int v389; // [rsp+120h] [rbp+A0h]
  int v390; // [rsp+124h] [rbp+A4h]
  __int64 v391; // [rsp+128h] [rbp+A8h]

  v6 = *(a4 + 240);
  if ( v6 >= sub_140012B20(Ix, a2, a3, a4, a5, a6) || *(a4 + 248) )
    return 0;
  v391 = sub_140018360(Ix, a2, *(a4 + 240), a4, v7, v8);
  n2 = *v391;
  if ( *v391 == 0xFF )
  {
    *(a4 + 248) = 1;
    return 0;
  }
  else
  {
    if ( n2 < 0x60u )
    {
      if ( n2 == 84 )
      {
        if ( sub_140012AD0(Ix, a2, v11, a4 + 160, v12, v13) != 1 )
        {
          v320 = sub_1400178A0(Ix, a2, v317, a4 + 160, v318, v319);
          v321 = *v320;
          *(a4 + 240) = *v320;
          sub_140017840(Ix, a2, v321, a4 + 160, v322, v323);
          return 1;
        }
      }
      else if ( n2 <= 0x54u )
      {
        switch ( n2 )
        {
          case 'S':
            v352 = *(a4 + 240) + 1LL;
            sub_140017900(Ix, a2, &v352, a4 + 160, v12, v13);
            *(a4 + 240) = *(v391 + 4);
            return 1;
          case 'R':
            if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
            {
              v390 = *sub_140017720(Ix, a2, v297, a4 + 24, v298, v299);
              sub_1400176C0(Ix, a2, v300, a4 + 24, v301, v302);
              if ( v390 )
              {
                *(a4 + 240) = *(v391 + 4);
                return 1;
              }
            }
            break;
          case 'Q':
            if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
            {
              v389 = *sub_140017720(Ix, a2, v291, a4 + 24, v292, v293);
              sub_1400176C0(Ix, a2, v294, a4 + 24, v295, v296);
              if ( !v389 )
              {
                *(a4 + 240) = *(v391 + 4);
                return 1;
              }
            }
            break;
          case 'P':
            *(a4 + 240) = *(v391 + 4);
            return 1;
          case 'A':
            if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
            {
              v388 = *sub_140017720(Ix, a2, v276, a4 + 24, v277, v278);
              sub_1400176C0(Ix, a2, v279, a4 + 24, v280, v281);
              v387 = *sub_140017720(Ix, a2, v282, a4 + 24, v283, v284);
              sub_1400176C0(Ix, a2, v285, a4 + 24, v286, v287);
              v288 = v387;
              v350 = v388;
              *sub_140015400(Ix, a2, &v350, a4 + 104, v289, v290, v324, v327) = v288;
            }
            break;
          default:
            if ( n2 <= 0x41u )
            {
              if ( n2 == 64 )
              {
                if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
                {
                  v386 = *sub_140017720(Ix, a2, v265, a4 + 24, v266, v267);
                  sub_1400176C0(Ix, a2, v268, a4 + 24, v269, v270);
                  v349 = v386;
                  v273 = sub_140015400(Ix, a2, &v349, a4 + 104, v271, v272, v324, v327);
                  sub_1400177B0(Ix, a2, v273, a4 + 24, v274, v275, v326);
                }
              }
              else if ( n2 == 50 )
              {
                if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
                {
                  v385 = *sub_140017720(Ix, a2, v231, a4 + 24, v232, v233);
                  sub_1400176C0(Ix, a2, v234, a4 + 24, v235, v236);
                  v346 = v385 == 0;
                  sub_140017780(Ix, a2, &v346, a4 + 24, v237, v238);
                }
              }
              else if ( n2 <= 0x32u )
              {
                switch ( n2 )
                {
                  case '1':
                    if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                    {
                      v384 = *sub_140017720(Ix, a2, v216, a4 + 24, v217, v218);
                      sub_1400176C0(Ix, a2, v219, a4 + 24, v220, v221);
                      v383 = *sub_140017720(Ix, a2, v222, a4 + 24, v223, v224);
                      sub_1400176C0(Ix, a2, v225, a4 + 24, v226, v227);
                      v230 = v383 || v384;
                      v345 = v230;
                      sub_140017780(Ix, a2, &v345, a4 + 24, v228, v229);
                    }
                    break;
                  case '0':
                    if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                    {
                      v382 = *sub_140017720(Ix, a2, v201, a4 + 24, v202, v203);
                      sub_1400176C0(Ix, a2, v204, a4 + 24, v205, v206);
                      v381 = *sub_140017720(Ix, a2, v207, a4 + 24, v208, v209);
                      sub_1400176C0(Ix, a2, v210, a4 + 24, v211, v212);
                      v215 = v381 && v382;
                      v344 = v215;
                      sub_140017780(Ix, a2, &v344, a4 + 24, v213, v214);
                    }
                    break;
                  case '%':
                    if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                    {
                      v380 = *sub_140017720(Ix, a2, v187, a4 + 24, v188, v189);
                      sub_1400176C0(Ix, a2, v190, a4 + 24, v191, v192);
                      v379 = *sub_140017720(Ix, a2, v193, a4 + 24, v194, v195);
                      sub_1400176C0(Ix, a2, v196, a4 + 24, v197, v198);
                      v343 = v379 >= v380;
                      sub_140017780(Ix, a2, &v343, a4 + 24, v199, v200);
                    }
                    break;
                  default:
                    if ( n2 <= 0x25u )
                    {
                      switch ( n2 )
                      {
                        case 0x24u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v378 = *sub_140017720(Ix, a2, v173, a4 + 24, v174, v175);
                            sub_1400176C0(Ix, a2, v176, a4 + 24, v177, v178);
                            v377 = *sub_140017720(Ix, a2, v179, a4 + 24, v180, v181);
                            sub_1400176C0(Ix, a2, v182, a4 + 24, v183, v184);
                            v342 = v378 < v377;
                            sub_140017780(Ix, a2, &v342, a4 + 24, v185, v186);
                          }
                          break;
                        case 0x23u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v376 = *sub_140017720(Ix, a2, v159, a4 + 24, v160, v161);
                            sub_1400176C0(Ix, a2, v162, a4 + 24, v163, v164);
                            v375 = *sub_140017720(Ix, a2, v165, a4 + 24, v166, v167);
                            sub_1400176C0(Ix, a2, v168, a4 + 24, v169, v170);
                            v341 = v376 >= v375;
                            sub_140017780(Ix, a2, &v341, a4 + 24, v171, v172);
                          }
                          break;
                        case 0x22u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v374 = *sub_140017720(Ix, a2, v145, a4 + 24, v146, v147);
                            sub_1400176C0(Ix, a2, v148, a4 + 24, v149, v150);
                            v373 = *sub_140017720(Ix, a2, v151, a4 + 24, v152, v153);
                            sub_1400176C0(Ix, a2, v154, a4 + 24, v155, v156);
                            v340 = v373 < v374;
                            sub_140017780(Ix, a2, &v340, a4 + 24, v157, v158);
                          }
                          break;
                        case 0x21u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v372 = *sub_140017720(Ix, a2, v131, a4 + 24, v132, v133);
                            sub_1400176C0(Ix, a2, v134, a4 + 24, v135, v136);
                            v371 = *sub_140017720(Ix, a2, v137, a4 + 24, v138, v139);
                            sub_1400176C0(Ix, a2, v140, a4 + 24, v141, v142);
                            v339 = v371 != v372;
                            sub_140017780(Ix, a2, &v339, a4 + 24, v143, v144);
                          }
                          break;
                        case 0x20u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v370 = *sub_140017720(Ix, a2, v117, a4 + 24, v118, v119);
                            sub_1400176C0(Ix, a2, v120, a4 + 24, v121, v122);
                            v369 = *sub_140017720(Ix, a2, v123, a4 + 24, v124, v125);
                            sub_1400176C0(Ix, a2, v126, a4 + 24, v127, v128);
                            v338 = v369 == v370;
                            sub_140017780(Ix, a2, &v338, a4 + 24, v129, v130);
                          }
                          break;
                        case 0x18u:
                          if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                          {
                            v368 = *sub_140017720(Ix, a2, v303, a4 + 24, v304, v305);
                            sub_1400176C0(Ix, a2, v306, a4 + 24, v307, v308);
                            v367 = *sub_140017720(Ix, a2, v309, a4 + 24, v310, v311);
                            sub_1400176C0(Ix, a2, v312, a4 + 24, v313, v314);
                            v351 = v368 ^ v367;
                            sub_140017780(Ix, a2, &v351, a4 + 24, v315, v316);
                          }
                          break;
                        default:
                          if ( n2 <= 0x18u )
                          {
                            switch ( n2 )
                            {
                              case 0x17u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v366 = *sub_140017720(Ix, a2, v252, a4 + 24, v253, v254);
                                  sub_1400176C0(Ix, a2, v255, a4 + 24, v256, v257);
                                  v365 = *sub_140017720(Ix, a2, v258, a4 + 24, v259, v260);
                                  sub_1400176C0(Ix, a2, v261, a4 + 24, v262, v263);
                                  v348 = v365 >> v366;
                                  sub_140017780(Ix, a2, &v348, a4 + 24, a4 + 24, v264);
                                }
                                break;
                              case 0x16u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v364 = *sub_140017720(Ix, a2, v239, a4 + 24, v240, v241);
                                  sub_1400176C0(Ix, a2, v242, a4 + 24, v243, v244);
                                  v363 = *sub_140017720(Ix, a2, v245, a4 + 24, v246, v247);
                                  sub_1400176C0(Ix, a2, v248, a4 + 24, v249, v250);
                                  v347 = v363 << v364;
                                  sub_140017780(Ix, a2, &v347, a4 + 24, a4 + 24, v251);
                                }
                                break;
                              case 0x15u:
                                if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
                                {
                                  v328 = *sub_140017720(Ix, a2, v109, a4 + 24, v110, v111);
                                  sub_1400176C0(Ix, a2, v112, a4 + 24, v113, v114);
                                  sub_1400177B0(Ix, a2, &v328, a4 + 24, v115, v116, v324);
                                }
                                break;
                              case 0x14u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v362 = *sub_140017720(Ix, a2, v95, a4 + 24, v96, v97);
                                  sub_1400176C0(Ix, a2, v98, a4 + 24, v99, v100);
                                  v361 = *sub_140017720(Ix, a2, v101, a4 + 24, v102, v103);
                                  sub_1400176C0(Ix, a2, v104, a4 + 24, v105, v106);
                                  if ( v362 )
                                  {
                                    v337 = v361 % v362;
                                    sub_140017780(Ix, a2, &v337, a4 + 24, v107, v108);
                                  }
                                }
                                break;
                              case 0x13u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v360 = *sub_140017720(Ix, a2, v81, a4 + 24, v82, v83);
                                  sub_1400176C0(Ix, a2, v84, a4 + 24, v85, v86);
                                  v359 = *sub_140017720(Ix, a2, v87, a4 + 24, v88, v89);
                                  sub_1400176C0(Ix, a2, v90, a4 + 24, v91, v92);
                                  if ( v360 )
                                  {
                                    v336 = v359 / v360;
                                    sub_140017780(Ix, a2, &v336, a4 + 24, v93, v94);
                                  }
                                }
                                break;
                              case 0x12u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v358 = *sub_140017720(Ix, a2, v67, a4 + 24, v68, v69);
                                  sub_1400176C0(Ix, a2, v70, a4 + 24, v71, v72);
                                  v357 = *sub_140017720(Ix, a2, v73, a4 + 24, v74, v75);
                                  sub_1400176C0(Ix, a2, v76, a4 + 24, v77, v78);
                                  v335 = v358 * v357;
                                  sub_140017780(Ix, a2, &v335, a4 + 24, v79, v80);
                                }
                                break;
                              case 0x11u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v356 = *sub_140017720(Ix, a2, v53, a4 + 24, v54, v55);
                                  sub_1400176C0(Ix, a2, v56, a4 + 24, v57, v58);
                                  v355 = *sub_140017720(Ix, a2, v59, a4 + 24, v60, v61);
                                  sub_1400176C0(Ix, a2, v62, a4 + 24, v63, v64);
                                  v334 = v355 - v356;
                                  sub_140017780(Ix, a2, &v334, a4 + 24, v65, v66);
                                }
                                break;
                              case 0x10u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v354 = *sub_140017720(Ix, a2, v39, a4 + 24, v40, v41);
                                  sub_1400176C0(Ix, a2, v42, a4 + 24, v43, v44);
                                  v353 = *sub_140017720(Ix, a2, v45, a4 + 24, v46, v47);
                                  sub_1400176C0(Ix, a2, v48, a4 + 24, v49, v50);
                                  v333 = v353 + v354;
                                  sub_140017780(Ix, a2, &v333, a4 + 24, v51, v52);
                                }
                                break;
                              case 4u:
                                if ( sub_140012A90(Ix, a2, v11, a4 + 24, v12, v13) > 1 )
                                {
                                  v330 = *sub_140017720(Ix, a2, v23, a4 + 24, v24, v25);
                                  sub_1400176C0(Ix, a2, v26, a4 + 24, v27, v28);
                                  v329 = *sub_140017720(Ix, a2, v29, a4 + 24, v30, v31);
                                  sub_1400176C0(Ix, a2, v32, a4 + 24, v33, v34);
                                  sub_1400177B0(Ix, a2, &v330, a4 + 24, v35, v36, v324);
                                  sub_1400177B0(Ix, a2, &v329, a4 + 24, v37, v38, v325);
                                }
                                break;
                              default:
                                if ( n2 <= 4u )
                                {
                                  if ( n2 == 3 )
                                  {
                                    if ( sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
                                    {
                                      v331 = *sub_140017720(Ix, a2, v18, a4 + 24, v19, v20);
                                      sub_1400177B0(Ix, a2, &v331, a4 + 24, v21, v22, v324);
                                    }
                                  }
                                  else if ( n2 == 1 )
                                  {
                                    v332 = *(v391 + 4);
                                    sub_140017780(Ix, a2, &v332, a4 + 24, v12, v13);
                                  }
                                  else if ( n2 == 2 && sub_140012AB0(Ix, a2, v11, a4 + 24, v12, v13) != 1 )
                                  {
                                    sub_1400176C0(Ix, a2, v15, a4 + 24, v16, v17);
                                  }
                                }
                                break;
                            }
                          }
                          break;
                      }
                    }
                    break;
                }
              }
            }
            break;
        }
      }
    }
    ++*(a4 + 240);
    return 1;
  }
}

可认为这就是 VM 主体了。

sub_140011AE0 则开始输出正确与否了,此函数应该为验证函数。