Desensamblador x86/Ensambladores y Compiladores

De Wikilibros, la colección de libros de texto de contenido libre.

Plantilla:X86 Disassembly/Page

Contenido

[editar] Ensambladores

Wikipedia
Para más información, véase el artículo ensamblador en Wikipedia.

Los Ensambladores son significativamente mas simples que los descompiladores, y son a menudo implementados simplemente para traducir el código ensamblador a código máquina mediante una correspondencia uno-a-uno Los ensambladores raramente optimizan mas allá de escoger la forma mas corta de una instrucción o rellenar delay slots.

Dado que el ensamblado es un proceso simple, el desensamblado a menudo puede ser igual de simple. Las instrucciones en ensamblador y las palabras de código máquina tienen una correspondencia biyectiva, así que cada palabra de código máquina se mapeará a exactamente una instrucción en ensamblador. Sin embargo, el desensamblado tiene otras dificultades que no pueden ser solucionadas usando estas simples formas de traducción. Introduciremos aquí los desensambladores, y hablaremos del desensamblado mas tarde.

[editar] Conceptos de Desensambladores

Los ensambladores, a su nivel mas básico, traducen instrucciones en ensamblador a bytes de código máquina con una correspondencia biyectiva. Los ensambladores tambien permiten variables con nombre que son traducidas a direcciones de memoria, y traducen etiquetas a sus direcciones de código relativas.

En general los ensambladores no ejecutan optimización al código. El código máquina que sale de un ensamblador es equivalente a las instrucciones en ensamblador que entran en el ensamblador. Algunos ensambladores tienen capacidades de alto nivel en la forma de Macros.

Alguna información sobre el programa es perdida durante el proceso de ensamblado. Primero y mas importante, los datos del programa son almacenados en el mismo formato binario crudo que las instrucciones de código máquina. Esto quiere decir que puede ser dificil determinar que partes del programa son instrucciones. Se puede desensamblar datos binarios crudos, pero el código ensamblador resultante será absurdo. Segundo, la información textual del fichero fuente de código ensamblador, como los nombres de variables o etiquetas, o los comentarios, son completamente destrozados durante el ensamblado. Cuando desensamblas el código, las instrucciones serán las mismas, pero toda otra información util desaparece. El código será exacto, pero mas dificil de leer.

Los compiladores, como veremos mas tarde, causan que incluso mas información sea perdida, y descompilar es a menudo y enrevesado que es practicamente imposible de llevar a cabo con exactitud.

[editar] Ensambladores con Sintaxis Intel

Dada la omnipresencia de microprocesadores basados en Intel IA-32 en el mercado del PC doméstico, la mayoria del trabajo de ensamblador hecho (y la mayoria del trabajp de desensamblador considerado en este wikilibro) será basado en x86. Muchos de estos ensambladores (o nuevas versiones de ellos) pueden manejar código IA-64 tambien, aunque este wikilibro se centrará principalmente en ejemplos de código de 32 bits.

[editar] MASM

MASM es el ensamblador de Microsoft, una abreviatura para "Macro Assembler." Sin embargo , mucha gente lo usan como un acrónimo para "Microsoft Assembler", y la diferencia no es realmante un problema. MASM 6.15 está disponible actualmente de forma gratuita y puede ser descargado de Microsoft, y MASM 7.xx está disponible actualmente como parte del DDK para plataformas Microsoft.

  • MASM usa sintaxis Intel.
  • MASM es usado por Microsoft para implementar algunas partes de bajo nivel de sus sistemas operativos Windows.
  • MASM, contrariamente a la creencia popular, ha estado en constante desarrollo desde 1980, y es puesto al dia cada vez que es necesario.
  • MASM siempre ha sido hecho compatible por Microsoft con la plataforma actual, y los tipos de fichero ejecutables.
  • MASM soporta actualmente todos los conjuntos de instrucciones de Intel, incluyendo SSE2.

Muchos usuarios aman MASM, pero a muchos todavia les desagrada el hecho de que no sea portable a otros sistemas.

[editar] TASM

TASM, "Turbo Assembler" de Borland, es un ensamblador funcional que se integra facilmente con las otras herramientas de desarrollo de Borland. La verión actual es la 5.0. La sintaxis de TASM es muy similar a la de MASM, aunque tiene un modo "IDEAL" que muchos usuarios prefieren. TASM no es gratis.

