跳转到主要内容

Python跨版本字节码反汇编器

项目描述

buildstatus Pypi Installs Latest Version Supported Python Versions

packagestatus

uncompyle6

A native Python cross-version decompiler and fragment decompiler. The successor to decompyle, uncompyle, and uncompyle2.

简介

uncompyle6 translates Python bytecode back into equivalent Python source code. It accepts bytecodes from Python version 1.0 to version 3.8, spanning over 24 years of Python releases. We include Dropbox’s Python 2.5 bytecode and some PyPy bytecodes.

为什么是它?

好的,我会说的:这个软件很棒。它不仅仅是一个普通的反汇编器。使用编译器技术,程序从指令创建程序的解析树;顶层节点有点像可能来自Python AST的结构。因此,我们可以真正地分类和理解Python字节码中的各个部分所发生的情况。

在此基础上,另一个使它与其他CPython字节码反编译器不同的地方是其能够仅反编译源代码的片段,并给出给定字节码偏移处的源代码信息。

我使用树片段在trepan 调试器中运行时反编译代码片段。为此,记录了字节码偏移并与其关联的源代码片段相关联。尽管这与原始意图兼容,但略有不同。更多信息请参阅这里

给定指令偏移的Python片段反编译在显示堆栈跟踪时很有用,并可以集成到任何希望在运行时显示比行号更详细的位置的程序中。当不存在源代码信息而只有字节码时,此代码也可以使用。同样,我的调试器也利用了这一点。

曾经(现在仍然有)许多decompyle、uncompyle、uncompyle2、uncompyle3的分支。其中许多基本来自同一个代码库,而且(几乎)都不再积极维护。有一个非常擅长反编译Python 1.5-2.3,另一个非常擅长Python 2.7,但仅限于此。另一个只处理Python 3.2;另一个修复了它并只处理3.3。你明白这个意思。此代码将这些分支汇集在一起并向前发展。在这个代码库中,对那些旧分支进行了一些严肃的重构和清理。在decompyle3中正在进行更多的实验性重构。

这在所有Python版本的反编译Python方面表现最好。即使有另一个项目只提供Python子集的反编译,我们通常也能在这些方面表现出色。

我们如何知道呢?通过使用与该版本Python一起分发的Python字节码进行反编译。在成功反编译的这些中,我们可以通过运行该字节码版本的Python解释器来确保结果程序在语法上是正确的。最后,在程序有自我测试的情况下,我们可以对反编译的代码运行检查。

我们使用自动化流程来查找错误。在其他反编译器的问题跟踪器中,你会发现我们在过程中发现的许多错误。其中非常少或没有在其他的反编译器中修复。

需求

git仓库中的代码可以在Python 2.4到最新Python版本上运行,除了Python 3.0到3.2。如果愿意,志愿者可以解决这些缺陷。

不过,它是通过将连续的Python版本隔离到git分支中来实现这一点的

master

Python 3.6及更高版本(使用类型注解)

python-3.3-to-3.5

Python 3.3到3.5(通用Python 3)

python-2.4

Python 2.4到2.7(通用Python 2)

PyPy 3-2.4及更高版本也可以。

它可以读取的字节码文件已经在Python 1.4、2.1-2.7、3.0-3.8及以后PyPy版本的Python字节码上进行了测试。

安装

您可以使用名称uncompyle6从PyPI进行安装

$ pip install uncompyle6

要从源代码安装,此项目使用setup.py,因此它遵循标准的Python流程

$ pip install -e .  # set up to run from source tree

$ python setup.py install # may need sudo

还提供了一个GNU Makefile,因此可以使用make install(可能需要root或sudo权限)来完成上述步骤。

运行测试

$  make check

已添加GNU makefile,以简化设置运行正确命令和从最快到最慢运行测试的过程。

如果您已安装remake,您可以通过remake --tasks查看包括测试在内的所有任务列表

使用

运行

$ uncompyle6 *compiled-python-file-pyc-or-pyo*

获取使用帮助

$ uncompyle6 -h

验证

在Python的旧版本中,可以通过反编译字节码来验证字节码,然后使用对应版本的Python解释器重新编译。完成这些操作后,生成的字节码可以与原始字节码进行比较。然而,随着Python代码生成质量的提高,这种方法不再可行。

如果您想验证反编译过程的正确性,请添加--syntax-verify选项。然而,由于Python语法的变化,您应该在使用此选项时确保字节码是即将检查语法的Python解释器正确的字节码。

您还可以将结果与另一个版本的uncompyle6进行比较,因为在反编译特定字节码时,随着整体质量的提高,有时会出现回归。

对于Python 3.7和3.8,decompyle3中的代码通常更好。

