pycdc 使用指南:把 Python 字节码反编译回源码,版本覆盖 1.0 到 3.13

📅 2026/8/27 1:25:25
pycdc 使用指南:把 Python 字节码反编译回源码,版本覆盖 1.0 到 3.13
pycdc 使用指南把 Python 字节码反编译回源码版本覆盖 1.0 到 3.13【免费下载链接】pycdcC python bytecode disassembler and decompiler项目地址: https://gitcode.com/GitHub_Trending/py/pycdcpycdcDecompyle是一个用 C 编写的 Python 字节码反编译工具能把编译后的 .pyc 文件还原成可读的 Python 源码附带一个反汇编器 pycdas 用于逐指令查看字节码。项目由 Michael Hansen 和 Darryl Pogue 开发采用 GPL v3 许可持续跟进 Python 新版本目前已识别 Python 3.13 的 .pyc 文件头并内置 3.13 的操作码映射。需要说明的是反编译意味着重建源码遇到无法还原的构造时会打印字节码回退——它不是保证 100% 还原的工具下文会讲清它的边界。场景手里只有 .pyc源码去哪了两种常见情况一是接手第三方分发包只有__pycache__里的 .pyc 没有 .py二是用marshal.dumps(compile(...))导出的裸代码对象连文件头都没有。Python 从 2.7 到 3.13字节码格式几乎每版都在变3.11 起引入宽操作码3.13 又新增了一批以_A结尾的指令如BEFORE_ASYNC_WITH、GET_AITER。大多数反编译器只盯一两个版本拿到新版本 .pyc 就直接拒绝。pycdc 的思路相反——为每个版本维护独立的解析规则表所以它能处理 1.0 到 3.13 跨度很大的文件。工作原理从文件头到源码的三步第 1 步读文件头识别版本pyc_module.cpp 中的PycModule::loadFromFile先读取 .pyc 开头的 4 字节 magic number即版本号在一张 switch 表里查到对应的 Python 版本查不到就报Bad MAGIC!。随后按版本差异解析头部3.7 的 flags 字段、3.3 的 source size 字段3.7 的 hash-based pyc 也会正确处理。第 2 步按版本查操作码映射表每个版本对应一个源文件bytes/ 目录下的python_X_Y.cpp用BEGIN_MAP宏定义操作码编号到指令名的完整映射如 bytes/python_3_13.cpp 包含BINARY_OP_A、BUILD_CONST_KEY_MAP_A等 3.13 新增指令。bytecode.cpp 根据第 1 步识别的版本调度到对应的解析逻辑。第 3 步构建 AST 并生成源码ASTree.cpp 把指令流还原成语法树AST抽象语法树再格式化输出函数、类、控制流尽量还原成 Python 语句遇到不认识的构造打印该处的字节码并继续。源码无法保留的信息——注释、字符串形式、未使用的全局名——也会丢失这是所有反编译器的共性不是 pycdc 独有的问题。五分钟编译并反编译第一个 pyc编译需要 CMake 和 C11 编译器GCC/Clang 或 MSVCgit clone https://gitcode.com/GitHub_Trending/py/pycdc cd pycdc cmake -DCMAKE_BUILD_TYPERelease . make -j4编译产物是两个可执行文件pycdc反编译和pycdas反汇编。第一条命令./pycdas demo.pyc输出是带行号的指令列表2 0 RESUME 0 2 2 LOAD_CONST 0再换成./pycdc demo.pyc得到源码输出带来源头# Source Generated with Decompyle # File: demo.pyc (Python 3.12)两个常见坑版本不匹配magic 无法识别时输出Bad MAGIC!说明文件不是 .pyc 或超出支持范围。报错在 stderrpycdc的源码走 stdout、错误走 stderr管道重定向时注意分流。进阶用法反汇编、批量处理与裸代码对象先反汇编定位问题。反编译失败或输出可疑时先用pycdas看指令流比盲猜原因快得多。批量转换一个包的全部 pycfind . -name *.pyc -exec ./pycdc {} -o {}.py \;还原 marshal 导出的代码对象。裸 marshal 数据不带版本信息必须显式指定./pycdc -c -v 3.12 code.bin注意 pyc_module.cpp 中isSupportedVersion目前接受 1.0–2.7 与 3.0–3.123.13 的 .pyc 文件头可以识别但 marshal 路径尚未开放 3.13。跑官方测试集。需要 Python 3.6 解释器make check JOBS4tests/ 目录按场景组织了大量用例控制流、异常、类、f-string 等tests/run_tests.py 是回归脚本。与 uncompyle6、decompyle3 的差异工具Python 版本覆盖输出形式公开基准pycdc1.0–3.13以文件头识别为准源码 字节码回退内置回归测试uncompyle62.7–3.8社区报告源码无公开基准decompyle33.0–3.8社区报告源码无公开基准三者都没有公开、同口径的准确率或速度对比上表只陈述版本覆盖这一可核实维度。实际差异主要在pycdc 支持的最新版本明显领先另外两个对旧 3.x 生态验证更久。如果你需要反编译 3.8 以后的文件pycdc 是少数可用选项之一。适用场景与局限适合需要分析 3.8 之后尤其 3.11–3.13的 .pyc没有其他工具可用只需要指令级视角时直接用 pycdas稳定且不依赖 AST 还原C 工具链环境无 Python 解释器也能运行不适合要求 100% 还原源码的场景——复杂控制流、动态结构可能回退为字节码需要保留注释、字符串字面量形式、变量原始命名编译后已丢失处理 3.13 的 marshal 裸代码对象见上文限制pycdc 的方向很明确持续跟进每个新 Python 版本的字节码格式。如果想深入从 tests/ 里的输入用例和make check开始能最快看清它对各版本实际做到了哪一步。【免费下载链接】pycdcC python bytecode disassembler and decompiler项目地址: https://gitcode.com/GitHub_Trending/py/pycdc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考