Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
python-uncompyle6 — Un descompilador de bytecode de Python multiversión | Kitploit
Herramientas/GitHubGitHub/rocky/python-uncompyle6
Análisis EstáticoIngeniería InversaDepuradoresAnálisis de Binarios
GitHubrocky/python-uncompyle6

python-uncompyle6

Un descompilador de bytecode de Python multiversión

Ver Repositorio
4.3k4623hace 4 mesesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

|buildstatus| |Pypi Installs| |Latest Version| |Supported Python Versions|

|packagestatus|

.. contents::

uncompyle6

Un descompilador nativo de Python para múltiples versiones y descompilador de fragmentos. El sucesor de decompyle, uncompyle y uncompyle2.

Di una charla sobre esto en BlackHat Asia 2024 <https://youtu.be/H-7ZNrpsV50?si=nOaixgYHr7RbILVS>_.

Introducción

uncompyle6 traduce bytecode de Python de vuelta a código fuente Python equivalente. Acepta bytecodes desde la versión 1.0 hasta la 3.8 de Python, abarcando más de 24 años de versiones de Python. Incluimos el bytecode de Python 2.5 de Dropbox y algunos bytecodes de PyPy.

¿Por qué esto?

Vale, lo diré: este software es increíble. Es más que un descompilador cutre normal. Usando tecnología de compiler_, el programa crea un árbol de análisis sintáctico del programa a partir de las instrucciones; nodos en los niveles superiores que se parecen un poco a lo que podría venir de un AST de Python. Así que realmente podemos clasificar y entender lo que está sucediendo en secciones de bytecode de Python.

Sobre esta base, otra cosa que hace que esto sea diferente de otros descompiladores de bytecode de CPython es que puede descompilar solo fragmentos de código fuente y dar información del código fuente alrededor de un desplazamiento de bytecode dado.

Utilizo los fragmentos de árbol para descompilar fragmentos de código en tiempo de ejecución dentro de mis depuradores trepan_. Para ello, se registran desplazamientos de bytecode y se asocian con fragmentos del código fuente. Este propósito, aunque compatible con la intención original, es un poco diferente. Vea this_ para más información.

La descompilación de fragmentos de Python, dado un desplazamiento de instrucción, es útil para mostrar trazas de pila y se puede incorporar en cualquier programa que quiera mostrar una ubicación con más detalle que solo un número de línea en tiempo de ejecución. Este código también se puede usar cuando la información del código fuente no existe y solo hay bytecode. Nuevamente, mis depuradores hacen uso de esto.

Descargar herramienta

Había (y todavía hay) varios forks de decompyle, uncompyle, uncompyle2, uncompyle3. Muchos de ellos provienen básicamente de la misma base de código, y (¿casi?) todos ya no se mantienen activamente. Uno era realmente bueno descompilando Python 1.5-2.3, otro es realmente bueno en Python 2.7, pero solo eso. Otro maneja solo Python 3.2; otro parcheó ese y manejaba solo 3.3. Ya entiende la idea. Este código une todos estos forks y avanza. Hay una seria refactorización y limpieza en esta base de código en comparación con esos forks antiguos. Una refactorización aún más experimental está ocurriendo en decompyle3_.

Esto demuestra ser lo mejor en descompilación de Python en todas las versiones de Python. E incluso cuando hay otro proyecto que solo proporciona descompilación para un subconjunto de versiones de Python, generalmente también lo hacemos demostrablemente mejor para esas.

¿Cómo podemos saberlo? Tomando bytecode de Python que viene distribuido con esa versión de Python y descompilándolo. Entre aquellos que se descompilan exitosamente, podemos asegurarnos de que los programas resultantes sean sintácticamente correctos ejecutando el intérprete de Python para esa versión de bytecode. Finalmente, en los casos donde el programa tiene una prueba para sí mismo, podemos ejecutar la verificación en el código descompilado.

Usamos procesos automatizados para encontrar errores. En los rastreadores de problemas de otros descompiladores, encontrará varios errores que hemos encontrado en el camino. Muy pocos de ellos se corrigen en los otros descompiladores.

