Engenharia reversa
Origem: Wikipédia, a enciclopédia livre.
A Engenharia Reversa é uma atividade que trabalha com um produto existente (um software, uma peça mecânica, uma placa de computador, etc.) e tenta entender como este produto funciona e o que ele faz exatamente (todas as suas propriedades em qualquer circunstâncias). Fazemos engenharia reversa quando queremos trocar ou modificar uma peça (ou um software) por outro, com as mesmas características, mas não temos todas as informações sobre essa peça.
Geralmente, trata-se de peças (software) velhas sobre os quais não temos informações suficientes: quem instalou a peça deixou a organização há muito tempo e não tem documentação escrita.
Por exemplo, numa fábrica, uma bomba falhou e tem que ser trocada por uma nova. A bomba foi instalada há 25 anos e as pessoas que fizeram o trabalho se aposentaram há muito tempo. A empresa que vendia essas bombas faliu também. A fábrica tem que achar uma nova bomba, com exatamente as mesmas características, por exemplo, ela tem que ser montada sobre a tubulação existente (dimensões definidas, como a bomba está fixada, volume ocupado pela bomba, etc.) que são características fáceis de descobrir, mas podem também existir outras menos evidentes (a bomba tem que fornecer um débito definido, ela precisa respeitar algumas restrições desconhecidas). Todas essas características da bomba existente podem ser importante ou não, a fábrica tem que descobrir isso antes de comprar uma nova.
A Engenharia Reversa pode também gerar problemas de legalidade, como uma empresa querendo criar uma cópia de um produto que se vende bem. Por exemplo, clones do Pentium da Intel.
Engenharia reversa de software
Existem os mesmos problemas na informática. Organizações trabalham com sistemas apresentando problemas tais como:
* O sistema foi iniciado há muitos anos (até 20 anos atrás).
* O sistema tem pouca documentação e ela não foi atualizada. O que quer dizer que a documentação descreve um estado anterior do sistema mas não a configuração atual.
* As pessoas que criaram o sistema deixaram a empresa, ninguém pode explicar muitas decisões que foram tomadas.
* Algumas partes do sistema foram implementadas com métodos ``estranhos ou sem método nenhum.
* Muitos programadores diferentes implementaram pequenas partes do sistema. Cada um usava um método e um estilo particular de programação.
* O sistema é implementado numa linguagem de programação antiga (Cobol, Fortran, APL, etc.) para a qual se tem poucas ferramentas.
* O sistema foi desenvolvido para computadores com restrições (ex: pouca memória, CPU lento) que obrigaram os programadores a usar ``truques de programação que dificultam o entendimento.
Para ter uma ideia da complexidade da engenharia reversa, veja o exemplo de um curto programa, em Fortran, para calcular as raízes de uma função. O que você faria se tivesse que re-programar isso em C ou em Java? Esse exemplo só tem 100 linhas de código, mas casos reais representam até milhões de linhas de código. Como no exemplo da bomba acima, ninguém sabe exatamente como ele funciona, as pessoas só sabem que esse programa tem que ser chamado de tal maneira, com tais parâmetros, e que o resultado é o tal.
Mas o sistema tem que evoluir:
* Para ser adaptado a novos computadores (mais barato, mais rápido ou porque ninguém mantém mais os velhos). * Para ser adaptado a novos softwares (novas bibliotecas, novas linguagem de programação, novas ferramentas). * Para ser adaptado a novas regras (troca de moeda em todos os países da europa). * Para disponibilizar novas funcionalidades que outras empresas usam. * Para corrigir bugs (bug do ano 2000).
Para software, restrições físicas como as dimensões da tubulação sobre a qual a bomba tem que ser montada, são restrições de interface. O velho programa tinha uma interface específica, e costumava ser chamado de maneira bem definida. O novo programa tem que respeitar a mesma interface. As outras características do programa vão se tornar requisitos não funcionais para o novo programa.
Nesses casos não é possível reimplementar o programa, porque ninguém tem os algoritmos exatos, porque custaria demais e porque todas as informações que o velho programa contém (dezenas de anos de debugging!) seriam perdidas.
É importante observar que esses problemas não são raros, pelo contrário, são muito freqüentes.
A engenharia reversa pode ser de programas como nos exemplos acima ou de dados. Por exemplo, se queremos construir um editor de texto compatível com o MS-Word, vamos ter que entender a representação que ele usa para ler os documentos MS-Word ou poder salvar documentos nesse formato. Outros exemplos são de banco de dados, por exemplo para passar de um banco de dados relacional a um banco de dados orientado a objetos.
Algumas definições
Nessa seção vamos apresentar várias definições de base que serão úteis durante todo o curso. Veja também o glossário (em inglês) ao fim desse documento.
Sistema legado:
Um sistema se torna legado na medida em que nenhuma pessoa que participou de sua concepção está mais disponível.
Por falta de documentação do sistema legado e falta de conhecimento sobre os detalhes de implementação por parte dos programadores atuais, sistemas legados podem apresentar um ou vários dos problemas apresentados no inicio da seção anterior.
Tradicionalmente, a engenharia reversa trabalha com velhos sistemas escritos em Cobol, Fortran, Assembler, etc. Mas essa definição inclui até sistemas mais recentes que foram desenvolvidos com linguagens modernas (com orientação a objeto por exemplo).
Componentes de software:
Um componente de software é uma entidade que faz parte da implementação de um sistema: sub-sistema, pacote, arquivo, rotina, variável, tipo, classe.
Nível de abstração:
Na engenharia reversa, o nível de abstração pode ser relacionado ao modelo de desenvolvimento de software em cascatas: Quanto mais cedo dentro do modelo, mais abstrato, é a informação. Assim, conceitos definidos na fase de projeto são mais abstratos que conceitos definidos na implementação.
Vamos agora definir algumas das atividades que tentam ajudar os engenheiros de software a manter esses sistemas. Existem várias abordagem (veja, também, as definições no glossário):
Engenharia reversa:
A ação de analisar um sistema com dois objetivos: (1) identificar os componentes do sistema e as relações entre eles; e (2) criar uma representação do sistema em uma outra forma ou em um nível de abstração mais alto.
Transliteração:
A ação de traduzir o código de um programa de uma linguagem de programação para uma outra ou para uma versão mais nova da mesma linguagem.
Re-engenharia:
A ação de analisar e modificar um sistema para recriá-lo e reimplementá-lo com uma nova estrutura.
A engenharia reversa inclui muitas atividades diferentes como: engenharia reversa de interfaces, re-documentação, modularização, descobrimento de anomalias no código, etc. Mas todas essas atividades são baseadas sobre um pequeno número de técnicas básicas, a diferença sendo mais na utilização dos resultados.