Desensamblador

Desensamblador
Información sobre la plantilla
Desensamblado.gif
Concepto:Programa de computadora que traduce el lenguaje de máquina a lenguaje ensamblador


Un desensamblador es un programa de computadora que traduce el lenguaje de máquina a lenguaje ensamblador, la operación inversa de la que hace el ensamblador. Un desensamblador difiere de de un decompilador, en que éste apunta a un lenguaje de alto nivel en vez de al lenguaje ensamblador. la salida de un desensamblador, el desensamblado, es a menudo formateada para la legibilidad humana en vez de ser adecuada para la entrada a un ensamblador, haciendo que éste sea principalmente una herramienta de ingeniería inversa.

Definición

Esencialmente, un desensamblador es exáctamente lo contrario de un ensamblador. Tal como un ensamblador convierte código escrito en ensamblador en código máquina binario, un desensamblador invierte el proceso e intenta recrear el código en ensamblador partiendo del código máquina binario. Dado que la mayoría de los lenguages ensambladores tienen una correspondencia uno a uno con instrucciones máquina subyacentes, el proceso de desensamblado es relativamente sencillo, y un desensamblador básico puede a menudo ser implementado simplemente leyendo bytes, y efectuando una búsqueda en una tabla. Muchos desensambladores tienen la opción de producir instrucciones en lenguage ensamblador usando la sintaxis de Intel, AT&T, o (ocasionalmente) HLA.

El desensamblado no es una ciencia exacta: En las plataformas CISC con instrucciones de ancho variable, o en presencia de código automodificable, es posible para un simple programa tener dos o más desensamblados razonables. Determinar qué instrucciones serían encontradas realmente durante una corrida del programa reduce al problema de parada probado no solucionable. El programa desensamblador a utilizar, por trabajar con lenguaje máquina y ensamblador, depende exclusivamente del microprocesador que estamos usando (para que pueda reconocer las instrucciones del código binario), de la arquitectura de la máquina y del sistema operativo en uso (no es lo mismo Microsoft Windows que GNU/Linux).

Desensambladores para Windows

  • IDA Pro: Es un desensamblador profesional extremadamente potente. La parte mala es su elevado precio. Por lo tanto, y aunque ciertamente merece su precio, este escrito no considera IDA Pro específicamente porque su precio es exclusivista. Dos versiones gratuitas existen; mira abajo.
   http://www.hex-rays.com/idapro/ 
  • PE Explorer: Es un desensamblador que "se centra en facilidad de uso, claridad y navegación". No es tan completo como IDA Pro, pero tiene un precio mas bajo.
   http://www.heaventools.com/PE_Explorer_disassembler.htm
  • W32DASM: W32DASM es un excelente desensamblador 16/32 bit para Windows.
   http://members.cox.net/w32dasm/
  • BORG Disassembler: BORG es un excelente desensamblador con interfaz gráfico para Win32.
   http://www.caesum.com/
  • HT Editor: Un desensamblador analizador para instrucciones x86. La última versión corre como un programa de interfaz gráfico de consola en Windows, pero hay versiones compiladas para Linux también.
   http://hte.sourceforge.net/
  • diStorm64: diStorm es una librería de desensamblador de stream altamente optimizada para 80x86 y AMD64.
   http://ragestorm.net/distorm/ 

Desensambladores para Linux

  • Bastard Disassembler: Bastard es un potente y programable desensamblador para Linux y FreeBSD.
   http://bastard.sourceforge.net/
  • ciasdis: El nombre oficial de ciasdis es computer_intelligence_assembler_disassembler. Esta herramienta basada en Forth permite construir conocimiento sobre un cuerpo de código de manera interactiva e incremental. Es único en que todo el código desensamblado puede ser re-ensamblado exactamente al mismo código. Soporta 8080, 6809, 8086, 80386, Pentium I y DEC Alpha. Facilidades de scripting ayudan en al análisis de cabeceras de fichero Elf y MSDOS y hacen esta herramienta extensible. ciadsis para Pentium I está disponible como imagen binaria, las otras están en código fuente, cargables sobre lina Forth, disponible del mismo sitio.
   http://home.hccnet.nl/a.w.m.van.der.horst/ciasdis.html
  • objdump: viene de manera estandar, y es tipicamente usada para inspección genérica de ficheros binarios. Presta atención a las opciones de relocation y dynamic symbol table.
  • gdb: viene de manera estandar, como depurador, pero es usado muy a menudo para desensamblar. Si tienes un bloque arbitrario de datos en hexadecimal que quieres desensamblar, simplemente introdúcelo (interactivamente) o compilalo en un programa como una cadena de texto así: char foo[] = {0x90, 0xcd, 0x80, 0x90, 0xcc, 0xf1, 0x90};
  • lida linux interactive disassembler: Un desensamblador interactivo con algunas funciones especiales como un criptoanalizador. Muestra referencias a cadenas, hace análisis de flujo de código, y no depende de objdump. Usa la librería de desensamblage Bastard para descodificar instrucciones individuales.
   http://lida.sourceforge.net
  • ldasm: LDasm (Linux Disassembler) es un interfaz gráfico basado en Perl/Tk para objdump/binutils que intenta imitar el aspecto de W32Dasm. Busca referencias cruzadas (por ejemplo cadenas), convierte el código de GAS a un estilo parecido a MASM, traza programas y mucho mas. Viene con PTrace, un logger para flujo de procesos.
   http://www.feedface.com/projects/ldasm.html