Requisitos

El código en el repositorio git se puede ejecutar desde Python 2.4 hasta la última versión de Python, excepto Python 3.0 hasta 3.2. Los voluntarios son bienvenidos para abordar estas deficiencias si hay deseo de hacerlo.

La forma en que lo hace, sin embargo, es segregando versiones consecutivas de Python en ramas git:

master Python 3.11 y superiores (usa instalación poetry y modismos más nuevos de Python) python-3.6-to-3.10 Python 3.6 hasta 3.10 (usa f-strings más nuevos, modismos más modernos y anotaciones de tipo más modernas) python-3.3-to-3.5 Python 3.3 hasta 3.5 (Python 3 genérico) python-3.0-to-3.2 Python 3.0 hasta 3.2 (Python 3 temprano; 3.0 estaba en algunas áreas más cerca de Python 2.6 que de Python 2.7) python-2.4-to-2.7 Python 2.4 hasta 2.7 (Python 2 genérico)

PyPy desde la versión 2.4 en adelante también funciona.

Los archivos de bytecode que puede leer se han probado en bytecodes de Python de las versiones 1.4, 2.1-2.7 y 3.0-3.8 y versiones posteriores de PyPy.

Instalación

Para versiones recientes de Python (Python 3.11+), puede instalar desde PyPI usando el nombre uncompyle6::

root@kitploit:~
pip install uncompyle6

Para versiones de Python anteriores a la 3.11, no instale usando PyPI, sino instale usando un archivo en la sección de Lanzamientos de GitHub. Python antiguo solía usar easy_install <https://python101.pythonlibrary.org/chapter29_pip.html#using-easy-install>_. Pero esto ya no es compatible en PyPi ni en versiones más nuevas de Python. Y viceversa, poetry ni pip (las formas más nuevas) no son compatibles en Pythons antiguos.

Si la versión de Python en la que ejecuta uncompyle6 está entre Python 2.4 y 2.7, use un tarball llamado uncompyle6_24-x.y.z.tar.gz.

Si la versión de Python en la que ejecuta uncompyle6 está entre Python 3.0 y 3.2, use un tarball llamado uncompyle6_30-x.y.z.tar.gz.

Si la versión de Python en la que ejecuta uncompyle6 está entre Python 3.3 y 3.5, use un tarball llamado uncompyle6_33-x.y.z.tar.gz.

Si la versión de Python en la que ejecuta uncompyle6 está entre Python 3.6 y 3.11, use un tarball llamado uncompyle6_36-x.y.z.tar.gz.

Si la versión de Python en la que ejecuta uncompyle6 es 3.11 o posterior, use un tarball llamado uncompyle6-x.y.z.tar.gz.

También puede probar eggs o wheels que tengan la misma designación de versión, por ejemplo, uncompyle6-x.y.z-py39-none-any.whl para una instalación de Python 3.9. Sin embargo, tenga en cuenta que la versión sin la designación significa Python 3.11 o superior.

De manera similar, un tarball sin _xx funciona solo desde Python 3.11 o superior.

Justificación del uso de ramas Git ++++++++++++++++++++++++++++++++++

Actualmente es imposible (si no poco práctico) tener un solo código fuente de Python de esta complejidad y con tantas características que pueda ejecutarse tanto en Python 2.7 como en Python 3.13+. Los lenguajes se han distanciado tanto, y el empaquetado es enormemente diferente. De hecho, la práctica de empaquetado para Python 3.11+ es incompatible con Python 2.7 (y antes, hasta Python 2.4), que favorecía "easy_install".

Instalación desde el código fuente ++++++++++++++++++++++++++++++++++

Para instalar desde el código fuente, asegúrese de tener la rama Git correcta. Consulte la sección Requisitos para los nombres de las ramas Git.

Después de configurar la rama correcta::

root@kitploit:~
$ pip install -e .  # configurar para ejecutar desde el árbol fuente

