这个题目主要就是阅读 pyc 反汇编代码,这边把注释过的 pyc 反汇编代码贴出来
部分变量名为了方便阅读做了转换
1 0 LOAD_CONST 0 (<code object keyinit at 0x0000028C1CC11D20, file "crackPYC.py", line 1>)
2 LOAD_CONST 1 ('keyinit')
4 MAKE_FUNCTION 0
6 STORE_NAME 0 (keyinit)
8 8 LOAD_NAME 1 (__name__)
10 LOAD_CONST 2 ('__main__')
12 COMPARE_OP 2 (==)
14 POP_JUMP_IF_FALSE 250
9 16 LOAD_NAME 2 (print)
18 LOAD_CONST 3 ('Can you crack pyc?')
20 CALL_FUNCTION 1
22 POP_TOP
10 24 LOAD_NAME 3 (input)
26 LOAD_CONST 4 ('Plz give me your flag:')
28 CALL_FUNCTION 1
30 STORE_NAME 4 (user_input) ; 输入数据
11 32 LOAD_CONST 5 (108)
34 LOAD_CONST 6 (17)
36 LOAD_CONST 7 (42)
38 LOAD_CONST 8 (226)
40 LOAD_CONST 9 (158)
42 LOAD_CONST 10 (180)
44 LOAD_CONST 11 (96)
46 LOAD_CONST 12 (115)
48 LOAD_CONST 13 (64)
50 LOAD_CONST 14 (24)
52 LOAD_CONST 15 (38)
54 LOAD_CONST 16 (236)
56 LOAD_CONST 17 (179)
58 LOAD_CONST 18 (173)
60 LOAD_CONST 19 (34)
62 LOAD_CONST 20 (22)
64 LOAD_CONST 21 (81)
66 LOAD_CONST 22 (113)
68 LOAD_CONST 15 (38)
70 LOAD_CONST 23 (215)
72 LOAD_CONST 24 (165)
74 LOAD_CONST 25 (135)
76 LOAD_CONST 26 (68)
78 LOAD_CONST 27 (7)
12 80 LOAD_CONST 28 (119)
82 LOAD_CONST 29 (97)
84 LOAD_CONST 30 (45)
86 LOAD_CONST 31 (254)
88 LOAD_CONST 32 (250)
90 LOAD_CONST 33 (172)
92 LOAD_CONST 34 (43)
94 LOAD_CONST 35 (62)
96 BUILD_LIST 32
98 STORE_NAME 5 (text)
13 100 LOAD_NAME 6 (len)
102 LOAD_NAME 4 (user_input)
104 CALL_FUNCTION 1
106 LOAD_CONST 36 (32)
108 COMPARE_OP 3 (!=) ; 比较长度
110 POP_JUMP_IF_TRUE 140
112 LOAD_NAME 4 (user_input)
114 LOAD_CONST 37 (0)
116 LOAD_CONST 27 (7)
118 BUILD_SLICE 2
120 BINARY_SUBSCR
122 LOAD_CONST 38 ('DASCTF{')
124 COMPARE_OP 3 (!=)
126 POP_JUMP_IF_TRUE 140
128 LOAD_NAME 4 (user_input)
130 LOAD_CONST 39 (31)
132 BINARY_SUBSCR
134 LOAD_CONST 40 ('}')
136 COMPARE_OP 3 (!=)
138 POP_JUMP_IF_FALSE 154
14 >> 140 LOAD_NAME 2 (print)
142 LOAD_CONST 41 ('Bye bye~~')
144 CALL_FUNCTION 1
146 POP_TOP
15 148 LOAD_NAME 7 (exit)
150 CALL_FUNCTION 0
152 POP_TOP
16 >> 154 LOAD_NAME 8 (list)
156 LOAD_NAME 4 (user_input)
158 CALL_FUNCTION 1
160 STORE_NAME 9 (st) ; 将 user_input 转换成 list 存入 st
17 162 BUILD_LIST 0
164 STORE_NAME 10 (key)
18 166 LOAD_NAME 0 (keyinit) ; 初始化 key
168 LOAD_NAME 10 (key)
170 CALL_FUNCTION 1
172 POP_TOP
19 174 SETUP_LOOP 48 (to 224)
176 LOAD_NAME 11 (range)
178 LOAD_CONST 36 (32)
180 CALL_FUNCTION 1
182 GET_ITER
>> 184 FOR_ITER 36 (to 222)
186 STORE_NAME 12 (i) ; for 循环
20 188 LOAD_NAME 13 (ord)
190 LOAD_NAME 4 (user_input)
192 LOAD_NAME 12 (i) ; ord(user_input[i])
194 BINARY_SUBSCR
196 CALL_FUNCTION 1
198 LOAD_NAME 10 (key)
200 LOAD_NAME 12 (i)
202 LOAD_NAME 6 (len)
204 LOAD_NAME 10 (key)
206 CALL_FUNCTION 1 ; len(key)
208 BINARY_MODULO ; i % len(key)
210 BINARY_SUBSCR ; key[i % len(key)]
212 BINARY_XOR ; ord(user_input[i]) ^ key[i % len(key)]
214 LOAD_NAME 9 (st)
216 LOAD_NAME 12 (i)
218 STORE_SUBSCR
220 JUMP_ABSOLUTE 184
>> 222 POP_BLOCK
21 >> 224 LOAD_NAME 9 (st)
226 LOAD_NAME 5 (text)
228 COMPARE_OP 2 (==)
230 POP_JUMP_IF_FALSE 242
22 232 LOAD_NAME 2 (print)
234 LOAD_CONST 42 ('Congratulations and you are good at PYC!')
236 CALL_FUNCTION 1
238 POP_TOP
240 JUMP_FORWARD 8 (to 250)
24 >> 242 LOAD_NAME 2 (print)
244 LOAD_CONST 43 ('Sorry,plz learn more about pyc.')
246 CALL_FUNCTION 1
248 POP_TOP
>> 250 LOAD_CONST 44 (None)
252 RETURN_VALUE
Disassembly of <code object keyinit at 0x0000028C1CC11D20, file "crackPYC.py", line 1>:
2 0 LOAD_CONST 1 (0)
2 STORE_FAST 1 (num)
3 4 SETUP_LOOP 42 (to 48)
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 2 (8)
10 CALL_FUNCTION 1
12 GET_ITER
>> 14 FOR_ITER 30 (to 46)
16 STORE_FAST 2 (i)
4 18 LOAD_FAST 1 (num)
20 LOAD_CONST 3 (7508399208111569251)
22 BINARY_SUBTRACT
24 LOAD_CONST 4 (4294967295)
26 BINARY_MODULO
28 STORE_FAST 1 (num)
5 30 LOAD_FAST 0 (key)
32 LOAD_METHOD 1 (append)
34 LOAD_FAST 1 (num)
36 LOAD_CONST 5 (24)
38 BINARY_RSHIFT
40 CALL_METHOD 1
42 POP_TOP
44 JUMP_ABSOLUTE 14
>> 46 POP_BLOCK
>> 48 LOAD_CONST 0 (None)
50 RETURN_VALUE
可以得到 key 的生成函数 keyinit 的代码应该是这样的
def keyinit():
num = 1
key = []
for i in range(8):
num = (num - 7508399208111569251) % 4294967295
key.append(num >> 24)
return key
加密过程为
data[i] ^ key[i % len(key)]
所以最后的解题代码
data =[108,17,42,226,158,180,96,115,64,24,38,236,179,173,34,22,81,113,38,215,165,135,68,7,119,97,45,254,250,172,43,62]
def keyinit():
num = 1
key = []
for i in range(8):
num = (num - 7508399208111569251) % 4294967295
key.append(num >> 24)
return key
if __name__ == '__main__':
key = keyinit()
for i in range(len(data)):
print(chr(data[i] ^ key[i % len(key)]), end="")