Trasteando con Ensamblador: segunda parte

Seguimos con la segunda parte de nuestro articulo sobre ensamblador, en esta parte vamos a entrar un poco mas en materia y vamos a ver como son las «tripas» de nuestros programas en ensamblador. Recordad que en el primer articulo, picamos un simple «hello world» para ver a modo de ejemplo muy sencillo, en este articulo necesitamos un código un «poco» mas complejo, por lo que vamos a hacernos un programa muy simple que dados dos números introducidos los sume y nos devuelva el resultado.

#include<stdio.h>
int suma(int mum1, int num2);
int main()
{
int num1;
int num2;
printf("Introduce dos numeros que sera sumados: ");
scanf("%d", &num1);
scanf("%d", &num2);
printf("La suma de los numeros es %d\n", suma(num1,num2));
getchar();
}
int suma (int num1, int num2)
{
return num1+num2;
}
  • Compilamos nuestro programa

      gcc -o suma suma.c
    
  • Lo ejecutamos de manera normal

      ./suma 
    

  • Abrimos el programa con nuestro programa de debug en nuestro caso gdb

      gdb suma
    
  • Y lo ejecutamos dentro de nuestro debugger

      run
    

Nuestro siguiente paso sera generar «breakpoints» para poder «parar» el código en el momento que deseemos y así poder analizarlo, pero para ello primero tenemos que hablar un poco sobre los «breakpoints».

¿Que es un breakpoint? Un «breakpoint» no es mas que una marca que le indica al debugger en que momento queremos parar nuestro código, para poder indagar en le memoria,ver los valores de las variables,examinar la «pila» o depurar nuestro programa paso por paso. Con gdb podemos establecer «breakpoints» por linea de código o por función de lenguaje c o c++

  • Fijamos un breakpoint en nuestra función main con el comando break seguido de la función

       b main
    

    Como podéis ver cada vez que generamos un «breakpoint» nos indica la posición de memoria donde esta fijado, si quisiéramos ver un listado de los que tenemos(puesto que podemos generar todos los que queramos) utilizaríamos el comando «info breakpoints»

  • Ahora vamos a ejecutar nuestro programa hasta nuestro breakpoint, para ello antes tenemos que activar el desensamblado

       set disassemble-next-line on
    
  • Ejecutamos nuestro programa hasta el breakpoint con el comando r

  • Desamblamos el codigo de nuestro funcion main

       disassemble
    

Analizando el código

No vamos a analizar todo el código(porque no es el objetivo de estos artículos) pero si quiero que os quedéis con una serie de porciones del código, con la que trabajaremos mas adelante.

callq 0x4004c0 <printf@plt> = Esta llamada hace referencia a nuestro primer «printf» en el que hacíamos referencia para que el usuario introdujera dos números.

callq 0x4004f0 <__isoc99_scanf@plt> = Esta llamada a «scanf» para capturar el dato que hemos introducido en el «printf»

mov $0x400731,%edi = Almacena en la posición de memoria los caracteres introducidos en el printf

Mas adelante veremos como debuggear programas en ejecución usando el pid del proceso, y entraremos algo mas en detalle en ver como podemos manipular el código ensamblador, para poder ver valores introducidos en la pila, modificar variables,saltar funciones,etc..

Happy debugging ;)

Compartir

3 Comentarios

Deja una respuesta

Your email address will not be published. Required fields are marked *