También se proporciona un Makefile de GNU, por lo que :code:make install (posiblemente como root o sudo) realizará los pasos anteriores.

Ejecución de pruebas

::

make check

Se ha añadido un makefile de GNU para suavizar la configuración y ejecución del comando correcto, y ejecutar las pruebas de la más rápida a la más lenta.

Si tiene instalado remake_, puede ver la lista de todas las tareas, incluidas las pruebas, mediante :code:remake --tasks

Uso

Ejecute

::

$ uncompyle6 archivo-python-compilado-pyc-o-pyo

Para ayuda de uso:

::

$ uncompyle6 -h

Verificación

En versiones anteriores de Python, era posible verificar el bytecode descompilándolo y luego compilándolo usando el intérprete de Python para esa versión de bytecode. Hecho esto, el bytecode producido podría compararse con el bytecode original. Sin embargo, a medida que la generación de código de Python mejoró, esto ya no fue factible.

Si desea verificación de sintaxis de Python de la corrección del proceso de descompilación, agregue la opción :code:--syntax-verify. Sin embargo, dado que la sintaxis de Python cambia. Debería usar esta opción si el bytecode es el bytecode correcto para el intérprete de Python que verificará la sintaxis.

También puede comparar cruzadamente los resultados con otra versión de uncompyle6, ya que a veces hay regresiones en la descompilación de bytecode específico, a medida que mejora la calidad general.

Para Python 3.7 y 3.8, el código en decompyle3_ es generalmente mejor.

O pruebe otro descompilador de Python específico como uncompyle2_, unpyc37_ o pycdc_. Dado que los dos últimos funcionan de manera diferente, los errores aquí a menudo no están en esos, y viceversa.

Hay una clase interesante de estos programas que está disponible fácilmente para dar una verificación más sólida: aquellos programas que, cuando se ejecutan, se prueban a sí mismos. Nuestro conjunto de pruebas incluye estos.

Y Python viene con otro conjunto de programas como este: su conjunto de pruebas para la biblioteca estándar. Tenemos algo de código en :code:test/stdlib para facilitar este tipo de verificación también.

Errores conocidos/Restricciones

El mayor problema conocido y posiblemente solucionable (pero difícil) tiene que ver con el manejo del flujo de control. (Python probablemente tenga el conjunto de declaraciones compuestas más diverso y extraño que haya visto; hay cláusulas "else" en bucles y bloques try que sospecho que muchos programadores desconocen.)

Todos los descompiladores de Python que he visto tienen problemas para descompilar el flujo de control de Python. En algunos casos, podemos detectar una descompilación errónea e informarlo.

El soporte de Python es bastante bueno para Python 2

En el extremo inferior de las versiones de Python, la descompilación parece bastante buena, aunque no tenemos pruebas automatizadas establecidas para las pruebas distribuidas de Python. Tampoco tenemos un intérprete de Python para las versiones 1.6 y 2.0.

En la serie Python 3, el soporte de Python es más fuerte alrededor de 3.4 o 3.3 y disminuye a medida que se aleja de esas versiones. Python 3.0 es extraño porque, en algunos aspectos, se parece más a 2.6 que a 3.1 o 2.7. Python 3.6 cambia las cosas drásticamente al usar códigos de palabra en lugar de códigos de byte. Como resultado, el campo de desplazamiento de salto en un argumento de instrucción de salto se ha reducido. Esto hace que las instrucciones :code:EXTENDED_ARG sean ahora más prevalentes en las instrucciones de salto; antes eran raras. Quizás para compensar las instrucciones adicionales :code:EXTENDED_ARG, se ha añadido una optimización de salto adicional. Así que en resumen, manejar el flujo de control por medios ad hoc, como se hace actualmente, es peor.

Entre Python 3.5, 3.6 y 3.7, ha habido cambios importantes en las instrucciones :code:MAKE_FUNCTION y :code:CALL_FUNCTION.

