Skip to content

x0ret/python-decompile3

 
 

Repository files navigation

decompyle3

A native Python cross-version decompiler and fragment decompiler. A reworking of uncompyle6.

Introduction

decompyle3 translates Python bytecode back into equivalent Python source code. It accepts bytecodes from Python version 3.7 on.

For decompilation of older Python bytecode see uncompyle6.

Why this?

Uncompyle6 is awesome, but it has has a fundamental problem in the way it handles control flow. In the early days of Python when there was little optimization and code was generated in a very template-oriented way, code generation could be done by simply looking at code patterns.

Over the years more code optimization, specifically around handling jumps has made it harder to support detecting control flow strictly from code patterns. This was noticed as far back as Python 2.4 (2004) but since this is a difficult problem, so far it hasn't been tackled.

The initial attempt to fix to this problem was to add markers in the instruction stream, initially this was a COME_FROM instruction, and then use that in pattern detection.

Over the years, I've extended that to be more specific, so COME_FROM_LOOP and COME_FROM_WITH were added. And I added checks at grammar reduce type to make try to make sure jumps match with supposed COME_FROM targets.

However all of this is complicated, not robust, and not really tenable.

So in this project we'll address control flow directly via the python-control-flow project.

I expect it will be a while before this is as good as uncompyle6 for Python 3.7, but if decompilation is to have a future in Python, this work is necessary.

Requirements

The code here can be run on Python versions 3.7 or later. The bytecode files it can read have been tested on Python bytecodes from versions 3.7 and later.

Installation

This uses setup.py, so it follows the standard Python routine:

pip install -e .  # set up to run from source tree
                  # Or if you want to install instead
python setup.py install # may need sudo

A GNU makefile is also provided so make install (possibly as root or sudo) will do the steps above.

Running Tests

make check

A GNU makefile has been added to smooth over setting running the right command, and running tests from fastest to slowest.

If you have remake installed, you can see the list of all tasks including tests via remake --tasks

Usage

Run

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

For usage help:

$ decompyle3 -h

If you want strong verification of the correctness of the decompilation process, add the --verify option. But there are situations where this will indicate a failure, although the generated program is semantically equivalent. Using option --weak-verify will tell you if there is something definitely wrong. Generally, large swaths of code are decompiled correctly, if not the entire program.

You can also cross compare the results with pycdc . Since they work differently, bugs here often aren't in that, and vice versa.

Also check against uncompyle6.

Verification

The verification checks to see if the resulting decompiled source is a valid Python program by running the Python interpreter. Because the Python language has changed so much, for best results you should use the same Python version in checking as was used in creating the bytecode.

There are however an interesting class of these programs that is readily available give stronger verification: those programs that when run check some computation, or even better themselves.

And already Python has a set of programs like this: the test suite for the standard library that comes with Python. We have some code in test/stdlib to facilitate this kind of checking.

Known Bugs/Restrictions

We support only released versions, not candidate versions. Note however that the magic of a released version is usually the same as the last candidate version prior to release.

We also don't handle PJOrion obfuscated code. For that try: PJOrion Deobfuscator to unscramble the bytecode to get valid bytecode before trying this tool. This program can't decompile Microsoft Windows EXE files created by Py2EXE, although we can probably decompile the code after you extract the bytecode properly. For situations like this, you might want to consider a decompilation service like Crazy Compilers. Handling pathologically long lists of expressions or statements is slow.

There is lots to do, so please dig in and help.

See Also

About

Python decompiler for 3.7+. Stripped down from uncompyle6 so we can refactor and fix up some long-standing problems

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 98.0%
  • Shell 1.1%
  • Other 0.9%