0% encontró este documento útil (0 votos)
5 vistas15 páginas

Depuración de Assembler con GDB en Ubuntu

Este documento explica cómo depurar programas ensamblador generados con NASM usando el depurador GDB en Linux. Describe los pasos para crear un programa simple en ensamblador y depurarlo, incluyendo la colocación de puntos de interrupción y la inspección de registros. También cubre cómo depurar cuando el código ensamblador llama a funciones de C.

Cargado por

Pedro Martos
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
5 vistas15 páginas

Depuración de Assembler con GDB en Ubuntu

Este documento explica cómo depurar programas ensamblador generados con NASM usando el depurador GDB en Linux. Describe los pasos para crear un programa simple en ensamblador y depurarlo, incluyendo la colocación de puntos de interrupción y la inspección de registros. También cubre cómo depurar cuando el código ensamblador llama a funciones de C.

Cargado por

Pedro Martos
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Organización del Computador

Depuración de assembler generado con NASM usando GDB en Linux


(Ubuntu 22.04)

Herramientas

Instalar NASM versión 2.16.01. Debe utilizarse esa versión porque hasta la version 2.15.x
hay un bug en la generación de la información de depuración en formato DWARF, que es
el formato que usa GDB y la version 2.16.02 requiere una versión de la librería de sistema
GLIBC más reciente que la que usa Ubuntu 22.04

Ejemplo básico

Cuando se escribe assmbler “puro”, es decir, sin utilizar funciones de C, es necesario


indicar al sistema operativo cuando ha finalizado el programa.
Para ello se utiliza el mecanismo de llamadas al sistema operativo “syscall”. Estas
llamadas permiten a una aplicación pedirle al sistema operativo que realice determinadas
tareas. En particular se utilizar syscall para pedirle al sistema operativo que finalice la
aplicación

1) Con un editor de texto crear el siguiente programa en assembler, guardarlo con el


nombre “[Link]”

section .data
exit_code dq 0 ; Codigo de finalización, 0 para indicar fin correcto
sys_call dq 60 ; Código de syscall para finalizar el programa

section .text
global main

main:
mov rax, [sys_call] ; Se mueve a RAX el código de syscall para Exit()
mov rdi, [exit_code] ; Se mueve a RDI el código de finalización (0)
syscall ; Se realiza la llamada al sistema operativo

1
Organización del Computador

2) Compilar el archivo [Link] con las siguientes lineas de comando

a) nasm -f elf64 -g -F dwarf -l [Link] -o test.o [Link]


b) gcc -no-pie -o test test.o

Como no se llama a funciones de C, tambien se podria haber enlazado con el comando


“ld”, la unica diferencia es que la etiqueta de inicio de codigo en ese caso debe ser _start

ld -o test test.o

2
Organización del Computador

3) Iniciar el depurador con la siguiente linea de comando

gdb test

4) Colocar un punto de interrupción (breakpoint) con el comando “b” al inicio del programa
(etiqueta “main”)

(gdb) b main

3
Organización del Computador

5) Cambiar a la vista de consola con el comando “layout regs”

(gdb) layout regs

6) Ejecutar el programa con el comando “run”

(gdb) run

Se observará en pantalla el código fuente assembler y el contenido de los registros

4
Organización del Computador

7) Ejecutar la primer linea de assembler (linea 9, mov RAX, [sys_call]) con el comando “s”)

(gdb) s

Se verá que el registro RAX ahora tiene el valor 60 (0x3c)

8) Ejecutar la siguiente linea de assembler (linea 10, mov RDI, [exit_code]) con el
comando “s”

(gdb) s

5
Organización del Computador

9) Ejecutar la siguiente linea de assembler (linea 11, syscall) con el comando “s”

(gdb) s

El programa finalizará.

10) Ejecutar nuevamente el programa con el comando “run”

(gdb) run

6
Organización del Computador

11) Se puede inspeccionar el valor de una variable con el comando “print”

(gdb) print (int) sys_call

