Skip to main content

Python cross-version byte-code deparser

Project description

buildstatus

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.5, and 2.1 to 3.7 or so, including PyPy bytecode and Dropbox’s Python 2.5 bytecode.

Why this?

There were a number of decompyle, uncompile, uncompyle2, uncompyle3 forks around. All of them came basically from the same code base, and almost all of them no were no longer actively maintained. Only one handled Python 3, and even there, only 3.2 or 3.3 depending on which code is used. This code pulls these together and moves forward. This project has the most complete support for Python 3.3 and above. It also addresses a number of open issues in the previous forks.

What makes this different from other CPython bytecode decompilers?: its ability to deparse just fragments and give source-code information around a given bytecode offset.

I use this to deparse fragments of code inside my trepan debuggers. For that, I need to record text fragments for all bytecode offsets (of interest). This purpose although largely compatible with the original intention is yet a little bit different. See this for more information.

The idea of Python fragment deparsing given an instruction offset can be used in showing stack traces or any program that wants to show a location in more detail than just a line number. It can be also used when source-code information does not exist and there is just bytecode information.

Requirements

This project requires Python 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 has been tested on Python bytecodes from versions 1.5, 2.1-2.7, and 3.0-3.6 and the above-mentioned PyPy versions.

Installation

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

pip install -e .
pip install -r requirements-dev.txt
python setup.py install # may need sudo
# or if you have pyenv:
python setup.py develop

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

Testing

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

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.

Known Bugs/Restrictions

The biggest known and possibly fixable (but hard) problem has to do with handling control flow. All of the Python decompilers I have looked at have the same problem. In some cases we can detect an erroneous decompilation and report that.

Over 98% of the decompilation of Python standard library packages in Python 2.7.12 verifies correctly. Over 99% of Python 2.7 and 3.3-3.5 “weakly” verify. Python 2.6 drops down to 96% weakly verifying. Other versions drop off in quality too.

Verification is the process of decompiling bytecode, compiling with a Python for that bytecode version, and then comparing the bytecode produced by the decompiled/compiled program. Some allowance is made for inessential differences. But other semantically equivalent differences are not caught. For example 1 and 0 is decompiled to the equivalent 0; remnants of the first true evaluation (1) is lost when Python compiles this. When Python next compiles 0 the resulting code is simpler.

Weak Verification on the other hand doesn’t check bytecode for equivalence but does check 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 used in the bytecode.

Later distributions average about 200 files. 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.5, 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.6 changes things drastically by using word codes rather than byte codes. That has been addressed, but then it also changes function call opcodes and its semantics and has more problems with control flow than 3.5 has.

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 the released magic. 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.

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-2.13.3.tar.gz (832.7 kB view details)

Uploaded Source

Built Distributions

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

uncompyle6-2.13.3-py35-none-any.whl (158.3 kB view details)

Uploaded Python 3.5

uncompyle6-2.13.3-py34-none-any.whl (158.3 kB view details)

Uploaded Python 3.4

uncompyle6-2.13.3-py33-none-any.whl (158.3 kB view details)

Uploaded Python 3.3

uncompyle6-2.13.3-py27-none-any.whl (158.3 kB view details)

Uploaded Python 2.7

uncompyle6-2.13.3-py26-none-any.whl (158.3 kB view details)

Uploaded Python 2.6

