重新组装Python字节码到源代码(CTF挑战)



我有一个python字节码的文本文件,这是你在发布python -m dis file.py.时得到的输出的一部分。我的目标是从字节码重新组装源。

我在这里看到过一个类似的问题,但提供的答案集中在(从我的理解)应该解决问题的工具只有如果我的字节码文件有所有必要的信息(python字节码版本,时间戳,标志等)。

。佩克代码:

##################################################
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

What I've try我尝试了一些类似问题中建议的工具,如uncompyle6, pycbc和pyc-xasm.

然而,根据我的理解,这些工具期望一个带有所有'头信息' (python字节码版本,时间戳,标志等)的.pyc/python反汇编文件能够工作,而我的文件没有,所以我无法使用这些工具,因为它们给我错误。我之所以指出这一点,还因为我不完全了解如何使用这些工具,所以我可能错过了一些有助于解决我的问题的东西。如果我确实错过了什么,我也希望你能帮我。

我当前的解决方案
我目前正试图通过找出操作码是如何按照https://docs.python.org/3/library/dis.html的文档工作并编写相应的python代码来重新组装源代码。到目前为止,我已经能够用下面的python代码复制到第二个返回语句。

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代码,以便我可以更好地反转字节码。希望我的问题和目标是明确的。一切帮助将不胜感激。

对安全谷"奇怪代码"的回答;周大福

你只需要转换.pyc.py文件。但是你必须手动执行uncompyle6而其他库由于不完整而无法工作。佩克文件.

以下是.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()

我希望这对你有帮助:)