
Enlaces de Python para JADX.
Enlaces de Python para JADX a través de JPype. Descompila archivos APK y DEX de Android a código fuente Java desde Python.
from pyjadx import Jadx
with Jadx("app.apk") as jadx:
for cls in jadx.classes:
print(cls.full_name)
print(cls.code)
JADX es el descompilador de Android de código abierto líder: produce código fuente Java/Kotlin limpio a partir del bytecode Dalvik, preservando jerarquías de clases, genéricos, manejo de excepciones y anotaciones. pyjadx trae esto a Python sin la sobrecarga de subprocesos: JADX se ejecuta en proceso a través de JPype.
pip install pyjadx
Requisitos: JDK 11+ (los JARs de JADX se descargan automáticamente en el primer uso).
from pyjadx import Jadx
with Jadx("app.apk") as jadx:
# All top-level classes (inner classes via cls.inner_classes)
for cls in jadx.classes:
print(cls.full_name, len(cls.methods), "methods")
# Search by fully qualified name
main = jadx.search_class("com.example.MainActivity")
if main:
print(main.code)
# Method-level decompilation
for method in main.methods:
print(f"{method.name}: {method.code}")
# Cross-references
for method in main.methods:
print(f"{method.name} called by: {[c.name for c in method.callers]}")
# Package navigation
for pkg in jadx.packages:
print(pkg.name, len(pkg.classes), "classes")
| Formato | Ejemplo |
|---|---|
| APK | Jadx("app.apk") |
| DEX | Jadx("classes.dex") |
| APK multi-DEX | Manejado de forma transparente: todas las clases se fusionan |
Jadx(path, *, threads=None, mode="auto", code_cache=False)Punto de entrada principal. Úsalo como administrador de contexto o llama a load()/close() manualmente.
| Parámetro | Descripción |
|---|---|
path | Ruta al archivo APK o DEX |
threads | Tamaño del grupo de hilos de JADX (None = número de CPU) |
mode | "auto", "restructure", "simple" o "fallback" |
code_cache | False = caché en memoria (predeterminado), True = respaldado por disco |
Propiedades:
| Propiedad | Tipo | Descripción |
|---|---|---|
classes | list[JavaClass] | Clases de nivel superior en todos los archivos DEX |
packages | list[JavaPackage] | Navegación a nivel de paquete |
class_count | int | Número de clases de nivel superior |
java | JObject | Vía de escape al jadx.api.JadxDecompiler subyacente |
Métodos:
| Método | Descripción |
|---|---|
load() | Cargar y resolver clases (llamado por __enter__) |
close() | Liberar recursos (llamado por __exit__) |
decompile_all() | Descompilar todas las clases de manera ansiosa |
search_class(name) | Encontrar clase por nombre completamente calificado |
JavaClass| Propiedad | Tipo | Descripción |
|---|---|---|
name | str | Nombre corto ("MainActivity") |
full_name | str | Completamente calificado ("com.example.MainActivity") |
package | str | Nombre del paquete |
code | str | Código fuente Java descompilado (perezoso, en caché) |
smali | str | Desensamblado Smali (perezoso, en caché) |
methods | list[JavaMethod] | Métodos en esta clase |
fields | list[JavaField] | Campos en esta clase |
inner_classes | list[JavaClass] | Clases internas/anónimas |
declaring_class | JavaClass | None | Clase padre (si es interna) |
top_class | JavaClass | Clase contenedora más externa |
dependencies | list[JavaClass] | Clases de las que depende esta clase |
is_inner | bool | Si esta es una clase interna |
java | JObject | Vía de escape a jadx.api.JavaClass |
JavaMethod| Propiedad | Tipo | Descripción |
|---|---|---|
name | str | Nombre del método |
full_name | str | Completamente calificado con clase |
code | str | Código fuente descompilado (perezoso, en caché) |
callers | list[JavaMethod] | Métodos que llaman a este (perezoso, en caché) |
callees | list[JavaMethod] | Métodos a los que llama este (perezoso, en caché) |
override_related | list[JavaMethod] | Cadena de sobrescritura bidireccional |
declaring_class | JavaClass | Clase a la que pertenece este método |
java | JObject | Vía de escape a jadx.api.JavaMethod |
JavaField| Propiedad | Tipo | Descripción |
|---|---|---|
name | str | Nombre del campo |
full_name | str | Completamente calificado con clase |
type | str | Tipo de campo como cadena |
callers | list[JavaMethod] | Métodos que referencian este campo (perezoso, en caché) |
declaring_class | JavaClass | Clase a la que pertenece este campo |
java | JObject | Vía de escape a jadx.api.JavaField |
JavaPackage| Propiedad | Tipo | Descripción |
|---|---|---|
name | str | Nombre completo del paquete |
classes | list[JavaClass] | Clases en este paquete |
sub_packages | list[JavaPackage] | Subpaquetes |
java | JObject | Vía de escape a jadx.api.JavaPackage |
Cada envoltorio expone su objeto Java JADX subyacente a través de .java. Esto te permite llamar a cualquier API de JADX que aún no hayamos envuelto:
with Jadx("app.apk") as jadx:
cls = jadx.search_class("com.example.Foo")
# Call JADX Java API directly
code_info = cls.java.getCodeInfo()
pyjadx coexiste con otros consumidores de JPype (p. ej., PyGhidra) en el mismo proceso. Si una JVM ya está en ejecución, pyjadx.start() añade los JARs de JADX al classpath existente. Si no, inicia una.
import pyghidra
pyghidra.start() # starts JVM for Ghidra
import pyjadx
pyjadx.start() # adds JADX JARs to existing JVM — no conflict
Instalación personalizada de JADX:
# Via environment variable
# export JADX_HOME=/opt/jadx
# Or at runtime
import pyjadx
pyjadx.start(jadx_home="/opt/jadx")
Caché de JARs: Los JARs de JADX se descargan automáticamente desde Maven Central en el primer uso y se guardan en caché en ~/.pyjadx/jars/<version>/.
MIT