uncompyle6-2.13.3-py3.6.egg (333.1 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py3.5.egg (339.0 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py3.4.egg (340.5 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py3.3.egg (344.8 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py2.7.egg (334.3 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py2.6.egg (334.9 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py2.5.egg (333.7 kB view details)

Uploaded Egg

uncompyle6-2.13.3-py2.4.egg (337.4 kB view details)

Uploaded Egg

File details

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

File metadata

  • Download URL: uncompyle6-2.13.3.tar.gz
  • Upload date:
  • Size: 832.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for uncompyle6-2.13.3.tar.gz
Algorithm Hash digest
SHA256 2a2cd1a526c91bd35b26ac68b3bfa494270b0041231ac13b31a1a914fcbd0afd
MD5 6a8e28e2f73ff9b2e5267bea01b43446
BLAKE2b-256 e752d636222cca0cf9f0fd57932976362c26dad1f5557ccbe3801ca976a001d7

See more details on using hashes here.

File details

Details for the file uncompyle6-2.13.3-py35-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py35-none-any.whl
Algorithm Hash digest
SHA256 9a1d121bcbff8e4353eb0facea9b5f2f3e3309ebb68e2280fd18f2e471a8bedc
MD5 b43b55258406353d896886dff5850acd
BLAKE2b-256 bc0a556574ae0863f951d5a33078c01943270551fb3f8fffbc9e938d13f109aa

See more details on using hashes here.

File details

Details for the file uncompyle6-2.13.3-py34-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py34-none-any.whl
Algorithm Hash digest
SHA256 d93c8a152b0437c38d115a3348593d454e2c28f94bcbd7b6b4d356c3490f2b7a
MD5 1019dee153def3747548766f61f0967b
BLAKE2b-256 0e81cd26dadfa5b0f5bebdd53630c74626fc1c9c1cc32c870326bf82222d67d8

See more details on using hashes here.

File details

Details for the file uncompyle6-2.13.3-py33-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py33-none-any.whl
Algorithm Hash digest
SHA256 92f233560f33ec9cbe1cff1e0de1de752e1b4a0968ce6770edad06df75fd129b
MD5 2b72147b14fb07d1f60e9c1b1ea96940
BLAKE2b-256 991251f75f7e499e3de39df291d3a86d54fbb8c2b2350e38390149f011f1970b

See more details on using hashes here.

File details

Details for the file uncompyle6-2.13.3-py27-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py27-none-any.whl
Algorithm Hash digest
SHA256 579e1a5c1c50d977a72f2247b91fe8a2683b6950534b9fb466a7a7ff0eb16ca6
MD5 2f63f947987a894aeaec74a6e458ee07
BLAKE2b-256 48f7f00132b57afb2a4da7ea02889dbf8ffbfa7b9c7bb7c68c8d7069ea06f615

See more details on using hashes here.

File details

Details for the file uncompyle6-2.13.3-py26-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py26-none-any.whl
Algorithm Hash digest
SHA256 6d5102165c24facb6f4227ee1ee2671b8eee8f981e4cce8d51e582194286029f
MD5 a417603b63bce0ddc76c56d5a2f74caa
BLAKE2b-256 3befa86ccedf888392eacec491f9a4f2f1b47285315ed54dd4d4212ff442b9f1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py3.6.egg
Algorithm Hash digest
SHA256 23395dc444e7d5e6018688a984ec932bcef0d8b105fb88faad8f866618e34b5b
MD5 04d8dfb7c65f9f1edda67fae3ac947ce
BLAKE2b-256 7890f6d134b76513c082e1ee6fff6c5f149230e6896cb6d822202036254344fe

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py3.5.egg
Algorithm Hash digest
SHA256 3f4aa7ea590475702d6fd0551ee61ab2fa84dcf24d68669486b76956f2a8710c
MD5 35ec88f56e23a605978e41369e5b4e76
BLAKE2b-256 7ae85a1bcc6e58f7a1c58d6e58a6e0fc9f48de9745868c6077022f2e6b9f4e03

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py3.4.egg
Algorithm Hash digest
SHA256 73d0b0327c292f59058ea73fb1ea71646aa88007db07a966eec4a8d2838acb80
MD5 4533195806fb6b7254f233ac864bcff9
BLAKE2b-256 fe69b16c43fab96b4a29c5fb3352f21566e0738230dd76dbe122fa57387e1d07

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py3.3.egg
Algorithm Hash digest
SHA256 cb4237460dc98a6c0e32d1b9059a4f7e4f4108a8c7815aed82d4dd28596f39cf
MD5 13bb5114a0f65a264d144b307c433290
BLAKE2b-256 d2ed654853f9767147a891c766237ec103f8efaa31a0405207cc8c779674c2e1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py2.7.egg
Algorithm Hash digest
SHA256 09264254176fddb152796d9853648a196384a37877f485495eabf78beb1fd670
MD5 2734d608f644f7365be11a1c9145acd7
BLAKE2b-256 6f3aa9ccd7601931293060f3edb5199e3609682d0c8e7b00c910966bc16a1b3b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py2.6.egg
Algorithm Hash digest
SHA256 cbadb533af775be98b0c3d88e1f0fcf7e7f67b9df74e3b30395bd9a34ab950a3
MD5 637e43cfa1e82da56575a6f093adfb28
BLAKE2b-256 1a6e9b1ec269ccd7affa614a43ed34dccf6a98c13c0fd027783453714a6e49be

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py2.5.egg
Algorithm Hash digest
SHA256 641aa5b5726232cc773904150ee699dfb59961b2e7215e4eb2914af62d6edb8d
MD5 79660d91c5c3bc368527345ac681ac76
BLAKE2b-256 64cfa9865a43512ef8ef8ee069c7062997349506e5955ff4e3f4bd0c8a4a633f

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.13.3-py2.4.egg
Algorithm Hash digest
SHA256 a3db4fcc66d55dfb718f9a5fd74dc00aebf6fb3f5d7355aed664bce08f91daf5
MD5 5b6d7fcd269b91c17b5590cf7f4e7d3c
BLAKE2b-256 9e015491638f9e74c2d561ec92b176c9672aa2aab838bdd6aa0c31e80728cae2

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