Comenzando.

Para comenzar con el libro The Art of Exploitation, construimos el siguiente programa en C:

#include <stdio.h>

int main() {
    char a[] = "Hola, memoria";
    char *p = "Hola, memoria";

    printf("a: %s\n", a);
    printf("p: %s\n", p);

    return 0;
}

Lo guardamos como compare.c.

Compilando

Al compilar el archivo .c a binario debemos hacerlo con el flag -g para que le diga al compilador que incluya información de depuración en el binario:

mapas entre el código fuente y el binario final

Es decir que incluya:

  • nombres de funciones (main, etc.)
  • nombres de variables (a, p)
  • tipos (char[], char * *)
  • líneas de código ↔ direcciones de memoria
  • estructura de stack frames
  • información de scopes (dónde existe cada variable)

comando

gcc -g compare.c -o compare

Al hacerlo de esta forma podremos debuguear de mejor manera nuestro binario.

Depurando

Para comenzar a entender como depurar algoritmos en c lo haremos con la herramienta gdb.

gdb ./comprare

Al compilar con el flag -g deberíamos ver el siguiente mensaje dentro del texto de inicio de gdb

Reading symbols from./compare...

Con lo cual podremos hacer cosas como esta:

break compare.c:7

Que hace esto? Le indicamos a gdb que ponga un punto de interrupción del flujo del algoritmo en la linea 7.

Al hacer

run

la ejecución se parará en la linea 7 y nos mostrara este mensaje en pantalla

Starting program: /home/student/workspace/chapter01/compare
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main () at compare.c:7
7	    printf("a: %s\n", a);

Siguiente misión decirle a gdb que nos muestre el frame actual del stack

info frame

info frame

Nos devuelve el siguente mensaje

tack level 0, frame at 0x7ffc8a3390c0:
 rip = 0x570f3c46d168 in main (compare.c:7); saved rip = 0x7009151c5ca8
 source language c.
 Arglist at 0x7ffc8a3390b0, args:
 Locals at 0x7ffc8a3390b0, Previous frame's sp is 0x7ffc8a3390c0
 Saved registers:
  rbp at 0x7ffc8a3390b0, rip at 0x7ffc8a3390b8

Este mensaje nos muestra no solo las variables locales, sino también la información necesaria para que el programa continúe ejecutándose correctamente al finalizar la función.

De esta forma, info frame nos permite observar no solo los datos, sino también el estado de ejecución del programa, lo que resulta clave para comprender cómo el flujo continúa correctamente entre funciones.

Info local

info locals

Este comando nos muestra el contenido de las variables locales que existen en el stack frame actual …mientras la función está activa.

En nuestro caso estamos en el stack level 0, correspondiente a la función main, y la salida es la siguiente:

a = "Hola, memoria"
p = 0x570f3c46e004 "Hola, memoria"

La variable a es un arreglo de caracteres, por lo que contiene directamente la cadena en memoria.

En cambio, p es un puntero, y lo que almacena es una dirección de memoria, que apunta al lugar donde se encuentra la cadena “Hola, memoria”.

Esta diferencia es fundamental para comprender cómo se organizan los datos en memoria y por qué ciertas operaciones pueden afectar regiones distintas del programa.

the art of exploition