如何反编译 Python 3.5 的 .pyc 文件?

6

我一直在寻找能够帮助我反编译Python 3.5的工具,但是一直没有找到。有谁知道有这样的工具吗?


1
你好,欢迎来到 Stack Overflow。很抱歉,这个问题在这里被认为是不适合讨论的。根据网站规则:“询问我们推荐或寻找书籍、工具、软件库、教程或其他外部资源的问题都不适合在 Stack Overflow 上讨论,因为它们往往会吸引主观性答案和垃圾信息。相反,请描述问题以及已经采取的解决方案。”很抱歉,在这种情况下,我认为这个问题将被关闭。 - Fabio says Reinstate Monica
1
@FabioTurati,只要理解“反编译”这个词,就可以看到一个非常明显的问题描述。这不是推荐特定工具的问题,而是尽可能以最标准的方式解决问题的问题。 - Pavel Šimerda
@PavelŠimerda 嗯,首先,这些答案只是推荐工具。无论如何,这些都是两年前的内容,而且有几个赞同。我仍然认为我的原始评论是有效的,但我不会采取任何行动。 - Fabio says Reinstate Monica
1
@FabioTurati 推荐工具选择是我认为对“如何实现”问题的有效回答的一部分。被批评的问题类型在我看来是:“我知道怎么做,但请告诉我哪个已知的工具更好。” 因为那将需要带有观点的答案。而这个问题不需要。 - Pavel Šimerda
3个回答

14
我所知道的能够处理Python 3.5(和其他版本Python)的工具有以下两种:
  1. uncompyle6
  2. pycdc
[免责声明:我是其中一种工具的开发者]
使用Python编写的uncompyle6能够处理Python 3.5引入的操作码,而用C++编写的pycdc在这方面仍然有些欠缺。但是这些操作码只会在使用新的Python 3.5语言特性时出现。因此,如果底层程序在早期版本的Python上运行良好,则在pycdc中遇到这些问题的可能性可能很小。
然而,对于Python 3.6及更高版本的情况有些不同。Python 3.6 添加了一些函数调用操作码并更改了其他操作码的语义。因此,与3.5不同,在即使没有使用任何Python 3.5或3.6中的新功能的代码中也会出现新的操作码。 Python 3.7又再次添加了方法操作码并更改了其他操作码的语义;目前,pycdc不支持这些更改。3.8通过删除SETUP_LOOP来进一步更改代码生成方式。 uncompyle6正在解决其中的一些问题,并受到各种错误报告的推动。随着3.6的引入,越来越多的新的3.5操作码和功能更加频繁地出现。uncompyle6在处理控制流方面对3.7的支持较弱,对3.8的支持甚至更弱。因此,我创建了一个全新的项目来处理Python控制流程。由于Python具有丰富的控制结构,仅仅这一点就很难。除了需要特殊处理异常处理和控制流图中的边缘之外,还有可能出现在forwhiletry结构中的else块,以及finally块。

当该项目能够合理地处理这些事情时(目前还无法做到),我将首先将其放入项目https://github.com/rocky/python-decompile3中的派生代码。这很困难;欢迎志愿者加入。

尽管未编译的6和pycdc都没有认真跟上Python的变化,但目前来看,未编译的6做得更全面。您可以查看每个问题的问题跟踪器,了解事情的最新状况。

最近使用uncompyle6和decompyle3的历史表明,修复一些问题可能会破坏其他问题。让我解释一下。 uncompyle6decompyle3模式匹配指令。可能有一个特定的模式,失败率达到50%。随着时间的推移,我会将模式改进为更复杂的模式,失败率更低,例如25%,但以前使用50%模式的特定实例已经可以工作。

最近我们在decompyle3和uncompyle6中添加了额外的检查,以在语法缩减时进行附加的流控制检查。然而,这再次表明需要使用控制流支配者信息进行更好的重新思考。这可以在decompyle3的fork上完成。

考虑到这一点,我的建议是当uncompyle6出现问题时,尝试使用不同的版本、使用pycdc,或者在实际操作中比较不同反编译工具的结果。


uncompyle6 在我的笔记本电脑出现可怕的问题导致我的 .py 文件乱码后拯救了我,但是 .pyc 文件却没有问题。一切似乎都正确反编译了!(一个 assert 语句变成了 if not x raise AssertionError,但除此之外一切正常) - andyhasit
很高兴uncompyle6有所帮助。它确实有assert语句的规则,但另一方面,任何反编译器都必须满足于它生成等效代码,我想这里是这种情况。如果不是这种情况,请在阅读如何报告错误后随时提出问题。当您在github上时,请考虑为该项目投票。尽管现在这是最高评级(除了realgud组中的realgud之外),但我使用评级来帮助我在有选择时决定要开展哪个项目。我注意到现在uncompyle6排名落后于我钦佩的pycdc。 - rocky
我不确定这是否属于错误分类,也许无法从pyc文件中判断assert语句是否被使用。在Github上点赞了。 - andyhasit

4
为了反编译已编译的 .pyc python3 文件,我在我的当前Ubuntu操作系统中使用了 uncompyle6 如下: (i) 安装 uncompyle6: pip3 install uncompyle6 (ii) 从 .pyc 文件创建 .py 文件运行: uncompyle6 -o . your_filename.pyc (iii) 自动创建一个新的 .py 文件,具有相同的现有 .pyc 文件名。 希望这会有所帮助。

1

截至目前为止,最新的uncompyle6已经很好地支持Python 3.8.0 -> 应该也能很好地支持你的Python 3.5。

  • 示例:

    • uncompyle6 ../pyc/utils.cpython-38.pyc > ../pyc/utils.py
  • 输出:

    • origin py和decompiled py之间的对比:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接