Você já sentiu o desejo de desmontar algum mecanismo para descobrir como ele funciona? Bem, quem ainda não o fez? Esse desejo é a força principal na engenharia reversa. Esta habilidade é útil para analisar a segurança do produto, descobrir o propósito de um arquivo .exe suspeito sem executá-lo, recuperar documentação perdida, desenvolver uma nova solução baseada em software legado, etc.

Neste artigo, discutimos a base de conhecimento necessária para realizar engenharia reversa, princípios básicos de engenharia reversa de uma peça de software Windows, desmontadores, e ferramentas. Também fornecemos um exemplo passo-a-passo de engenharia reversa de uma aplicação.

Escrito por

Sergii Bratus,

Coordenador de Desenvolvimento,

Equipe de Segurança da Rede

e

Anton Kukoba,

Líder da Pesquisa de Segurança

Conteúdo

O que é a inversão de software?

O que precisamos para a engenharia reversa?

Conhecimento teórico. Processo de Engenharia Inversa de Software

Ferramentas úteis para Engenharia Reversa de Software Windows

>

Disassemblers

Sistemas Windows

>

Ferramentas de Monitorização de Redes

>

Debuggers

>

Real-exemplo de engenharia reversa de software de vida

Como fazer engenharia reversa de um motorista

Conclusão

O que é a inversão de software?

A engenharia reversa é o processo de descobrir princípios por trás de um hardware ou software, tais como sua arquitetura e estrutura interna. A questão que conduz a engenharia reversa é Como funciona?

Obviamente, se você tiver documentação, todo o processo se torna muito mais simples. Mas muitas vezes acontece que não há documentação e você precisa encontrar outra maneira de aprender como funciona um software.

Quando você pode precisar fazer engenharia reversa em um software e como fazer isso pode ajudá-lo?

Existem muitos usos da engenharia reversa na área da informática, incluindo:

  • Pesquisar protocolos de comunicação de rede
  • Encontrar algoritmos usados em malware como vírus de computador, trojans, ransomware, etc.
  • Pesquisando o formato de arquivo usado para armazenar qualquer tipo de informação, por exemplo bancos de dados de e-mails e imagens de disco
  • Verificando a capacidade do seu próprio software para resistir à engenharia reversa
  • Melhorando a compatibilidade do software com plataformas e softwares de terceiros
  • Usando recursos de plataforma não documentados

A legalidade da engenharia reversa depende da sua finalidade e de como o software será usado. Todos os fins mencionados acima são completamente legítimos, assumindo que você tenha obtido uma cópia do software legalmente. Mas se você pretende, por exemplo, fazer engenharia reversa de uma determinada característica de uma aplicação fechada e depois implementá-la em outra aplicação, você provavelmente terá problemas.

No que diz respeito à documentação legal, a engenharia reversa é frequentemente proibida por acordos de licença de usuário final (EULAs). Mas o US Digital Millennium Copyright Act especifica que a reversão de um software é legal se for feita para melhorar a compatibilidade com outros produtos.

Requisitos legais variam de país para país, por isso leve seu tempo para pesquisá-los antes de começar.

Agora vamos ver como fazer engenharia reversa de software.

O que precisamos para engenharia reversa?

Para iniciar software de engenharia reversa, você precisa:

  1. conhecimento no campo onde você quer aplicar engenharia reversa
  2. ferramentas que lhe permitirão aplicar seu conhecimento enquanto tenta desmontar software.

Vamos considerar um exemplo genérico que não está ligado ao software. Digamos que você tem um relógio e quer descobrir se ele é mecânico, quartzo ou automático.

Aparar conhecimento do campo significa que você deve saber que existem três tipos de relógios. Além disso, você deve saber que se houver uma bateria, ela está localizada dentro do relógio, e você pode vê-la se você abri-lo. Você também deve ter conhecimento básico da estrutura interna de um relógio, como é a bateria e que ferramentas você precisa para abrir uma caixa de relógio. Ter as ferramentas para aplicar seus conhecimentos significa que você precisa ter uma chave de fenda ou outra ferramenta dedicada que lhe dará a chance de abrir o relógio.

Apenas como engenharia reversa um relógio requer um conjunto de habilidades e ferramentas específicas, software de engenharia reversa requer seus próprios conhecimentos e ferramentas específicas de campo.

Conhecimento teórico. Software Reverse Engineering Process

Para diferentes tarefas de engenharia reversa de software, você precisa de diferentes tipos de conhecimento. Claro que há um conhecimento comum que o ajudará na maioria das tarefas de engenharia reversa: conhecimento de estruturas de aplicação comuns, linguagens de programação, compiladores, e assim por diante. No entanto, sem conhecimentos teóricos especiais, você não pode resolver tarefas específicas de engenharia reversa.