[editar] NASM

NASM, el "Netwide Assembler," es un ensamblador portable y retargetable que funcionan tanto en Windows como en Linux. Soporta una variedad de formatos de fichero ejecutable de Windows y Linux, e incluso produce binario puro. NASM viene con su propio desensamblador.

NASM no es tan "maduro" como MASM o TASM, pero es a) mas portable que MASM, b) mas barato que TASM, y c) se esfuerza en ser muy facil de usar para el usuario.

[editar] FASM

FASM, el "Flat Assembler", es un ensamblador de código abierto que soporta arquitecturas Intel x86 y IA-64.

[editar] Ensambladores de sintaxis (x86) AT&T

La sintaxis de AT&T para código ensamblador de microprocesador x86 no es tan común como la sintaxis Intel, pero el ensamblador GAS de GNU la usa, y es el ensamblador estándar de facto en Linux.

[editar] GAS

Wikipedia
Para más información, véase el artículo GNU_Assembler en Wikipedia.

El ensamblador GNU GAS es el back-end por defecto para la suite de compilación GNU GCC. Como tal, GAS es tan portable y retargetable como GCC. Sin embargo, GAS usa la sintaxis AT&T para sus instrucciones, que algunos usuarios encuentran menos legible que la sintaxis de Intel. Como resultado, el código ensamblador empotrado en ficheros C para GCC tambien debe ser escrito en sintaxis GAS.

GAS es desarrollado especificamente para ser usado como el back-end de GCC. GCC siempre produce código sintacticamente correcto a GAS, así que GAS a menudo tiene una comprobación de errores mínima.

GAS está disponible bien a) en el paquete GCC, o b) en el paquete GNU binutils. [1]

[editar] Otros Ensambladores

[editar] HLA

Wikipedia
Para más información, véase el artículo High Level Assembly en Wikipedia.


HLA, o "High Level Assembler", es un proyecto iniciado por Randall Hyde para crear un ensamblador con sintaxis de alto nivel. HLA funciona como un front-end a otros ensambladores como MASM, NASM, y GAS. HLA soporta instrucciones de lenguaje ensamblador "común", pero tambien implementa una serie de construcciones de alto nivel como bucles, bifurcaciones if-then-else, y funciones. HLA viene completo con una completa libreria estándar.

Dado que HLA funciona como un front-end a otro ensamblador, el programador debe tener otro ensamblador instalado para ensamblar programas con HLA. La generación de código de HLA, por lo tanto, es tan bueno como el ensamblador subyaciente, pero el código es mucho mas facil de escribir para el desarrollador. Los componentes de alto nivel de HLA pueden hacer los programas menos eficientes, pero tal costo a menudo es sobrepasado por la facilidad de escribir código. La sintaxis HLA de alto nivel es muy similar en muchos respectos a Pascal (que es en si mismo similar en muchos aspectos a C), asi que muchos programadores de alto nivel aprenderan inmediatamente muchos de los aspectos de HLA.

Este es un ejemplo de código HLA:

 mov(src, dest);  // Comentarios estilo C++
 pop(eax);
 push(ebp);
 for(mov(0, ecx); ecx < 10; inc(ecx)) do
    mul(ecx);
 endfor;

Algunos desensambladores y depuradores pueden desensamblarm código binario a formato HLA, aunque ninguno recrean lealmente las macros HLA.

[editar] Compilers

Wikipedia
Para más información, véase el artículo compiler en Wikipedia.

Un compilador es un programa que convierte instrucciones de un lenguaje a instrucciones equivalentes en otro lenguaje. Un error común es considerar que un compilador siempre convierte directamente un lenguaje de alto nivel en lenguaje máquina, pero no siempre es así. Muchos compiladores convierten el código en lenguaje ensamblador, e incluso algunos conviernten código de un lenguaje de alto nivel a otro. Ejemplos comunes de lenguajes compilados son: C/C++, Fortran, Ada, and Visual Basic.

