Frida no Android: Instrumentação Dinâmica, Bypass e Reempacotamento de APKs
26 de maio de 2026
O que é o Frida
Frida é um framework de instrumentação dinâmica que injeta um agente JavaScript em processos em execução. No contexto de pentest Android, ele permite interceptar chamadas de método, modificar retornos e bypassar proteções em tempo real — sem precisar do código-fonte do app.
Ambiente de laboratório
Requisitos:
- Dispositivo Android com root (físico ou emulador como Genymotion/AVD rooteado)
adbinstalado e dispositivo conectado- Python 3 para o servidor Frida
# Instala o Frida CLI e ferramentas
pip install frida-tools
# Verifica a versão
frida --version
Baixar o frida-server para o dispositivo:
# Descobre a arquitetura do dispositivo
adb shell getprop ro.product.cpu.abi
# Exemplo de saída: arm64-v8a
# Baixa o frida-server correspondente em:
# https://github.com/frida/frida/releases
# Ex: frida-server-16.x.x-android-arm64
# Envia para o dispositivo
adb push frida-server /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server
# Inicia o servidor (em segundo plano)
adb shell /data/local/tmp/frida-server &
Hooking básico de método Java
Estrutura base de um script Frida:
Java.perform(() => {
const TargetClass = Java.use('com.exemplo.app.MinhaClasse')
TargetClass.metodoAlvo.implementation = function (param) {
console.log('[*] metodoAlvo chamado com:', param)
const resultado = this.metodoAlvo(param) // chama o original
console.log('[*] retorno original:', resultado)
return resultado // ou retorna valor modificado
}
})
Executando o script:
frida -U -f com.exemplo.app -l meu_script.js --no-pause
| Flag | Significado |
|------|-------------|
| -U | Conecta via USB |
| -f | Spawna o app (cold start) |
| -l | Script a carregar |
| --no-pause | Não pausa na inicialização |
Bypass de SSL Pinning
SSL Pinning é implementado de formas diferentes. Abaixo os bypasses mais comuns:
OkHttp / CertificatePinner
Java.perform(() => {
const CertificatePinner = Java.use('okhttp3.CertificatePinner')
CertificatePinner.check.overload('java.lang.String', 'java.util.List')
.implementation = function (hostname, peerCertificates) {
console.log('[*] SSL Pinning bypassado para:', hostname)
// Não chama o original — remove a validação
}
})
TrustManager customizado
Java.perform(() => {
const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager')
const SSLContext = Java.use('javax.net.ssl.SSLContext')
const TrustManagerImpl = Java.registerClass({
name: 'com.frida.TrustManager',
implements: [X509TrustManager],
methods: {
checkClientTrusted(chain, authType) {},
checkServerTrusted(chain, authType) {},
getAcceptedIssuers() { return [] },
},
})
const ctx = SSLContext.getInstance('TLS')
ctx.init(null, [TrustManagerImpl.$new()], null)
SSLContext.setDefault(ctx)
console.log('[*] TrustManager substituído')
})
Dica: O script universal ssl-pinning-bypass do frida-codeshare cobre a maioria dos casos com uma linha:
frida-codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -U -f com.exemplo.app
Bypass de Root Detection
Java.perform(() => {
// RootBeer
try {
const RootBeer = Java.use('com.scottyab.rootbeer.RootBeer')
RootBeer.isRooted.implementation = function () {
console.log('[*] RootBeer.isRooted bypassado')
return false
}
} catch (_) {}
// Verificação via Runtime.exec
const Runtime = Java.use('java.lang.Runtime')
Runtime.exec.overload('java.lang.String').implementation = function (cmd) {
if (cmd.indexOf('su') !== -1) {
console.log('[*] Bloqueando execução de:', cmd)
return null
}
return this.exec(cmd)
}
})
Desempacotamento e reempacotamento de APK com APKTool
O APKTool decompila o APK em smali (bytecode legível) e recursos — útil para modificar o app antes de reanálise.
Instalação
# Linux
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.x.x.jar
chmod +x apktool
sudo mv apktool apktool_2.x.x.jar /usr/local/bin/
Desempacotar
apktool d app.apk -o app_decompilado/
Estrutura gerada:
app_decompilado/
├── AndroidManifest.xml # Manifesto decodificado
├── res/ # Recursos (layouts, strings)
├── smali/ # Bytecode Dalvik em texto
└── apktool.yml # Metadados do APKTool
Modificar e reempacotar
# Após modificações no smali ou recursos:
apktool b app_decompilado/ -o app_modificado.apk
# Assinar o APK (necessário para instalar)
keytool -genkey -v -keystore minha_chave.keystore -alias alias_name \
-keyalg RSA -keysize 2048 -validity 10000
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \
-keystore minha_chave.keystore app_modificado.apk alias_name
# Instalar no dispositivo
adb install app_modificado.apk
Atenção: Apps com Play Integrity ou SafetyNet detectam APKs não originais. Nesses casos, use o Frida sem modificar o APK.
Detectando anti-Frida em runtime
Alguns apps detectam o Frida verificando o nome do processo ou /proc/self/maps. Para contornar:
// Oculta o nome do processo frida-server
Java.perform(() => {
const ActivityThread = Java.use('android.app.ActivityThread')
ActivityThread.currentProcessName.implementation = function () {
return 'com.exemplo.app' // retorna nome legítimo
}
})
Para detecções baseadas em /proc/maps, considere usar frida-gadget embutido no APK em vez do frida-server separado.