MASTG-TOOL-0031: Frida
Frida é um kit de ferramentas gratuito e de código aberto para instrumentação dinâmica de código, escrito por Ole André Vadla Ravnås, que funciona injetando o motor JavaScript QuickJS (anteriormente Duktape e V8) no processo instrumentado. O Frida permite que você execute trechos de JavaScript em aplicativos nativos no Android e iOS (assim como em outras plataformas).

Instalação¶
Para instalar o Frida localmente, basta executar:
pip install frida-tools
Ou consulte a página de instalação para mais detalhes.
Modos de Operação¶
O código pode ser injetado de várias maneiras. Por exemplo, o Xposed modifica permanentemente o carregador de aplicativos Android, fornecendo hooks para executar seu próprio código sempre que um novo processo é iniciado. Em contraste, o Frida implementa a injeção de código escrevendo diretamente na memória do processo. Quando anexado a um aplicativo em execução:
- O Frida usa ptrace para sequestrar uma thread de um processo em execução. Essa thread é usada para alocar um bloco de memória e preenchê-lo com um mini-inicializador.
- O inicializador inicia uma nova thread, conecta-se ao servidor de depuração do Frida que está em execução no dispositivo e carrega uma biblioteca compartilhada que contém o agente Frida (
frida-agent.so). - O agente estabelece um canal de comunicação bidirecional de volta para a ferramenta (por exemplo, o REPL do Frida ou seu script Python personalizado).
- A thread sequestrada é retomada após ser restaurada ao seu estado original, e a execução do processo continua normalmente.

