Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I decompile Python 3.5 .pyc?

I have been searching around and haven't been able to find anything that can help me to decompile Python 3.5. Does anyone know of one?

like image 867
Matthew Zielke Avatar asked Mar 01 '16 23:03

Matthew Zielke


People also ask

Is it possible to decompile Python?

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.


1 Answers

The ones I know about that handle Python 3.5 (and other Python versions) are:

  1. uncompyle6
  2. pycdc

[Disclamer: I develop 1]

uncompyle6 (written in Python) handles opcodes introduced in Python 3.5, while pycdc (written in C++) is still a little lacking here. But these opcodes appear only when new Python 3.5 language features are used. So the likelihood of running into this in pycdc may be small if the underlying program works on earlier versions of Python.

The situation though is a little bit different for Python 3.6 and later. Python 3.6 adds some function-call opcodes and changes the semantics of other opcodes. So in contrast to 3.5, the new opcodes appear even with code that doesn't use any of the new features used in Python 3.5, or 3.6. Python 3.7, yet again, adds method opcodes and changes the semantics of of others; and right now pycdc doesn't support that. 3.8 changes code generation a bit more than others with it's removal of SETUP_LOOP.

uncompyle6 is addressing some of these these, with the prodding of various bug reports. And with the introduction of 3.6, more of the newer 3.5 opcodes and features appear more often.

uncompyle6 is weak for 3.7 in handling control flow and even weaker for 3.8, even though it is probably the current front runner. Therefore, what I have done here is to create a new project altogether just to handle Python control flow. Just this alone is hard because of Python's rich control structures. In addition to exception handling which needs special handling to and edges in a control-flow graph, there are else blocks that can appear as part of for, while, and try structures; also, there are finally blocks.

When that project can handle things reasonably well (and right now it can't), I will put that first into forked code in project https://github.com/rocky/python-decompile3. This is hard stuff; volunteers are welcome here.

Although neither uncompyle6 nor pycdc are seriously keeping up with changes to Python, for now, uncompyle6 does a more thorough job. You can look at the issue trackers for each of the problems to get an up-to-date sense of where things stand.

Recent history with uncompyle6 and decompyle3 is that things are to the point where fixing some problems may break others. Let me explain. uncompyle6 and decompyle3 pattern match on instructions. There may be an particular pattern that fails 50% of the time. Over time I'll refine the pattern to something more complicated that fails less, say 25% of the time, but specific instances worked with the 50% pattern used previously.

More recently we have added additional checks in decompyle3 and uncompyle6 to do additional flow-control checks at grammar reduction time. However this again suggests a better rethinking is needed using control-flow dominator information. This may be done on a fork off of decompyle3.

Given this, my suggestion currently is that when there is a problem with uncompyle6 is to try different versions, use pycdc, or when practical, compare results of different decompilers.

like image 95
rocky Avatar answered Sep 20 '22 23:09

rocky