Se você…

Você precisa de conhecimentos de…

engenheiro reversível de quaisquer aplicações de rede

princípios das comunicações inter-processo, a estrutura das redes, conexões, pacotes de rede, etc.

algoritmos criptográficos reversíveis

criptografia e os algoritmos mais populares usados no campo

arquivo de pesquisa estruturas

conceitos básicos de arquivo e como diferentes sistemas ou componentes trabalham com arquivos

Técnicas especiais podem economizar muito tempo ao reverter tipos especiais de software. No caso de interações de arquivos, fazer um teste que escreve valores de tipos únicos em um arquivo enquanto registra os offsets e o tamanho dos dados no arquivo de armazenamento real pode ajudar você a encontrar padrões comuns nos offsets. Isso lhe dará uma dica sobre as estruturas internas desses arquivos.

Ao iniciar um processo de engenharia reversa, os desenvolvedores de software geralmente usam um disassembler a fim de encontrar algoritmos e lógica de programa no local. Existem muitos formatos diferentes de arquivos executáveis, compiladores (que dão diferentes saídas) e sistemas operacionais. Esta diversidade de tecnologias impede o uso de uma única tecnologia para inverter todos os tipos de software.

Para entender o código descompilado, você precisa de algum conhecimento da linguagem assembler, convenções de chamada de funções, estrutura de pilha, conceito de quadros de pilha, etc.

Conhecer a saída assembler para diferentes amostras de código pode ajudá-lo a descobrir a funcionalidade original. Vamos considerar alguns exemplos para a plataforma Windows x86.

Vamos dizer que temos o seguinte código:

int count = 0;for (int i = 0; i < 10; ++i){count++;}std::cout << count;

Se compilarmos este código para um arquivo executável, veremos isto no disassembler:

004113DE loc_4113DE:004113DE mov eax, 004113E1 add eax, 1004113E4 mov , eax004113E7 loc_4113E7:004113E7 cmp , 0Ah004113EB jge short loc_4113F8004113ED mov eax, 004113F0 add eax, 1004113F3 mov , eax004113F6 jmp short loc_4113DE004113F8 loc_4113F8:004113F8 mov ecx, ds:004113FE push eax00411400 call ds:<<(int)00411404 xor eax, eax00411406 retn 

Como podemos ver, o ciclo regular transformou-se em código assembly com comparações e saltos. Note que o código de montagem não usa o loop de montagem regular com o contador no registro ecx. Além disso, variáveis locais aqui são referidas como e de acordo.

Vejamos o que acontecerá se compilarmos este código usando a release build:

00401000 main proc near00401000 mov ecx, ds:00401006 push 0Ah00401008 call ds:<<(int)0040100E xor eax, eax00401010 retn00401010 main endp

Este pedaço de código não se parece nada com o anterior. Isto é por causa de como o código foi otimizado. Tecnicamente, o loop foi removido, já que não está fazendo nada de valioso além de incrementar a variável de contagem para 10. Então o otimizador decidiu apenas manter o valor final da variável de contagem e colocar o valor diretamente como argumento para o operador de saída da contagem.

Os compiladores que usamos hoje em dia são muito bons em otimizar o código. É por isso que quando se faz engenharia reversa, é melhor entender a idéia por trás do código (os princípios do código) do que tentar obter o código original em si. Se você entender a idéia por trás do código, você pode simplesmente escrever seu próprio protótipo que se encaixa na tarefa original.

Será muito útil saber que código de montagem você terá se compilar diferentes operadores, estruturas e outras construções de linguagem. Entender o código de assembly resultante é uma boa maneira de iniciar o processo de engenharia reversa C++, mas não entraremos em detalhes técnicos dele aqui.

Ferramentas úteis para software de engenharia reversa do Windows

Já descrevemos várias ferramentas de engenharia reversa, incluindo ProcessMonitor e ProcessExplorer, em nossa pesquisa de arquitetura de aplicação. Estas ferramentas são absolutamente indispensáveis para engenharia reversa.

Nesta seção, vamos rever os disassemblers mais populares e mais algumas ferramentas que usamos para nossos projetos de engenharia reversa.

Você pode obter mais detalhes e exemplos de uso em nosso artigo sobre as melhores ferramentas de engenharia reversa de software.

Disassemblers

Um disassembler é um programa que traduz um arquivo executável para a linguagem assembly. O mais popular é o IDA Pro

IDA Pro

IDA Pro

IDA Pro é uma ferramenta conveniente e poderosa para a desmontagem. Possui um grande número de instrumentos que lhe permitem desmontar rapidamente uma peça de software. Ele pode mostrar a árvore de chamadas de funções, importar e exportar o executável, e mostrar informações sobre eles. Ele pode até mesmo mostrar o código em C. Além disso, ele suporta múltiplas arquiteturas de CPU, então é possível usar o IDA Pro para engenharia reversa de código para ARM, AVR, M68k, e muitas outras arquiteturas.

