Отладка кода NASM c помощью командных файлов GDB

В данной заметке на примере простой программы на Ассемблере NASM в среде Linux приводятся примеры использования командных файлов в консольном отладчике GDB (GNU Debugger).

Наряду с интерактивным режимом работы (управляющие команды вводятся пользователем непосредственно) в GDB существует возможность использования пакетного режима (управляющие команды GDB выполняются из предварительно подготовленного командного файла). Командные файлы позволяют автоматизировать выполнение рутинных, многократноповторяющихся операций в процессе отладки.
Пусть существует некоторый код:

Листинг 1. dcod.asm
section .data
 a dw 185
section .text
 global _start
_start:
main:
 xor eax,eax 
 mov ax,[a]
 not ax
 add ax,1
fin:
 mov eax,1
 mov ebx,0
 int 0x80

Метка main указывает на основной блок кода; также потребуется для установки точки останова (в связи с особенностями GDB на первую после _start инструкцию установить breakpoint затруднительно). Под меткой fin находится код для корректного завершения процесса в Linux.

Компиляция и компоновка исполняемого файла осуществляется следующим образом:
$ nasm -g -f elf -o dcod.o -l dcod.list dcod.asm
$ ld -m elf_i386 -o dcod dcod.o

В nasm ключ -g указан для включения отладочной информации, а ключ -l создает файл листинг (dcom.list), содержащий полезную информацию о созданном бинарном коде.
Ключ -m требует от ld создавать 32-битный исполняемый файл даже на 64-битной платформе.

Создадим командный файл GDB, показывающий значение регистра ax после выполнения последней инструкции блока main:

Листинг 2. dcod.gdb
# загрузить программу
file dcod
# устанавить breakpoint на fin
b fin
# запустить программу
run 
# программа остановится на метке fin
# отобразить ax 
print /t $ax
# продолжить выполнение программы
c
# выйти из отладчика
quit

Спецификатор /t в команде print указывает на двоичную форму записи (/x —шестнадцатиричная, /u и /d — десятичная и т.д.). Комментарии в командных файлах начинаются с # (нельзя писать комментарии в одной строке с командами).

Для запуска GDB в пакетном режиме служит ключ -x с указанием имени командного файла:
$ gdb -q -x dcod.gdb

Результат работы GDB приведен в листинге 3 (значение ax в третьей строке):

Листинг 3.Результат выполнения dcod.gdb
Breakpoint 1 at 0x804808f
Breakpoint 1, 0x0804808f in fin ()
$1 = 1111111101000111
Program exited normally.

Создадим командный файл GDB, дизассемблирующий блоки кода и отображающий значения регистров при выполнении инструкций блока main:

Листинг 4. dcodadv.gdb
file dcod
set disassembly-flavor intel
# дизассемблировать блоки кода
disas main
disas fin
b main
run
# цикл пока счетчик команд меньше
# адреса метки fin
while $pc<fin
 # показать текущую инструкцию
 x/i $pc
 # выполнить инструкцию
 ni 
 # показать регистры
 info registers
end
c
quit

Можно указать GDB использовать Intel-синтаксис Ассемблера (set disassembly-flavor intel
), т. к. по умолчанию используется синтаксис AT&T.

Для отображения областей памяти используется команда x (examine). В общем виде ее формат:
x/nfu адрес
где:
u -размерность еденицы измерения (b — байт, h — два байта, w — четыре байта, g — восемь байт);
f -формат отображения (i — машинная инструкция, x- шестнадцатиричная форма, s — строка);
-n — число повторений.
В данном случае (x/i $pc) в виде машинной инструкции отображается адрес памяти, на которую указывает счетчик команд.

Для пошагового выполнения машинных инструкций без захода в подпрограммы используется команда ni (для трассировки с заходом в подпрограммы — si).

Источники:
1.Ричард Столмен, Роланд Пеш, Стан Шебс и другие. Отладка с помощью GDB 2000г. /Перевод Дмитрий Сиваченко.
2.Погружение в технику и философию gdb Крис Касперски Хакер, номер #093, стр. 093-122-1
3.Страница поддержки gdb: www.gnu.org/software/gdb/
4.Страница поддержки Ассемблера NASM: www.nasm.us/


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.