Uno de los decompiladores más grandes que está aquí ahora es definitivamente Hex-Rays Decompiler. Si quieres ver qué puede generar, echa un vistazo al http://www.hex-rays.com/products/decompiler/compare_vs_disassembly.shtml.
Su autor, ilfak guilfanov, dio un discurso sobre el funcionamiento interno de su decompilador en algún estafador, y aquí está el libro blanco: http://www.hex-rays.com/products/ida/support/ppt/decompilers_and_beyond_white_paper.pdf y una presentación aquí: http://www.hex-rays.com/products/ida/support/ppt/decompilers_and_beyond.ppt Esto describe una buena visión general de lo que son todas las dificultades en construyendo un descompilador y cómo hacer que todo funcione.
Aparte de eso, hay algunos documentos bastante antiguos, p. Ej. la tesis doctoral clásica de Cristina Cifuentes aquí: http://itee.uq.edu.au/~cristina/dcc.html#thesis
En cuanto a la complejidad, todas las cosas de "descompilación" dependen del lenguaje y el tiempo de ejecución del binario. Por ejemplo, descompilar .NET y Java se considera "hecho", ya que hay decompiladores libres disponibles, que tienen una proporción de éxito muy alta (producen la fuente original). Pero eso es causado por la naturaleza muy específica de las máquinas virtuales que utilizan estos tiempos de ejecución.
En cuanto a los lenguajes verdaderamente compilados, como C, C++, Obj-C, Delphi, Pascal, ... la tarea se vuelve mucho más complicada. Lea los documentos anteriores para más detalles.
¿Cuál es la diferencia entre un desensamblador y un descompilador?
Cuando tiene un programa binario (ejecutable, biblioteca DLL, ...), consta de instrucciones del procesador. El idioma de estas instrucciones se llama conjunto (o ensamblador). En un binario, estas instrucciones están codificadas en binario, por lo que el procesador puede ejecutarlas directamente. Un desensamblador toma este código binario y lo traduce en una representación de texto. Esta traducción generalmente es 1-a-1, lo que significa que una instrucción se muestra como una línea de texto.Esta tarea es compleja, pero sencilla, el programa solo necesita conocer todas las diferentes instrucciones y cómo se representan en un binario.
Por otro lado, un descompilador hace una tarea mucho más difícil. Toma el código binario o la salida del desensamblador (que es básicamente el mismo, porque es de 1 a 1) y produce un código de alto nivel. Dejame mostrarte un ejemplo. Digamos que tenemos esta función C:
int twotimes(int a) {
return a * 2;
}
Cuando se compila, el compilador genera primero y archivo de ensamblaje para esa función, que podría ser algo como esto:
_twotimes:
SHL EAX, 1
RET
(la primera línea es solo una etiqueta y no una instrucción real, SHL
realiza una operación de desplazamiento a la izquierda, que hace una multiplicación rápida por dos, RET
significa que la función está hecha). En el resultado binario, se ve así:
08 6A CF 45 37 1A
(lo inventé, no eran instrucciones binarias reales). Ahora ya sabes, que un desensamblador te lleva del formulario binario al formulario de ensamblaje. Un decompilador lo lleva al código C (u otro lenguaje de nivel superior).
posible duplicado de [¿Qué es un decompilador? ¿Cómo funciona?] (Http://stackoverflow.com/questions/2902074/what-is-a-de-compiler-how-does-it-work) –