Se verá que el valor de “sys_call” es “60”. Es importante siempre indicar entre parentesís
el tipo de variable (en este caso INT), o se obtendrá un error.

12) Se puede obtener la dirección de memoria de una variable con el comando “info”

(gdb) info address sys_call

Se verá que la dirección asociada al simbolo “sys_call” es 0x404030 (la direccion puede
cambiar)

7
Organización del Computador

13) Se puede obtener el contenido de una posicion de memoria con el modificador “*”
(similar a un puntero en C)

(gdb) print (int) *0x404030

Se verá que el contenido de dicha posicion de memoria es el valor “60”, que es el valor de
la variable sys_call

8
Organización del Computador

14) Si no se usa el layout y se maneja solo por linea de comandos GDB, es posble ver los
registros con el comando “info registers”

(gdb) info registers

Se verá un listado con todos los registros y su contenido

9
Organización del Computador

15) Si se desea ver el contenido de un registro específico, se utiliza el comando “info


register <nombre del registro>

(gdb) info register rax

Se verá el contenido del registro RAX

10
Organización del Computador

Ejemplo con funciones de C

Funcion PUTS

1) Modificar el programa [Link] de la siguiente manera

extern puts

section .data
cadena db “Hola”,0

section .text
global main

main:
mov rdi, cadena ; Paso la posicion de inicio del String

sub rsp, 0x28 ; Reservo 40 bytes (32+8) para reservar 32 bytes


; de shadow space (necesario en windows) y agrego 8
; bytes para que sumado a los 8 bytes de la posicion de
; retorno de puts sea un total de 48 bytes y el stack
; quede alineado a un multiplo de 16 bytes (16x3=48)
llamada:
call puts ; Invoco a la funcion PUTS de C

add rsp 0x28 ; Recupero el espacio reservado


fin:
ret ; Cierre del programa principal

Guardarlo como [Link]

11
Organización del Computador

2) Compilar [Link] con la siguiente linea de comandos

a) nasm -f elf64 -g -F dwarf -l [Link] -o test2.o [Link]


b) gcc -no-pie -o test2 test2.o

En este caso, como utilizamos una función de C (PUTS) es necesario enlazar utilizando el
comando “gcc”, ya que es necesario enlazar al ejecutable tambien la librería en tiempo de
ejecucion de C (C Runtime). Por otra parte, como se ejecuta el C Runtime, nuestro codigo
debe finalizar con un retorno (RET) en vez de con una llamada al sistema operativo para
que termine la aplicación

3) Iniciar el depurador con la siguiente linea de comando

gdb test2

4) Colocar un punto de interrupción (breakpoint) con el comando “b” al inicio del programa
(etiqueta “main”), y en la llamada a PUTS (etiqueta “llamada”).

(gdb) b main

(gdb) b llamada

12
Organización del Computador

5) Cambiar a la vista de consola con el comando “layout regs”

(gdb) layout regs

13
Organización del Computador

6) Ejecutar el programa con el comando “run”

(gdb) run

Se observará en pantalla el código fuente assembler y el contenido de los registros

7) Ejecutar en forma continua el programa con el comando “c”

(gdb) c

Se observara la ejecución del programa hasta el siguiente punto de interrupcion, en la


etiqueta “llamada”, antes de la invocación a la función “PUTS”

14
Organización del Computador

8) Ejecutar la linea con la llamada a PUTS (call puts) utilizando el comando “n”

(gdb) n

Se observara la salida de texto “Hola”, producida por la invocación a la función PUTS.


También se observara que el comando “n” ejecuta la llamada a PUTS y se detiene en la
siguiente instrucción luego del retorno de PUTS. Por lo que este comando sirve para
ejecutar una subrutina sin necesidad de fijar un punto de interrupcion (breakpoint) en la
siguiente instrucción a la llamada “call” y sin necesidad de ejecutar la subrutina paso a
paso.

9) Ejecutar en forma continua el programa con el comando “c”

(gdb) c

El programa terminará su ejecución


De esta manera es posible depurar programas en assembler que utilizan funciones de C
mediante la herramienta GDB

15

También podría gustarte