Como entender uma feature de um app Electron sem o código-fonte usando o REA

Resposta rápida

Dá pra entender como uma feature de um app Electron funciona sem o código-fonte. O REA (Reverse Engineer Anything) é uma suíte de engenharia reversa agent-first e servidor MCP que lê um diretório extraído ou o próprio app.asar e monta um JavaScript Application Graph, sem executar o app. Rode npx -y rea-agents@latest analyze-javascript-application /caminho/absoluto --json, procure a API exposta via contextBridge e siga até o canal IPC. O REA só pareia canais IPC que são string literal exata, e canais dinâmicos, aliases e preloads sobrescritos ficam para revisão manual

Fala aí, beleza? Sabe aquele app desktop que tu usa todo dia e fica pensando COMO aquele botão salva o arquivo, ou como a sincronização acontece por trás?

Dá pra descobrir isso sem ter o código-fonte, só com o app instalado 😀

Se o app é feito em Electron, por dentro ele é basicamente JavaScript empacotado, e é aí que entra o REA (Reverse Engineer Anything)

Que REA? É uma suíte de engenharia reversa agent-first, ou seja, pensada pra agentes de IA usarem, e que também funciona como servidor MCP

Ele deixa o agente inspecionar localmente binários compilados e bundles Electron, tudo sem o código-fonte

No caso de JavaScript e Electron, a análise é estática: o REA lê os arquivos e NÃO executa o app

Neste post eu te mostro o caminho completo, do pacote do app até a explicação da feature, e também ONDE a análise para (porque ela para, e é bom saber disso antes de confiar cegamente no resultado haha)

REA em vídeo

Também gravei um vídeo sobre o REA no canal Hora de Codar. Dê o play abaixo ou assista no YouTube.

Como uma feature viaja dentro de um app Electron (main, preload e renderer)?

Antes de rodar qualquer comando, vale entender o caminho que uma feature percorre, porque é exatamente esse caminho que a gente vai seguir no grafo

Um app Electron se divide em três peças:

  • renderer: a parte da interface, onde fica o código da janela
  • preload: o script que fica no meio do caminho e expõe APIs pro renderer via contextBridge
  • main: o processo principal, que recebe os pedidos e faz o trabalho pesado

A conversa entre renderer e main acontece por canais IPC (ipcRenderer de um lado, ipcMain do outro)

Se você vem do desenvolvimento web, pensa assim: o renderer é o front, o preload é tipo um client de API bem enxuto que o front pode chamar, e o canal IPC é a rota que leva o pedido até o "back", que é o main

Então, quando tu clica naquele botão de salvar, o fluxo é mais ou menos: o renderer chama uma API do preload, o preload manda uma mensagem num canal IPC, e o main responde

Achou a API no contextBridge e o canal IPC dela? Achou o fio da meada 🙂

O que você precisa antes de começar:

A lista é curtinha:

  • Node com npm/npx funcionando, já que todos os comandos do REA rodam por aí
  • O app Electron instalado, com acesso ao arquivo app.asar dele ou a um diretório da aplicação
  • O caminho absoluto desse diretório ou do ASAR
  • Opcional: um agente com MCP, como o Claude Code, pra pedir a explicação da feature em linguagem natural em vez de ler o JSON na mão

O lugar exato do app.asar muda de app pra app e de sistema pra sistema, então o primeiro trabalho é localizar esse arquivo dentro da pasta de instalação do app que você quer investigar

Passo a passo: analisando um app Electron com o REA

Bora ver na prática?

  1. Instale o REA (ou use direto via npx)

Se quiser o comando rea disponível no terminal, instala global e confere:

npm install --global rea-agents
rea --help

Se preferir não instalar nada, dá pra chamar tudo via npx, como você vai ver no passo 4

O erro comum deste passo: instalar e já sair rodando análise sem checar o rea --help, aí qualquer problema de instalação aparece misturado com erro de análise e tu perde tempo caçando o lugar errado

  1. Conecte o REA ao seu agente (opcional)

Se a ideia é conversar com o agente sobre o app, roda o setup guiado:

npx rea-agents setup

Você escolhe os agentes, revisa as mudanças propostas e aprova

O setup adiciona o servidor MCP do REA e as instruções de workflow, e faz backup da configuração que você já tinha (massa, né? Nada de perder config por acidente)

No Claude Code, a skill que vem com o REA fica em ~/.claude/skills, ou em $CLAUDE_CONFIG_DIR/skills se essa variável estiver configurada

Se quiser fazer na mão, a alternativa é clonar o repositório e copiar a skill:

git clone https://github.com/morluto/rea && cp -r "rea/skills/reverse-engineer-anything" ~/.claude/skills/

O erro comum deste passo: não reiniciar o agente depois do setup. Sem reiniciar, ele não enxerga o servidor MCP novo e parece que nada foi instalado

  1. Extraia o ASAR (se quiser ler os arquivos)

O REA aceita o app.asar direto, então extrair não é obrigatório pra análise

