我有一个带有 python 字节码的文本文件,它是你在发布时得到的输出的一部分
python -m dis file.py.
我的目标是从字节码重新组装源代码。
我看到一个类似的问题被问到here但提供的答案集中在(根据我的理解)应该解决问题的工具仅如果我的字节码文件具有所有必要的信息(python字节码版本,时间戳,标志等)。
.pyc代码:
##################################################
15 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('loading application')
4 CALL_FUNCTION 1
6 POP_TOP
17 8 LOAD_GLOBAL 1 (magic)
10 LOAD_CONST 2 ('8934')
12 LOAD_GLOBAL 2 (get_flag)
14 CALL_FUNCTION 0
16 CALL_FUNCTION 2
18 STORE_FAST 0 (d)
19 20 LOAD_GLOBAL 0 (print)
22 LOAD_FAST 0 (d)
24 CALL_FUNCTION 1
26 POP_TOP
28 LOAD_CONST 0 (None)
30 RETURN_VALUE
None
##################################################
4 0 LOAD_CONST 1 ('k\\PbYUHDAM[[VJlVAMVk[VWQE')
2 RETURN_VALUE
None
##################################################
7 0 LOAD_CONST 1 (b'')
2 STORE_FAST 2 (out)
9 4 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (len)
8 LOAD_FAST 1 (f)
10 CALL_FUNCTION 1
12 CALL_FUNCTION 1
14 GET_ITER
>> 16 FOR_ITER 46 (to 64)
18 STORE_FAST 3 (i)
10 20 LOAD_FAST 2 (out)
22 LOAD_GLOBAL 2 (bytes)
24 LOAD_GLOBAL 3 (ord)
26 LOAD_FAST 1 (f)
28 LOAD_FAST 3 (i)
30 BINARY_SUBSCR
32 CALL_FUNCTION 1
34 LOAD_GLOBAL 3 (ord)
36 LOAD_FAST 0 (k)
38 LOAD_FAST 3 (i)
40 LOAD_GLOBAL 1 (len)
42 LOAD_FAST 0 (k)
44 CALL_FUNCTION 1
46 BINARY_MODULO
48 BINARY_SUBSCR
50 CALL_FUNCTION 1
52 BINARY_XOR
54 BUILD_LIST 1
56 CALL_FUNCTION 1
58 INPLACE_ADD
60 STORE_FAST 2 (out)
62 JUMP_ABSOLUTE 16
12 >> 64 LOAD_FAST 2 (out)
66 RETURN_VALUE
None
我试过的
我尝试了类似问题中建议的一些工具,例如 uncompyle6、pycbc 和 pyc-xasm.
然而,根据我的理解,这些工具需要一个包含所有“头信息”(python 字节码版本、时间戳、标志等)的 .pyc/python 反汇编文件才能工作,而我的文件没有,所以我无法使用这些工具,因为它们会给我错误。我也指出了这一点,因为我不完全了解如何使用这些工具,所以我可能错过了一些有助于解决我的问题的东西。如果我确实错过了什么,我也希望在这里得到一些帮助。
我目前的解决方案
我目前正在尝试按照 https://docs.python.org/3/library/dis.html 上的文档弄清楚操作码如何工作并编写相应的 python 代码来重新组装源代码。到目前为止,我已经能够使用下面的 python 代码重现代码,直到第二个 return 语句。
test.py
def bla():
print("loading app")
d = magic("8934", get_flag())
print(d)
def magic():
return "k\\PbYUHDAM[[VJlVAMVk[VWQE"
python -m dis test.py:
的输出
Disassembly of <code object bla at 0x7fea8a11e240, file "test.py", line 5>:
6 0 LOAD_GLOBAL 0 (print)
2 LOAD_CONST 1 ('loading app')
4 CALL_FUNCTION 1
6 POP_TOP
7 8 LOAD_GLOBAL 1 (magic)
10 LOAD_CONST 2 ('8934')
12 LOAD_GLOBAL 2 (get_flag)
14 CALL_FUNCTION 0
16 CALL_FUNCTION 2
18 STORE_FAST 0 (d)
8 20 LOAD_GLOBAL 0 (print)
22 LOAD_FAST 0 (d)
24 CALL_FUNCTION 1
26 POP_TOP
28 LOAD_CONST 0 (None)
30 RETURN_VALUE
Disassembly of <code object magic at 0x7fea8a11e2f0, file "test.py", line 11>:
12 0 LOAD_CONST 1 ('k\\PbYUHDAM[[VJlVAMVk[VWQE')
2 RETURN_VALUE
但是,我在重现与最后一个代码块上的操作码匹配的 python 代码时遇到问题(块由多个 '#' 分隔)。我已经将一些操作码与正确的 python 指令相匹配,但参数计数仍然不正确,而且 python 代码显然没有意义......到目前为止。
函数get_flag:
def get_flag():
out = b""
for i in range(len(f)):
out += bytes([ord(f[i]) ^ ord(k[i % len(k)])])
return out
dis 函数 get_flag 的输出
Disassembly of <code object get_flag at 0x7fea8a11e3a0, file "test.py", line 15>:
16 0 LOAD_CONST 1 (b'')
2 STORE_FAST 0 (out)
17 4 LOAD_GLOBAL 0 (range)
6 LOAD_GLOBAL 1 (len)
8 LOAD_GLOBAL 2 (f)
10 CALL_FUNCTION 1
12 CALL_FUNCTION 1
14 GET_ITER
>> 16 FOR_ITER 46 (to 64)
18 STORE_FAST 1 (i)
18 20 LOAD_FAST 0 (out)
22 LOAD_GLOBAL 3 (bytes)
24 LOAD_GLOBAL 4 (ord)
26 LOAD_GLOBAL 2 (f)
28 LOAD_FAST 1 (i)
30 BINARY_SUBSCR
32 CALL_FUNCTION 1
34 LOAD_GLOBAL 4 (ord)
36 LOAD_GLOBAL 5 (k)
38 LOAD_FAST 1 (i)
40 LOAD_GLOBAL 1 (len)
42 LOAD_GLOBAL 5 (k)
44 CALL_FUNCTION 1
46 BINARY_MODULO
48 BINARY_SUBSCR
50 CALL_FUNCTION 1
52 BINARY_XOR
54 BUILD_LIST 1
56 CALL_FUNCTION 1
58 INPLACE_ADD
60 STORE_FAST 0 (out)
62 JUMP_ABSOLUTE 16
19 >> 64 LOAD_CONST 2 ('')
66 RETURN_VALUE
具体来说,我需要帮助理解字节码参数计数如何改变相应的 python 代码,这样我才能更好地逆向字节码。 希望我的问题和目标很明确。所有帮助将不胜感激。
安全谷“怪代码”CTF的答案
您只需要将.pyc文件转换为.py文件。但是,您必须手动执行此操作,因为 uncompyle6 并且其他库由于不完整的 .pyc 文件.
而无法工作这是 .pyc 文件的 .py 代码:-
def get_flag():
return "k\\PbYUHDAM[[VJlVAMVk[VWQE"
def magic(k,f):
out = b""
for i in range(len(f)):
out += bytes([ord(f[i])^ord(k[i%len(k)])])
return out
def hello():
print("loading application")
d = magic('8934',get_flag())
print(d)
hello()
我希望这有帮助:)