如何反编译Python 3.9.13中marshal.loads加载的字节码?
Python 3.9字节码反编译方案(针对marshal加载的code对象)
问题描述
我有一段代码:
import marshal code = b'c\x00\x00\x...' exec(marshal.loads(code))
想要查看这段字节码对应的源代码,将exec()替换为print()后,仅得到以下输出:
<code object <module> at 0x000001E56EA9E660, file "Specter", line 1>
已尝试的方法:
- 将字节码存入.pyc文件,使用pycdc反编译
- 使用仅支持Python 2.7的unmarshal脚本
- 使用python-xdis工具
当前Python版本为3.9.13,求可行的反编译方案。
可行反编译方案
1. 正确使用python-xdis
python-xdis原生支持Python 3.9,若之前操作无效,可按以下步骤执行:
- 先安装依赖包:
pip install xdis xasm - 直接对加载后的code对象反编译:
import marshal from xdis import decompile_code from xdis.version_info import PYTHON_VERSION_TRIPLE code = b'c\x00\x00\x...' code_obj = marshal.loads(code) # 指定目标Python版本为3.9.13 print(decompile_code(code_obj, PYTHON_VERSION_TRIPLE(3,9,13)))
若直接反编译报错,可尝试生成标准.pyc文件后再反编译:
import marshal import tempfile import os from xdis import disassemble_file code = b'c\x00\x00\x...' code_obj = marshal.loads(code) # 生成Python 3.9格式的pyc文件头(魔法数+时间戳) magic = b'\x42\x0d\x0d\x0a' # Python 3.9专属魔法数 timestamp = b'\x00\x00\x00\x00\x00\x00\x00\x00' pyc_header = magic + timestamp with tempfile.NamedTemporaryFile(mode='wb', suffix='.pyc', delete=False) as f: f.write(pyc_header) marshal.dump(code_obj, f) # 反编译临时pyc文件 disassemble_file(f.name) os.unlink(f.name)
2. 使用uncompyle6
uncompyle6对Python 3.6-3.9的兼容性较好,可直接处理code对象:
- 安装工具:
pip install uncompyle6 - 执行反编译并导出源码:
import marshal from uncompyle6 import decompile code = b'c\x00\x00\x...' code_obj = marshal.loads(code) # 第二个参数为Python版本标识,3.9对应39 decompile(39, code_obj, outfile=open('output.py', 'w'))
运行后会在当前目录生成output.py,文件内即为反编译后的源代码。
3. 字节码手动分析(兜底方案)
如果工具反编译失败,可借助Python自带的dis模块查看字节码指令,手动还原逻辑:
import marshal import dis code = b'c\x00\x00\x...' code_obj = marshal.loads(code) dis.dis(code_obj)
对照Python官方字节码文档,逐行解析指令即可还原源代码。
内容的提问来源于stack exchange,提问作者xKian
相关产品推荐
相关产品推荐

