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

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. Many 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, 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. Even more experimental refactoring is going on in decompyle3.

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 and later. 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 later 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 either another version of uncompyle6 since there are are sometimes regressions in decompiling specific bytecode as the overall quality improves.

For Python 3.7 and above, the code in decompyle3 is generally better.

Or try specific another python decompiler like uncompyle2, unpyc37, or pycdc. Since the later two 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, 3.7 there have been major changes to the MAKE_FUNCTION and CALL_FUNCTION instructions. Python

Python 3.8 removes SETUP_LOOP, SETUP_EXCEPT, BREAK_LOOP, and CONTINUE_LOOP, instructions which may make control-flow detection harder, lacking the more sophisticated control-flow analysis that is planned. We’ll see.

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 bytecode. 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.7.2.tar.gz (2.4 MB view details)

Uploaded Source

Built Distributions

uncompyle6-3.7.2-py3.8.egg (611.5 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.7.egg (609.9 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.6.egg (612.8 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.5.egg (622.1 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.4.egg (625.4 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.3.egg (631.8 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3.2.egg (624.5 kB view details)

Uploaded Source

uncompyle6-3.7.2-py3-none-any.whl (313.1 kB view details)

Uploaded Python 3

uncompyle6-3.7.2-py2.7.egg (613.8 kB view details)

Uploaded Source

uncompyle6-3.7.2-py2.6.egg (615.0 kB view details)

Uploaded Source

uncompyle6-3.7.2-py2.5.egg (614.5 kB view details)

Uploaded Source

uncompyle6-3.7.2-py2.4.egg (620.4 kB view details)

Uploaded Source

uncompyle6-3.7.2-py2-none-any.whl (313.1 kB view details)

Uploaded Python 2

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2.tar.gz
Algorithm Hash digest
SHA256 aa8b79d6cf013aad9736ff124d6310244df49d1d00bfeef9920084e93c089f00
MD5 6d1b57208beb5f09ffd01fcc3b20dce8
BLAKE2b-256 f20748e8995fb704ca7d95d4ed941624444fc8ad7e8211ff576068875567f9ee

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.7.2-py3.8.egg.

File metadata

  • Download URL: uncompyle6-3.7.2-py3.8.egg
  • Upload date:
  • Size: 611.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.8.egg
Algorithm Hash digest
SHA256 7003643cc327c42b829b5c9c0957ee4948c66028a0c7df69f0d9b874281e61fc
MD5 50067b5ec9d31c213d5de2fd65240bd7
BLAKE2b-256 04c2f203362301f79d27697ee13f7d4e8b59f52534f00daed5fe57960632d7da

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.7.egg
  • Upload date:
  • Size: 609.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.7.egg
Algorithm Hash digest
SHA256 6390ce670297fca0273e0d715b899df43265934cdc086d71735e9ef7f41af74c
MD5 3ba673a13eb708d70c93a3209f92421f
BLAKE2b-256 737e465d0046a9d884edd6e958ee2223a6e58924c651a90b80866675ef0ae66f

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.6.egg
  • Upload date:
  • Size: 612.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.6.egg
Algorithm Hash digest
SHA256 ca52c12a136c5a353dfb964feac0ed43520570da6228499b1050216b5eca8484
MD5 4d27193c4b4f80b8dd847d373f32aa06
BLAKE2b-256 6d0d514dc6e2a1f3a6041f4cb1ada964d02c8ef06628022899a196d43a50b90b

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.5.egg
  • Upload date:
  • Size: 622.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.5.egg
Algorithm Hash digest
SHA256 fc0126f14dea00f8c4f162ac1b9a4ece8c7924f525d93d33c54d8443d98af2e9
MD5 b41a6c8a9af6bb1c8b3ba906e5740661
BLAKE2b-256 369f5e33890e438e1dbb9a9348695319d6858c394cdd005f3ea5eb71f3c6ab5e

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.4.egg
  • Upload date:
  • Size: 625.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.4.egg
Algorithm Hash digest
SHA256 694659ef0a243ff63a64a4568b25f643af262f9190494d469b496d6116ded7c3
MD5 60996c73ba4f4cc92f7678a7037c8b95
BLAKE2b-256 9000c80b6f756db9b548f937fdda3ff8f85610b796dbaade3ea74b6844f78eec

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.3.egg
  • Upload date:
  • Size: 631.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.3.egg
Algorithm Hash digest
SHA256 3fae2be0cabe4cbf5e1ff872734e35daf51e96133322fcac7d3a919cef63117e
MD5 a95fa6608472ddd5965d2fc123e6ba50
BLAKE2b-256 558fde1119ccdf1fa933f832c49daea761919585afd122347c67744581490a7b

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3.2.egg
  • Upload date:
  • Size: 624.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3.2.egg
Algorithm Hash digest
SHA256 c30b60c0ffab6f6789414be9a6ffac1ccd50427fcccaf6985728173b34f3953f
MD5 a7485a3f7dd3770b5db42fcb99da9553
BLAKE2b-256 3ad17ab25108abe155f1df550dc4f2d001fcde2baaaaf2f4a4ed0db8d3bf6501

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py3-none-any.whl
  • Upload date:
  • Size: 313.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6bb18c17a326a5e065fdd55d3713e2f66d385464e11b321ae0d376726b9643eb
MD5 80f76d9cb85988e4e4358992f12e4de0
BLAKE2b-256 492b644ce92a2544660953be9c28f4ccf2048fe2c782ea42b293175b4579e45f

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py2.7.egg
  • Upload date:
  • Size: 613.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py2.7.egg
Algorithm Hash digest
SHA256 0f1bcfe144faa02f52a3d050b8677aaf7012d2a2f0ce9ba30145c3f3b8d2bf1e
MD5 151ee3e237792d69e36a521ecb104f34
BLAKE2b-256 ed31c791cb18c56ffd4e82a1a63e4a5d7ecbd5acfc0588e3c5f6db94ddc46613

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py2.6.egg
  • Upload date:
  • Size: 615.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py2.6.egg
Algorithm Hash digest
SHA256 48cb05ba0bff0cdf2f0414e5b9a530c7493a91af4b6f24dc7bfedb140b391f9a
MD5 b898223fba2ccf554c5a239ed27b425a
BLAKE2b-256 977bdfd05e47c81b120e619b9aecc1ab5e5e24b61b2a48704bf896f4e5fc5618

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.7.2-py2.5.egg.

File metadata

  • Download URL: uncompyle6-3.7.2-py2.5.egg
  • Upload date:
  • Size: 614.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py2.5.egg
Algorithm Hash digest
SHA256 75f6aa68c003735418d796a91849c614b6d30bbc0c950d6da36e58826cc1a556
MD5 77d19121881332f7dfbca42f75368682
BLAKE2b-256 f6f42df82b2226ba1cb33d824d11afbc5b9deee05c0c308367e8a8b2bc02f312

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-3.7.2-py2.4.egg.

File metadata

  • Download URL: uncompyle6-3.7.2-py2.4.egg
  • Upload date:
  • Size: 620.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py2.4.egg
Algorithm Hash digest
SHA256 aed752c39af2d782abad9a1e0f0ec290cf128849bc7b2440468bf2f05d304a52
MD5 e8498e1518314146e33095dbac8b41f2
BLAKE2b-256 fe017e10bdab36985d9ecc96cf29910516c19b846ab913b90cb7f82d7a65fd15

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.7.2-py2-none-any.whl
  • Upload date:
  • Size: 313.1 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for uncompyle6-3.7.2-py2-none-any.whl
Algorithm Hash digest
SHA256 dd3d8b0fc8055ee217123cccab14b068665ceea6b1160f0dcee1bd9784b0f630
MD5 78e5ae9773a8adf45cae1810ebbaef70
BLAKE2b-256 88a8ebaabea2a47369d23d35d2faefa0fb77de2931bd320d9df248b2ef281e5d

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