Skip to main content

Python cross-version byte-code deparser

Project description

buildstatus Supported Python Versions

uncompyle6

A native Python cross-version Decompiler and Fragment Decompiler. Follows in the tradition of 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.6 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.10.1.tar.gz (831.8 kB view details)

Uploaded Source

Built Distributions

uncompyle6-2.10.1.win-amd64.exe (462.3 kB view details)

Uploaded Source

uncompyle6-2.10.1-py3.4.egg (345.4 kB view details)

Uploaded Source

uncompyle6-2.10.1-py3.3.egg (349.6 kB view details)

Uploaded Source

uncompyle6-2.10.1-py2.py3-none-any.whl (159.1 kB view details)

Uploaded Python 2 Python 3

uncompyle6-2.10.1-py2.5.egg (330.3 kB view details)

Uploaded Source

uncompyle6-2.10.1-py2.4.egg (333.9 kB view details)

Uploaded Source

File details

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

File metadata

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

File hashes

Hashes for uncompyle6-2.10.1.tar.gz
Algorithm Hash digest
SHA256 0d44ea6ae48a4639cf492503e12e3dc3b782f0881ca6798cce552875405f945f
MD5 96dc3ef6f3e53f0e9afa77f4e7012048
BLAKE2b-256 4bc68e476d65cc266131a80b89ef7f1ab97b6bb966eefeeccdc395a5a430e67d

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-2.10.1.win-amd64.exe.

File metadata

File hashes

Hashes for uncompyle6-2.10.1.win-amd64.exe
Algorithm Hash digest
SHA256 7267ca5c3f871e75e8093ab8131c225b5c99d404c99e9db36b57bcd3e16988cf
MD5 be46f896b0e510e5e10b966fc85e064d
BLAKE2b-256 87bc296021cf6bbc2310da3202ac3f2310ca735d4276dbdbe4139b4d477da601

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.10.1-py3.4.egg
Algorithm Hash digest
SHA256 d7a3c9ba69d798acb019ac0c6fcb718c4834d0eede1a6e43db5a7af9018176f8
MD5 393d9489dff50b4aca5ba80a004da229
BLAKE2b-256 bf3903af02e26e34a09ad02041b1e87966f909ebb189b684c01d62dd196e5616

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.10.1-py3.3.egg
Algorithm Hash digest
SHA256 ef3d49d405c867091c90f88cd3960faaf4a6872eee05d80732642227929ed843
MD5 831b0317bc2447354cbde1188d69ec53
BLAKE2b-256 5b6aee6ea380a5e4e5cb215992c4a9bcc8845b8e507ae5e2ff12779a4d9fccae

See more details on using hashes here.

Provenance

File details

Details for the file uncompyle6-2.10.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for uncompyle6-2.10.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 1866d9631c2d0265630efb9f3812a8179b01d22dae854237b8fffab403f424de
MD5 a4f4b41c3c2d318dd81917860b605fa7
BLAKE2b-256 4f702ba1ac45e3de4c36724fa91b93d3cb96c50735991c67968c266dd97fd556

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.10.1-py2.5.egg
Algorithm Hash digest
SHA256 d48413ff406f4818f91ccc7031b670fa92a9ccf03ecef0b250a1ce0c72d27d7e
MD5 1172b78aa61e86f72777a0fbe9d88896
BLAKE2b-256 495dc5ec30ee152aab7e45be0dfb36e5abbc273795b0500ccaf2f3d1c94b0677

See more details on using hashes here.

Provenance

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.10.1-py2.4.egg
Algorithm Hash digest
SHA256 2d7be11af08e5afc984aafdce194783b425b31bc3f0df467c4cbd8ac23cd5815
MD5 ee9a83c101572d38c117249950577687
BLAKE2b-256 b35488f2fd7721fde959bbd1f0381e2592f57d6149f6b46c242403243550f670

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