Skip to main content

Python cross-version byte-code decompiler

Project description

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.

Introduction

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 bytecode.

Why this?

Ok, I’ll say it: this software is amazing. It is more than your normal hacky decompiler. Using compiler technology, the program creates a parse tree of the program from the instructions; nodes at the upper levels that look a little like what might come from a Python AST. So we can really classify and understand what’s going on in sections of Python bytecode.

Building on this, another thing that makes this different from other CPython bytecode decompilers is the ability to deparse just fragments of source code and give source-code information around a given bytecode offset.

I use the tree fragments to deparse fragments of code at run time inside my trepan debuggers. For that, bytecode offsets are recorded and associated with fragments of the source code. This purpose, although compatible with the original intention, is yet a little bit different. See this for more information.

Python fragment deparsing given an instruction offset is useful in showing stack traces and can be encorporated into any program that wants to show a location in more detail than just a line number at runtime. This code can be also used when source-code information does not exist and there is just bytecode. Again, my debuggers make use of this.

There were (and still are) a number of decompyle, uncompyle, uncompyle2, uncompyle3 forks around. Almost all of them come basically from the same code base, and (almost?) all of them are no longer actively maintained. One was really good at decompiling Python 1.5-2.3 or so, another really good at Python 2.7, but that only. Another handles Python 3.2 only; another patched that and handled only 3.3. You get the idea. This code pulls all of these forks together and moves forward. There is some serious refactoring and cleanup in this code base over those old forks.

This demonstrably does the best in decompiling Python across all Python versions. And even when there is another project that only provides decompilation for subset of Python versions, we generally do demonstrably better for those as well.

How can we tell? By taking Python bytecode that comes distributed with that version of Python and decompiling these. Among those that successfully decompile, we can then make sure the resulting programs are syntactically correct by running the Python interpreter for that bytecode version. Finally, in cases where the program has a test for itself, we can run the check on the decompiled code.

We are serious about testing, and use automated processes to find bugs. In the issue trackers for other decompilers, you will find a number of bugs we’ve found along the way. Very few to none of them are fixed in the other decompilers.

Requirements

The code here can be run on Python versions 2.6 or later, PyPy 3-2.4, or PyPy-5.0.1. Python versions 2.4-2.7 are supported in the python-2.4 branch. The bytecode files it can read have been tested on Python bytecodes from versions 1.4, 2.1-2.7, and 3.0-3.8 and the above-mentioned PyPy versions.

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

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

For usage help:

$ uncompyle6 -h

Verification

In older versions of Python it was possible to verify bytecode by decompiling bytecode, and then compiling using the Python interpreter for that bytecode version. Having done this the bytecode produced could be compared with the original bytecode. However as Python’s code generation got better, this no longer was feasible.

If you want Python syntax verification of the correctness of the decompilation process, add the --syntax-verify option. However since Python syntax changes, you should use this option if the bytecode is the right bytecode for the Python interpreter that will be checking the syntax.

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

There is an interesting class of these programs that is readily available give stronger verification: those programs that when run test themselves. Our test suite includes these.

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

Known Bugs/Restrictions

The biggest known and possibly fixable (but hard) problem has to do with handling control flow. (Python has probably the most diverse and screwy set of compound statements I’ve ever seen; there are “else” clauses on loops and try blocks that I suspect many programmers don’t know about.)

All of the Python decompilers that I have looked at have problems decompiling Python’s control flow. In some cases we can detect an erroneous decompilation and report that.

Python support is strongest in Python 2 for 2.7 and drops off as you get further away from that. Support is also probably pretty good for python 2.3-2.4 since a lot of the goodness of early the version of the decompiler from that era has been preserved (and Python compilation in that era was minimal)

There is some work to do on the lower end Python versions which is more difficult for us to handle since we don’t have a Python interpreter for versions 1.6, and 2.0.

