拿到文件,先用工具扫一下
推测是用pyinstaller打包pyc成exe
所以要将python的exe反编译
先使用pyinstxtractor.py反编译exe就行
把pyinstxtractor.py和main.exe放在同一文件夹下,然后用命令python pyinstxtractor.py main.exe即可得到main.exe_extracted文件夹
打开后找到main.pyc和struct.pyc,分别用010Editor打开
发现main前十六个字节有问题,复制struct的前十六个字节覆盖main前十六个字节即可
然后使用uncompyle6或者在线工具反编译就行
但是这题是python3.9,只能手撸字节码了
首先反汇编得到字节码,然后手撸就行了
反汇编要用工具pycdc,直接在linux里面装就行了,我另外写一篇安装的吧,这里不说了
把main.pyc复制到linux里面
cd pycdc
./pycdas 文件路径 #反汇编
./pycdc 文件路径 #反编译
字节码如下
main.pyc (Python 3.9)
[Code]
File Name: main.py
Object Name: <module>
Arg Count: 0
Pos Only Arg Count: 0
KW Only Arg Count: 0
Locals: 0
Stack Size: 4
Flags: 0x00000040 (CO_NOFREE)
[Names]
'base64'
'encode'
'enCodeAgain'
'correct'
'flag'
'print'
'input'
[Var Names]
[Free Vars]
[Cell Vars]
[Constants]
0
None
[Code]
File Name: main.py
Object Name: encode
Arg Count: 1
Pos Only Arg Count: 0
KW Only Arg Count: 0
Locals: 4
Stack Size: 5
Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)
[Names]
'chr'
'base64'
'b64encode'
'encode'
[Var Names]
'message'
's'
'i'
'x'
[Free Vars]
[Cell Vars]
[Constants]
None
''
32
16
'utf-8'
[Disassembly]
0 LOAD_CONST 1: ''
2 STORE_FAST 1: s
4 LOAD_FAST 0: message
6 GET_ITER
8 FOR_ITER 32 (to 42)
10 STORE_FAST 2: i
12 LOAD_FAST 2: i
14 LOAD_CONST 2: 32
16 BINARY_XOR
18 STORE_FAST 3: x
20 LOAD_FAST 3: x
22 LOAD_CONST 3: 16
24 BINARY_ADD
26 STORE_FAST 3: x
28 LOAD_FAST 1: s
30 LOAD_GLOBAL 0: chr
32 LOAD_FAST 3: x
34 CALL_FUNCTION 1
36 INPLACE_ADD
38 STORE_FAST 1: s
40 JUMP_ABSOLUTE 8
42 LOAD_GLOBAL 1: base64
44 LOAD_METHOD 2: b64encode
46 LOAD_FAST 1: s
48 LOAD_METHOD 3: encode
50 LOAD_CONST 4: 'utf-8'
52 CALL_METHOD 1
54 CALL_METHOD 1
56 RETURN_VALUE
'encode'
[Code]
File Name: main.py
Object Name: enCodeAgain
Arg Count: 2
Pos Only Arg Count: 0
KW Only Arg Count: 0
Locals: 5
Stack Size: 5
Flags: 0x00000043 (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)
[Names]
'str'
'range'
'len'
[Var Names]
'string'
'space'
's'
'i'
'j'
[Free Vars]
[Cell Vars]
[Constants]
None
''
'utf-8'
0
[Disassembly]
0 LOAD_CONST 1: ''
2 STORE_FAST 2: s
4 LOAD_GLOBAL 0: str
6 LOAD_FAST 0: string
8 LOAD_CONST 2: 'utf-8'
10 CALL_FUNCTION 2
12 STORE_FAST 0: string
14 LOAD_GLOBAL 1: range
16 LOAD_CONST 3: 0
18 LOAD_FAST 1: space
20 CALL_FUNCTION 2
22 GET_ITER
24 FOR_ITER 50 (to 76)
26 STORE_FAST 3: i
28 LOAD_GLOBAL 1: range
30 LOAD_FAST 3: i
32 LOAD_GLOBAL 2: len
34 LOAD_FAST 0: string
36 CALL_FUNCTION 1
38 LOAD_FAST 1: space
40 CALL_FUNCTION 3
42 GET_ITER
44 FOR_ITER 28 (to 74)
46 STORE_FAST 4: j
48 LOAD_FAST 4: j
50 LOAD_GLOBAL 2: len
52 LOAD_FAST 0: string
54 CALL_FUNCTION 1
56 COMPARE_OP 0 (<)
58 POP_JUMP_IF_FALSE 44
60 LOAD_FAST 2: s
62 LOAD_FAST 0: string
64 LOAD_FAST 4: j
66 BINARY_SUBSCR
68 INPLACE_ADD
70 STORE_FAST 2: s
72 JUMP_ABSOLUTE 44
74 JUMP_ABSOLUTE 24
76 LOAD_FAST 2: s
78 RETURN_VALUE
'enCodeAgain'
'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ='
''
'Input flag:'
'utf-8'
2
'correct'
'wrong'
[Disassembly]
0 LOAD_CONST 0: 0
2 LOAD_CONST 1: None
4 IMPORT_NAME 0: base64
6 STORE_NAME 0: base64
8 LOAD_CONST 2: <CODE> encode
10 LOAD_CONST 3: 'encode'
12 MAKE_FUNCTION 0
14 STORE_NAME 1: encode
16 LOAD_CONST 4: <CODE> enCodeAgain
18 LOAD_CONST 5: 'enCodeAgain'
20 MAKE_FUNCTION 0
22 STORE_NAME 2: enCodeAgain
24 LOAD_CONST 6: 'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ='
26 STORE_NAME 3: correct
28 LOAD_CONST 7: ''
30 STORE_NAME 4: flag
32 LOAD_NAME 5: print
34 LOAD_CONST 8: 'Input flag:'
36 CALL_FUNCTION 1
38 POP_TOP
40 LOAD_NAME 6: input
42 CALL_FUNCTION 0
44 STORE_NAME 4: flag
46 LOAD_NAME 4: flag
48 LOAD_METHOD 1: encode
50 LOAD_CONST 9: 'utf-8'
52 CALL_METHOD 1
54 STORE_NAME 4: flag
56 LOAD_NAME 5: print
58 LOAD_NAME 2: enCodeAgain
60 LOAD_NAME 1: encode
62 LOAD_NAME 4: flag
64 CALL_FUNCTION 1
66 LOAD_CONST 10: 2
68 CALL_FUNCTION 2
70 CALL_FUNCTION 1
72 POP_TOP
74 LOAD_NAME 2: enCodeAgain
76 LOAD_NAME 1: encode
78 LOAD_NAME 4: flag
80 CALL_FUNCTION 1
82 LOAD_CONST 10: 2
84 CALL_FUNCTION 2
86 LOAD_NAME 3: correct
88 COMPARE_OP 2 (==)
90 POP_JUMP_IF_FALSE 102
92 LOAD_NAME 5: print
94 LOAD_CONST 11: 'correct'
96 CALL_FUNCTION 1
98 POP_TOP
100 JUMP_FORWARD 8 (to 110)
102 LOAD_NAME 5: print
104 LOAD_CONST 12: 'wrong'
106 CALL_FUNCTION 1
108 POP_TOP
110 LOAD_CONST 1: None
112 RETURN_VALUE
然后开始手撸字节码,看不懂没事,推荐下面看雪的文章,看完还有不会的就去官方文档用Ctrl+F查询就行了
最后得到
import base64
def encode(message):
s = ''
for i in message:
x = i ^ 32
x += 16
s += chr(x)
return (base64.b64encode(s.encode('utf-8')))
def enCodeAgain(string, space):
s = ''
string = str(string, 'utf-8')
for i in range(0, space):
for j in range(i, len(string), space):
if j < len(string):
s += string[j]
return s
correct = 'VxVtd5dKIPjMw9wVb=lR2WVTcPWC2goWoeQ='
flag = ''
print('Input flag:')
flag = input()
flag = flag.encode('utf-8')
print(enCodeAgain(encode(flag), 2))
if enCodeAgain(encode(flag), 2) == correct:
print(correct)
else:
print('wrong')
对应脚本
import base64
s1 = 'VxVtd5dKIPjMw9wVb='
s2 = 'lR2WVTcPWC2goWoeQ='
string = []
for i in range(len(s1)):
string.append(s1[i])
string.append(s2[i])
string = ''.join(string)
s = base64.b64decode(string)
s = s.decode()
for x in s:
x = ord(x) - 16
i = chr(x ^ 32)
print(i, end='')