Depurando programas em assembly no GNU/Linux (parte 1)

September 27, 2009

[Warning: This post is a backup recovery from my previous Wordpress blog. All content was automatically converted accessing a MySQL database using a Python script (details). Mostly are in Portuguese but if you are interest I can translate to English. If you found any problem dont’t hesitate to contact me in comments.]

Embora eu particularmente prefira a sintaxe AT&T Intel. Estou tendo que aprender a us-la (e bem). Para os estudos optei pelo NASM, GNU ld e o GDB. Um processo simples, descrito abaixo:

#nasm -g -f elf programa.asm #ld programa.o #gdb -q a.out Vamos fazer um pequeno programa teste que carrega no registro ecx o valor da varivel (var1) e em edx seu endereo:

section .data

   var1 dd 40

section .text

   global _start

   _start:
      nop
      nop
      mov   ecx, [var1]
      lea   edx, [var1]

   _exit:
      mov   eax, 1
      int   80h
Dentro do gdb:
(gdb) break 11
Breakpoint 1 at 0x80480a1: file teste.asm, line 11.
(gdb) r
Starting program: /home/maluta/coding/a.out
Breakpoint 1, _start () at teste.asm:11
11            nop
(gdb) print var1
$1 = 40
(gdb) info registers ecx edx
ecx            0x0      0
edx            0x0      0
Adicionamos um breakpoint (eu precisei inserir duas instrues nop para o gdb realmente para no ponto) e verificamos os valores de var1, ecx e edx.
(gdb) si
_start () at teste.asm:12
12            mov   ecx, [var1]
(gdb) si
_start () at teste.asm:13
13            lea   edx, [var1]
(gdb) info registers ecx
ecx            0x28     40
(gdb) si
_exit () at teste.asm:16
16            mov   eax, 1
(gdb) info registers edx
edx            0x80490b8        134516920
E por fim, verificamos o contedo no endereo definido em edx.
(gdb) print *0x80490b8
$2 = 40

Algumas consideraes:

  • O Data Diplay Debugger (DDD) um front-end muito bom para o GDB que pode ser utilizado ao invs da interface de linha de comando.
  • O aps label _exit h uma chamada a uma syscall (adivinha qual?) do kernel. Passa-se o valor (no registro eax) e chama uma interrupo (80h). A verdadeira "diverso" est em associar essas syscalls (write, fork, execve, ...) mas isto para outro post... Por enquanto vou lidar com os diferentes modos de endereamento e operaes lgicas e aritmticas.