May 2, 2023

d3sky出题小记

写在前面

只是d3逆向题里分值最低的一道题 555被师傅们日烂了 下次争取多整点活(x

比赛中做过这道题的选手可以跳过这一段。
题目主体是使用与非指令构建了一个虚拟机,其他的部分都很常规,主要为以下几点:

来源

单指令虚拟机这个idea来自于前年年底做的TetCTF的第一道题magicbox

关于这道题的详细情况和解法在track神的博客有讲 (如果此链接失效,请去🔨track) ,所以如何解题我就不再分析,这里主要讲讲如何从一个与或非的简单组合去构建虚拟机。

使用与非构建虚拟机

虚拟机主逻辑部分题目里都能直接看到,这里就说说如何构建opcode。

使用与非构建逻辑运算

显然,如果学过逻辑代数,就能够理解为什么与非指令就可以实现所有逻辑运算。

非运算

非运算是最好构建的。通过~(a&a) = ~a就可以构建非运算,即令2个操作数都为a。

与运算

对与非运算再次取非,就可以得到与运算:
~(~(a&b)) = a&b

或运算

构建过非运算和与运算,就很容易构建或运算:
~(~a&~b)=a|b

异或

通过与或非运算就可以构建异或运算:
(~a&b)|(a&~b) = a ^ b

构建出与或非运算,其实就可以完成所有的逻辑运算了。因为高级的逻辑运算都由低级的逻辑运算构成。了解上面逻辑运算的构建过程,后面的分析就会清晰很多。
或非运算构建虚拟机与上述过程大致类似,以前面讲到过的那个题为例,按照track神的博客里的做法,仿写虚拟机,对源码插桩打log,会得到一堆console log。

以对flag第一位的验证为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
0x400:		mem[0x3fe] = ~(mem[0x1a23] | mem[0x1a23])		RES: 0xffcf		SHIFT_REG: 0xff9f
0x403: mem[0x3ff] = ~(mem[0x1a0e] | mem[0x1a0e]) RES: 0xffa8 SHIFT_REG: 0xff51
0x406: mem[0x7] = ~(mem[0x40c] | mem[0x40c]) RES: 0xfbf0 SHIFT_REG: 0xf7e1
0x409: mem[0] = ~(mem[0x7] | mem[0x7]) RES: 0x40f SHIFT_REG: 0x81e
0x40f: mem[0x40d] = ~(mem[0x1a23] | mem[0x1a23]) RES: 0xffcf SHIFT_REG: 0xff9f
0x412: mem[0x40e] = ~(mem[0x3ff] | mem[0x3ff]) RES: 0x57 SHIFT_REG: 0xae
0x415: mem[0x7] = ~(mem[0x40d] | mem[0x40e]) RES: 0x20 SHIFT_REG: 0x40
0x418: mem[0x7] = ~(mem[0x7] | mem[0x7]) RES: 0xffdf SHIFT_REG: 0xffbf
0x41b: mem[0x3ff] = ~(mem[0x7] | mem[0x7]) RES: 0x20 SHIFT_REG: 0x40
0x41e: mem[0x7] = ~(mem[0x424] | mem[0x424]) RES: 0xfbd8 SHIFT_REG: 0xf7b1
0x421: mem[0] = ~(mem[0x7] | mem[0x7]) RES: 0x427 SHIFT_REG: 0x84e
0x427: mem[0x425] = ~(mem[0x1a0e] | mem[0x1a0e]) RES: 0xffa8 SHIFT_REG: 0xff51
0x42a: mem[0x426] = ~(mem[0x3fe] | mem[0x3fe]) RES: 0x30 SHIFT_REG: 0x60
0x42d: mem[0x7] = ~(mem[0x425] | mem[0x426]) RES: 0x47 SHIFT_REG: 0x8e
0x430: mem[0x7] = ~(mem[0x7] | mem[0x7]) RES: 0xffb8 SHIFT_REG: 0xff71
0x433: mem[0x3fe] = ~(mem[0x7] | mem[0x7]) RES: 0x47 SHIFT_REG: 0x8e
0x436: mem[0x7] = ~(mem[0x3fe] | mem[0x3ff]) RES: 0xff98 SHIFT_REG: 0xff31
0x439: mem[0x1a0d] = ~(mem[0x7] | mem[0x7]) RES: 0x67 SHIFT_REG: 0xce
0x43c: mem[0x7] = ~(mem[0x1a0d] | mem[0x1ee]) RES: 0xff98 SHIFT_REG: 0xff31
0x43f: mem[0x1ee] = ~(mem[0x7] | mem[0x7]) RES: 0x67 SHIFT_REG: 0xce

从后往前看,用于check的位是mem[0x1ee],这一位在程序原数据中的初始值是0。
往前分析,这一位存的实际上是mem[0x1a0d]的结果,而mem[0x1a0d]又来自于mem[0x3fe] | mem[0x3ff](叠加了两次或非运算,即一个或运算),所以我们去分析这两位即可。

line1为mem[0x3fe]赋值~x(x是第一位输入),line13为mem[0x426]赋值x
line12为mem[0x425]赋值mem[0x1a0e],这是一个写死的值,值为0x57。
line14将~(mem[0x425] | mem[0x426])存入mem[0x7],line15 line16两次取非后存入mem[0x3fe],即mem[0x3fe]存储了x|~0x57的结果。

与上述分析类似,mem[0x3ff]存了~x|0x57的结果。mem[0x3fe] | mem[0x3ff](x & ~0x57) | (~x & 0x57),亦即x ^ 0x57,所以flag第一位应该是0x57,即W
此后分析类似,第二位是input[0]^input[1]^0x12,即E,第3位是0x12^0x23^input[2],即49(字符1)。

编写opcode

核心逻辑

比如说要计算两个值的异或,如何编写opcode?其实只要理解上面的逻辑运算分析,一步步去写即可。
首先,我们需要几个寄存器来暂存用于运算的值,这道题里我使用了opcode[11]、opcode[12]、opcode[13]、opcode[17]、opcode[18]、opcode[19]这6个寄存器(其中opcode[19]是标志位,若非0则说明输入错误),那么要实现a^b,就可以写出如下opcode:

1
2
3
4
5
a, a, 11,   //reg0 = ~a
11, b, 11, //reg0 = ~(~a&b) = a|~b
b, b, 12, //reg1 = ~b
12, a, 12, //reg1 = ~(a&~b) = ~a|b
11, 12, 17, //reg2 = ~(reg0&reg1) = a^b

将a和b分别换成输入的索引值,就可以实现对输入的异或。
d3sky虚拟机的核心逻辑是每次取输入的4个字节异或,然后与密文异或,写成opcode就是如下形式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//eg: input[0]^input[1]^input[2]^input[3]^enc[0]
scanf_idx, scanf_idx, 11, // ~a
11, scanf_idx + 1, 11, // ~(~a&b)
scanf_idx + 1, scanf_idx + 1, 12, // ~b
12, scanf_idx, 12, // ~(a&~b)
11, 12, 17, //a^b i0^i1

scanf_idx + 2, scanf_idx + 2, 11, // ~a
11, scanf_idx + 3, 11, // ~(~a&b)
scanf_idx + 3, scanf_idx + 3, 12, // ~b
12, scanf_idx + 2, 12, // ~(a&~b)
11, 12, 18, //a^b i2^i3

17, 17, 11, // ~a
11, 18, 11, // ~(~a&b)
18, 18, 12, // ~b
12, 17, 12, // ~(a&~b)
11, 12, 18, //i0^i1^i0^i1

enc_idx, enc_idx, 11, // ~a
11, 18, 11, // ~(~a&b)
18, 18, 12, // ~b
12, enc_idx, 12, // ~(a&~b)
11, 12, 19, //i0^i1^i2^i3^enc0

后面的逻辑都一样,opcode直接用脚本批量生成即可。注意这种加密方式有多解,所以限制一下某一位即可。

其他部分

如果需要字符串混淆,可以用虚拟机实现输入输出。本题使用opcode[20]来改变标志位(这一位永远是1)

使用虚拟机实现输入:选择一位作为标志位,一位作为解密后的符号位。字符解密后修改标志位即可。

1
2
3
//print_f mem[2]
//print_c mem[3]
print_wel_idx, print_wel_idx, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2

使用虚拟机实现输入:修改标志位后将输入字符暂存入寄存器,由于存入寄存器的值是取非之后的,所以再取非一次就可以放入事先准备好的输入内存中。

1
2
3
//scanf_f mem[7]
//scanf_c mem[8]
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx

如果需要字符串混淆,可以考虑这种混淆方式。 由于出题人没想着隐藏逻辑所以只混淆了一部分字符串就摆烂了
由于我采用的是4字节混合加密,所以没有考虑直接爆破的可能性,验证一位有错误就直接退出。如果采用单字节加密,可以考虑把所有字节都读进去全部检测后再决定是否退出。当然,如果真的是单字节加密,那么直接仿写虚拟机自己爆破就完事了(x

如何解题

了解了这个idea,其实解题很简单,上面已经详细分析过,插桩打log去观察逻辑即可。注意一下解密opcode后还要再加密一次。似乎很多师傅都是用z3做出来的,呜呜呜好吧这里放一下直接逆的做法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enc = [36, 11, 109, 15, 3, 50, 66, 29, 43, 67, 120, 67, 115, 48, 43, 78, 99, 72, 119, 46, 50, 57, 26, 18, 113, 122, 66, 23, 69, 114, 86, 12, 92, 74, 98, 83, 51]
dec = [0] * 37
dec[-1] = 126

for i in range(32, -1, -4):
dec[i] = enc[i] ^ enc[i+1] ^ dec[i+4]

dec[33] = enc[33] ^ enc[34] ^ dec[0]

for i in range(29, 0, -4):
dec[i] = enc[i] ^ enc[i+1] ^ dec[i+4]

dec[2] = enc[-1] ^ dec[0] ^ dec[1] ^ dec[-1]

for i in range(3, 37):
dec[i] = enc[i-3] ^ dec[i-1] ^ dec[i-2] ^ dec[i-3]

print(bytes(dec))

题目代码

这道题的雏形代码长这样:(标志位我均已写在注释中)

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

#define print_wel_idx 2766
#define scanf_idx print_wel_idx + 6
#define enc_idx scanf_idx + 37

uint16_t mem[] = {21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//print("Input:")
print_wel_idx, print_wel_idx, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
print_wel_idx+1, print_wel_idx+1, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
print_wel_idx+2, print_wel_idx+2, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
print_wel_idx+3, print_wel_idx+3, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
print_wel_idx+4, print_wel_idx+4, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
print_wel_idx+5, print_wel_idx+5, 11, 11, 11, 3, 20, 20, 11, 11, 11, 2,
//scanf
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 1 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 2 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 3 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 4 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 5 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 6 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 7 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 8 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 9 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 10 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 11 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 12 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 13 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 14 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 15 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 16 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 17 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 18 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 19 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 20 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 21 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 22 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 23 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 24 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 25 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 26 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 27 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 28 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 29 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 30 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 31 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 32 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 33 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 34 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 35 ,
20, 20, 11, 11, 11, 7, 8, 8, 7, 7, 7, scanf_idx+ 36 ,

//eg: input[0]^input[1]^input[2]^input[3]^enc[0]
scanf_idx, scanf_idx, 11, // ~a
11, scanf_idx + 1, 11, // ~(~a&b)
scanf_idx + 1, scanf_idx + 1, 12, // ~b
12, scanf_idx, 12, // ~(a&~b)
11, 12, 17, //a^b i0^i1

scanf_idx + 2, scanf_idx + 2, 11, // ~a
11, scanf_idx + 3, 11, // ~(~a&b)
scanf_idx + 3, scanf_idx + 3, 12, // ~b
12, scanf_idx + 2, 12, // ~(a&~b)
11, 12, 18, //a^b i2^i3

17, 17, 11, // ~a
11, 18, 11, // ~(~a&b)
18, 18, 12, // ~b
12, 17, 12, // ~(a&~b)
11, 12, 18, //i0^i1^i0^i1

enc_idx, enc_idx, 11, // ~a
11, 18, 11, // ~(~a&b)
18, 18, 12, // ~b
12, enc_idx, 12, // ~(a&~b)
11, 12, 19, //i0^i1^i2^i3^enc0

//for i in range(1,37):
// mem[19]=input[i]^input[(i+1)%37]^input[(i+2)%37]^input[(i+3)%37]^enc[i]
scanf_idx+1, scanf_idx+1, 11,11, scanf_idx + 2, 11,scanf_idx + 2, scanf_idx + 2, 12,12, scanf_idx + 1, 12,11, 12, 17, scanf_idx + 3, scanf_idx + 3, 11,11, scanf_idx + 4, 11,scanf_idx + 4, scanf_idx + 4, 12,12, scanf_idx + 3, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 1, enc_idx + 1, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 1, 12,11, 12, 19,
scanf_idx+2, scanf_idx+2, 11,11, scanf_idx + 3, 11,scanf_idx + 3, scanf_idx + 3, 12,12, scanf_idx + 2, 12,11, 12, 17, scanf_idx + 4, scanf_idx + 4, 11,11, scanf_idx + 5, 11,scanf_idx + 5, scanf_idx + 5, 12,12, scanf_idx + 4, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 2, enc_idx + 2, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 2, 12,11, 12, 19,
scanf_idx+3, scanf_idx+3, 11,11, scanf_idx + 4, 11,scanf_idx + 4, scanf_idx + 4, 12,12, scanf_idx + 3, 12,11, 12, 17, scanf_idx + 5, scanf_idx + 5, 11,11, scanf_idx + 6, 11,scanf_idx + 6, scanf_idx + 6, 12,12, scanf_idx + 5, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 3, enc_idx + 3, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 3, 12,11, 12, 19,
scanf_idx+4, scanf_idx+4, 11,11, scanf_idx + 5, 11,scanf_idx + 5, scanf_idx + 5, 12,12, scanf_idx + 4, 12,11, 12, 17, scanf_idx + 6, scanf_idx + 6, 11,11, scanf_idx + 7, 11,scanf_idx + 7, scanf_idx + 7, 12,12, scanf_idx + 6, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 4, enc_idx + 4, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 4, 12,11, 12, 19,
scanf_idx+5, scanf_idx+5, 11,11, scanf_idx + 6, 11,scanf_idx + 6, scanf_idx + 6, 12,12, scanf_idx + 5, 12,11, 12, 17, scanf_idx + 7, scanf_idx + 7, 11,11, scanf_idx + 8, 11,scanf_idx + 8, scanf_idx + 8, 12,12, scanf_idx + 7, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 5, enc_idx + 5, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 5, 12,11, 12, 19,
scanf_idx+6, scanf_idx+6, 11,11, scanf_idx + 7, 11,scanf_idx + 7, scanf_idx + 7, 12,12, scanf_idx + 6, 12,11, 12, 17, scanf_idx + 8, scanf_idx + 8, 11,11, scanf_idx + 9, 11,scanf_idx + 9, scanf_idx + 9, 12,12, scanf_idx + 8, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 6, enc_idx + 6, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 6, 12,11, 12, 19,
scanf_idx+7, scanf_idx+7, 11,11, scanf_idx + 8, 11,scanf_idx + 8, scanf_idx + 8, 12,12, scanf_idx + 7, 12,11, 12, 17, scanf_idx + 9, scanf_idx + 9, 11,11, scanf_idx + 10, 11,scanf_idx + 10, scanf_idx + 10, 12,12, scanf_idx + 9, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 7, enc_idx + 7, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 7, 12,11, 12, 19,
scanf_idx+8, scanf_idx+8, 11,11, scanf_idx + 9, 11,scanf_idx + 9, scanf_idx + 9, 12,12, scanf_idx + 8, 12,11, 12, 17, scanf_idx + 10, scanf_idx + 10, 11,11, scanf_idx + 11, 11,scanf_idx + 11, scanf_idx + 11, 12,12, scanf_idx + 10, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 8, enc_idx + 8, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 8, 12,11, 12, 19,
scanf_idx+9, scanf_idx+9, 11,11, scanf_idx + 10, 11,scanf_idx + 10, scanf_idx + 10, 12,12, scanf_idx + 9, 12,11, 12, 17, scanf_idx + 11, scanf_idx + 11, 11,11, scanf_idx + 12, 11,scanf_idx + 12, scanf_idx + 12, 12,12, scanf_idx + 11, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 9, enc_idx + 9, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 9, 12,11, 12, 19,
scanf_idx+10, scanf_idx+10, 11,11, scanf_idx + 11, 11,scanf_idx + 11, scanf_idx + 11, 12,12, scanf_idx + 10, 12,11, 12, 17, scanf_idx + 12, scanf_idx + 12, 11,11, scanf_idx + 13, 11,scanf_idx + 13, scanf_idx + 13, 12,12, scanf_idx + 12, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 10, enc_idx + 10, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 10, 12,11, 12, 19,
scanf_idx+11, scanf_idx+11, 11,11, scanf_idx + 12, 11,scanf_idx + 12, scanf_idx + 12, 12,12, scanf_idx + 11, 12,11, 12, 17, scanf_idx + 13, scanf_idx + 13, 11,11, scanf_idx + 14, 11,scanf_idx + 14, scanf_idx + 14, 12,12, scanf_idx + 13, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 11, enc_idx + 11, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 11, 12,11, 12, 19,
scanf_idx+12, scanf_idx+12, 11,11, scanf_idx + 13, 11,scanf_idx + 13, scanf_idx + 13, 12,12, scanf_idx + 12, 12,11, 12, 17, scanf_idx + 14, scanf_idx + 14, 11,11, scanf_idx + 15, 11,scanf_idx + 15, scanf_idx + 15, 12,12, scanf_idx + 14, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 12, enc_idx + 12, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 12, 12,11, 12, 19,
scanf_idx+13, scanf_idx+13, 11,11, scanf_idx + 14, 11,scanf_idx + 14, scanf_idx + 14, 12,12, scanf_idx + 13, 12,11, 12, 17, scanf_idx + 15, scanf_idx + 15, 11,11, scanf_idx + 16, 11,scanf_idx + 16, scanf_idx + 16, 12,12, scanf_idx + 15, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 13, enc_idx + 13, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 13, 12,11, 12, 19,
scanf_idx+14, scanf_idx+14, 11,11, scanf_idx + 15, 11,scanf_idx + 15, scanf_idx + 15, 12,12, scanf_idx + 14, 12,11, 12, 17, scanf_idx + 16, scanf_idx + 16, 11,11, scanf_idx + 17, 11,scanf_idx + 17, scanf_idx + 17, 12,12, scanf_idx + 16, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 14, enc_idx + 14, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 14, 12,11, 12, 19,
scanf_idx+15, scanf_idx+15, 11,11, scanf_idx + 16, 11,scanf_idx + 16, scanf_idx + 16, 12,12, scanf_idx + 15, 12,11, 12, 17, scanf_idx + 17, scanf_idx + 17, 11,11, scanf_idx + 18, 11,scanf_idx + 18, scanf_idx + 18, 12,12, scanf_idx + 17, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 15, enc_idx + 15, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 15, 12,11, 12, 19,
scanf_idx+16, scanf_idx+16, 11,11, scanf_idx + 17, 11,scanf_idx + 17, scanf_idx + 17, 12,12, scanf_idx + 16, 12,11, 12, 17, scanf_idx + 18, scanf_idx + 18, 11,11, scanf_idx + 19, 11,scanf_idx + 19, scanf_idx + 19, 12,12, scanf_idx + 18, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 16, enc_idx + 16, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 16, 12,11, 12, 19,
scanf_idx+17, scanf_idx+17, 11,11, scanf_idx + 18, 11,scanf_idx + 18, scanf_idx + 18, 12,12, scanf_idx + 17, 12,11, 12, 17, scanf_idx + 19, scanf_idx + 19, 11,11, scanf_idx + 20, 11,scanf_idx + 20, scanf_idx + 20, 12,12, scanf_idx + 19, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 17, enc_idx + 17, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 17, 12,11, 12, 19,
scanf_idx+18, scanf_idx+18, 11,11, scanf_idx + 19, 11,scanf_idx + 19, scanf_idx + 19, 12,12, scanf_idx + 18, 12,11, 12, 17, scanf_idx + 20, scanf_idx + 20, 11,11, scanf_idx + 21, 11,scanf_idx + 21, scanf_idx + 21, 12,12, scanf_idx + 20, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 18, enc_idx + 18, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 18, 12,11, 12, 19,
scanf_idx+19, scanf_idx+19, 11,11, scanf_idx + 20, 11,scanf_idx + 20, scanf_idx + 20, 12,12, scanf_idx + 19, 12,11, 12, 17, scanf_idx + 21, scanf_idx + 21, 11,11, scanf_idx + 22, 11,scanf_idx + 22, scanf_idx + 22, 12,12, scanf_idx + 21, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 19, enc_idx + 19, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 19, 12,11, 12, 19,
scanf_idx+20, scanf_idx+20, 11,11, scanf_idx + 21, 11,scanf_idx + 21, scanf_idx + 21, 12,12, scanf_idx + 20, 12,11, 12, 17, scanf_idx + 22, scanf_idx + 22, 11,11, scanf_idx + 23, 11,scanf_idx + 23, scanf_idx + 23, 12,12, scanf_idx + 22, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 20, enc_idx + 20, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 20, 12,11, 12, 19,
scanf_idx+21, scanf_idx+21, 11,11, scanf_idx + 22, 11,scanf_idx + 22, scanf_idx + 22, 12,12, scanf_idx + 21, 12,11, 12, 17, scanf_idx + 23, scanf_idx + 23, 11,11, scanf_idx + 24, 11,scanf_idx + 24, scanf_idx + 24, 12,12, scanf_idx + 23, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 21, enc_idx + 21, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 21, 12,11, 12, 19,
scanf_idx+22, scanf_idx+22, 11,11, scanf_idx + 23, 11,scanf_idx + 23, scanf_idx + 23, 12,12, scanf_idx + 22, 12,11, 12, 17, scanf_idx + 24, scanf_idx + 24, 11,11, scanf_idx + 25, 11,scanf_idx + 25, scanf_idx + 25, 12,12, scanf_idx + 24, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 22, enc_idx + 22, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 22, 12,11, 12, 19,
scanf_idx+23, scanf_idx+23, 11,11, scanf_idx + 24, 11,scanf_idx + 24, scanf_idx + 24, 12,12, scanf_idx + 23, 12,11, 12, 17, scanf_idx + 25, scanf_idx + 25, 11,11, scanf_idx + 26, 11,scanf_idx + 26, scanf_idx + 26, 12,12, scanf_idx + 25, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 23, enc_idx + 23, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 23, 12,11, 12, 19,
scanf_idx+24, scanf_idx+24, 11,11, scanf_idx + 25, 11,scanf_idx + 25, scanf_idx + 25, 12,12, scanf_idx + 24, 12,11, 12, 17, scanf_idx + 26, scanf_idx + 26, 11,11, scanf_idx + 27, 11,scanf_idx + 27, scanf_idx + 27, 12,12, scanf_idx + 26, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 24, enc_idx + 24, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 24, 12,11, 12, 19,
scanf_idx+25, scanf_idx+25, 11,11, scanf_idx + 26, 11,scanf_idx + 26, scanf_idx + 26, 12,12, scanf_idx + 25, 12,11, 12, 17, scanf_idx + 27, scanf_idx + 27, 11,11, scanf_idx + 28, 11,scanf_idx + 28, scanf_idx + 28, 12,12, scanf_idx + 27, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 25, enc_idx + 25, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 25, 12,11, 12, 19,
scanf_idx+26, scanf_idx+26, 11,11, scanf_idx + 27, 11,scanf_idx + 27, scanf_idx + 27, 12,12, scanf_idx + 26, 12,11, 12, 17, scanf_idx + 28, scanf_idx + 28, 11,11, scanf_idx + 29, 11,scanf_idx + 29, scanf_idx + 29, 12,12, scanf_idx + 28, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 26, enc_idx + 26, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 26, 12,11, 12, 19,
scanf_idx+27, scanf_idx+27, 11,11, scanf_idx + 28, 11,scanf_idx + 28, scanf_idx + 28, 12,12, scanf_idx + 27, 12,11, 12, 17, scanf_idx + 29, scanf_idx + 29, 11,11, scanf_idx + 30, 11,scanf_idx + 30, scanf_idx + 30, 12,12, scanf_idx + 29, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 27, enc_idx + 27, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 27, 12,11, 12, 19,
scanf_idx+28, scanf_idx+28, 11,11, scanf_idx + 29, 11,scanf_idx + 29, scanf_idx + 29, 12,12, scanf_idx + 28, 12,11, 12, 17, scanf_idx + 30, scanf_idx + 30, 11,11, scanf_idx + 31, 11,scanf_idx + 31, scanf_idx + 31, 12,12, scanf_idx + 30, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 28, enc_idx + 28, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 28, 12,11, 12, 19,
scanf_idx+29, scanf_idx+29, 11,11, scanf_idx + 30, 11,scanf_idx + 30, scanf_idx + 30, 12,12, scanf_idx + 29, 12,11, 12, 17, scanf_idx + 31, scanf_idx + 31, 11,11, scanf_idx + 32, 11,scanf_idx + 32, scanf_idx + 32, 12,12, scanf_idx + 31, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 29, enc_idx + 29, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 29, 12,11, 12, 19,
scanf_idx+30, scanf_idx+30, 11,11, scanf_idx + 31, 11,scanf_idx + 31, scanf_idx + 31, 12,12, scanf_idx + 30, 12,11, 12, 17, scanf_idx + 32, scanf_idx + 32, 11,11, scanf_idx + 33, 11,scanf_idx + 33, scanf_idx + 33, 12,12, scanf_idx + 32, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 30, enc_idx + 30, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 30, 12,11, 12, 19,
scanf_idx+31, scanf_idx+31, 11,11, scanf_idx + 32, 11,scanf_idx + 32, scanf_idx + 32, 12,12, scanf_idx + 31, 12,11, 12, 17, scanf_idx + 33, scanf_idx + 33, 11,11, scanf_idx + 34, 11,scanf_idx + 34, scanf_idx + 34, 12,12, scanf_idx + 33, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 31, enc_idx + 31, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 31, 12,11, 12, 19,
scanf_idx+32, scanf_idx+32, 11,11, scanf_idx + 33, 11,scanf_idx + 33, scanf_idx + 33, 12,12, scanf_idx + 32, 12,11, 12, 17, scanf_idx + 34, scanf_idx + 34, 11,11, scanf_idx + 35, 11,scanf_idx + 35, scanf_idx + 35, 12,12, scanf_idx + 34, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 32, enc_idx + 32, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 32, 12,11, 12, 19,
scanf_idx+33, scanf_idx+33, 11,11, scanf_idx + 34, 11,scanf_idx + 34, scanf_idx + 34, 12,12, scanf_idx + 33, 12,11, 12, 17, scanf_idx + 35, scanf_idx + 35, 11,11, scanf_idx + 36, 11,scanf_idx + 36, scanf_idx + 36, 12,12, scanf_idx + 35, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 33, enc_idx + 33, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 33, 12,11, 12, 19,
scanf_idx+34, scanf_idx+34, 11,11, scanf_idx + 35, 11,scanf_idx + 35, scanf_idx + 35, 12,12, scanf_idx + 34, 12,11, 12, 17, scanf_idx + 36, scanf_idx + 36, 11,11, scanf_idx + 0, 11,scanf_idx + 0, scanf_idx + 0, 12,12, scanf_idx + 36, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 34, enc_idx + 34, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 34, 12,11, 12, 19,
scanf_idx+35, scanf_idx+35, 11,11, scanf_idx + 36, 11,scanf_idx + 36, scanf_idx + 36, 12,12, scanf_idx + 35, 12,11, 12, 17, scanf_idx + 0, scanf_idx + 0, 11,11, scanf_idx + 1, 11,scanf_idx + 1, scanf_idx + 1, 12,12, scanf_idx + 0, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 35, enc_idx + 35, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 35, 12,11, 12, 19,
scanf_idx+36, scanf_idx+36, 11,11, scanf_idx + 0, 11,scanf_idx + 0, scanf_idx + 0, 12,12, scanf_idx + 36, 12,11, 12, 17, scanf_idx + 1, scanf_idx + 1, 11,11, scanf_idx + 2, 11,scanf_idx + 2, scanf_idx + 2, 12,12, scanf_idx + 1, 12,11, 12, 18,17, 17, 11,11, 18, 11,18, 18, 12,12, 17, 12,11, 12, 18,enc_idx + 36, enc_idx + 36, 11,11, 18, 11, 18, 18, 12,12, enc_idx + 36, 12,11, 12, 19,10, 10, 0, 0, 0, 0, 0, 0, 0,

//print_welcom
73, 110, 112, 117, 116, 58,

//scanf_char
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

//enc
36, 11, 109, 15, 3, 50, 66, 29, 43, 67, 120, 67, 115, 48, 43, 78, 99, 72, 119, 46, 50, 57, 26, 18, 113, 122, 66, 23, 69, 114, 86, 12, 92, 74, 98, 83, 51,0};

//reg1 mem[11]
//reg2 mem[12]
//reg3 mem[13]
//17 18 19
//flag mem[19]
//print_f mem[2]
//print_c mem[3]
//scanf_f mem[7]
//scanf_c mem[8]

int main() {
uint16_t *p_mem = mem;
uint16_t PC, a, b, f, r;
int idx = 0;
while (*p_mem != 0xffff) {
if (p_mem[2] == 1) {
p_mem[2] = 0;
printf("%c", p_mem[3]);
}
if (p_mem[7] == 1) {
p_mem[7] = 0;
scanf("%c", p_mem + 8);
idx += 1;
if(idx == 37)
{
if(p_mem[8] != 126)
{
puts("Wrong!");
return 0;
}
}
}
if(p_mem[19])
{
puts("Wrong!");
return 0;
}
PC = *p_mem;
a = p_mem[PC + 1];
b = p_mem[PC];
r = p_mem[PC + 2];
*p_mem = PC + 3;
f = ~(p_mem[b] & p_mem[a]);
p_mem[r] = f;
}
puts("Right!");

return 0;
}

最后加一点点反调、一点点异常、一点点RC4,就变成了最后那样(x