Python 3.8 elimina las instrucciones :code:SETUP_LOOP, :code:SETUP_EXCEPT, :code:BREAK_LOOP y :code:CONTINUE_LOOP, lo que puede dificultar la detección del flujo de control, al carecer del análisis de flujo de control más sofisticado que se planea. Ya veremos.

Actualmente, no todos los números mágicos de Python son compatibles. Específicamente en algunas versiones de Python, notablemente Python 3.6, el número mágico ha cambiado varias veces dentro de una versión.

Soportamos solo versiones publicadas, no versiones candidatas. Sin embargo, tenga en cuenta que el número mágico de una versión publicada suele ser el mismo que el de la última versión candidata antes del lanzamiento.

También hay intérpretes de Python personalizados, notablemente Dropbox, que usan su propio número mágico y cifran el bytecode. Excepto por el antiguo intérprete de Python 2.5 de Dropbox, este tipo de cosas no se manejan.

Tampoco manejamos código ofuscado de PJOrion_ o similar. Para PJOrion, pruebe: PJOrion Deobfuscator_ para descifrar el bytecode y obtener bytecode válido antes de usar esta herramienta; pydecipher_ podría ayudar con eso.

Este programa no puede descompilar archivos EXE de Microsoft Windows creados por Py2EXE_, aunque probablemente podamos descompilar el código después de extraer el bytecode correctamente. Pydeinstaller <https://github.com/charles-dyfis-net/pydeinstaller>_ puede ayudar a desempaquetar empaquetadores de Pyinstaller.

Manejar listas patológicamente largas de expresiones o declaraciones es lento. No manejamos Cython_ ni MicroPython, que no usan bytecode.

Hay numerosos errores en la descompilación. Y eso es cierto para todos los demás descompiladores de CPython que he encontrado, incluso aquellos que afirmaban ser "perfectos" en alguna versión particular como 2.4.

A medida que Python progresa, la descompilación también se vuelve más difícil porque la compilación es más sofisticada y el lenguaje en sí es más sofisticado. Sospecho que habrá menos intentos ad hoc como unpyc37_ (que se basa en un descompilador 3.3) simplemente porque es más difícil hacerlo. La buena noticia, al menos desde mi punto de vista, es que creo que entiendo lo que se necesita para abordar los problemas de manera más robusta. Pero ahora mismo, hasta que el proyecto esté mejor financiado, no tengo la intención de hacer ningún esfuerzo serio para soportar las versiones 3.8 o 3.9 de Python, incluidos los errores que puedan surgir. Imagino que en algún momento podría interesarme.

Puede encontrar errores fácilmente ejecutando las pruebas contra el conjunto de pruebas estándar que Python usa para verificarse a sí mismo. En cualquier momento dado, hay docenas de problemas conocidos que están bastante bien aislados y que podrían resolverse si alguien dedicara el tiempo para hacerlo. El problema es que no hay tantas personas que hayan estado trabajando en la corrección de errores.

Algunos de los errores en 3.7 y 3.8 son simplemente una cuestión de portar hacia atrás las correcciones en decompyle3. ¿Algún voluntario?

Puede encontrarse con un error que desee informar. Por favor, hágalo después de leer Cómo reportar un error <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>_ y siga las instrucciones al abrir un issue <https://github.com/rocky/python-uncompyle6/issues/new?assignees=&labels=&template=bug-report.md>_.

Sea consciente de que puede que no llame mi atención por un tiempo. Si patrocina o apoya el proyecto de alguna manera, priorizaré sus problemas por encima de la cola de otras cosas que podría estar haciendo. En situaciones raras, puedo hacer una descompilación manual de bytecode por una tarifa. Sin embargo, esto es costoso, generalmente más de lo que la mayoría de las personas está dispuesta a gastar.