Mas, se tu quer abrir os arquivos e conferir o código com os próprios olhos (e nos limites lá embaixo você VAI querer), extrai assim:

npx asar extract app.asar <diretorio_de_saida>

O diretório de saída fica com o código, os assets e os outros recursos do app

O erro comum deste passo: anotar o caminho relativo da pasta extraída e usar ele no próximo passo. Tome cuidado! A análise pede caminho absoluto

  1. Rode a análise

Aqui é onde a mágica acontece (sem mágica nenhuma, é análise estática mesmo xD):

npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json

No lugar de /absolute/path/to/app, coloca o caminho absoluto do diretório extraído ou do próprio ASAR

Existem três portas de entrada pro mesmo serviço:

Onde você está Como chamar
CLI dedicada rea analyze-javascript-application
CLI genérica rea analyze PATH (apontando pra um diretório ou ASAR)
Agente via MCP ferramenta analyze_javascript_application

As três devolvem um envelope Evidence com o grafo da aplicação e um resumo das fronteiras do Electron

Ou seja, tanto faz se quem chama é você no terminal ou o agente, o resultado vem do mesmo lugar

  1. Peça ao agente a explicação da feature

Com o grafo em mãos, o pulo do gato é ancorar a pergunta na fronteira preload/IPC, que é o trajeto que vimos lá em cima

Um exemplo de pedido (é só um modelo de como perguntar, não um prompt mágico, beleza?):

Analise o app em /caminho/absoluto/do/app com o REA.
Liste as APIs que o preload expõe via contextBridge.
Para a API ligada ao botão de salvar arquivo, mostre em qual canal IPC ela envia mensagens
e onde esse canal é tratado no processo main.
Marque o que ficou como não resolvido.

Repara que a ordem é: primeiro a API do contextBridge, depois o canal IPC dela, depois quem responde no main

O erro comum deste passo: perguntar algo genérico tipo "como esse app salva arquivos?" sem apontar pra fronteira preload/IPC. O agente fica solto no grafo inteiro e a resposta tende a ser vaga

O que o REA entrega quando analisa um app Electron?

A saída é um JavaScript Application Graph, montado a partir do diretório ou ASAR que você forneceu, sem executar o código da aplicação

Traduzindo cada pedaço pra pergunta que ele responde:

O que o REA reconstrói Pergunta que você consegue responder
Metadados do package.json e entrypoints main/renderer declarados Por onde esse app começa?
Caminhos de preload e arquivos de renderer visíveis na sintaxe estática Qual preload está ligado a qual janela?
BrowserWindow, contextBridge, IPC e native add-ons Quais APIs a interface pode chamar e por qual canal elas falam com o main? Tem código nativo no meio?
Entrypoints de script em HTML local Quais scripts cada tela carrega?
Chunks e module factories de Webpack e Rspack representados como literais na AST Em qual pedaço do bundle está o código da feature?
Imports estáticos e dinâmicos, require do CommonJS, workers e service workers Quem depende de quem? Tem trabalho rodando em segundo plano?
Observações de rotas, endpoints de rede, storage e marcadores de vendor Com quais servidores o app conversa, onde guarda dados e quais bibliotecas usa?
Declarações de source map locais com nomes de fontes originais e digests de conteúdo Qual era o nome original do arquivo antes do build?

Pra quem é dev web, esse último item é ULTRA útil: quando o app traz source maps locais, você ganha uma pista de como o projeto era organizado antes de virar bundle 😀

Onde a análise para: limites que você precisa conhecer

Agora a parte honesta do post

O REA dá o mapa, mas tem pontos em que ele não chega: canal IPC montado em runtime, uso de API do Electron por alias e preload sobrescrito depois de declarado

E todos têm a ver com uma coisa: a análise é estática

Como ela não executa o app, tudo que só se resolve em runtime não aparece por esse caminho

Canal IPC aparece como não resolvido:

  • Sintoma: você acha a API no contextBridge, mas o canal IPC dela vem marcado como não resolvido
  • Causa: o REA só pareia canais que são string literal exata. Se o nome do canal é montado em runtime (concatenado, vindo de variável e etc), ele não tem como saber o valor
  • Solução: abre o código extraído no passo 3 e segue na mão como o nome do canal é construído
  • Como prevenir: trate qualquer "não resolvido" como um marcador de "olha aqui", não como ausência de canal

