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 :code:`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 :code:`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
--------

* https://github.com/zrax/pycdc : supports all versions of Python and is written in C++. Support for later Python 3 versions is a bit lacking though.
* https://code.google.com/archive/p/unpyc3/ : supports Python 3.2 only. The above projects use a different decompiling technique than what is used here.
* https://github.com/figment/unpyc3/ : fork of above, but supports Python 3.3 only. Include some fixes like supporting function annotations
* The HISTORY_ file.
* `How to report a bug <https://github.com/rocky/python-uncompyle6/blob/master/HISTORY.md>`_
.. |downloads| image:: https://img.shields.io/pypi/dd/uncompyle6.svg
.. _trepan: https://pypi.python.org/pypi/trepan
.. _HISTORY: https://github.com/rocky/python-uncompyle6/blob/master/HISTORY.md
.. _debuggers: https://pypi.python.org/pypi/trepan3k
.. _remake: https://bashdb.sf.net/remake
.. _pycdc: https://github.com/zrax/pycdc
.. _this: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting
.. |buildstatus| image:: https://travis-ci.org/rocky/python-uncompyle6.svg
:target: https://travis-ci.org/rocky/python-uncompyle6
.. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/uncompyle6.svg
:target: https://pypi.python.org/pypi/uncompyle6/
.. _PJOrion: http://www.koreanrandom.com/forum/topic/15280-pjorion-%D1%80%D0%B5%D0%B4%D0%B0%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F-%D0%BE%D0%B1%D1%84
.. _Deobfuscator: https://github.com/extremecoders-re/PjOrion-Deobfuscator

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.11.1.tar.gz (1.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-2.11.1-py3.5.egg (346.1 kB view details)

Uploaded Egg

uncompyle6-2.11.1-py3.4.egg (347.6 kB view details)

Uploaded Egg

uncompyle6-2.11.1-py3.3.egg (351.9 kB view details)

Uploaded Egg

uncompyle6-2.11.1-py2.py3-none-any.whl (160.3 kB view details)

Uploaded Python 2Python 3

uncompyle6-2.11.1-py2.7.egg (341.4 kB view details)

Uploaded Egg

uncompyle6-2.11.1-py2.5.egg (199.4 kB view details)

Uploaded Egg

uncompyle6-2.11.1-py2.4.egg (192.7 kB view details)

Uploaded Egg

File details

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

File metadata

  • Download URL: uncompyle6-2.11.1.tar.gz
  • Upload date:
  • Size: 1.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for uncompyle6-2.11.1.tar.gz
Algorithm Hash digest
SHA256 d2257b75cda072df48074f4e4108eeb08acd8458115f16c99a370c2aef05d68d
MD5 31211d1bc2f047fa7d6fa8b5ecd308cb
BLAKE2b-256 d81c88bad21553759e5aacda075c79cca2d787e660bf81cb9fbf4cb5c2df576d

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py3.5.egg
Algorithm Hash digest
SHA256 dd257d8dd194a6c9bd71879a08b88aca5eb8e87d5db4afe56ad3b46fb17c3811
MD5 80e5e76f1780de30a56beca03e9f7b8f
BLAKE2b-256 38f82d8f6ab95726571a13b391b6bf879edb5af1d11115dd5b4a2979eec960dd

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py3.4.egg
Algorithm Hash digest
SHA256 ac2486b0fc4e2ae5b7043ae448c34e2bf32de0ff9dcddd7de1fbfe8f52759581
MD5 701f7591d9208d210050ef8223c585aa
BLAKE2b-256 766c9e429e29cc24cf8b5f57fd905c2a55a91fd7b5a0fe9dd54b174012060a14

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py3.3.egg
Algorithm Hash digest
SHA256 54814f5a34a7a72ec5e50f138564b8338cc7d5a3176e39a819c4f05f34c52950
MD5 524d440f1eb17a1714644bcedc8d6690
BLAKE2b-256 91db8f537f372b423677de42145044c506a451dd948aa1163f00726a8cb5db42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 f12d7ba80fb60c63320aed08f7d33739a25c4be22024fb93947967c64df9d609
MD5 befe2f44dba0a1b34a25aa96459986a0
BLAKE2b-256 2d24e415a29ddb386d96aba25ee72470ab20b23dcb56066644c95e86a6ba8d19

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py2.7.egg
Algorithm Hash digest
SHA256 168bdb443153cbb51e2f35dd05971954140379f5baa233ef4964ecb9e76772ab
MD5 1e8a32b28bbd8434dc2bda9ccd16d479
BLAKE2b-256 bea36123bce628dde1877d24c030bf18608e1603fb43880180f6e6eada7e2e42

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py2.5.egg
Algorithm Hash digest
SHA256 ac5f7b13506635de82c5cedf0b7a5df7a3ce25955b8c628aaa57df5bb5d30286
MD5 1fca40a0800d6f0fd4e954493313bfe6
BLAKE2b-256 9cf41b2a3c27a6b1d5f8d5a10a039260322d5208507c2133a96a3afe278d9d53

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for uncompyle6-2.11.1-py2.4.egg
Algorithm Hash digest
SHA256 e294a8ed0804b59725c61c15dcd9d94519696e30117c44f169e78b7ea2f22c9a
MD5 b30430f6efd2e15d37a2b914e0220a5d
BLAKE2b-256 2b9dd01d9c0063f345611e8a4d1923a68995e2f32291adf5a200f9f434933509

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