Vea también

  • https://rocky.github.io/blackhat-asia-2024-additional/all-notes-print.html : Cómo leer y escribir un descompilador de bytecode de alto nivel: uncompyle6 decompyle3 -- BlackHat 2024 Asia (video <https://www.youtube.com/watch?v=NA77SFncppE>_). Un gran agradecimiento a los Organizadores y Revisores por dejarme hablar. Este tipo de cosas me anima a trabajar en proyectos como este.
  • https://github.com/rocky/python-decompile3 : Código mucho más pequeño y moderno, centrado en 3.7 y 3.8. Los cambios en ese se migrarán de vuelta aquí.
  • https://code.google.com/archive/p/unpyc3/ : soporta solo Python 3.2. Los proyectos anteriores usan una técnica de descompilación diferente a la que se usa aquí. Actualmente sin mantenimiento.
  • https://github.com/figment/unpyc3/ : fork del anterior, pero soporta solo Python 3.3. Incluye algunas correcciones como soporte para anotaciones de funciones. Actualmente sin mantenimiento.
  • https://github.com/wibiti/uncompyle2 : soporta solo Python 2.7, pero lo hace bastante bien. Hay situaciones donde los resultados de :code:uncompyle6 son incorrectos, mientras que los de :code:uncompyle2 no, pero más a menudo uncompyle6 es correcto cuando uncompyle2 no lo es. Debido a que :code:uncompyle6 se adhiere a la precisión sobre el Python idiomático, :code:uncompyle2 puede producir código de aspecto más natural cuando es correcto. Actualmente :code:uncompyle2 se mantiene ligeramente. Consulte su tracker de issues <https://github.com/wibiti/uncompyle2/issues>_ para más detalles.
  • Cómo reportar un error <https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md>_
  • El archivo HISTORY_.
  • https://github.com/rocky/python-xdis : Desensamblador de versiones cruzadas de Python
  • https://github.com/rocky/python-xasm : Ensamblador de versiones cruzadas de Python
  • https://github.com/rocky/python-uncompyle6/wiki : Documentos Wiki que describen el código y aspectos del mismo con más detalle
  • https://github.com/zrax/pycdc : El README de este código en C++ dice que pretende soportar todas las versiones de Python. Puede apuntar su honda a la luna también, pero dudo que la acierte. Este código es mejor para versiones de Python alrededor de 2.7 y 3.3, cuando el código se desarrolló inicialmente. La precisión para versiones actuales de Python 3 y versiones tempranas de Python es deficiente. Sin un esfuerzo importante, es poco probable que pueda soportar el Python 3 actual. Consulte su tracker de issues <https://github.com/zrax/pycdc/issues>_ para más detalles. Actualmente mantenido ligeramente.

.. _Cython: https://en.wikipedia.org/wiki/Cython .. _trepan: https://pypi.python.org/pypi/trepan3k .. _compiler: https://github.com/rocky/python-uncompyle6/wiki/How-does-this-code-work%3F .. _HISTORY: https://github.com/rocky/python-uncompyle6/blob/master/HISTORY.md .. _report_bug: https://github.com/rocky/python-uncompyle6/blob/master/HOW-TO-REPORT-A-BUG.md .. _debuggers: https://pypi.python.org/pypi/trepan3k .. _remake: https://bashdb.sf.net/remake .. _pycdc: https://github.com/zrax/pycdc .. _decompyle3: https://github.com/rocky/python-decompile3 .. _uncompyle2: https://github.com/wibiti/uncompyle2 .. _unpyc37: https://github.com/andrew-tavera/unpyc37 .. _this: https://github.com/rocky/python-uncompyle6/wiki/Deparsing-technology-and-its-use-in-exact-location-reporting .. |buildstatus| image:: https://circleci.com/gh/rocky/python-uncompyle6.svg?style=svg :target: https://app.circleci.com/pipelines/github/rocky/python-uncompyle6 .. |packagestatus| image:: https://repology.org/badge/vertical-allrepos/python:uncompyle6.svg :target: https://repology.org/project/python:uncompyle6/versions .. _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 .. _pydecipher: https://github.com/mitre/pydecipher .. _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/uncompyle6.svg .. |Latest Version| image:: https://badge.fury.io/py/uncompyle6.svg :target: https://badge.fury.io/py/uncompyle6 .. |Pypi Installs| image:: https://pepy.tech/badge/uncompyle6/month