¿Qué hace un desensamblador?

El desensamblador transforma el código binario en instrucciones básicas del PC en la que se ejecuta, el programa no es capaz de distinguir si dichas instrucciones provienen de un "if", de un "for" o de un "while". Tampoco conoce los nombres de las variables (no se incluyen en el código binario ya que la máquina no usa nombres), así que suele inventar nombres como VAR_0001, VAR_0002, etc. En cuanto a las funciones, algo parecido pasa con las funciones internas del programa, se suelen llamar CALL_0001 o JMP_0001, o similares, dependiendo de si son direcciones de llamadas con o sin retorno, espectivamente. Las funciones externas son dependientes según el sistema en el que se corra el programa a desensamblar: Bajo sistemas como DOS, la mayoría de las veces puede indicar las funciones que se llaman (llamar a una función requiere típicamente un llamado a interrupción con valores específicos en los registros, que deben ser consultados si no son provistos por el programa desensamblador). Por ejemplo, para imprimir un texto en pantalla:

  • mov ax, 0009
  • mov dx, offset TEXTO
  • int 21h

En cambio bajo sistemas operativos modernos como Windows, las funciones se llaman por nombres, y esto suele ser bastante autoexplicativo. Esto resulta cierto para la mayoría de las funciones provistas por el sistema operativo y llamados externos en las bibliotecas de enlace dinámico. Por ejemplo, las funciones CreateFile o ReadFile.

¿Qué no hace un desensamblador?

Un desensamblador no puede:

  • Rescatar los nombres de las variables o las funciones nombradas por el programador.
  • Recuperar los comentarios.
  • Rescatar código fuente perdido.

Existe una salvedad a todo esto y es cuando el que compiló el programa ha habilitado una opción, que es incluir la información de depuración en el programa (usualmente se trata de programas en fase de desarrollo y no de programas finales).

Problemas del desensamblador

Separación de código y datos

Puesto que tanto instrucciones como datos están almacenados como datos binarios en un fichero ejecutable, una pregunta surge espontáneamente: ¿Como puede un desensamblador separar código de datos? ¿Es un byte en particular una variable, o parte de una instrucción?. El problema no sería tan dificil si los datos se limitaran a la sección .data del ejecutable (explicado en un capítulo posterior) y si el código ejecutable estuviese limitado también a la sección .code del ejecutable, pero a menudo este no es el caso. Los datos pueden estar insertados directamente en la sección de código (por ejemplo, las tablas de direcciones de salto), y código ejecutable puede estar almacenado en la sección de datos ( aunque sistemas nuevos evitarán esto por razones de seguridad).

Muchos desensambladores interactivos ofrecerán al usuario la opción de mostrar segmentos de código como código o datos, pero los desensambladores no interactivos harán esta separación automáticamente. Los desensambladores suelen proveer en la misma línea la instrucción y sus correspondientes datos en hexadecimal, para reducir la necesidad de hacer decisiones sobre la naturaleza del código. Algunos desensambladores (por ejemplo, ciasdis) te permiten especificar reglas sobre si desensamblar como datos o código e inventar nombres para la etiquetas, basándose en el contenido del objeto bajo escrutinio. Scriptaer tu propio "crawler" de esta manera es más eficiente; para programas grandes el desensamblaje interactivo puede ser difícil hasta el punto de no ser practicable.

El problema general de separar datos de código en ejecutables arbitrarios es equivalente al Halting Problem. Como consecuencia, no es posible escribir un desensamblador que separe correctamente datos de código para todos los programas de input. La ingeniería Inversa está llena de tales limitaciones teóricas, anuque por el teorema de Rice ( Rice's theorem ) todas las preguntas interesantes sobre propiedades de los programas son indecidibles (así que los compiladores y muchas otras herramientas que tratan con programas en cualquier manera también se encuentran con tales límites). En la práctica una combinación de análisis automático e interactivo con perseverancia puede manejar todos los programas excepto aquellos específicamente diseñados para frustrar la ingeniería inversa, como el uso de encripción o el desencriptado de código justo antes de usarse, y mover código de un lado a otro en memoria.

Lost Information

Mucha información se pierde al compilar el programa. Típicamente, para C-code los nombre de p.e. variables locales son perdidas irremediablemente. Los nombres de funciones, variables pueden estar presente en una imagen, sobre todo si se ha compilado con la opción de depuración, pero estas tablas de simbolos pueden ser eliminados por un proceso llamado stripping.

Enlaces internos

Enlaces externos