
Torna a engenharia reversa de aplicativos Android mais fácil, automatizando tarefas repetitivas como extrair, decodificar, reconstruir e aplicar patches em um APK.
apk.sh é um script Bash que facilita a engenharia reversa de aplicativos Android, automatizando algumas tarefas repetitivas como extrair, decodificar, reconstruir e aplicar patch em um APK.
O apk.sh usa basicamente o apktool para desmontar, decodificar e reconstruir recursos, e algum Bash para automatizar o processo de injeção do frida gadget. Também suporta app bundles/APKs divididos.
⬅️ Extrair um APK de um dispositivo é tão simples quanto executar ./apk.sh pull <package_name>
🔧 Decodificar um APK é tão simples quanto executar ./apk.sh decode <apk_name>
🔩 Reconstruir um APK é tão simples quanto executar ./apk.sh build <apk_dir>
apk.sh pull extrai um APK de um dispositivo.
Ele suporta app bundles/APKs divididos, o que significa que APKs divididos serão unidos em um único APK (isso é útil para aplicar patch).
Se o pacote for um app bundle/APK dividido, o apk.sh combinará os APKs em um único APK, corrigindo todos os identificadores de recursos públicos.
apk.sh patch aplica patch em um APK para carregar frida-gadget.so na inicialização.
frida-gadget.so é uma biblioteca compartilhada do Frida destinada a ser carregada por programas para serem instrumentados (quando o modo de operação Injetado não é adequado). Simplesmente carregando a biblioteca, você poderá interagir com ela usando ferramentas existentes baseadas em Frida, como frida-trace. Ela também suporta uma abordagem totalmente autônoma, onde pode executar scripts do sistema de arquivos sem qualquer comunicação externa.
Aplicar patch em um APK é tão simples quanto executar ./apk.sh patch <apk_name> --arch arm.
Você também pode especificar uma configuração do gadget Frida em um json: ./apk.sh patch <apk_name> --arch arm --gadget-conf <config.json>
Se você encontrar erros "already interned" do apktool d como em #30, pode passar a flag --only-main-classes, que será passada para o apktool ao decodificar seu APK.
Na interação padrão, o Frida Gadget expõe uma interface compatível com frida-server, ouvindo em localhost:27042 por padrão. Para conseguir instrumentação antecipada, o Frida permite que a função construtora do Gadget bloqueie até que você execute attach() no processo ou chame resume() após passar pelas etapas habituais de spawn() -> attach() -> ...aplicar instrumentação....
Se você não quiser esse comportamento de bloqueio e preferir deixar o programa iniciar diretamente, ou quiser que ele ouça em uma interface ou porta diferente, pode personalizar isso através de um arquivo de configuração json.
A configuração padrão é:
{
"interaction": {
"type": "listen",
"address": "127.0.0.1",
"port": 27042,
"on_port_conflict": "fail",
"on_load": "wait"
}
}
Você pode passar o arquivo de configuração do gadget para o apk.sh com a opção --gadget-conf.
Uma configuração tipicamente sugerida poderia ser:
{
"interaction": {
"type": "script",
"path": "/data/local/tmp/script.js",
"on_change":"reload"
}
}
script.js poderia ser algo como:
var android_log_write = new NativeFunction(
Module.getExportByName(null, '__android_log_write'),
'int',
['int', 'pointer', 'pointer']
);
var tag = Memory.allocUtf8String("[frida-script][ax]");
var work = function() {
setTimeout(function() {
android_log_write(3, tag, Memory.allocUtf8String("ping @ " + Date.now()));
work();
}, 1000);
}
work();
android_log_write(3, tag, Memory.allocUtf8String(">--(O.o)-<"));
adb push script.js /data/local/tmp
./apk.sh patch <apk_name> --arch arm --gadget-conf <config.json>
adb install file.gadget.apk
Adicione o seguinte código para imprimir no logcat a saída console.log de qualquer script do frida codeshare ao usar o tipo de interação Script.
// print to logcat the console.log output
// see: https://github.com/frida/frida/issues/382
var android_log_write = new NativeFunction(
Module.getExportByName(null, '__android_log_write'),
'int',
['int', 'pointer', 'pointer']
);
var tag = Memory.allocUtf8String("[frida-script][ax]");
console.log = function(str) {
android_log_write(3, tag, Memory.allocUtf8String(str));
}
apk.sh [SUBCOMANDO] [ARQUIVO APK|DIR APK|NOME PKG] [FLAGS]
apk.sh pull [NOME PKG] [FLAGS]
apk.sh decode [ARQUIVO APK] [FLAGS]
apk.sh build [DIR APK] [FLAGS]
apk.sh patch [ARQUIVO APK] [FLAGS]
apk.sh rename [ARQUIVO APK] [NOME PKG] [FLAGS]
pull Extrai um apk do dispositivo/emulador.
decode Decodifica um apk.
build Reconstrói um apk.
patch Aplica patch em um apk.
rename Renomeia o pacote do apk.
-a, --arch <arch> Especifica a arquitetura alvo, obrigatório ao aplicar patch.
-g, --gadget-conf <json_file> Especifica um arquivo de configuração do frida-gadget, opcional ao aplicar patch.
-n, --net Adiciona uma configuração de segurança de rede permissiva ao construir, opcional. Pode ser usado também com patch, pull e rename.
-r, --no-res Não decodifica recursos ao decodificar (ex.: apktool -r), opcional. Pode ser usado ao aplicar patch.
-s, --no-src Não desmonta dex ao decodificar (ex.: apktool -s), opcional. Pode ser usado ao aplicar patch.
https://lief-project.github.io/doc/latest/tutorials/09_frida_lief.html
https://koz.io/using-frida-on-android-without-root/
https://github.com/sensepost/objection/
https://github.com/NickstaDB/patch-apk/
https://neo-geo2.gitbook.io/adventures-on-security/frida-scripting-guide/frida-scripting-guide