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

This version

3.6.5

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

Uploaded Source

Built Distributions

uncompyle6-3.6.5-py3.8.egg (607.5 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3.7.egg (606.0 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3.5.egg (618.1 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3.4.egg (621.4 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3.3.egg (627.7 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3.2.egg (620.4 kB view details)

Uploaded Source

uncompyle6-3.6.5-py3-none-any.whl (310.8 kB view details)

Uploaded Python 3

uncompyle6-3.6.5-py2.7.egg (609.7 kB view details)

Uploaded Source

uncompyle6-3.6.5-py2.6.egg (610.9 kB view details)

Uploaded Source

uncompyle6-3.6.5-py2.5.egg (606.8 kB view details)

Uploaded Source

uncompyle6-3.6.5-py2.4.egg (611.1 kB view details)

Uploaded Source

uncompyle6-3.6.5-py2-none-any.whl (310.8 kB view details)

Uploaded Python 2

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5.tar.gz
Algorithm Hash digest
SHA256 ddbb2f9919464215fba4a7cc5522d1417e1e252d4940a11a6b3a888790d102ea
MD5 7050bbc8d3bf551accf4866175cc5030
BLAKE2b-256 8cd44da3a20760a399062f7ee4b40350b0bc8769f3a419eae7342213859c34bb

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.8.egg
  • Upload date:
  • Size: 607.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.8.egg
Algorithm Hash digest
SHA256 897cabbbff294592a79abc2fddf1625fb2327c59910ce0929200fbeb6479de7d
MD5 0be3cdda46ce61eac37bb2a044fdbe05
BLAKE2b-256 3af1fdc59180224506dff55c3511864e4a58f432bb7f96b26e6bbc144deda960

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.7.egg
  • Upload date:
  • Size: 606.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.7.egg
Algorithm Hash digest
SHA256 ec1c7db92728fac784cfdf98a20498ba700c7574b04c9b49ea7646b804beb098
MD5 34ae748d77cdecc303bd0b7dd43c9852
BLAKE2b-256 38c4606908de2bf9bcf03fa17b385e2d4cd0d2c82edeb75f97fe34e06ee57546

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.5.egg
  • Upload date:
  • Size: 618.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.5.egg
Algorithm Hash digest
SHA256 42829af38b0ff6d82b18e6caa65be1e31855079b7325151ed8bf56b4b28edb6e
MD5 95a8244233029312de22c5a200903655
BLAKE2b-256 4953c8c81cd7c699a1a0f14f95955c016a4cbb463f0fd1ecef63be39505b4727

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.4.egg
  • Upload date:
  • Size: 621.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.4.egg
Algorithm Hash digest
SHA256 2bdb9bc80fa9d32fdfe84565a9d701b03ab74fc84677b8fc3334be576f31d24d
MD5 9bd342fe4840300a75f37f3a61f7866d
BLAKE2b-256 9852bf73d9644c4ab937d3cd35f46ce7a9ad8bea6d1ff37f264ee28b2e0b0149

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.3.egg
  • Upload date:
  • Size: 627.7 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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.3.egg
Algorithm Hash digest
SHA256 912a567728124fa79a8d57977ecf1652479533a365b316ba4a2c50857272f721
MD5 dd5af6e8b8df96f4346f42ca946b794a
BLAKE2b-256 bea3d026dfbe17f5580cab899ec9cceb4ca01e34c4de90fe449b5e0850bfa8cb

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3.2.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3.2.egg
Algorithm Hash digest
SHA256 9b64f04dd7dbe7088f6b6fa621fd14ed28b787c4b72b0de3f22d8267755104db
MD5 e12936a6f753d0ab751aecda60668ca8
BLAKE2b-256 0b07326362cef3dad9502b19b3dffcacfdd5781728467fb5bdb206158e4fd489

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py3-none-any.whl
  • Upload date:
  • Size: 310.8 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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py3-none-any.whl
Algorithm Hash digest
SHA256 4bd5213dbbda30c53ae3eb2fa2da6afb07bb119496e05ce4029e52d5434a9be8
MD5 b1834e74ef0aa92bacb52f609f9e7bc8
BLAKE2b-256 69053c62f8332915e2af44836e976ada77358adcb528eda0f28945ca31700e76

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py2.7.egg
  • Upload date:
  • Size: 609.7 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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py2.7.egg
Algorithm Hash digest
SHA256 5ec08cfdef88e9d101940b546e70277df4f17782f2b3a36b8878d75eec881016
MD5 047d0e59af968383d62d0c69e8c34352
BLAKE2b-256 84ea407d528c60c38bafb143315c1afd38a0102d5f2ce5eaa4b29979ff9e868b

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py2.6.egg
  • Upload date:
  • Size: 610.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py2.6.egg
Algorithm Hash digest
SHA256 3d6c28027bc13d782a747e4f1eff362716b9a41db59e0d37639883a462786e53
MD5 39838dd893ee3ca551cf37d6e2fe6747
BLAKE2b-256 7aef85da3f7edbe8688e3d22b7d8ca389d520e9d4e5f51ac7e4a396cd4fd1d2d

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py2.5.egg
  • Upload date:
  • Size: 606.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py2.5.egg
Algorithm Hash digest
SHA256 347a19015832722cc3974acd9eebb3d0a82b1a3a95d6ea172ada817144f9f7f1
MD5 07cda7c4834174b9d0866ac7da788c9a
BLAKE2b-256 54335ec1970dbc0e64aec09c524acd8fa8306876676de7d35dd94e38feb1ca33

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py2.4.egg
  • Upload date:
  • Size: 611.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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py2.4.egg
Algorithm Hash digest
SHA256 e00ec713f85f48911adfc63da469cb2388e39289cca6581008c62cf753e15ba3
MD5 de95ccd3b4fa9fc4129d2b8b9c9f9dc0
BLAKE2b-256 74c536ebc2a2baa36a887ddc3af9ce9d63d4e12ac22e262ef7e6736e1d1e87bc

See more details on using hashes here.

Provenance

File details

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

File metadata

  • Download URL: uncompyle6-3.6.5-py2-none-any.whl
  • Upload date:
  • Size: 310.8 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.43.0 CPython/3.8.2

File hashes

Hashes for uncompyle6-3.6.5-py2-none-any.whl
Algorithm Hash digest
SHA256 3d95db4bad7957bec7075b3f9ca3338866389fcafb3b22fe449b153143608c19
MD5 57fd74705bdce2503f61101572b291ff
BLAKE2b-256 8c05c9a5ba0808d65b325a40294faeff605a16697e2b5a46783ae86a7d7c5def

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