- Arquitetura do Frida, fonte: https://www.frida.re/docs/hacking/
O Frida oferece três modos de operação:
- Injetado: este é o cenário mais comum quando o frida-server está em execução como um daemon no dispositivo iOS ou Android. O frida-core é exposto via TCP, ouvindo em localhost:27042 por padrão. A execução neste modo não é possível em dispositivos que não estão com root ou jailbreak.
- Incorporado: este é o caso quando seu dispositivo não está com root nem jailbreak (você não pode usar ptrace como um usuário não privilegiado), você é responsável pela injeção da biblioteca frida-gadget incorporando-a em seu aplicativo, manualmente ou via ferramentas de terceiros, como objection.
- Pré-carregado: semelhante a
LD_PRELOADouDYLD_INSERT_LIBRARIES. Você pode configurar o frida-gadget para executar de forma autônoma e carregar um script do sistema de arquivos (por exemplo, caminho relativo à localização do binário do Gadget).
APIs¶
Independentemente do modo escolhido, você pode fazer uso das APIs JavaScript do Frida para interagir com o processo em execução e sua memória. Algumas das APIs fundamentais são:
- Interceptor: Ao usar a API Interceptor, o Frida injeta um trampolim (também conhecido como hooking em linha) no prólogo da função, o que provoca um redirecionamento para nosso código personalizado, executa nosso código e retorna para a função original. Observe que, embora muito eficaz para nosso propósito, isso introduz uma sobrecarga considerável (devido aos saltos relacionados ao trampolim e à troca de contexto) e não pode ser considerado transparente, pois sobrescreve o código original e age de forma semelhante a um depurador (colocando breakpoints) e, portanto, pode ser detectado de maneira semelhante, por exemplo, por aplicativos que verificam periodicamente a soma de verificação de seu próprio código.
- Stalker: Se seus requisitos de rastreamento incluem transparência, desempenho e alta granularidade, o Stalker deve ser sua API de escolha. Ao rastrear código com a API Stalker, o Frida aproveita a recompilação dinâmica just-in-time (usando Capstone): quando uma thread está prestes a executar suas próximas instruções, o Stalker aloca alguma memória, copia o código original e intercala a cópia com seu código personalizado para instrumentação. Por fim, executa a cópia (deixando o código original intacto e, portanto, evitando quaisquer verificações anti-depuração). Essa abordagem aumenta consideravelmente o desempenho da instrumentação e permite uma granularidade muito alta no rastreamento (por exemplo, rastreando exclusivamente instruções CALL ou RET). Você pode aprender detalhes mais aprofundados no post do blog "Anatomy of a code tracer" pelo criador do Frida, Ole [#vadla]. Alguns exemplos de uso do Stalker são, por exemplo, who-does-it-call ou diff-calls.
- Java: Ao trabalhar no Android, você pode usar esta API para enumerar classes carregadas, enumerar carregadores de classes, criar e usar instâncias de classes específicas, enumerar instâncias ativas de classes escaneando a heap, etc.
- ObjC: Ao trabalhar no iOS, você pode usar esta API para obter um mapeamento de todas as classes registradas, registrar ou usar instâncias de classes ou protocolos específicos, enumerar instâncias ativas de classes escaneando a heap, etc.
Frida 17¶
O Frida 17 introduz mudanças significativas, como a remoção das bridges de runtime empacotadas (frida-{objc,swift,java}-bridge) dentro do runtime GumJS do Frida. Isso significa que você agora deve instalar explicitamente as bridges necessárias usando frida-pm install:
frida-pm install frida-java-bridge
No entanto, os comandos frida e frida-trace vêm com as bridges Java, Objective-C e Swift pré-empacotadas, então você ainda pode usá-las sem instalação manual nesses contextos. Você pode aprender mais sobre bridges na documentação do Frida.
O Frida fez alterações em suas APIs nativas. Embora essas alterações possam quebrar alguns de seus scripts existentes, elas incentivam você a escrever código mais legível e performático. Por exemplo, agora Process.enumerateModules() retorna um array de objetos Module, permitindo que você trabalhe com eles diretamente.
for (const module of Process.enumerateModules()) {
console.log(module.name);
}
Outra API que foi removida é Module.getSymbolByName, que é usada em muitos scripts. Dependendo de você saber em qual módulo o símbolo está localizado ou não, você pode usar uma das duas alternativas a seguir:
// Se você conhece o módulo
Process.getModuleByName('libc.so').getExportByName('open')
// Se você não conhece (ou seja, o antigo Module.getSymbolByName(null, 'open'); )
Module.getGlobalExportByName('open');
Para mais detalhes, consulte as Notas de Lançamento do Frida 17.0.0.
Ferramentas¶
O Frida também fornece algumas ferramentas simples construídas sobre a API do Frida e disponíveis diretamente do seu terminal após instalar o frida-tools via pip. Por exemplo:
- Você pode usar o CLI do Frida (
frida) para prototipagem rápida de scripts e cenários de tentativa/erro. frida-pspara obter uma lista de todos os aplicativos (ou processos) em execução no dispositivo, incluindo seus nomes, identificadores e PIDs.frida-ls-devicespara listar seus dispositivos conectados executando servidores ou agentes do Frida.frida-tracepara rastrear rapidamente métodos que fazem parte de um aplicativo iOS ou que são implementados dentro de uma biblioteca nativa Android.
Além disso, você também encontrará várias ferramentas de código aberto baseadas no Frida, como:
- Grapefruit: um kit de ferramentas de instrumentação de aplicativo em tempo de execução para iOS.
- Fridump: uma ferramenta de despejo de memória para Android e iOS.
- objection: uma estrutura de avaliação de segurança móvel em tempo de execução.
- r2frida: um projeto que combina as poderosas capacidades de engenharia reversa do radare2 com o kit de ferramentas de instrumentação dinâmica do Frida.
- JNITrace: uma ferramenta para rastrear o uso dos métodos de runtime JNI do Android por uma biblioteca nativa.
Usaremos todas essas ferramentas ao longo do guia.
Você pode usar essas ferramentas como estão, ajustá-las às suas necessidades ou tomá-las como excelentes exemplos de como usar as APIs. Tê-las como exemplo é muito útil quando você escreve seus próprios scripts de hooking ou quando constrói ferramentas de introspecção para apoiar seu fluxo de trabalho de engenharia reversa.