或者尝试其他特定的Python反编译器,如uncompyle2unpyc37pycdc。由于后两种工作方式不同,这里的错误可能不在于它们,反之亦然。

有一类程序可以通过自我运行来提供更强的验证:这些程序运行时会对自己进行测试。我们的测试套件包括这些。

Python还附带了一组类似的程序:它的标准库测试套件。我们在test/stdlib中添加了一些代码来简化这种检查。

已知错误/限制

已知并可能可以修复(但难度很大)的最大问题与控制流处理有关。(Python可能是我见过的最多样化且古怪的一组复合语句;循环和try块中都有“else”子句,我怀疑许多程序员都不了解这些。)

我所查看的所有Python反编译器在反编译Python的控制流时都有问题。在某些情况下,我们可以检测到错误的反编译并报告。

Python 2的支持相当好。

在Python版本较低的情况下,反编译看起来相当不错,尽管我们没有为Python的分布式测试设置自动化测试。此外,我们没有Python 1.6和2.0版本的Python解释器。

在Python 3系列中,Python的支持在3.4或3.3附近最强,离这些版本越远,支持度就越低。Python 3.0在某些方面更像2.6而不是3.1或2.7。Python 3.6通过使用单词码而不是字节码来彻底改变了一切。因此,跳转指令中的跳转偏移字段已减小。这使得EXTENDED_ARG指令在跳转指令中更为普遍;之前它们很少见。可能为了补偿额外的EXTENDED_ARG指令,还增加了额外的跳转优化。因此,总的来说,当前通过自定义方式处理控制流的方法更差。

在Python 3.5、3.6、3.7之间,对MAKE_FUNCTIONCALL_FUNCTION指令进行了重大更改。

Python 3.8移除了SETUP_LOOPSETUP_EXCEPTBREAK_LOOPCONTINUE_LOOP指令,这可能使得控制流检测更加困难,缺乏计划中的更复杂控制流分析。我们将拭目以待。

目前,并非所有Python魔数都受到支持。具体来说,在某些版本的Python中,尤其是Python 3.6,一个版本内的魔数已更改多次。

我们只支持已发布的版本,不支持候选版本。然而,请注意,已发布版本的魔数通常与发布前的最后一个候选版本相同。

还有定制的Python解释器,如Dropbox,它们使用自己的魔数并加密字节码。除了Dropbox的旧Python 2.5解释器外,这类情况不予以处理。

我们也不处理PJOrion或任何其他混淆代码。对于PJOrion,尝试使用Deobfuscator来解密字节码,在尝试此工具之前获取有效字节码;pydecipher可能会有所帮助。

此程序不能反编译由Py2EXE创建的Microsoft Windows EXE文件,尽管我们可能在你正确提取字节码后能够反编译代码。《Pydeinstaller》(Pydeinstaller)可能有助于解压Pyinstaller捆绑器。

处理异常长的表达式或语句列表很慢。我们不处理不使用字节码的Cython或MicroPython。

反编译过程中存在许多错误。这是我所遇到的每个其他CPython反编译器的情况,即使是那些声称在某些特定版本(如2.4)上“完美”的反编译器。

随着Python的发展,反编译也变得更加困难,因为编译更加复杂,语言本身也更加复杂。我怀疑尝试将会有更少的像unpyc37(基于3.3反编译器)这样的特定尝试,因为这更难实现。好消息是,至少从我的角度来看,我认为我理解了如何以更稳健的方式解决这些问题。但到目前为止,直到项目得到更好的资金支持,我无意在Python 3.8或3.9上投入大量努力,包括可能出现的错误。我想在某些时候我可能会对此感兴趣。

您可以通过运行Python用于检查自身的标准测试套件的测试来轻松找到错误。在任何给定时间,都有数十个已知问题相当独立,如果投入时间,这些问题是可以解决的。问题是,从事错误修复工作的人并不多。

3.7和3.8中的某些错误只是将《decompyle3》中的修复回滚过来。有任何志愿者吗?

如果您遇到错误并希望报告,请阅读如何报告错误并遵循创建问题时遵循的说明

请注意,可能需要一段时间才能引起我的注意。如果您以某种方式赞助或支持该项目,我将在其他可能正在做的事情的队列中优先处理您的问题。在罕见的情况下,我可以有偿进行字节码的手动反编译。但是这费用较高,通常超出了大多数人愿意支付的范围。

另请参阅

发布历史 发布通知 | RSS订阅

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

uncompyle6-3.9.2.tar.gz (2.5 MB 查看哈希值)

上传时间

构建分发版

uncompyle6-3.9.2-py3-none-any.whl (358.8 kB 查看哈希值)

上传时间 Python 3

uncompyle6-3.9.2-py2-none-any.whl (364.0 kB 查看哈希值)

上传时间 Python 2

支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页