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 use an 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 pretty good for Python 2

On the lower end of Python versions, decompilation seems pretty good although we don’t have any automated testing in place for Python’s distributed tests. Also, 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 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 or otherwise obfuscated code. For PJOrion 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. Handling pathologically long lists of expressions or statements is slow. We don’t handle Cython or MicroPython which don’t use bytecode.

There are numerous bugs in decompilation. And that’s true for every other CPython decompiler I have encountered, even the ones that claimed to be “perfect” on some particular version like 2.4.

As Python progresses decompilation also gets harder because the compilation is more sophisticated and the language itself is more sophisticated. I suspect that attempts there will be fewer ad-hoc attempts like unpyc37 (which is based on a 3.3 decompiler) simply because it is harder to do so. The good news, at least from my standpoint, is that I think I understand what’s needed to address the problems in a more robust way. But right now until such time as project is better funded, I do not intend to make any serious effort to support Python versions 3.8 or 3.9, including bugs that might come in. I imagine at some point I may be interested in it.

You can easily find bugs by running the tests against the standard test suite that Python uses to check itself. At any given time, there are dozens of known problems that are pretty well isolated and that could be solved if one were to put in the time to do so. The problem is that there aren’t that many people who have been working on bug fixing.

Some of the bugs in 3.7 and 3.8 are simply a matter of back-porting the fixes in decmopyle3.

You may run across a bug, that you want to report. Please do so. But be aware that it might not get my attention for a while. If you sponsor or support the project in some way, I’ll prioritize your issues above the queue of other things I might be doing instead.

See Also

Release history Release notifications | RSS feed

This version

3.7.4

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

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