In the Python 3 series, Python support is is strongest around 3.4 or 3.3 and drops off as you move further away from those versions. Python 3.0 is weird in that it in some ways resembles 2.6 more than it does 3.1 or 2.7. Python 3.6 changes things drastically by using word codes rather than byte codes. As a result, the jump offset field in a jump instruction argument has been reduced. This makes the EXTENDED_ARG instructions are now more prevalent in jump instruction; previously they had been rare. Perhaps to compensate for the additional EXTENDED_ARG instructions, additional jump optimization has been added. So in sum handling control flow by ad hoc means as is currently done is worse.

Between Python 3.5, 3.6 and 3.7 there have been major changes to the MAKE_FUNCTION and CALL_FUNCTION instructions.

Currently not all Python magic numbers are supported. Specifically in some versions of Python, notably Python 3.6, the magic number has changes several times within a version.

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.

There are also customized Python interpreters, notably Dropbox, which use their own magic and encrypt bytcode. With the exception of the Dropbox’s old Python 2.5 interpreter this kind of thing is not handled.

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

Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uncompyle6-3.5.0.tar.gz (2.3 MB view details)

Uploaded Source

Built Distributions

uncompyle6-3.5.0-py31-none-any.whl (237.6 kB view details)

Uploaded Python 3.1

uncompyle6-3.5.0-py3.7.egg (474.1 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.6.egg (476.3 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.5.egg (483.7 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.4.egg (486.2 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.3.egg (491.3 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.2.egg (485.3 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3.1.egg (481.0 kB view details)

Uploaded Source

uncompyle6-3.5.0-py3-none-any.whl (243.3 kB view details)

Uploaded Python 3

uncompyle6-3.5.0-py2.7.egg (477.2 kB view details)

Uploaded Source

uncompyle6-3.5.0-py2.6.egg (477.9 kB view details)

Uploaded Source

uncompyle6-3.5.0-py2-none-any.whl (243.3 kB view details)

Uploaded Python 2

File details

Details for the file uncompyle6-3.5.0.tar.gz.

File metadata

  • Download URL: uncompyle6-3.5.0.tar.gz
  • Upload date:
  • Size: 2.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0.tar.gz
Algorithm Hash digest
SHA256 4e6e86c05de588cbf5a2c35ddd080f23cd1770a1ad15c84dc1b2c78d65113af7
MD5 a6d5c6ec07e0129bb4a8b1cbd987afd0
BLAKE2b-256 94fa23c16669a76b7b35604c4188e78a22d0b68e8bc3cf535a87462012bf99af

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py31-none-any.whl.

File metadata

  • Download URL: uncompyle6-3.5.0-py31-none-any.whl
  • Upload date:
  • Size: 237.6 kB
  • Tags: Python 3.1
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py31-none-any.whl
Algorithm Hash digest
SHA256 1f6eb4864be08bf5af2b97612c12ba834965b978674aee268d60ef2ca471f01c
MD5 7e7f48a9aa8c15660fab8f3133dbf821
BLAKE2b-256 5bfed9bd93d87e33d7c0818f3f0d8e43df2dd8e2696653c5754db2e08b01e5d6

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.7.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.7.egg
  • Upload date:
  • Size: 474.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.7.egg
Algorithm Hash digest
SHA256 53d1094bcc360e57b78ee165ae1ce3753d0f79d2d522b99d602e1c2f5738b473
MD5 36fd9e6288d23c5bccacf16409a0e35b
BLAKE2b-256 fb10c22ba341fa8c62f671f7e650864b0ec99baba3d4ec5776277722baf88c4d

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.6.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.6.egg
  • Upload date:
  • Size: 476.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.6.egg
Algorithm Hash digest
SHA256 d9279c7cbc882208f56b49f6f6661cc0a588e2afae8e07aaec7261234f37492a
MD5 18b7c732045db657646d89a86fb91c8d
BLAKE2b-256 bc6f565c387fcbd74c08b1c4edc33aaae862cb695bb89de423ce74578fd7e4c5

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.5.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.5.egg
  • Upload date:
  • Size: 483.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.5.egg
Algorithm Hash digest
SHA256 ccea95582fcb8591d28bdd618e5de81a503477f5cca065738efc478b0162ecac
MD5 afdc7ca39416a6d7b0ff2faaac9c4e81
BLAKE2b-256 050e92bdeb3d78c9b3054981efd0fb3d0843e312d063b96709eeaf04434130f5

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.4.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.4.egg
  • Upload date:
  • Size: 486.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.4.egg
Algorithm Hash digest
SHA256 11c88cbbfe916c96a23a7ab2fab4d136a1de03234e56ffa825215490bd9db9a2
MD5 e4b34b6d11e9936de9d887d9e21d590c
BLAKE2b-256 7d5dd6af17c724fad67df2c909777f174c7910b27bf9e6936990169273ad751b

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.3.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.3.egg
  • Upload date:
  • Size: 491.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.3.egg
Algorithm Hash digest
SHA256 5d7817222957c8e6d906b07b446e73710e7de0001050ccdf06554a7a3d4dda07
MD5 afe61dbb4da3751b41c3b08d36ae9db0
BLAKE2b-256 22c28be7f16cd4bdacd3e5f8ce77ffff4081feaae5f8982e01199f5665b39655

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.2.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.2.egg
  • Upload date:
  • Size: 485.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.2.egg
Algorithm Hash digest
SHA256 3a57bef96658133601b206db2e2f4d97b2cc07bae73f791b602d2a8684ac3b70
MD5 89579e2b74c8c57b8affd35ca3b7eb62
BLAKE2b-256 f31109d5cd40f5747216d7a5fe00201aea55faabbdaacb2d9220877d0374bf36

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3.1.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py3.1.egg
  • Upload date:
  • Size: 481.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3.1.egg
Algorithm Hash digest
SHA256 db25ffdae545eb28693b857d3dfaf9af225208ebfaf91a61fdd72575c99681f6
MD5 85c99d171e797f11e8f9294ad0520df2
BLAKE2b-256 43e96a412146591ad05ceb60fac87986d1fc807f6069c507bb8f99ab51cc025b

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py3-none-any.whl.

File metadata

  • Download URL: uncompyle6-3.5.0-py3-none-any.whl
  • Upload date:
  • Size: 243.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e6c1af13d140fd1e5976db94db5c58db6a07fb3bc93bccb498b08e1f7c0f6c54
MD5 8d2c6f827711e8d3c7179314280cd32f
BLAKE2b-256 c8bb9a993926ba2222e372378fdc0a4d62fba93c578252e991f7eb1a1b0f3413

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py2.7.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py2.7.egg
  • Upload date:
  • Size: 477.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py2.7.egg
Algorithm Hash digest
SHA256 7b56f597dd500c6390c2725ded91f81530e2d2cc58524ff336019313edda376d
MD5 0e1b918fb5566d5839bb3d1b8663fd68
BLAKE2b-256 c08dad3b060e2c4bfab8076fffa75c47880a421450976958570e9726c90345b3

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py2.6.egg.

File metadata

  • Download URL: uncompyle6-3.5.0-py2.6.egg
  • Upload date:
  • Size: 477.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py2.6.egg
Algorithm Hash digest
SHA256 3b5f7992a6708da424699af4f14c3d1ee7a3af714b9cd0a293c4137eb5b0ff3c
MD5 76cf0762e61b73e0dc529d5990d575fc
BLAKE2b-256 e1f6d8c9d4a4267879218338e5da1269522e2aadc1d367ccfd474c4bfa1b875c

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.5.0-py2-none-any.whl.

File metadata

  • Download URL: uncompyle6-3.5.0-py2-none-any.whl
  • Upload date:
  • Size: 243.3 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/28.8.0 requests-toolbelt/0.9.1 tqdm/4.32.2 CPython/3.5.7

File hashes

Hashes for uncompyle6-3.5.0-py2-none-any.whl
Algorithm Hash digest
SHA256 c994206384db21a7d8ce740e9b5f28fdcfd1f1fa1ba5440c298836eaa4d5e40c
MD5 43bd25f7c9a868e95c39b57eb00131fa
BLAKE2b-256 4b5b58a787892dde2aca2517a532a686c5ddf2083fb731a9793fb37815e713fd

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page