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

问题描述 投票:0回答:1

我有一个带有 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 代码,这样我才能更好地逆向字节码。 希望我的问题和目标很明确。所有帮助将不胜感激。

python disassembly opcode
1个回答
0
投票

安全谷“怪代码”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()

我希望这有帮助:)

© www.soinside.com 2019 - 2024. All rights reserved.