
Um plugin para introduzir símbolos interativos no seu depurador a partir do seu descompilador
A engenharia reversa envolve análises tanto estática (descompilador) quanto dinâmica (depurador), mas frequentemente usamos essas análises sem compartilhar conhecimento entre as duas. No caso de reverter binários estáticos, a troca de contexto entre o assembly do depurador e os símbolos que você recuperou na descompilação pode ser ineficiente.
O decomp2dbg tem como objetivo encurtar a lacuna de troca de contexto entre descompilador e depurador, introduzindo uma API genérica para sincronização de símbolos do descompilador para o depurador. Na prática, dando ao analista o poder do seu depurador com os símbolos e linhas de descompilação que ele recupera em seu descompilador.

Interessado em ver o decomp2dbg na prática? Confira a palestra gravada no CactusCon 2023, que apresenta a depuração de um binário arm32 remoto a partir de uma máquina x64 com símbolos do Ghidra.
Para ajuda ativa, entre no Discord do BinSync abaixo, onde respondemos perguntas sobre o decomp2dbg:
Instale via pip, depois use o instalador integrado para descompiladores:
pip3 install decomp2dbg && decomp2dbg --install
Isso abrirá um prompt onde você será solicitado a informar o caminho para seu descompilador e depurador de escolha.
Para o Ghidra, você precisará iniciar no modo PyGhidra e ativar o plugin (d2d_client.py), conforme mostrado aqui.
Se você instalou o lado do descompilador no Gerenciador de Plugins do Binja, ainda precisa instalar o lado do depurador com o comando acima.
Observação: você deve instalar decomp2dbg no mesmo ambiente Python do seu descompilador e depurador.
Observação: Pode ser necessário permitir conexões de entrada na porta 3662, ou na porta que você usa, para que o decomp2dbg se conecte ao descompilador. Se estiver instalando o decomp2dbg com GEF ou pwndbg, é importante que, no seu ~/.gdbinit, o arquivo d2d.py seja carregado após o GEF ou pwndbg.
Pule esta seção se você conseguiu usar a instalação acima sem erros. Se você não puder usar o script integrado (instalação no Windows sem WSL para o descompilador), siga os passos abaixo:
Se você precisar apenas do lado do descompilador, copie o plugin do descompilador correspondente para a pasta de plugins do descompilador. Veja como fazer no IDA:
Primeiro, clone o repositório:
git clone https://github.com/mahaloz/decomp2dbg.git
Instale:
pip install .
Copie o arquivo do servidor:
cp ./decomp2dbg/d2d_server.py /caminho/para/plugins/do/ida/
Se também precisar instalar o lado do gdb, use a linha abaixo:
cp ./decomp2dbg/d2d_client.py ~/.d2d.py && echo "source ~/.d2d.py" >> ~/.gdbinit
Primeiro, inicie o servidor de descompilação no seu descompilador. É recomendável aguardar até que seu descompilador termine a análise normal antes de iniciá-lo. Após a análise normal, isso pode ser feito usando o atalho Ctrl-Shift-D, ou selecionando a aba decomp2dbg: configure na sua aba de plugins associada. Após iniciar o servidor, você deverá ver uma mensagem no seu descompilador:
[+] Iniciando servidor XMLRPC: localhost:3662
[+] Servidor de descompilação registrado!
Em seguida, no seu depurador, execute:
decompiler connect <nome_do_descompilador>
Se você estiver executando o descompilador em uma VM ou máquina diferente, pode fornecer opcionalmente o host e a porta para conectar. Exemplo:
decompiler connect ida --host 10.211.55.2 --port 3662
Você pode descobrir como usar todos os comandos executando o comando do descompilador com a flag --help.
A primeira conexão pode levar até 30 segundos para ser registrada, dependendo da quantidade de globais no binário. Se tudo correr bem, você verá:
[+] Conectado ao descompilador!
Se você estiver usando o decomp2dbg para uma biblioteca, ou seja, o binário principal ao qual seu depurador está conectado não é o binário para o qual você deseja o código-fonte, então você deve dar uma olhada na seção Uso Avançado - Bibliotecas Compartilhadas deste README.
Em cada evento de breakpoint, você verá a descompilação impressa e a linha em que você está associada ao endereço do break.
Funções e Variáveis Globais da sua descompilação agora são mapeadas no seu GDB como símbolos normais de nível de código-fonte. Isso significa que comandos normais do GDB, como impressão e exame, são nativos:
b sub_46340
x/10i sub_46340
p dword_267A2C
x dword_267A2C
Algumas variáveis armazenadas localmente em uma função são variáveis de pilha. Para as variáveis que podem ser mapeadas para a pilha ou registradores, nós as importamos como variáveis de conveniência. Você pode ver seu conteúdo como uma variável de conveniência normal do GDB:
p $v4
Variáveis de pilha sempre armazenam seu endereço na pilha. Para ver o valor real nessa variável de pilha, basta desreferenciar a variável:
x $v4
Isso também funciona com argumentos de função, quando aplicável (a eficácia pode variar):
p $a1
Observação: $v4, neste caso, será mapeado apenas enquanto você estiver na mesma função. Ao sair da função, pode ser desmapeado ou remapeado para outro valor.
Quando você deseja que a descompilação (e símbolos) seja exibida para uma seção de memória que não é o binário principal, como ao depurar uma biblioteca compartilhada, é necessário seguir alguns passos extras. Atualmente, o d2d suporta apenas um descompilador conectado por vez, o que significa que, se você tiver algum descompilador conectado que não seja a biblioteca, precisa desconectá-lo.
Após seguir a configuração normal para ter seu descompilador executando o servidor d2d para sua biblioteca compartilhada, você precisa definir manualmente o endereço base dessa biblioteca e seu endereço final:
decompiler connect ida --base-addr-start 0x00007ffff7452000 --base-addr-end 0x00007ffff766d000
Para encontrar o endereço base no qual sua biblioteca está carregada na memória, recomenda-se usar algo como o comando vmmap do GEF para procurar o nome da biblioteca no espaço de memória. Após conectar com esse endereço definido manualmente, os símbolos funcionarão como no d2d normal. A descompilação será impressa na tela apenas quando você estiver dentro do intervalo desse espaço de endereço.