Jugando con el gdb

in #gdb7 years ago (edited)

Hola Steemiters,

Creo que la mayoría de la gente que sigue estas entradas entiende que funcionalidades tiene gdb y como se instala, para no decir lo que ya se sabe y ahórrarnos tiempo en la misma, meramente se hará referencia de algunos de los parámetros que se pueden utilizar en la depuración de un ejecutable con gdb. Este post sólo pretende ser únicamente una mini guía práctica con algunos ejemplos en código, observaremos algunos screenshot para mostrar la salida de comandos ejecutados una vez attacheado el proceso. El presente documento será utilizado como referencia para futuros post.

La principal motivación de este post es darle al lector un pequeño cheatsheet o una breve introducción de esta excelente herramienta.

Este documento podrá ser modificado a largo plazo, con el fin de añadirle mejoras complementando así ciertas secciones del mismo.

Todos estos test se han realizado bajo un sistema operativo de 64 bits.
alt text

(gdb) b main

Asigna un breakpoint en proceso attacheado en la función main

(gdb) disas main

Obtiene un dump en ensamblador de la función main

(gdb) s

Step over, ejecuta instrucción por instrucción después de un breakpoint

(gdb) p strEjmploVal

Print, hace un dump del valor de una variable en este caso strEjmploVal, es necesario que el ejecutable este corriendo suspendido por un breakpoint para observar los valores.

Otra modo de ver los datos en una forma aún mas útil es...

(gdb) x /1bt &int16var1

EXamine obtiene la dirección de memoria de la variable int16var1, nótese el &, sintaxis similar a la de C o C++ de igual modo obtiene el valor de dicha variable; este comando se puede descomponer de la siguiente forma.

/1bt        Muestra 1 byte en memoria, en tal caso de necesitar mostrar una valor de 4 bytes se puede definir /4bt; en caso de querer mostrar un valor de 10 bytes entonces se establecerá /10bt

El comando eXemine tiene muchos parámetros y es bastante flexible a la hora de presentar valores y posiciones de memoria.

(gdb) bt

Backtrace, Muestra las funciones en el stack y sus argumentos

(gdb) x /4xw $sp

EXamine 4 palabras (w) en notación hexadecimal (x) del Stack Pointer ($sp).

(gdb) info registers

Como es de notar, muestra la información de algunos registros importantes; si le suministras un registro de uso específico (rdi, rsi, rdx) entonces devolverá el valor del mismo. Como por ejemplo:

(gdb) info registers rdi
(gdb) info registers rsi

Mejor lo vemos en código corto y sencillo en ASM x64.

global _start


section .text
_start:


mov rax, 9099
mov rbx, 555



; sycall_exit()
mov rbx, 0
mov rax, 1
int 0x80

Compilamos y luego en el gdb vemos algo como esto: alt text

Con el gdb, breakponiamos, corremos y vamos ejecutando la aplicación con varios s hasta llegar a la instrucción que nos interesa el mov rax, 9099 y vemos el dump de los registros que seteamos en el código en ensamblador, la primera columna nos muestra el nombre del registro rax en la segunda columna el valor en memoria del registro en hexadecimal y finalmente la tercera columna nos muestra el valor en sistema decimal del registro rax con valores 9099 y 555 para el registro rbx

Bien, creo que la idea se entiende cuando son variables con enteros, ¿pero que pasa con las variables strings? veamos otro ejemplo con cadenas de caracteres en ASM x64:

section .text

global _start


_start:
    

mov rbx, txt



; syscal_exit()
mov rbx, 0
mov rax, 1
int 0x80



section .data
    txt db 'oPen syLar', 0

Compilamos y luego en el gdb vemos algo como esto: alt text

Por lo anterior, se denota que el formato que presenta eXamine es el adecuado para explicar muchos temas que no se habían tratado con más detalle.

En primera instancia, vemos comandos b r s que ya fueron tratados en este mismo post, luego observamos el comando x pero éste nos muestra valores en binario que se pueden descomponer de diferentes formas:

Si no cuentas con suficiente tiempo, además te gusta simplificar las cosas, puedes tomar una calculadora, convertir valores binarios a decimales y decimales a valores ASCII.

Dirección en memoriaBinarioDecimalASCII
0x6000c801101111111o
0x6000c80101000080P
0x6000c801100101101e
0x6000c801101110110n
0x6000c80010000032
0x6000c801110011115s
0x6000c801111001121y
0x6000c80100110076L
0x6000d00110000197a
0x6000d001110010114r
0x6000d0000000000NULL

Creo que no hace falta explicar la tabla

alt text

Bonus track

Si tienes de tiempo libre, puedes usar la siguiente táctica para convertir decimales a binarios y comparar valores con una tabla ASCII.

Dicho procedimiento lo vi en un blog, es de mucha ayuda para quienes les apasiona hacer las cosas más interesantes; este método es solo uno de tantos que existen para convertir valores decimales a binarios, no es el mejor ni el peor, pero es el que me a servido.

Bien, tomemos el carácter y de la cadena de ejemplo oPen syLar

  • Si al número le podemos restar 128, lo hacemos y escribimos un uno, si no se puede colocamos un cero

    • Según la tabla ASCII el valor decimal es 121 por lo tanto no podemos restarle 128, entonces escribimos 0
  • Verificamos si al resultado anterior le podemos restar 64, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero

    • 121 si le podemos restar 64 por lo tanto escribimos 1
  • Verificamos si al resultado anterior le podemos restar 32, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero.

    • 57 si le podemos restar 32 por lo tanto escribimos 1
  • Verificamos si al resultado anterior le podemos restar 16, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero.

    • 25 si podemos restarle 16 por lo tanto escribimos 1
  • Verificamos si al resultado anterior le podemos restar 8, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero.

    • 9 si podemos restarle 8 por lo tanto escribimos 1
  • 1 no podemos restarle 4 por lo tanto escribimos 0
  • Verificamos si al resultado anterior le podemos restar 2, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero.

    • 1 no podemos restarle 4 por lo tanto escribimos 0
  • Verificamos si al resultado anterior le podemos restar 1, si es así, lo hacemos y escribimos un uno, si no lo permite entonces colocamos un cero.

    • 1 si le podemos restar 1 por lo tanto escribimos 1

Resultado: 01111001

alt text

Referencias
Dartmouth
ASM86 Wordpress
Sourceware
SCSS

alt text

Por si alguien le sirve en mi repo de Github están estos ejemplos y alguno que otro Makefile para no andar escribiendo lo mismo todo el tiempo.

Lo siento por si sus ojos sangraron al ver código en ASM sin un highlight decente pero es que no me adapto completamente al markdown del Steemit o tiene soporte parcial =(

Mejoras, criticas, errores o cualquier tipo de modificación por favor dejarlo en la zona de comentarios, es posible que esta publicación cambie a través del tiempo, añadiéndole información o modificando su estructura.

If you speak English you can also read it here it here

Coin Marketplace

STEEM 0.20
TRX 0.18
JST 0.031
BTC 87237.56
ETH 3192.65
USDT 1.00
SBD 2.94