Saltearse al contenido

Depuración con GDB

GDB (GNU Debugger) es la herramienta central para el análisis dinámico en Linux: te permite ejecutar un programa paso a paso, pararlo en puntos concretos (breakpoints), inspeccionar y modificar registros y memoria, y ver exactamente qué hace en cada instante. Para pwn y reversing es imprescindible: con GDB confirmas offsets, ves el estado del stack/heap, depuras tus exploits y entiendes código que es ilegible estáticamente. Potenciado con pwndbg o GEF, se convierte en una navaja suiza de explotación.

# GDB "pelado" es incómodo; pwndbg/GEF añaden vistas de exploit
pwndbg github.com/pwndbg/pwndbg # vistas de registros/stack/heap, comandos de pwn
GEF github.com/hugsy/gef # alternativa muy completa
# tras instalar, GDB muestra automáticamente contexto útil en cada parada
# arrancar
gdb ./binario ; gdb -p <pid> # abrir binario / adjuntar a proceso
run (r) [args] ; starti # ejecutar / parar en la 1ª instrucción
# breakpoints
break main (b main) ; b *0x401234 # parar en función / dirección
b *main+42 # offset dentro de una función
info breakpoints ; delete <n>
# ejecución
continue (c) ; next (n) ; step (s) # continuar / siguiente línea / entrar
nexti (ni) ; stepi (si) # siguiente/entrar a nivel INSTRUCCIÓN (clave en reversing)
finish # ejecutar hasta que la función actual retorne
# inspección
info registers (i r) ; p $rip # registros
x/20gx $rsp # examinar memoria (20 qwords en hex desde RSP)
x/s 0x404050 ; x/i $rip # como string / como instrucción
disassemble (disas) func # desensamblar
x/<cantidad><formato><tamaño> direccion
# formato: x hex, d decimal, s string, i instrucción, c char
# tamaño: b byte, h 2, w 4, g 8 (giant)
x/20gx $rsp # 20 qwords en hex desde el stack pointer
x/s $rdi # la cadena apuntada por RDI (p. ej. argumento de una función)
x/5i $rip # las 5 próximas instrucciones
# confirmar un offset de overflow
b *vuln+X ; run < <(cyclic 200) # al crashear: cyclic -l $rsp
# ver el estado antes de un ret
b *func+ret_offset ; x/20gx $rsp
# depurar un exploit con pwntools
from pwn import *
p = gdb.debug('./vuln', 'b *main\nc') # lanza con GDB adjunto y breakpoints
# o: p = process('./vuln') ; gdb.attach(p, 'b *0x...')

gdb.debug/gdb.attach de pwntools integran GDB con tu script de exploit: desarrollas el exploit viendo la memoria en cada paso.

# seguir la lógica difícil de leer estáticamente
b *función_de_comprobación
# avanzar con ni/si viendo registros y memoria
# ver qué compara: la contraseña correcta aparece en un registro/memoria antes del cmp
# modificar en vivo: set $rax = 1 (forzar un resultado), set {int}0x... = valor
# saltarse una comprobación: cambiar el flujo con set $rip = ...

GDB permite modificar el estado en vivo: cambiar un registro, un valor en memoria, o RIP para saltarte comprobaciones y ver qué pasa — muy útil en crackmes.

# puntos de observación (watchpoints): parar cuando cambia una variable/memoria
watch *0x404050
# condiciones en breakpoints
b func if $rdi == 0x1234
# backtrace de la pila de llamadas
bt
# TUI (interfaz de texto) o directamente el contexto de pwndbg/GEF

El malware y el software protegido detectan GDB/debuggers (ptrace, timing, breakpoints) para dificultar el análisis dinámico — se cubre en rev-antidebug. El analista los sortea (parchear la comprobación, LD_PRELOAD de ptrace, etc.).

  • Instalar pwndbg/GEF y entender el contexto que muestran
  • Breakpoints por función, dirección y offset
  • Ejecución paso a paso (ni/si/finish/continue)
  • Examinar memoria con x (formatos y tamaños)
  • Ver y modificar registros/memoria/RIP en vivo
  • Confirmar offsets de overflow (cyclic)
  • Integrar GDB con pwntools (gdb.debug/attach)
  • Usar watchpoints y breakpoints condicionales