Uso de API do Electron some quando chega por alias:

  • Sintoma: você sabe que o main trata mensagens IPC, mas o grafo não mostra esse uso
  • Causa: limitação reportada no repositório (Issue #1656): o analyze-javascript-application não recupera o uso de uma API do Electron quando ela chega ao ponto de chamada por uma variável que é alias, tipo isso:
const ipc = ipcMain
  • Solução: busca no código extraído as variáveis que recebem ipcMain ou ipcRenderer e segue os usos delas manualmente
  • Como prevenir: quando o grafo parecer "vazio demais" num app que claramente usa IPC, desconfia de alias antes de concluir qualquer coisa

Janela aparece ligada a um preload que talvez não seja o real:

  • Sintoma: a relação janela para preload aparece como resolvida, mas o comportamento do app não bate com aquele preload
  • Causa: limitação reportada no repositório (Issue #1237): a análise estática pode manter um preload literal antigo do BrowserWindow mesmo quando uma propriedade duplicada desconhecida, um spread ou uma chave computada definida depois pode substituí-lo. Aí o preload efetivo é desconhecido, mesmo marcado como resolvido
  • Solução: confere à mão as opções passadas pro BrowserWindow no código extraído, olhando o que vem DEPOIS do preload declarado
  • Como prevenir: se a feature que você está seguindo depende de um preload específico, valida esse vínculo antes de seguir o resto do trajeto

Já viu o padrão, né? Em todos os casos o código extraído é teu melhor amigo, por isso vale fazer o passo 3 mesmo o REA aceitando o ASAR direto

Próximo passo: da sua primeira análise à feature mapeada

Resumindo o veredito: o REA te dá o mapa estrutural de um app Electron rapidinho e aponta o trajeto da feature, do contextBridge até o canal IPC e o main

Porém, os pontos dinâmicos (canal montado em runtime, alias de API, preload sobrescrito) continuam com você, e o grafo deixa isso visível quando marca algo como não resolvido

Então é menos "a IA me explicou tudo" e mais "a IA me levou direto pro lugar certo pra eu olhar", o que já é muiiito mais rápido que sair abrindo arquivo de bundle no escuro haha

O próximo passo concreto é simples: escolhe um app Electron que você usa, roda o analyze-javascript-application apontando pro ASAR dele, acha uma API exposta via contextBridge e segue até o canal IPC

A documentação completa está no repositório morluto/rea no GitHub, vale dar uma olhada antes de partir pra apps maiores

Faz o teste e me conta qual feature tu conseguiu destrinchar 🙂

Até o próximo post!

Perguntas frequentes

Dá pra usar o REA sem ter o código-fonte do app Electron?

Dá sim, essa é a ideia central do REA. Ele faz análise estática a partir de um diretório aprovado ou direto do arquivo app.asar, sem executar o código da aplicação.

O resultado é um JavaScript Application Graph com a estrutura do app, mesmo sem acesso ao projeto original.

Preciso extrair o ASAR antes de rodar a análise?

Não é obrigatório. O comando analyze-javascript-application aceita tanto um diretório quanto o app.asar diretamente.

A extração com npx asar extract app.asar <diretorio_de_saida> só vale a pena se você quiser abrir os arquivos com os próprios olhos, principalmente pra investigar os casos que o REA marca como não resolvido.

O REA consegue achar canais IPC que são montados em runtime?

Não. O REA só pareia canais IPC quando o nome é uma string literal exata no código.

Se o canal é montado dinamicamente em tempo de execução, ele aparece como não resolvido no grafo, e aí a investigação precisa ser feita à mão.

O REA funciona com qualquer agente de IA ou só com Claude Code?

O REA é uma suíte agent-first e também um servidor MCP, então ele foi pensado pra funcionar com agentes de forma geral. O setup guiado (npx rea-agents setup) deixa você escolher os agentes na hora de configurar.

No caso específico do Claude Code, a skill que acompanha o REA é instalada em ~/.claude/skills (ou em $CLAUDE_CONFIG_DIR/skills, se essa variável estiver configurada).

Por que a análise do REA pode mostrar um preload errado pra uma janela do Electron?

Existe uma limitação reportada no repositório (Issue #1237) sobre isso. A análise estática pode manter o caminho de um preload antigo quando uma propriedade duplicada, um spread ou uma chave computada definida depois substitui esse valor em runtime.

Na prática, a relação janela→preload aparece como resolvida no grafo, mas o preload efetivo que realmente roda pode ser outro.

O REA reconhece chamadas às APIs do Electron feitas através de uma variável com alias?

Não, e isso também é uma limitação reportada no repositório (Issue #1656). Se o código faz algo como const ipc = ipcMain e chama a API através dessa variável, o analyze-javascript-application não recupera esse uso.

Por isso vale sempre cruzar o grafo gerado com uma conferência manual nos pontos mais sensíveis do fluxo.

Escrito por | Matheus Battisti

Matheus Battisti
Fundador da Hora de Codar

Programador apaixonado pelo mundo das tecnologias, sempre buscando em aprender e se aprofundar em linguagens, frameworks e o que mais for necessário para executar um bom trabalho. Agora tem uma nova missão que é de passar seu conhecimento adiante para formar novos programadores e especializar mais os que já são.

Subscribe
Notify of
guest

0 Comentários
Oldest
Newest Most Voted

Formações

Formação Vibe Coding

Formação Vibe Coding

Do Prompt ao Produto: Crie Software Real com IA

  • 474 aulas
  • 20 projetos
  • 39h 30min

Blog | Mais populares