Para los propósitos de este libro, sólo consideraremos el caso de un compilador que convierte código C o C++ en código ensamblador o lenguaje máquina. Algunos compiladores como el compilador Microsoft C, compilarán código fuente C y C++ directamente en código máquina. Por otro lado, GCC compilará C y C++ en lenguaje ensamblador, y se usa un ensamblador para convertirlo en el código máquina apropiado. Desde el punto de vista de un desensamblador, no importa exactamente cómo fue creado el programa original. Note también que no es posible reproducir exactamente el código C o C++ utilizado originalmente para crear un ejecutable. Sin embargo, es posible crear código que compile identicamente, o código que realiza la misma tarea.

C language statements do not share a one to one relationship with assembly language. Consider that the following C statements will typically all compile into the same assembly language code:

*arrayA = arrayB[x++];
 
*arrayA = arrayB[x]; x++;
 
arrayA[0] = arrayB[x++];
 
arrayA[0] = arrayB[x]; x++;

Also, consider how the following loop constructs perform identical tasks, and are likely to produce similar or even identical assembly language code:

for(;;) { ... }
 
while(1) { ... }
 
do { ... } while(1)

[editar] Common C/C++ Compilers

The purpose of this chapter is to list some of the most common C and C++ Compilers in use for developing production-level software. There are many many C compilers in the world, but the reverser doesn't need to consider all cases, especially when looking at professional software. This page will discuss each compiler's strengths and weaknesses, its availability (download sites or cost information), and it will also discuss how to generate an assembly listing file from each compiler.

[editar] Microsoft C Compiler

The Microsoft C compiler is available from Microsoft for free as part of the Windows Server 2003 SDK. It is the same compiler and library as is used in MS Visual Studio, but doesn't come with the fancy IDE. The MS C Compiler has a very good optimizing engine. It compiles C and C++, and has the option to compile C++ code into MSIL (the .NET bytecode).

Microsoft's compiler only supports Windows systems, and Intel-compatible 16/32/64 bit architectures.

The Microsoft C compiler is cl.exe and the linker is link.exe

[editar] Listing Files

In this wikibook, cl.exe is frequently used to produce assembly listing files of C source code. To produce an assembly listing file yourself, use the syntax:

cl.exe /Fa<assembly file name> <C source file>

The "/Fa" switch is the command-line option that tells the compiler to produce an assembly listing file.

For example, the following command line:

cl.exe /FaTest.asm Test.c

would produce an assembly listing file named "Test.asm" from the C source file "Test.c". Notice that there is no space between the /Fa switch and the name of the output file.

[editar] FSF GCC Compiler

This compiler is available for most systems and it is free. Many people use it exclusively so that they can support many platforms with just one compiler to deal with. The GNU GCC Compiler is the de facto standard compiler for Linux and Unix systems. It is retargetable, allowing for many input languages (C, C++, Obj-C, Ada, Fortran, etc...), and supporting multiple target OSes and architectures. It optimizes well, but has a non-aggressive IA-32 code generation engine.

The GCC frontend program is "gcc" ("gcc.exe" on Windows) and the associated linker is "ld" ("ld.exe" on Windows).

[editar] Listing Files

To produce an assembly listing file in GCC, use the following command line syntax:

gcc.exe -S <C sourcefile>.c

For example, the following commandline:

gcc.exe -S test.c

will produce an assembly listing file named "test.s". Assembly listing files generated by GCC will be in GAS format. GCC listing files are frequently not as well commented and laid-out as are the listing files for cl.exe.

[editar] Intel C Compiler

This compiler is used only for x86, x86-64, and IA-64 code. It is available for both Windows and Linux. The Intel C compiler was written by the people who invented the original x86 architecture: Intel. Intel's development tools generate code that is tuned to run on Intel microprocessors, and is intended to squeeze every last ounce of speed from an application. AMD IA-32 compatible processors are not guaranteed to get the same speed boosts because they have different internal architectures.

[editar] Metrowerks CodeWarrior

This compiler is commonly used for classic MacOS and for embedded systems. If you try to reverse-engineer a piece of consumer electronics, you may encounter code generated by Metrowerks CodeWarrior.

[editar] Green Hills Software Compiler

This compiler is commonly used for embedded systems. If you try to reverse-engineer a piece of consumer electronics, you may encounter code generated by Green Hills C/C++.

Herramientas personales