Radare

Radare

O desassembler do Radare é uma alternativa ao IDA. Ele tem basicamente todas as características do IDA sem ser tão robusto e estável. Mas é gratuito e de código aberto. O Radare em si é uma ferramenta de console, mas tem um frontend Cutter, o que o torna uma verdadeira alternativa ao IDA.

Sysinternals do Windows

Utilitários Sysinternals do Windows são geralmente usados para gerenciamento, diagnóstico, solução de problemas e monitoramento do ambiente Microsoft Windows. Mas eles também são adequados para software de engenharia reversa do Windows.

TCPView é um sniffer de rede que mostra todas as informações sobre pacotes TCP/UDP de todos os processos. Esta ferramenta é útil para reverter protocolos de rede.

PortMon é um monitor de porta física do sistema. Ele monitora portas seriais e paralelas e todo o tráfego que passa por elas.

WinObj mostra todos os objetos globais do sistema em uma estrutura hierárquica. Esta ferramenta pode ser útil ao reverter uma aplicação que trabalha com primitivas de sincronização como mutexes e semáforos e também ao reverter drivers de modo de kernel de engenharia.

Ferramentas de monitoramento de rede

Wireshark

Wireshark

Wireshark é um dos mais poderosos sniffers de rede. Ele não só permite que você capture tráfego de rede, mas também contém analisadores para vários protocolos de rede, começando de um nível realmente baixo como Ethernet, TCP e IP para protocolos específicos de aplicação como WebSockets e XMPP.

Fiddler

Fiddler

Fiddler é um proxy web que grava tráfego de navegadores e permite que você analise solicitações HTTP/HTTPS. Ao contrário do Wireshark, ele mostra sessões HTTP ao invés de pacotes de rede separados. O Fiddler também permite que você analise dados comprimidos enviados por HTTP e analise dados JSON e XML ao monitorar requisições SOAP, REST e AJAX.

API Monitor

API Monitor

API Monitor é uma ferramenta útil para descobrir quais APIs são chamadas por uma aplicação e qual comportamento a aplicação espera dessas APIs. Esta ferramenta tem uma base de dados poderosa e permite que você veja chamadas para um grande número de funções de APIs não só do kernel32 e ntdll, mas também COM, ambiente gerenciado, e outros. Além disso, o API Monitor fornece mecanismos de filtragem convenientes.

Debuggers

Um debugger é inestimável para qualquer desenvolvedor para ver o que um programa está fazendo agora. Você obtém o mesmo benefício de depuração ao reverter aplicações que obtém ao depurar aplicações ao vivo.

Os depuradores mais populares são OllyDbg, WinDbg, e Windbg Preview.

OllyDbg

OllyDBG

OllyDbg (e seu sucessor x64dbg) é provavelmente o melhor depurador quando se trata de engenharia reversa de software. Foi especificamente desenvolvido para as necessidades de inversão, e tem todas as ferramentas necessárias para esse fim:

  • um desmontador incorporado com a capacidade de analisar e identificar estruturas de dados chave
  • um recurso de análise de importação e exportação
  • um motor de montagem e remendo incorporado

A capacidade de analisar funções API e seus parâmetros torna fácil reverter interações com um sistema. A vista da pilha fornece muitas informações sobre a pilha de chamadas. Uma vantagem mais importante é que você pode usar OllyDbg com aplicações protegidas contra depuração, quando os depuradores usuais não podem fazer nada.

WinDbg

Windbg

Apesar de sua interface simples, WinDbg tem ferramentas poderosas para depuração. Ele tem um desassembler embutido, vários comandos que permitem que você saiba quase tudo sobre o processo/sistema que você está depurando, e a habilidade de fazer depuração em modo kernel, que é provavelmente a característica mais valiosa. É uma grande vantagem para inverter drivers, em particular drivers de modo do kernel.

Windbg Preview

Windbg Preview

Windbg Preview é uma nova versão do Windbg desenvolvida pela Microsoft. Ele é distribuído apenas através do Windows Store. Tem todos os recursos do clássico Windbg acoplado a uma nova IU e vários recursos novos. Um desses novos recursos é o Time Travel Debugging, que permite que você grave algum período de execução do programa e depois o reproduza quantas vezes forem necessárias. Desta forma, você pode executar as partes interessantes do código por um passo, sem ter medo de executar algum código acidentalmente e perder o contexto ou todos os dados.

Ler também:
9 Melhor ferramenta de engenharia reversa para 2018

Exemplo de engenharia reversa de software da vida real

