将编译后的代码转换回源代码

Convert compiled code back into source code

提问人:Dimuth De Zoysa 提问时间:8/28/2023 最后编辑:Dimuth De Zoysa 更新时间:8/28/2023 访问量:162

问:

我有一个混淆的 Python 代码对象,该对象已使用各种模块进行编码和压缩,包括 base64、zlib、gzip 和 marshal。

我的目标是对这个代码对象进行逆向工程,以便提取原始源代码。

下面是我用来生成混淆代码对象的过程:

import gzip, zlib, marshal, base64
pycode = "print('Hello world')"
obfuscated_code = base64.b64encode(zlib.compress(gzip.compress(marshal.dumps(compile(pycode, <string>, "exec"))), level=zlib.Z_BEST_COMPRESSION))

然后我做了以下操作来运行混淆的 python 代码以运行..

import gzip, zlib, marshal, base64

exec(marshal.loads(gzip.decompress(zlib.decompress(base64.b64decode(obfuscated_code)))))

我尝试将 exec 更改为打印。 但是,我收到的输出不是打印源代码,而是:


bash<code object <module> at 0x15034df59df0, file "Nice Try", line 1>

我的问题是:我怎样才能对这个代码对象进行逆向工程以成功提取原始源代码?

有没有办法从给定的混淆代码对象中恢复源代码?

谢谢你的帮助!

Python 编译 字节码

评论

1赞 Klaus D. 8/28/2023
“我将python代码编译为字节码。不,你没有。
0赞 ctrl-alt-delor 8/28/2023
你正在做哪些挑战?
0赞 Dimuth De Zoysa 8/28/2023
@ctrl-alt-delor 我没有做挑战。你能帮忙吗?
0赞 ctrl-alt-delor 8/28/2023
很难推断你想做什么。请通过编辑问题来澄清。
0赞 Dimuth De Zoysa 8/28/2023
@ctrl-alt-delor 我改写了问题,请再读一遍

答:

2赞 Musabbir Arrafi 8/28/2023 #1

以下是更正后的代码:

import zlib
import gzip
import marshal
import base64

# Your Python source code
pycode = "print('Hello world')"

# Compile the code
compiled_code = compile(pycode, "Nice Try", "exec")

# Serialize and compress the compiled code
compressed_code = zlib.compress(gzip.compress(marshal.dumps(compiled_code)), level=zlib.Z_BEST_COMPRESSION)

# Encode the compressed code in base64
encoded_code = base64.b64encode(compressed_code)

# print the encoded code
print(encoded_code)

# Decode the base64-encoded code
compressed_code = base64.b64decode(encoded_code)

# Decompress the compressed code using zlib
gzip_compressed_code = zlib.decompress(compressed_code)

# Decompress the gzip-compressed code
bytecode = gzip.decompress(gzip_compressed_code)

# Unmarshal the serialized bytecode
compiled_code = marshal.loads(bytecode)

# print the compiled code
print(compiled_code)

# Execute the compiled code
exec(compiled_code)

输出:

b'eNoBZgCZ/x+LCACIfOxkAv97zIAGmIDYAYiLeYBEKkMKQzMjI0MKYzCDJlMVt0dqTk6+Qnl+UU6KnybjLdaCosy8kpUMRSBNYOIXh19mcqpCSFHlLQ6b3PyU0pxUO0ag+GeQ0QBLaA7pbAAAADlZKhY='
<code object <module> at 0x7fcfc14d6920, file "Nice Try", line 1>
Hello world

这里还有两种方法可以让你反编译你的字节码,但你需要原始的.pyc或.pyo文件来反编译回源代码。

解决方案 1

我建议你使用这个包,如果你正在使用 .uncompyle6python <= 3.6

  • 您可以从 PyPI 安装:
pip install uncompyle6
  • 您可以像这样从命令行使用它:
uncompyle6 path/to/bytecode/file.pyc
  • 或者,如果您想从 python 脚本中使用它:
import subprocess

def decompile_pyc(pyc_file_path):
    try:
        command = ["uncompyle6", pyc_file_path]
        result = subprocess.run(command, capture_output=True, text=True, check=True)
        decompiled_code = result.stdout
        return decompiled_code
    except subprocess.CalledProcessError as e:
        print("Error:", e)
        return None

# Provide the path to your .pyc file
pyc_file_path = "__pycache__/test.cpython-38.pyc"

# Call the function to decompile the .pyc file
decompiled_code = decompile_pyc(pyc_file_path)

# Print the decompiled code
if decompiled_code:
    print(decompiled_code)

查看 https://github.com/rocky/python-uncompyle6 以了解更多信息

解决方案 2

如果您正在使用或签出 .用法和以前基本一样:python-3.7python-3.8decompyle3

  • 您可以从 PyPI 安装:
pip install decompyle6
  • 您可以像这样从命令行使用它:
decompyle6 path/to/bytecode/file.pyc
  • 或来自 python 脚本
import subprocess
def decompile_pyc(pyc_file_path):
    try:
        command = ["decompyle3", pyc_file_path]
        result = subprocess.run(command, capture_output=True, text=True, check=True)
        decompiled_code = result.stdout
        return decompiled_code
    except subprocess.CalledProcessError as e:
        print("Error:", e)
        return None

# Provide the path to your compiled .pyc file
pyc_file_path = "__pycache__/test.cpython-38.pyc"

# Call the function to decompile the .pyc file
decompiled_code = decompile_pyc(pyc_file_path)

# Print the decompiled code
if decompiled_code:
    print(decompiled_code)

查看 https://github.com/rocky/python-decompile3 以了解更多信息。

评论

0赞 Dimuth De Zoysa 8/28/2023
两者都不起作用。
1赞 Musabbir Arrafi 8/28/2023
它在这里对我有用。如答案中所述,您必须有 python<=3.8,所以字节码应该是。你的道路正确吗?你遇到任何错误了吗?还是别的什么?.pyc
1赞 Musabbir Arrafi 8/28/2023
我还更正了您的代码并将其添加到我的答案中,也请检查一下。我正在跑步python3.8.16
0赞 Dimuth De Zoysa 8/29/2023
这仅适用于 pyc 文件,而不适用于代码对象。尝试将代码对象转换为 py c 并这样做,但不起作用。
1赞 Musabbir Arrafi 8/29/2023
在第一个答案中检查您更正的代码,我在那里添加了它。