
Décompilateur Python pour 3.7-3.8, allégé à partir d’uncompyle6 afin de permettre une refonte et de commencer à corriger certains problèmes de longue date.
|buildstatus| |Pypi Installs| |Latest Version| |Supported Python Versions|
|packagestatus|
.. contents::
Un décompilateur Python natif multi-version et décompilateur de fragments. Une refonte de uncompyle6_.
J'ai donné une conférence à ce sujet au BlackHat Asia 2024 <https://youtu.be/H-7ZNrpsV50?si=nOaixgYHr7RbILVS>_.
decompyle3 traduit le bytecode Python en code source Python équivalent. Il accepte les bytecodes à partir de la version 3.7 de Python.
Pour la décompilation d'anciens bytecodes Python, voir uncompyle6_.
Uncompyle6 est génial, mais il a un problème fondamental dans la manière dont il gère le flux de contrôle. Aux débuts de Python, lorsqu'il y avait peu d'optimisation et que le code était généré de manière très orientée modèle, on pouvait déterminer les structures de flux de contrôle en regardant simplement les motifs de code.
Au fil des ans, davantage d'optimisations du code, notamment en ce qui concerne la gestion des sauts, ont rendu plus difficile la détection du flux de contrôle uniquement à partir des motifs de code. Cela a été remarqué dès Python 2.4 (2004), mais comme il s'agit d'un problème difficile, il n'a pas encore été résolu de manière satisfaisante.
La première tentative pour résoudre ce problème a été d'ajouter des marqueurs dans le flux d'instructions, initialement une instruction COME_FROM, puis de les utiliser dans la détection de motifs.
Au fil des ans, j'ai étendu cela pour être plus spécifique, donc COME_FROM_LOOP et COME_FROM_WITH ont été ajoutés. Et j'ai ajouté des vérifications au moment de la réduction de la grammaire pour essayer de garantir que les sauts correspondent aux cibles COME_FROM supposées.
Cependant, tout cela est compliqué, peu robuste, a considérablement ralenti le déparsing et n'est pas vraiment viable.
Dans ce projet, nous avons commencé à réécrire et à refactoriser la grammaire.
Cependant, même cela ne suffit pas. Le flux de contrôle doit être traité en utilisant les dominators et les reverse-dominators, que le projet python-control-flow_ peut fournir.
C'est ce que je fais enfin lentement dans un autre projet non public. C'est beaucoup de travail. Le financement sous forme de parrainage, bien que grandement apprécié, n'est pas à la hauteur de l'effort nécessaire, et j'ai actuellement un emploi à temps plein. Il faudra donc peut-être du temps avant qu'il ne soit disponible publiquement, si tant est qu'il le soit.
Le code ici peut être exécuté sur Python versions 3.7 ou 3.8. Les fichiers bytecode qu'il peut lire ont été testés sur des bytecodes Python des versions 3.7 et 3.8.
Vous pouvez l'installer depuis PyPI en utilisant le nom decompyle3::
pip install decompyle3
Pour installer à partir du code source, ce projet utilise setup.py, donc il suit la routine Python standard::
$ pip install -e . # configurer pour exécuter depuis l'arborescence source
ou::
$ python setup.py install # peut nécessiter sudo
Un Makefile GNU est également fourni, donc :code:make install (éventuellement en tant que root ou
sudo) effectuera les étapes ci-dessus.
::
make check
Un Makefile GNU a été ajouté pour faciliter la configuration et l'exécution de la bonne commande, et pour exécuter les tests du plus rapide au plus lent.
Si vous avez remake_ installé, vous pouvez voir la liste de toutes les tâches
y compris les tests via :code:remake --tasks
Exécutez
::
$ decompyle3 fichier-python-compilé-pyc-ou-pyo
Pour obtenir de l'aide sur l'utilisation :
::
$ decompyle3 -h
Si vous voulez une vérification de la syntaxe Python de l'exactitude du processus de décompilation, ajoutez l'option :code:--syntax-verify. Cependant, comme la syntaxe Python change. Vous devriez utiliser cette option si le bytecode est le bon bytecode pour l'interpréteur Python qui vérifiera la syntaxe.
Vous pouvez également comparer les résultats avec un autre décompilateur Python comme unpyc37_ . Comme ils fonctionnent différemment, les bogues ici ne se retrouvent souvent pas dans celui-ci, et vice versa.
Il existe une classe intéressante de ces programmes facilement disponibles pour donner une vérification plus solide : ceux qui, lorsqu'ils sont exécutés, se testent eux-mêmes. Notre suite de tests en inclut.
Et Python est livré avec un autre ensemble de programmes de ce type : sa suite de tests pour la bibliothèque standard. Nous avons du code dans :code:test/stdlib pour faciliter ce genre de vérification également.
Nous ne supportons que les versions publiées, pas les versions candidates. Notez cependant que le magic d'une version publiée est généralement le même que celui de la dernière version candidate avant la publication.
Nous ne gérons pas non plus PJOrion_ ou le code obfusqué. Pour PJOrion, essayez : PJOrion Deobfuscator_ pour désembrouiller le bytecode et obtenir un bytecode valide avant d'essayer cet outil ; pydecipher_ pourrait aider.
Ce programme ne peut pas décompiler les fichiers EXE Microsoft Windows créés par Py2EXE_, même si nous pouvons probablement décompiler le code après avoir extrait correctement le bytecode. Pydeinstaller <https://github.com/charles-dyfis-net/pydeinstaller>_ peut aider à déballer les bundleurs Pyinstaller.
La gestion de listes anormalement longues d'expressions ou d'instructions est lente. Nous ne gérons pas Cython_ ou MicroPython, qui n'utilisent pas de bytecode.
Il existe de nombreux bogues dans la décompilation. Et c'est vrai pour tous les autres décompilateurs CPython que j'ai rencontrés, même ceux qui prétendaient être « parfaits » sur une version particulière comme 2.4.
Au fur et à mesure que Python progresse, la décompilation devient également plus difficile car la compilation est plus sophistiquée et le langage lui-même est plus sophistiqué. Je soupçonne qu'il y aura moins de tentatives ad hoc comme unpyc37_ (qui est basé sur un décompilateur 3.3) simplement parce que c'est plus difficile à faire. La bonne nouvelle, du moins de mon point de vue, est que je pense comprendre ce qui est nécessaire pour résoudre les problèmes de manière plus robuste. Mais pour l'instant, jusqu'à ce que le projet soit mieux financé, je n'ai pas l'intention de faire un effort sérieux pour supporter les versions Python 3.8 ou 3.9, y compris les bogues qui pourraient survenir. J'imagine qu'à un moment donné, je pourrais m'y intéresser.
Vous pouvez facilement trouver des bogues en exécutant les tests par rapport à la suite de tests standard que Python utilise pour se vérifier. À tout moment, il existe des dizaines de problèmes connus qui sont assez bien isolés et qui pourraient être résolus si quelqu'un prenait le temps de le faire. Le problème est qu'il n'y a pas beaucoup de personnes qui ont travaillé sur la correction des bogues.
Vous pourriez rencontrer un bogue que vous souhaitez signaler. Veuillez le faire. Mais sachez qu'il pourrait ne pas attirer mon attention avant un certain temps. Si vous parrainez ou soutenez le projet d'une manière ou d'une autre, je prioriserai vos problèmes par rapport à la file d'attente d'autres choses que je pourrais faire à la place. Dans de rares situations, je peux faire une décompilation manuelle du bytecode contre rémunération. Cependant, c'est cher, généralement au-delà de ce que la plupart des gens sont prêts à dépenser.
uncompyle et decompyle... |buildstatus| image:: https://dl.circleci.com/status-badge/img/gh/rocky/python-decompile3/tree/master.svg?style=svg :target: https://dl.circleci.com/status-badge/redirect/gh/rocky/python-decompile3/tree/master .. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg :target: https://repology.org/project/python:decompyle3/versions .. _Cython: https://en.wikipedia.org/wiki/Cython .. _MicroPython: https://micropython.org .. _uncompyle6: https://pypi.python.org/pypi/uncompyle6 .. _python-control-flow: https://github.com/rocky/python-control-flow .. _trepan: https://pypi.python.org/pypi/trepan3k .. _compiler: https://pypi.python.org/pypi/spark_parser .. _HISTORY: https://github.com/rocky/python-decompile3/blob/master/HISTORY.md .. _debuggers: https://pypi.python.org/pypi/trepan3k .. _remake: https://bashdb.sf.net/remake .. _unpyc37: https://github.com/andrew-tavera/unpyc37/ .. _this: https://github.com/rocky/python-decompile3/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting .. |TravisCI| image:: https://travis-ci.org/rocky/python-decompile3.svg :target: https://travis-ci.org/rocky/python-decompile3 .. |CircleCI| image:: https://circleci.com/gh/rocky/python-decompile3.svg?style=svg :target: https://circleci.com/gh/rocky/python-decompile3
.. _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 .. _Py2EXE: https://en.wikipedia.org/wiki/Py2exe .. |Supported Python Versions| image:: https://img.shields.io/pypi/pyversions/decompyle3.svg .. |Latest Version| image:: https://badge.fury.io/py/decompyle3.svg :target: https://badge.fury.io/py/decompyle3 .. |PyPI Installs| image:: https://pepy.tech/badge/decompyle3/month .. _pydecipher: https://github.com/mitre/pydecipher