uncompyle6-3.7.4-py3.8.egg (616.4 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.7.egg (614.8 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.6.egg (617.7 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.5.egg (627.0 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.4.egg (630.4 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.3.egg (636.7 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3.2.egg (629.5 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py3-none-any.whl (316.1 kB view details)

Uploaded Python 3

uncompyle6-3.7.4-py2.7.egg (618.6 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py2.6.egg (619.8 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py2.5.egg (619.3 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py2.4.egg (625.2 kB view details)

Uploaded Egg

uncompyle6-3.7.4-py2-none-any.whl (316.1 kB view details)

Uploaded Python 2

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4.tar.gz
  • Upload date:
  • Size: 2.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4.tar.gz
Algorithm Hash digest
SHA256 af8330861bf940e7a3ae0f06d129b8e645191a36bf73ca15ff51997a837d41f8
MD5 91863d299a7739b422e934d3f65cb9d4
BLAKE2b-256 5e3d4990c5113b425b71eb54cc89ab3933dce2576af854b2363b0f74aa7fdcd9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.8.egg
  • Upload date:
  • Size: 616.4 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.8.egg
Algorithm Hash digest
SHA256 313ff7aed35c7dadb51aa265a54101911046d32000bef1f3ed4c9b0c19f5d88b
MD5 230997e93055c8bf2788499e45451024
BLAKE2b-256 ef9107f46d34bf8d3bf385785b98b13ebddaa414638f553d9b33c8aa320f45cd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.7.egg
  • Upload date:
  • Size: 614.8 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.7.egg
Algorithm Hash digest
SHA256 ec3b3cfd6c248b210faa0f09a83a6c5a1d7f77394a009675b4ea7cf8ab434f52
MD5 caf33bebccbb91681477b030f0a8ade0
BLAKE2b-256 428c04ec82e4d94411c0fc9ab02bee72a6a01bf8eec61ece12e036ed62611e96

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.6.egg
  • Upload date:
  • Size: 617.7 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.6.egg
Algorithm Hash digest
SHA256 2f9af225ae2df9cfba005197086a1e9ce08ade021232b491dcad7c235206bede
MD5 f3657bfc94ca86fc099cb4be70b361b0
BLAKE2b-256 ece5f4a2599f6ddb5b51ea7986a3560f4f78f33030d09ee9e36bb58c480cc30f

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.5.egg
  • Upload date:
  • Size: 627.0 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.5.egg
Algorithm Hash digest
SHA256 4274b53653dab9249b773ae1110f89a8cac82a38c8e46c236a42c6e3a9164d53
MD5 9acd1cca25ce34eb8d25643c1720192c
BLAKE2b-256 48bbcd60ab7deb6a1875be48d2d1487022a1211f76845bbf6ab0ed9e9adeb685

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.4.egg
  • Upload date:
  • Size: 630.4 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.4.egg
Algorithm Hash digest
SHA256 b4a6b375bf0d0348ac13876011a07a01ab169ec1a0f0e95b49616a740f6741ae
MD5 0b7bbed7ea7e95fcfddd7e200f2a13e4
BLAKE2b-256 eb7f330c2c9e907b62d279ef564e44a6a960f57fc5ee0f02754394f4dc5d6f59

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.3.egg
  • Upload date:
  • Size: 636.7 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.3.egg
Algorithm Hash digest
SHA256 67e9c259444f86f715b98c243017d3f7b70a1ab84f05a4c6dda713b74621474c
MD5 fdde1623836afc43b7d3c74e9ec3709f
BLAKE2b-256 8bc0b474166eae5b4b358a49814b267daa2eed3f0c5a6cbd2f3f32449e14a51c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3.2.egg
  • Upload date:
  • Size: 629.5 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3.2.egg
Algorithm Hash digest
SHA256 2452e326245998aba5694ae304f74f39605bb327e742483edfa5c147d76a5dbe
MD5 ae9422271e680cb2f81fe7ce0ddb2a4e
BLAKE2b-256 f842cecabf1d02485ae908f2adc59ed6f579a4bf1be06a5ef7e5745f63e58514

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py3-none-any.whl
  • Upload date:
  • Size: 316.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py3-none-any.whl
Algorithm Hash digest
SHA256 1d4159c4962ae990bdf903e53b0f52b3a7b50c44e391834fc7dd2f30dd46f49c
MD5 b3ee32e134da108444d963fb9b71cd4b
BLAKE2b-256 652404e4e3eeb1d39c2a910f552bf0a69185a4d618924be2a98fad8e048e7cdf

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py2.7.egg
  • Upload date:
  • Size: 618.6 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py2.7.egg
Algorithm Hash digest
SHA256 a6544683b1f93f025601c5e0cba6f777e1e0b0f4a4e286a420f34ca977df0845
MD5 cec81f4df583da7857953be0e0f31ae1
BLAKE2b-256 f45c90dbd5469aeded50776078fc5abaeb58ed74b8f1bc1b7b59938c8244790d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py2.6.egg
  • Upload date:
  • Size: 619.8 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py2.6.egg
Algorithm Hash digest
SHA256 36e90b244129efd75e4c5866827bdf1d8650ee5b227d733197cc5f66db2fa220
MD5 0b14ffdf13ce81e82d718aedb6bce901
BLAKE2b-256 5eb89efa3808b9810505c37ea06cf83dd648b013d5c324ed0744680e4aed57cc

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py2.5.egg
  • Upload date:
  • Size: 619.3 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py2.5.egg
Algorithm Hash digest
SHA256 3dd03b6b8d851b32fcf56d2e6fb33e52e29f52857b711725258703caf67b9808
MD5 e3e2ca1abfe08938e4124b5f5b76d9ad
BLAKE2b-256 92abfadae3252f20bb73e593b33b5dcb4abb4b4746a58badfa27155b41435a67

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py2.4.egg
  • Upload date:
  • Size: 625.2 kB
  • Tags: Egg
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py2.4.egg
Algorithm Hash digest
SHA256 fb9fe09fb9e4b491d9c59d95b7bfa40c096f78f17f07c62d1303f449a5dfd0d6
MD5 4a73e571410e98b65ddb42a289c3f368
BLAKE2b-256 47e4ab8cd3be64e7f99eef84d288373fd6b88213064dc436b4cf42a0dfb7d303

See more details on using hashes here.

File details

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

File metadata

  • Download URL: uncompyle6-3.7.4-py2-none-any.whl
  • Upload date:
  • Size: 316.1 kB
  • Tags: Python 2
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/47.1.0 requests-toolbelt/0.9.1 tqdm/4.48.0 CPython/3.8.5

File hashes

Hashes for uncompyle6-3.7.4-py2-none-any.whl
Algorithm Hash digest
SHA256 61e91c0d3f58bdc4282833ac71b84c75070d3d4b91d0dada93278e7d32266c1a
MD5 f1ad2bbc26faa3e70d0973cb3ae6f958
BLAKE2b-256 7090e64eda9e9e67600c97db9e85beddbf4326b5de12002e0b3ba9c4ea0c83eb

See more details on using hashes here.

Supported by

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