Até então eu não tinha visto falar em descompiladores.
Agora aprendi.
Segue a definição segundo a wikipedia:
"Descompilador é um programa de computador que realiza a operação inversa de um compilador, transformando código objeto em código fonte. O termo entretanto é mais utilizado para designar programas de computador que traduzem código de máquina (programas executáveis) em código fonte em uma linguagem de programação de alto nível que, quando novamente compilado, produzirá um programa executável de características e comportamento igual ao programa executável original. Em comparação, um desmontador transforma código de máquina em linguagem de montagem.
O sucesso da descompilação depende da quantidade de informação presente no código e da sofisticação da rotina de análise. As representações intermediárias usadas em máquinas virtuais (como Java e . NET) normalmente incluem bastante metadados e informações de alto nível que facilitam a descompilação. Entretanto, linguagens de máquina possuem muito menos metadados e portanto são bem mais difíceis de serem descompiladas.
Descompiladores automáticos, que geram códigos fontes a partir de arquivos binários, são a utopia de descompilação e mesmo descompiladores (ou desmontadores) avançados atualmente não são capazes de produzir tais resultados sem que o usuário tenha que tomar varias decisões antes que o código fonte possa ser efetivamente utilizado."
Basicamente, o processo de compilação é dividido em analise e sintese. Supomos que eu tenho um código fonte em linguagem de alto nível;
Objetivo da análise: entender o código fonte e representá-lo em uma estrutura intermediária.
2) Análise Léxica - le o código fonte, caracter a caracter, buscando a separação e identificação dos elementos componentes do programa fonte, denominados símbolos léxicos ou tokens; elimina elementos "decorativos", tais como espaços em branco, marcas de formatação de texto e comentários.
3) Análise Sintática - determina se uma cadeia de símbolos léxicos pode ser gerada por uma gramática.
4) Análise Semântica; assegurar que todas as regras sensíveis ao contexto da linguagem estejam analisadas e verificadas quanto à sua validade.
Objetivo da síntese é construir o código objeto a partir dessa representação intermediária.
1) Geração de código intermediário (em java, bytecode, por exemplo);
2) Otimizador de código - A Otimização de código é a estratégia de examinar o código intermediário, produzido durante a fase de geração de código com objetivo de produzir um código que execute com eficiência(detectar padrões dentro do código produzido e substituí-los por códigos mais eficientes).
3) Montagem de código objeto - Verifica a arquitetura;
4) Link Edição;
5) Geração de código final;
Como a descompilação é o inverso, os processos são os mesmos, até a obtenção do código de alto nivel. Outro detalhe: o código intermediário não leva em consideração a arquitetura especifica. Isso é feito na fase da montagem de código objeto.
O processo de descompilação é complexo, o programa pode não permanecer e mesmo ao final do processo, pois muitas das variáveis são substituidas por endereços de memória(isso se o autor do código não quis tornar esse processo mais dificil, com o uso de ofuscadores de codigos, por exemplo).
Em java, diferente de outras linguagens, quando um código é descompilado, a chance de obter um código quase totalmente perfeito se dar por causa da geração do código intermediário (bytecode) que não sofre a etapa de otimização que será executada pela JVM em um processo do JIT (Just in time) em tempo de execução.
Com essas definições em mente, vamos às alternativas:
a) Ao contrário da compilação, a descompilação não usa uma representação intermediária para gerar o código-fonte do programa. Errado.
b) Representações intermediárias usam um grande conjunto de instruções, com centenas de orientações diferentes. Errado.
c) Representações intermediárias geralmente contêm detalhes específicos da arquitetura do sistema no qual o programa é executado. Errado.
d) Sempre é possível gerar código-fonte completo de alto nível a partir de código binário nativo, independentemente da arquitetura do sistema ou do uso de técnicas assembly. Errado.
e) Descompilação de programas em bytecode, como os da linguagem Java, têm maior possibilidade de sucesso que programas em código nativo. Certo.