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 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. 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. The bytecode files it can read has been tested on Python bytecodes from versions 2.1-2.7, and 3.2-3.6 and the above-mentioned PyPy versions.

Installation

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

pip install -r requirements.txt
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

Known Bugs/Restrictions

The biggest known and possibly fixable (but hard) problem has to do with handling control flow. In some cases we can detect an erroneous decompilation and report that.

About 90% 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 if x: foo() is equivalent to x and foo() and decompilation may turn one into the other. 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.

Python 3.0 support is weak; Python 3.5 largely works, but still has some bugs in it. 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.

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.

There is lots to do, so please dig in and help.

See Also

Project details


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

Uploaded Source

Built Distributions

uncompyle6-2.9.6-py3.5.egg (319.7 kB view details)

Uploaded Egg

uncompyle6-2.9.6-py3.4.egg (321.2 kB view details)

Uploaded Egg

uncompyle6-2.9.6-py3.3.egg (325.0 kB view details)

Uploaded Egg

uncompyle6-2.9.6-py2.py3-none-any.whl (146.9 kB view details)

Uploaded Python 2 Python 3

uncompyle6-2.9.6-py2.6.egg (315.5 kB view details)

Uploaded Egg

File details

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

File metadata

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

File hashes

Hashes for uncompyle6-2.9.6.tar.gz
Algorithm Hash digest
SHA256 5257fa0c98d116c632aa369ecc641db737ad14783cff98d3d6d166fe63faa42c
MD5 a19686146475583acf0e603a1db1e933
BLAKE2b-256 1c18202b49bf13c7b028bcc6e8f7914a4e1d0ce7e685966d7c12a27083f14c05

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.9.6-py3.5.egg
Algorithm Hash digest
SHA256 ec3447cd9d9a0676c49ccc401d1a21fa06200c0e95f1a97277230c37b1ccc15a
MD5 2681248c35a1f5d3acb8bdb60d0a8628
BLAKE2b-256 130641110cc814040c4d9bbea4fad4dafea3265d3e947c3c3cc4545f2216fd5a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.9.6-py3.4.egg
Algorithm Hash digest
SHA256 0378075f5bc092501ee5eeeb4f812f444132c76a095f86b369c3269e91b075b3
MD5 d69230c86bb94c5ffd564c2db19db503
BLAKE2b-256 c852d1d4593957a04a047ee08be8e50ff99faa78673bf963fce162b16e9b9d34

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.9.6-py3.3.egg
Algorithm Hash digest
SHA256 c97b5e05f6912da14b4ec4b8efba2ada088d85f1f3a6b51ad9afbccde1faec4b
MD5 a55e08ee35315a50210e105acacc495e
BLAKE2b-256 3cdf41df126643aca305c6f5ba9fb7d3c780a0cb6b7bc1ca3ecb5ad1ddea252d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.9.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 2cd03630fd4e1909e3ae7fff98e28f864e4e8687b77030899113cffcdd65c23d
MD5 5c639981591a6215631cca90946f2df4
BLAKE2b-256 7515af5c582223005eaf88385335f2a3f94795c272268490273527c918e8706e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.9.6-py2.6.egg
Algorithm Hash digest
SHA256 fedcbaa6ce2016ed92815989d751c66cd9179ea8ea191a28913d8a72a3a08b9e
MD5 9dc176bd9f083e951aad9d631ffacd25
BLAKE2b-256 5841c672909064b15187c3a4b7f80e51f5248fb68555c2a015948acb2a4fb1f9

See more details on using hashes here.

Supported by

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