Com base em técnicas, estágios e processos da descompilação...
Gabarito comentado
Confira o gabarito comentado por um dos nossos professores
Alternativa Correta: E - Descompilação de programas em bytecode, como os da linguagem Java, têm maior possibilidade de sucesso que programas em código nativo.
Vamos mergulhar no tema da descompilação para entender o porquê dessa alternativa ser a correta. A descompilação é o processo inverso da compilação. Ela tenta, a partir de um código em linguagem de máquina ou bytecode, recuperar um código-fonte em linguagem de alto nível que seja legível para humanos e possa ser modificado e entendido. Este é um processo bastante complexo, pois muitas das informações presentes no código-fonte original são perdidas durante a compilação, como nomes de variáveis e comentários.
O bytecode é uma representação intermediária de um programa, que é mais abstrata que o código de máquina nativo, mas ainda assim de baixo nível. No caso de linguagens como Java, o bytecode é projetado para ser executado em uma máquina virtual (JVM - Java Virtual Machine), o que o torna independente de plataforma. Isso quer dizer que o bytecode preserva mais informações de alto nível do que o código de máquina nativo.
Agora, por que a descompilação de bytecode tende a ser mais bem-sucedida do que a descompilação de código nativo? A razão é que o bytecode, por ser independente de plataforma e conter informações de alto nível, mantém uma estrutura que está mais próxima do código-fonte original. Isso facilita o processo de reverter o código para uma forma que se assemelha ao original. Além disso, a especificação da JVM fornece uma semântica bem definida para cada instrução, o que ajuda a entender a lógica do programa.
Em contraste, o código nativo é específico para a arquitetura de uma máquina particular, o que significa que ele contém otimizações e características que são dependentes do hardware específico onde o código será executado. Isso torna o processo de descompilação muito mais difícil, pois requer conhecimento sobre a arquitetura específica e as convenções de chamada, além de ter que lidar com a perda de informações que ocorre na compilação para código nativo.
Portanto, a alternativa E está correta porque reflete a realidade de que a descompilação de bytecode é um processo com uma taxa de sucesso maior em comparação com a descompilação de código nativo, principalmente devido à sua natureza independente de plataforma e à preservação de informações de alto nível.
Clique para visualizar este gabarito
Visualize o gabarito desta questão clicando no botão abaixo
Comentários
Veja os comentários dos nossos alunos
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."
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.
Nas pouquíssimas fontes onde consegui material sobre este assunto, o processo de compilação é referenciado como o processo que traduz um código fonte em um código executável. O que sabemos é que o processo não ocorre exatamente assim. Falando de uma forma geral, na compilação, o código fonte é traduzido em uma linguagem de montagem (Assembly) e o programa Assembler (montador) traduz o código assembly em código objeto. Durante a descompilação ocorre mais ou menos a mesma coisa, só que de maneira inversa. Primeiramente tenta-se fazer a tradução do código objeto em uma linguagem intermediária (correspondente ao assembly) e, posteriormente, traduz-se o código já nessa linguagem intermediária para um código fonte. Portanto, esta alternativa está ERRADA.
Essa alternativa me deixou em dúvida. Uma fonte que consegui sobre este assunto afirma justamente isso. Na fase de carregamento, um dos objetivos é descobrir, após a tradução do código objeto em uma linguagem intermediária, a arquitetura sobre a qual o programa executa, além de encontrar uma função correspondente à main function (onde o código se inicia). Se disponíveis, a tabela de símbolos e dados de depuração também são carregados.
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.
Clique para visualizar este comentário
Visualize os comentários desta questão clicando no botão abaixo