
Bindings Python para JADX.
Bindings Python para JADX via JPype. Descompila arquivos APK e DEX do Android para código fonte Java a partir do Python.
from pyjadx import Jadx
with Jadx("app.apk") as jadx:
for cls in jadx.classes:
print(cls.full_name)
print(cls.code)
O JADX é o principal descompilador Android de código aberto — ele produz código fonte Java/Kotlin limpo a partir do bytecode Dalvik, preservando hierarquias de classes, genéricos, tratamento de exceções e anotações. O pyjadx traz isso para o Python sem a sobrecarga de subprocessos: o JADX é executado no mesmo processo via JPype.
pip install pyjadx
Requisitos: JDK 11+ (os JARs do JADX são baixados automaticamente na primeira utilização).
from pyjadx import Jadx
with Jadx("app.apk") as jadx:
# Todas as classes de nível superior (classes internas via cls.inner_classes)
for cls in jadx.classes:
print(cls.full_name, len(cls.methods), "métodos")
# Pesquisa por nome totalmente qualificado
main = jadx.search_class("com.example.MainActivity")
if main:
print(main.code)
# Descompilação a nível de método
for method in main.methods:
print(f"{method.name}: {method.code}")
# Referências cruzadas
for method in main.methods:
print(f"{method.name} chamado por: {[c.name for c in method.callers]}")
# Navegação por pacotes
for pkg in jadx.packages:
print(pkg.name, len(pkg.classes), "classes")
| Formato | Exemplo |
|---|---|
| APK | Jadx("app.apk") |
| DEX | Jadx("classes.dex") |
| Multi-DEX APK | Manipulado de forma transparente — todas as classes mescladas |
Jadx(path, *, threads=None, mode="auto", code_cache=False)Ponto de entrada principal. Use como gerenciador de contexto ou chame load()/close() manualmente.
| Parâmetro | Descrição |
|---|---|
path | Caminho para o arquivo APK ou DEX |
threads | Tamanho do pool de threads do JADX (None = número de CPUs) |
mode | "auto", "restructure", "simple" ou "fallback" |
code_cache | False = cache em memória (padrão), True = cache em disco |
Propriedades:
| Propriedade | Tipo | Descrição |
|---|---|---|
classes | list[JavaClass] | Classes de nível superior em todos os arquivos DEX |
packages | list[JavaPackage] | Navegação por pacotes |
class_count | int | Número de classes de nível superior |
java | JObject | Escape hatch para o jadx.api.JadxDecompiler subjacente |
Métodos:
| Método | Descrição |
|---|---|
load() | Carrega e resolve classes (chamado por __enter__) |
close() | Libera recursos (chamado por __exit__) |
decompile_all() | Descompila todas as classes imediatamente |
search_class(name) | Encontra classe pelo nome totalmente qualificado |
JavaClass| Propriedade | Tipo | Descrição |
|---|---|---|
name | str | Nome curto ("MainActivity") |
full_name | str | Totalmente qualificado ("com.example.MainActivity") |
package | str | Nome do pacote |
code | str | Código fonte Java descompilado (preguiçoso, cacheado) |
smali | str | Disassembly Smali (preguiçoso, cacheado) |
methods | list[JavaMethod] | Métodos desta classe |
fields | list[JavaField] | Campos desta classe |
inner_classes | list[JavaClass] | Classes internas/anônimas |
declaring_class | JavaClass | None | Classe pai (se for interna) |
top_class | JavaClass | Classe envolvente mais externa |
dependencies | list[JavaClass] | Classes das quais esta depende |
is_inner | bool | Se é uma classe interna |
java | JObject | Escape hatch para jadx.api.JavaClass |
JavaMethod| Propriedade | Tipo | Descrição |
|---|---|---|
name | str | Nome do método |
full_name | str | Totalmente qualificado com classe |
code | str | Código fonte descompilado (preguiçoso, cacheado) |
callers | list[JavaMethod] | Métodos que chamam este (preguiçoso, cacheado) |
callees | list[JavaMethod] | Métodos que este chama (preguiçoso, cacheado) |
override_related | list[JavaMethod] | Cadeia bidirecional de sobrescrita |
declaring_class | JavaClass | Classe à qual este método pertence |
java | JObject | Escape hatch para jadx.api.JavaMethod |
JavaField| Propriedade | Tipo | Descrição |
|---|---|---|
name | str | Nome do campo |
full_name | str | Totalmente qualificado com classe |
type | str | Tipo do campo como string |
callers | list[JavaMethod] | Métodos que referenciam este campo (preguiçoso, cacheado) |
declaring_class | JavaClass | Classe à qual este campo pertence |
java | JObject | Escape hatch para jadx.api.JavaField |
JavaPackage| Propriedade | Tipo | Descrição |
|---|---|---|
name | str | Nome completo do pacote |
classes | list[JavaClass] | Classes neste pacote |
sub_packages | list[JavaPackage] | Subpacotes |
java | JObject | Escape hatch para jadx.api.JavaPackage |
Cada wrapper expõe seu objeto Java JADX subjacente através de .java. Isso permite que você chame qualquer API do JADX que ainda não encapsulamos:
with Jadx("app.apk") as jadx:
cls = jadx.search_class("com.example.Foo")
# Chama a API Java do JADX diretamente
code_info = cls.java.getCodeInfo()
O pyjadx coexiste com outros consumidores do JPype (por exemplo, PyGhidra) no mesmo processo. Se uma JVM já estiver em execução, pyjadx.start() adiciona os JARs do JADX ao classpath existente. Caso contrário, inicia uma.
import pyghidra
pyghidra.start() # inicia JVM para Ghidra
import pyjadx
pyjadx.start() # adiciona JARs do JADX à JVM existente — sem conflito
Instalação personalizada do JADX:
# Via variável de ambiente
# export JADX_HOME=/opt/jadx
# Ou em tempo de execução
import pyjadx
pyjadx.start(jadx_home="/opt/jadx")
Cache de JARs: Os JARs do JADX são baixados automaticamente do Maven Central na primeira utilização e armazenados em cache em ~/.pyjadx/jars/<version>/.
MIT