Para entender como trabaja un descompilador vamos a intentar entender un compilador. Este puede ser entendido como un traductor de lenguaje, tomando como base las sentencias de lenguaje bien estructuradas y aplicando sobre ellas un conjunto de reglas de conversión para obtener así unas sentencias de salida en lenguaje diferente, normalmente conocido como el lenguaje ensamblador.
Los autores del compilador deben examinar exhaustivamente todas las posibles variaciones sintácticas permitidas de cada sentencia en el lenguaje fuente y después determinar que transformaciones deben aplicarse a esa sentencia para generar otra o más sentencia en el lenguaje ensamblador.
Es totalmente indiferente si la sentencia original requiere una tarea a realizar por el sistema operativo, si esta realizando una operación aritmética o bien, esta probando una condición y se desglosa como un resultado de ese test.
Por ejemplo, si una sentencia tal como
x = y + (q * n) / y
está permitida, los autores diseñaran un algoritmo para producir la operación necesitada según la prioridad. Pero los pueden ver, que en el caso del algoritmo x = y + z + q no sea necesario y, sin embargo traducirlo sumando Y a X y después Z y luego Q. Los autores pueden ver que no hay un cambio en la prioridad, y así continuar indefinidamente x=y+z+...+q o pueden usar el algoritmo si más de cierto número de operadores se utilizan en la expresión.
El descompilador, será entonces un traductor de lenguaje que invierte los lenguajes fuente y ensamblador. Toma como entrada el lenguaje ensamblador y produce una salida en lenguaje fuente original.
El descompilador tiene una ventaja en que no tiene que ser un traductor total, sino que sólo tiene que preocuparse con las reglas originales aplicadas en el compilador. |
El descompilador no tiene que traducir cada posible sentencia de instrucciones sino solo aquellas que pudieran haberse producido por la aplicación de las reglas originales. El desarrollo del descompilador está basado en el descubrimiento de las reglas y revertirlas. Si x = p(y) produce op1op2…opn entonces op1op2…opn produce x = p(y). Un descompilador debería ser capaz de ser escrito por una investigación minuciosa de todos las sentencias disponibles permitidas en el lenguaje fuente.
El desarrollo de un descompilador parece entonces un proceso muy simple que bien podría ser automatizado. Simplemente cree un fuente con todas las posibles variaciones de sentencias, compílelo, determine las reglas, escriba el código y hecho. Desafortunadamente, existen algunas restricciones en el mundo real.
En primer lugar, habrá varias versiones del compilador dentro del cual los modos en que las operaciones son traducidas puede variarse. Sin la posibilidad de compilar utilizando cada una de las versiones de compilador, el único modo de establecer que sentencia fuente se utilizó es examinar las instrucciones del ensamblador y encontrar un equivalente funcional en el lenguaje fuente.
En segundo lugar, los optimizadores post-link pueden compilar, para ser realizadas, un segundo set de transformaciones. Tercero y último. Aunque un descompilador puede estar completo en un momento dado, el compilador en si mismo será igualmente cambiado y esos cambios deberán ser tomados en cuenta.
Aproximándonos al proceso de descompilación de fuente como hemos visto, JuggerSoft ha sido capaz de escribir y licenciar descompiladores en cuatro arquitecturas y cinco lenguajes. Como autores de los únicos descompiladores autorizados para ordenadores mainframe y midrange, los desarrolladores de JuggerSoft son aceptados mundialmente como los principales expertos en este campo. |