Agora veremos um exemplo de como fazer engenharia reversa de um software. Vamos imaginar que você tem um arquivo executável suspeito. Você precisa descobrir o que este programa faz e se ele é seguro para os usuários.

Considerando o cenário, é uma boa idéia não rodar este executável no seu computador de trabalho, mas usar uma máquina virtual em seu lugar. Vamos iniciar a aplicação na nossa máquina virtual.

Processo cria um serviço

Como podemos ver, este ficheiro cria um serviço Windows chamado TestDriver. Ele tem o tipo kernel, por isso sabemos que é um driver. Mas de onde ele leva o arquivo de driver para ser executado? Nós podemos usar o ProcessMonitor do Sysinternals Suite para descobrir. Quando abrimos o ProcessMonitor, podemos configurar filtros para nos mostrar apenas a atividade do arquivo do processo no qual estamos interessados. Seu log de atividades se parece com isto:

Informação do FileMon

O arquivo de driver é criado pelo processo que estamos revertendo, e este processo coloca este arquivo no diretório temporário do usuário. Não há necessidade de procurar o arquivo na pasta temp, pois vemos que o processo o apaga logo após o uso. Então o que o processo faz com este arquivo? Se ele descompacta o arquivo, podemos tentar encontrá-lo na seção de recursos do processo, já que este é um local comum para armazenar tais dados. Vamos procurar lá. Vamos usar outra ferramenta – Resource Hacker – para examinar os recursos. Vamos executá-lo:

Examinar recursos com Resource Hacker

Bingo! Como podemos ver pelo conteúdo do recurso encontrado, este é provavelmente o arquivo executável do Windows, já que ele começa com uma assinatura MZ e tem a string “Este programa não pode ser executado no modo DOS”. Vamos verificar se é o nosso ficheiro de driver. Para isso, nós extraímos o recurso usando o Resource Hacker e o abrimos no disassembler.

Disassembler screen

Como sabemos, DriverEntry é o ponto de entrada para os drivers do kernel-mode nos sistemas Windows. Podemos continuar a nossa pesquisa, pois parece que encontramos o driver certo.

Como fazer engenharia reversa de um driver

Para começar a engenharia reversa do driver, examinamos as funções que são chamadas do DriverEntry uma a uma. Se formos à sub_14005, não encontramos nada interessante, por isso continuamos com a sub_110F0 e encontramos este código:

Código peça 1

Código peça 2

Código peça 3

Código peça 4

Algumas linhas são omitidas aqui por uma questão de simplicidade.

Na primeira listagem, uma cadeia unicode é criada, e esta cadeia aponta para o caminho C:\hello.txt. Depois disso, a estrutura OBJECT_ATTRIBUTES é preenchida com valores regulares; sabemos que esta estrutura é frequentemente necessária quando chamamos funções como ZwCreateFile.

Na segunda listagem, vemos que ZwCreateFile é de facto chamado, o que nos faz ter a certeza que o driver cria o ficheiro – e sabemos onde este ficheiro está localizado depois de ter sido criado.

Na terceira e quarta listagem, podemos ver que o driver pega a string unicode e a escreve no buffer (isso acontece na função sub_11150), e o buffer será escrito no arquivo usando a função ZwWriteFile. No final, o driver fecha o arquivo usando a API ZwClose.

Summary. Descobrimos que o programa original extrai o arquivo do driver de seus recursos, coloca-o na pasta temp do usuário atual, cria o serviço do Windows para este driver e o executa. Depois disso, o programa pára e apaga o serviço e o arquivo do driver original do diretório temp. A partir deste comportamento e da análise da desmontagem, parece que o driver não faz nada, exceto criar um arquivo no drive C chamado hello.txt e escrever a string “Hello from driver”.

Agora precisamos verificar se estamos corretos. Vamos executar o programa e verificar o drive C:

Application screen

Wonderful! Nós fizemos a engenharia reversa deste programa simples e agora sabemos que é seguro de usar.

Podemos ter alcançado este resultado de muitas maneiras diferentes – usando depuração ou API Mon, escrevendo testes, etc. Você pode encontrar suas próprias formas de engenharia reversa de software que funcionam para você.

Conclusão

A engenharia reversa de software Windows requer uma sólida formação e experiência em programação. Para realizar engenharia reversa, você precisa combinar habilidades em desmontagem, monitoramento de rede, depuração, integração de API, várias linguagens de programas, compiladores, etc. Você também tem que ter muito cuidado ao reverter software para não infringir as leis de direitos autorais ou prejudicar seu sistema.

Na Apriorit, nós temos uma equipe experiente de engenheiros reversíveis. Se você quiser aplicar habilidades de engenharia reversa ao seu projeto, sinta-se à vontade para entrar em contato conosco!

Deixe uma resposta

O seu endereço de email não será publicado.