
Descompilador Python para 3.7-3.8 Simplificado a partir do uncompyle6 para que possamos refatorar e começar a corrigir alguns problemas de longa data
|buildstatus| |Pypi Installs| |Latest Version| |Supported Python Versions|
|packagestatus|
.. contents::
Um decompilador nativo Python multi-versão e decompilador de fragmentos. Uma reformulação do uncompyle6_.
Eu fiz uma apresentação sobre isso no BlackHat Asia 2024 <https://youtu.be/H-7ZNrpsV50?si=nOaixgYHr7RbILVS>_.
decompyle3 traduz bytecode Python de volta para código fonte Python equivalente. Aceita bytecodes a partir da versão 3.7 do Python.
Para descompilação de bytecode Python mais antigo, veja uncompyle6_.
Uncompyle6 é fantástico, mas tem um problema fundamental na forma como lida com fluxo de controle. Nos primeiros dias do Python, quando havia pouca otimização e o código era gerado de uma forma muito orientada a modelos, descobrir estruturas de fluxo de controle podia ser feito simplesmente olhando para padrões de código.
Ao longo dos anos, mais otimização de código, especificamente em torno do tratamento de saltos, tornou mais difícil suportar a detecção de fluxo de controle estritamente a partir de padrões de código. Isso foi notado já no Python 2.4 (2004), mas como é um problema difícil, até agora não foi tratado de forma satisfatória.
A tentativa inicial de corrigir este problema foi adicionar marcadores no fluxo de instruções, inicialmente uma instrução COME_FROM, e então usá-la na detecção de padrões.
Ao longo dos anos, estendi isso para ser mais específico, então foram adicionados e . E adicionei verificações no momento da redução da gramática para tentar garantir que os saltos correspondam aos supostos alvos .
COME_FROM_LOOPCOME_FROM_WITHCOME_FROMNo entanto, tudo isso é complicado, não robusto, reduziu muito a velocidade da descompilação e não é realmente sustentável.
Neste projeto, começamos a reescrever e refatorar a gramática.
No entanto, mesmo isso não é suficiente. O fluxo de controle precisa ser abordado usando dominadores e dominadores reversos, que o projeto python-control-flow_ pode fornecer.
Isso eu estou finalmente fazendo lentamente em outro projeto não público. É muito trabalho. O financiamento na forma de patrocínio, embora muito apreciado, não é proporcional ao esforço, e atualmente tenho um emprego em tempo integral. Portanto, pode levar tempo até que esteja disponível publicamente, se é que estará.
O código aqui pode ser executado nas versões Python 3.7 ou 3.8. Os arquivos de bytecode que pode ler foram testados em bytecodes Python das versões 3.7 e 3.8.
Pode instalar a partir do PyPI usando o nome decompyle3::
pip install decompyle3
Para instalar a partir do código fonte, este projeto usa setup.py, então segue a rotina padrão Python::
$ pip install -e . # configurar para executar a partir da árvore fonte
ou::
$ python setup.py install # pode precisar de sudo
Um Makefile GNU também é fornecido, então :code:make install (possivelmente como root ou sudo) fará os passos acima.
::
make check
Um makefile GNU foi adicionado para suavizar a configuração e execução do comando certo, e executar testes do mais rápido ao mais lento.
Se tiver remake_ instalado, pode ver a lista de todas as tarefas incluindo testes via :code:remake --tasks
Execute
::
$ decompyle3 arquivo-python-compilado-pyc-ou-pyo
Para ajuda de uso:
::
$ decompyle3 -h
Se quiser verificação de sintaxe Python da correção do processo de descompilação, adicione a opção :code:--syntax-verify. No entanto, como a sintaxe do Python muda. Deve usar esta opção se o bytecode for o bytecode correto para o interpretador Python que irá verificar a sintaxe.
Também pode comparar os resultados com outro descompilador Python como unpyc37_. Como eles funcionam de forma diferente, bugs aqui muitas vezes não estão lá, e vice-versa.
Há uma classe interessante desses programas que está prontamente disponível para dar verificação mais forte: aqueles programas que, quando executados, testam a si mesmos. Nosso conjunto de testes inclui estes.
E o Python vem com outro conjunto de programas assim: seu conjunto de testes para a biblioteca padrão. Temos algum código em :code:test/stdlib para facilitar este tipo de verificação também.
Suportamos apenas versões lançadas, não versões candidatas. Note no entanto que a magic de uma versão lançada é geralmente a mesma que a última versão candidata antes do lançamento.
Também não lidamos com PJOrion_ ou código obfusado de outra forma. Para PJOrion, tente: PJOrion Deobfuscator_ para desembaralhar o bytecode e obter bytecode válido antes de usar esta ferramenta; pydecipher_ pode ajudar com isso.
Este programa não pode descompilar arquivos EXE do Microsoft Windows criados por Py2EXE_, embora possamos provavelmente descompilar o código depois de extrair o bytecode corretamente. Pydeinstaller <https://github.com/charles-dyfis-net/pydeinstaller>_ pode ajudar a desempacotar empacotadores Pyinstaller.
O tratamento de listas patologicamente longas de expressões ou instruções é lento. Não lidamos com Cython_ ou MicroPython, que não usam bytecode.
Existem inúmeros bugs na descompilação. E isso é verdade para todos os outros descompiladores CPython que encontrei, mesmo aqueles que afirmavam ser "perfeitos" em alguma versão específica como 2.4.
À medida que o Python progride, a descompilação também se torna mais difícil porque a compilação é mais sofisticada e a linguagem em si é mais sofisticada. Suspeito que haverá menos tentativas ad-hoc como unpyc37_ (que é baseado num descompilador 3.3) simplesmente porque é mais difícil fazê-lo. A boa notícia, pelo menos do meu ponto de vista, é que acho que entendo o que é preciso para abordar os problemas de uma forma mais robusta. Mas agora, até que o projeto seja melhor financiado, não pretendo fazer nenhum esforço sério para suportar as versões Python 3.8 ou 3.9, incluindo bugs que possam surgir. Imagino que em algum momento possa me interessar por isso.
Pode encontrar bugs facilmente executando os testes contra o conjunto de testes padrão que o Python usa para se verificar. A qualquer momento, existem dezenas de problemas conhecidos que estão bastante isolados e que poderiam ser resolvidos se alguém dedicasse tempo para isso. O problema é que não há muitas pessoas que têm trabalhado na correção de bugs.
Pode encontrar um bug que queira reportar. Por favor, faça-o. Mas esteja ciente de que pode não receber a minha atenção por um tempo. Se patrocinar ou apoiar o projeto de alguma forma, priorizarei os seus problemas acima da fila de outras coisas que possa estar a fazer. Em situações raras, posso fazer uma descompilação manual de bytecode por uma taxa. No entanto, isso é caro, geralmente além do que a maioria das pessoas está disposta a gastar.
uncompyle e 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