¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Depurar con gdb: puntos de interrupción

Después de esta lección: Puedo parar un programa en gdb y leer los textos que compara.

Lección de 55 min3 comandosLaboratorio de ingeniería inversa: leer programas con gdb, radare2, strace y ltrace en una VM

Qué es un depurador como gdb

gdb es un depurador: ejecuta un programa, lo detiene donde tú dices y te deja leer sus registros y su memoria. Con él ves qué dos textos compara un programa justo antes de decidir.

Un desensamblador solo lee el archivo. Un depurador mira el programa mientras corre, y por eso encuentra datos que el archivo no muestra.

Al final de esta lección

Nota

Puedo parar un programa en gdb y leer los textos que compara.

Palabras clave

PalabraQué significaEjemplo
Depuradoruna herramienta que ejecuta un programa y lo detiene donde quierasgdb
Punto de interrupciónun lugar donde el depurador detiene el programabreak strcmp
Direcciónel número que dice dónde está un dato en la memoria
Argumentoun valor que se entrega a una función al llamarla
Memoriael espacio donde el programa guarda sus datos mientras corre

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un punto de interrupción detiene el programa

break strcmp detiene el programa cada vez que llega a strcmp. En x86-64, los dos primeros argumentos de una llamada están en rdi y rsi, y aquí son direcciones de textos.

x/s $rsi examina la memoria en esa dirección y la muestra como texto. La x es de examinar, la s de string. El primer Run crea tienda, el programa de ejemplo, y no es uno de los de la práctica del laboratorio.

Crea el programa de ejemplo tienda

Comando
printf '#include <stdio.h>\n#include <string.h>\nint main(int argc, char **argv) {\n    if (argc == 2 && strcmp(argv[1], "REBAJAS26") == 0) { puts("Descuento aplicado"); return 0; }\n    puts("Codigo incorrecto");\n    return 1;\n}\n' | gcc -O0 -no-pie -x c -o /tmp/tienda -

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Por qué el punto va después de main

Antes de main, el cargador de bibliotecas también usa strcmp para sus cosas. Un punto de interrupción puesto demasiado pronto se detiene ahí, y lees un texto que no es de tu programa.

Los Runs ponen LD_BIND_NOW=1, que hace que el cargador resuelva las llamadas al arrancar, y detienen primero el programa en main. Solo la última pareja de textos entrecomillados es la que buscas.

Lee lo que compara con el texto hola

Comando
gdb -batch -ex 'set environment LD_BIND_NOW=1' -ex 'break main' -ex run -ex 'break strcmp' -ex continue -ex 'x/s $rsi' -ex 'x/s $rdi' --args /tmp/tienda hola 2>&1 | grep -o '"[^"]*"' | tail -n 2

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Lee lo que compara con otro texto

Comando
gdb -batch -ex 'set environment LD_BIND_NOW=1' -ex 'break main' -ex run -ex 'break strcmp' -ex continue -ex 'x/s $rsi' -ex 'x/s $rdi' --args /tmp/tienda PRUEBA 2>&1 | grep -o '"[^"]*"' | tail -n 2

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Una sesión interactiva de gdb, escrita

Código: bash
gdb --args /tmp/tienda hola
(gdb) break main
(gdb) run
(gdb) break strcmp
(gdb) continue
(gdb) x/s $rsi
(gdb) x/s $rdi
(gdb) info registers rdi rsi
(gdb) quit

Un error frecuente

Advertencia

Mucha gente cree que la primera parada en strcmp es siempre la comparación de su programa. No siempre: el cargador de bibliotecas u otra función pueden llamarla antes. Mira los argumentos. Si no son tuyos, pulsa continue o pon el punto después de main.

Para ir más lejos

En una sesión interactiva, después de la parada en strcmp, escribe bt. Es la pila de llamadas: quién llamó a quién hasta llegar ahí.

Explica con tus palabras cómo bt te habría avisado de que la parada era del cargador y no de tu programa.

Sobre este laboratorio y su código: Laboratorio de ingeniería inversa: leer programas con gdb, radare2, strace y ltrace en una VM

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.