Basic instructions
Click to view details
-Basic instructions before reading the code below
LOAD_CONST 加载常量 1
STORE_NAME 将变量储存为常量值 a=1 局部变量
STORE_GLOBAL同上功能 全局变量
BUILD_LIST 生成list
BUILD_MAP声明字典元素数量
STORE_MAP生成键值对 并储存
LOAD_NAME加载局部变量
BINARY_ADD加法
BINARY_SUBTRACT减法
BINARY_MULTIPLY乘法
BINARY_DIVIDE除法
BINARY_MODULO取余
BINARY_SUBSCR()
BUILD_SLICE切片
POP_TOP将结果从堆栈顶部弹出,以保证堆栈平衡
SETUP_LOOP表明循环开始 (to 28)参数说明此循环知道字节码偏移28字节的指令结束(也就是28字节开始不是循环)。
FOR_ITER调用堆栈 声明generator作用到字节码偏移位置27字节。
PRINT_ITEM为一个print函数。
COMPARE_OP指令对堆栈中两个常量进行比较
POP_JUMP_IF_FALSE指令,判断栈顶值来决定程序运行顺序实现判断功能。
Basic view
Open is a txt document. The content inside is, python bytecode. Python's bytecode can only be read by itself, there is no other way.
The purpose of Python reverse or disassembly is to understand the running content of the source code through byte code without the source code.
analysis
# Python 2.7
# Embedded file name: game.py
#源码行号|指令在函数中的偏移|指令符号|指令参数|实际参数值
1 0 LOAD_CONST 249
3 LOAD_CONST 91
6 LOAD_CONST 149
9 LOAD_CONST 113
12 LOAD_CONST 16
15 LOAD_CONST 91
18 LOAD_CONST 53
21 LOAD_CONST 41
24 BUILD_LIST_8 8
27 STORE_NAME 0 'arr0'
#arr0=[249,91,149,113,16,91,53,41]
2 30 LOAD_CONST 43
33 LOAD_CONST 1
36 LOAD_CONST 6
39 LOAD_CONST 69
42 LOAD_CONST 20
45 LOAD_CONST 62
48 LOAD_CONST 6
51 LOAD_CONST 44
54 LOAD_CONST 24
57 LOAD_CONST 113
60 LOAD_CONST 6
63 LOAD_CONST 35
66 LOAD_CONST 0
69 LOAD_CONST 3
72 LOAD_CONST 6
75 LOAD_CONST 44
78 LOAD_CONST 20
81 LOAD_CONST 22
84 LOAD_CONST 127
87 LOAD_CONST 60
90 BUILD_LIST_20 20
93 STORE_NAME 1 'arr1'
#arr1=[43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
3 96 LOAD_CONST 90
99 LOAD_CONST 100
102 LOAD_CONST 87
105 LOAD_CONST 109
108 LOAD_CONST 86
111 LOAD_CONST 108
114 LOAD_CONST 86
117 LOAD_CONST 105
120 LOAD_CONST 90
123 LOAD_CONST 104
126 LOAD_CONST 88
129 LOAD_CONST 102
132 BUILD_LIST_12 12
135 STORE_NAME 2 'arr2'
#arr2=[90,100,87,109,86,108,86,105,90,104,88,102]
5 138 LOAD_CODE <code_object check0>
141 MAKE_FUNCTION_0 0 None
144 STORE_NAME 3 'check0'
#check0()
8 147 LOAD_CODE <code_object check1>
150 MAKE_FUNCTION_0 0 None
153 STORE_NAME 4 'check1'
#check1()
14 156 LOAD_CODE <code_object check2>
159 MAKE_FUNCTION_0 0 None
162 STORE_NAME 5 'check2'
#check2()
20 165 LOAD_CODE <code_object check3>
168 MAKE_FUNCTION_0 0 None
171 STORE_NAME 6 'check3'
#check3()
37 174 LOAD_NAME 7 'raw_input'
177 CALL_FUNCTION_0 0 None
180 STORE_NAME 8 'flag'
#flag=raw_input()
38 183 LOAD_NAME 3 'check0'
186 LOAD_NAME 8 'flag'
189 CALL_FUNCTION_1 1 None
192 POP_JUMP_IF_FALSE 239 'to 239'
195 LOAD_NAME 4 'check1'
198 LOAD_NAME 8 'flag'
201 CALL_FUNCTION_1 1 None
204 POP_JUMP_IF_FALSE 239 'to 239'
207 LOAD_NAME 5 'check2'
210 LOAD_NAME 8 'flag'
213 CALL_FUNCTION_1 1 None
216 POP_JUMP_IF_FALSE 239 'to 239'
219 LOAD_NAME 6 'check3'
222 LOAD_NAME 8 'flag'
225 CALL_FUNCTION_1 1 None
228_0 COME_FROM 216 '216'
228_1 COME_FROM 204 '204'
228_2 COME_FROM 192 '192'
228 POP_JUMP_IF_FALSE 239 'to 239'
#if check0(flag):
#if check1(flag):
# if check2(flag):
# if check3(flag):
# print 'no'
# else print'ok'
39 231 LOAD_CONST 'ok'
234 PRINT_ITEM
235 PRINT_NEWLINE_CONT
236 JUMP_FORWARD 5 'to 244'
41 239 LOAD_CONST 'no'
242 PRINT_ITEM
243 PRINT_NEWLINE_CONT
244_0 COME_FROM 236 '236'
244 LOAD_CONST None
247 RETURN_VALUE
# check0 line 5 of game.py
6 0 LOAD_GLOBAL 0 'all'
3 LOAD_GENEXPR '<code_object <genexpr>>'
6 MAKE_FUNCTION_0 0 None
9 LOAD_FAST 0 's'
12 GET_ITER
13 CALL_FUNCTION_1 1 None
16 CALL_FUNCTION_1 1 None
19 RETURN_VALUE
#all='<code_object <genexpr>>'
# check1 line 8 of game.py
9 0 LOAD_GLOBAL 0 'len'
3 LOAD_FAST 0 's'
6 CALL_FUNCTION_1 1 None
9 LOAD_CONST 100
12 COMPARE_OP 0 <
15 POP_JUMP_IF_FALSE 58 'to 58'
18 LOAD_GLOBAL 0 'len'
21 LOAD_FAST 0 's'
24 CALL_FUNCTION_1 1 None
27 LOAD_GLOBAL 0 'len'
30 LOAD_FAST 0 's'
33 CALL_FUNCTION_1 1 None
36 BINARY_MULTIPLY
37 LOAD_CONST 777
40 BINARY_MODULO
41 LOAD_CONST 233
44 BINARY_XOR
45 LOAD_CONST 513
48 COMPARE_OP 2 ==
51_0 COME_FROM 15 '15'
51 POP_JUMP_IF_FALSE 58 'to 58'
#if len(s)<100:
# if (len(s)*len(s))%777)^233==513
# return True
# else:
# False
#else:
# False
10 54 LOAD_GLOBAL 1 'True'
57 RETURN_END_IF
58_0 COME_FROM 51 '51'
12 58 LOAD_GLOBAL 2 'False'
61 RETURN_VALUE
62 LOAD_CONST None
65 RETURN_VALUE
# check2 line 14 of game.py
15 0 LOAD_GLOBAL 0 'ord'
3 LOAD_FAST 0 's'
6 LOAD_CONST 0
9 BINARY_SUBSCR
10 CALL_FUNCTION_1 1 None
13 LOAD_CONST 128
16 BINARY_MULTIPLY
17 LOAD_GLOBAL 0 'ord'
20 LOAD_FAST 0 's'
23 LOAD_CONST 1
26 BINARY_SUBSCR
27 CALL_FUNCTION_1 1 None
30 BINARY_ADD
31 LOAD_CONST 128
34 BINARY_MULTIPLY
35 LOAD_GLOBAL 0 'ord'
38 LOAD_FAST 0 's'
41 LOAD_CONST 2
44 BINARY_SUBSCR
45 CALL_FUNCTION_1 1 None
48 BINARY_ADD
49 LOAD_CONST 128
52 BINARY_MULTIPLY
53 LOAD_GLOBAL 0 'ord'
56 LOAD_FAST 0 's'
59 LOAD_CONST 3
62 BINARY_SUBSCR
63 CALL_FUNCTION_1 1 None
66 BINARY_ADD
67 LOAD_CONST 128
70 BINARY_MULTIPLY
71 LOAD_GLOBAL 0 'ord'
74 LOAD_FAST 0 's'
77 LOAD_CONST 4
80 BINARY_SUBSCR
81 CALL_FUNCTION_1 1 None
84 BINARY_ADD
85 LOAD_CONST 128
88 BINARY_MULTIPLY
89 LOAD_GLOBAL 0 'ord'
92 LOAD_FAST 0 's'
95 LOAD_CONST 5
98 BINARY_SUBSCR
99 CALL_FUNCTION_1 1 None
102 BINARY_ADD
103 LOAD_CONST 3533889469877L
106 COMPARE_OP 2 ==
109 POP_JUMP_IF_FALSE 138 'to 138'
112 LOAD_GLOBAL 0 'ord'
115 LOAD_FAST 0 's'
118 LOAD_CONST -1
121 BINARY_SUBSCR
122 CALL_FUNCTION_1 1 None
125 LOAD_CONST 125
128 COMPARE_OP 2 ==
131_0 COME_FROM 109 '109'
131 POP_JUMP_IF_FALSE 138 'to 138'
#if ((((ord(s[0])*128+ord(s[1]))*128+ord(s[2]))*128+ord(s[3]))*128+ord(s[4]))*128+ord(s[5]) == 3533889469877:
# if ord(s[-1])==125:
# return True
# else:
# return False
#else:
# return False
16 134 LOAD_GLOBAL 1 'True'
137 RETURN_END_IF
138_0 COME_FROM 131 '131'
18 138 LOAD_GLOBAL 2 'False'
141 RETURN_VALUE
142 LOAD_CONST None
145 RETURN_VALUE
# check3 line 20 of game.py
21 0 LOAD_GLOBAL 0 'map'
3 LOAD_GLOBAL 1 'ord'
6 LOAD_FAST 0 's'
9 CALL_FUNCTION_2 2 None
12 STORE_FAST 1 'arr'
#arr=map(ord,s)
22 15 LOAD_FAST 1 'arr'
18 LOAD_CONST 6
21 LOAD_CONST 30
24 LOAD_CONST 3
27 BUILD_SLICE_3 3
30 BINARY_SUBSCR
31 STORE_FAST 2 'a'
#a=arr[6:30:3]
23 34 SETUP_LOOP 62 'to 99'
37 LOAD_GLOBAL 2 'range'
40 LOAD_GLOBAL 3 'len'
43 LOAD_FAST 2 'a'
46 CALL_FUNCTION_1 1 None
49 CALL_FUNCTION_1 1 None
52 GET_ITER
53 FOR_ITER 42 'to 98'
56 STORE_FAST 3 'i'
#for i in range(len(a))
24 59 LOAD_FAST 2 'a'
62 LOAD_FAST 3 'i'
65 BINARY_SUBSCR
66 LOAD_CONST 17684
69 BINARY_MULTIPLY
70 LOAD_CONST 372511
73 BINARY_ADD
74 LOAD_CONST 257
77 BINARY_MODULO
78 LOAD_GLOBAL 4 'arr0'
81 LOAD_FAST 3 'i'
84 BINARY_SUBSCR
85 COMPARE_OP 3 !=
88 POP_JUMP_IF_FALSE 53 'to 53'
#if (a[i]*17684+372511)%257!=arr0[i]
25 91 LOAD_GLOBAL 5 'False'
94 RETURN_END_IF
95_0 COME_FROM 88 '88'
95 JUMP_BACK 53 'to 53'
98 POP_BLOCK
99_0 COME_FROM 34 '34'
#return Flase
26 99 LOAD_FAST 1 'arr'
102 LOAD_CONST -2
105 LOAD_CONST 33
108 LOAD_CONST -1
111 BUILD_SLICE_3 3
114 BINARY_SUBSCR
115 LOAD_CONST 5
118 BINARY_MULTIPLY
119 STORE_FAST 4 'b'
#b=arr[-2:33:-1]*5
27 122 LOAD_GLOBAL 0 'map'
125 LOAD_LAMBDA '<code_object <lambda>>'
128 MAKE_FUNCTION_0 0 None
131 LOAD_GLOBAL 6 'zip'
134 LOAD_FAST 4 'b'
137 LOAD_FAST 1 'arr'
140 LOAD_CONST 7
143 LOAD_CONST 27
146 SLICE+3
147 CALL_FUNCTION_2 2 None
150 CALL_FUNCTION_2 2 None
153 STORE_FAST 5 'c'
#c=map('<code_object <lambda>>' zip(b,arr[7,27]))
28 156 LOAD_FAST 5 'c'
159 LOAD_GLOBAL 7 'arr1'
162 COMPARE_OP 3 !=
165 POP_JUMP_IF_FALSE 172 'to 172'
#if c!=arr1
29 168 LOAD_GLOBAL 5 'False'
171 RETURN_END_IF
172_0 COME_FROM 165 '165'
#else:return False
30 172 LOAD_CONST 0
175 STORE_FAST 6 'p'
#p=0
31 178 SETUP_LOOP 105 'to 286'
181 LOAD_GLOBAL 2 'range'
184 LOAD_CONST 28
187 LOAD_CONST 34
190 CALL_FUNCTION_2 2 None
193 GET_ITER
194 FOR_ITER 88 'to 285'
197 STORE_FAST 3 'i'
#for i in range(28,34)
32 200 LOAD_FAST 1 'arr'
203 LOAD_FAST 3 'i'
206 BINARY_SUBSCR
207 LOAD_CONST 107
210 BINARY_ADD
211 LOAD_CONST 16
214 BINARY_DIVIDE
215 LOAD_CONST 77
218 BINARY_ADD
219 LOAD_GLOBAL 8 'arr2'
222 LOAD_FAST 6 'p'
225 BINARY_SUBSCR
226 COMPARE_OP 3 !=
229 POP_JUMP_IF_TRUE 268 'to 268'
232 LOAD_FAST 1 'arr'
235 LOAD_FAST 3 'i'
238 BINARY_SUBSCR
239 LOAD_CONST 117
242 BINARY_ADD
243 LOAD_CONST 16
246 BINARY_MODULO
247 LOAD_CONST 99
250 BINARY_ADD
251 LOAD_GLOBAL 8 'arr2'
254 LOAD_FAST 6 'p'
257 LOAD_CONST 1
260 BINARY_ADD
261 BINARY_SUBSCR
262 COMPARE_OP 3 !=
265_0 COME_FROM 229 '229'
265 POP_JUMP_IF_FALSE 272 'to 272'
#if (arr[i]+107)/16+77!=arr2[p]:
#if (arr[i]+117)/16+99!=arr2[p+1]:
33 268 LOAD_GLOBAL 9 'false'
271 RETURN_END_IF
272_0 COME_FROM 265 '265'
#else:return False
34 272 LOAD_FAST 6 'p'
275 LOAD_CONST 2
278 INPLACE_ADD
279 STORE_FAST 6 'p'
282 JUMP_BACK 194 'to 194'
285 POP_BLOCK
286_0 COME_FROM 178 '178'
#p+=2
35 286 LOAD_GLOBAL 10 'True'
289 RETURN_VALUE
# <genexpr> line 6 of game.py
6 0 LOAD_FAST 0 '.0'
3 FOR_ITER 32 'to 38'
6 STORE_FAST 1 'x'
9 LOAD_GLOBAL 0 'ord'
12 LOAD_FAST 1 'x'
15 CALL_FUNCTION_1 1 None
18 LOAD_GLOBAL 1 'range'
21 LOAD_CONST 32
24 LOAD_CONST 128
27 CALL_FUNCTION_2 2 None
30 COMPARE_OP 6 in
33 YIELD_VALUE
34 POP_TOP
35 JUMP_BACK 3 'to 3'
38 LOAD_CONST None
41 RETURN_VALUE
#for x in range(ord(x))
# <lambda> line 27 of game.py
27 0 LOAD_FAST 0 'x'
3 LOAD_CONST 0
6 BINARY_SUBSCR
7 LOAD_FAST 0 'x'
10 LOAD_CONST 1
13 BINARY_SUBSCR
14 BINARY_XOR
15 RETURN_VALUE
#lambda x[0]^x[1]
After finishing
arr0=[249,91,149,113,16,91,53,41]
arr1=[43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
arr2=[90,100,87,109,86,108,86,105,90,104,88,102]
def check0()
def check1()
def check2()
def check3()
flag=raw_input()
if check0(flag):
if check1(flag):
if check2(flag):
if check3(flag):
print 'ok'
else:
print'no'
def check0():
all=ord(x) for x in range(32,128)
iter(s)
def check1():
if len(s)<100:
if (len(s)*len(s))%777)^233==513:
return True
else:
False
else:
False
def check2():
if ((((ord(s[0])*128+ord(s[1]))*128+ord(s[2]))*128+ord(s[3]))*128+ord(s[4]))*128+ord(s[5]) == 3533889469877:
if ord(s[-1])==125:
return True
else:
return False
else:
return False
def check3():
arr=map(ord,s)
a=arr[6:30:3]
for i in range(len(a))
if (a[i]*17684+372511)%257!=arr0[i]:
return Flase
b=arr[-2:33:-1]*5
c=map(lambda x[0]:x[0]^x[1] zip(b,arr[7,27]))
if c!=arr1:
p=0
for i in range(28,34):
if (arr[i]+107)/16+77!=arr2[p]:
if (arr[i]+117)/16+99!=arr2[p+1]:
p+=2
else:
return False
#<genexpr> ord(x) for x in range(32,128)
#<lambda> x[0]^x[1]
This can only be seen roughly ... not necessarily completely accurate ... If there are different opinions, please correct me and leave a message QAQ is actually very much looking forward to getting advice. After all, this is the first time I read this.
Analysis code
In conjunction with the official wp analysis
flag, the check0, check1, check2, and check3 functions are required to check
check0. The flag characters are all in the range of 32, 128. Check1
, condition l <100 and ((l * l)% 777) ^ 233 = = 513 Get the length of the flag as 39
check2, and get the flag starting with "flag {5" and ending with "}"
check3 in 128 hexadecimal , in which three flags are calculated, the first part can be obtained by blasting expression, the second The part needs to be obtained by XORing the result of the first part, and the third part is similar to the hexadecimal encoding and can be directly recovered
Problem-solving script
blasting
flag = [' ']*39
x = 3533889469877
t = ''
while x != 0:
t += chr(x%128)
x/=128
flag[:6] = t[::-1]
flag[-1] = '}'
arr0 = [249,91,149,113,16,91,53,41]
for i in range(8):
for ch in range(32, 128):
if (ch * 17684 + 372511) % 257 == arr0[i]:
flag[6+i*3]=chr(ch)
arr1 = [43, 1, 6, 69, 20, 62, 6, 44, 24, 113, 6, 35, 0, 3, 6, 44, 20, 22, 127, 60]
key = [0]*4
key[0] = arr1[8] ^ ord(flag[15])
key[1] = arr1[5] ^ ord(flag[12])
key[2] = arr1[2] ^ ord(flag[9])
key[3] = arr1[11] ^ ord(flag[18])
flag[-2] = chr(key[0])
flag[-3] = chr(key[1])
flag[-4] = chr(key[2])
flag[-5] = chr(key[3])
for i in range(len(arr1)):
flag[7+i] = chr(arr1[i] ^ key[i%4])
arr2 = [90, 100, 87, 109, 86, 108, 86, 105, 90, 104, 88, 102]
z3 script solution
from z3 import *
arr0 = [249,91,149,113,16,91,53,41]
arr1 = [43,1,6,69,20,62,6,44,24,113,6,35,0,3,6,44,20,22,127,60]
arr2 = [90,100,87,109,86,108,86,105,90,104,88,102]
k = Solver()
s = [BitVec('s[%d]'%i,64)for i in range(39)]
for i in range(39):
k.add(32<=s[i])
k.add(s[i]<128)
k.add(((((s[0]*128+s[1])*128+s[2])*128+s[3])*128+s[4])*128+s[5] == 3533889469877)
k.add(s[-1]== ord('}'))
arr = list(s)
a = arr[6:30:3]
for i in range(len(a)):
k.add((a[i]*17684+372511)%257==arr0[i])
b = arr[-2:33:-1]*5
c = list(map(lambda x:x[0]^x[1] ,zip(b,arr[7:27])))
for i in range(len(c)):
k.add(c[i]==arr1[i])
p = 0
for i in range(28,34):
k.add(arr2[p] == (arr[i]+107)/16+77)
k.add((arr[i]+117)%16+99==arr2[p+1])
p+=2
print(k.check())
print(k.model())
z3 script secondary conversion
s = [0]*39
s[5]=53
s[4]=123
s[34]=117
s[7]=90
s[6]=76
s[30]=52
s[18]=86
s[35]=51
s[33]=78
s[24]=80
s[12]=120
s[11]=101
s[20]=69
s[15]=105
s[3]=103
s[25]=76
s[23]=101
s[2]=97
s[16]=55
s[29]=53
s[17]=53
s[22]=89
s[36]=70
s[21]=53
s[8]=71
s[13]=53
s[28]=108
s[26]=73
s[14]=89
s[0]=102
s[37]=113
s[31]=49
s[10]=48
s[1]=108
s[9]=53
s[27]=75
s[32]=112
s[19]=113
s[38]=125
for i in range(39):
print(chr(s[i]),end="")
z3 works great. This part of the z3 script is detailed in the CX-330 blog post.
Knowing this kind of thing for the first time is worth learning!