Отладка кода NASM c помощью командных файлов GDB
В данной заметке на примере простой программы на Ассемблере NASM в среде Linux приводятся примеры использования командных файлов в консольном отладчике GDB (GNU Debugger).
Наряду с интерактивным режимом работы (управляющие команды вводятся пользователем непосредственно) в GDB существует возможность использования пакетного режима (управляющие команды GDB выполняются из предварительно подготовленного командного файла). Командные файлы позволяют автоматизировать выполнение рутинных, многократноповторяющихся операций в процессе отладки.
Пусть существует некоторый код:
Листинг 1. dcod.asm
Метка main указывает на основной блок кода; также потребуется для установки точки останова (в связи с особенностями GDB на первую после _start инструкцию установить breakpoint затруднительно). Под меткой fin находится код для корректного завершения процесса в Linux.
Компиляция и компоновка исполняемого файла осуществляется следующим образом:
В nasm ключ -g указан для включения отладочной информации, а ключ -l создает файл листинг (dcom.list), содержащий полезную информацию о созданном бинарном коде.
Ключ -m требует от ld создавать 32-битный исполняемый файл даже на 64-битной платформе.
Создадим командный файл GDB, показывающий значение регистра ax после выполнения последней инструкции блока main:
Листинг 2. dcod.gdb
Спецификатор /t в команде print указывает на двоичную форму записи (/x —шестнадцатиричная, /u и /d — десятичная и т.д.). Комментарии в командных файлах начинаются с # (нельзя писать комментарии в одной строке с командами).
Для запуска GDB в пакетном режиме служит ключ -x с указанием имени командного файла:
Результат работы GDB приведен в листинге 3 (значение ax в третьей строке):
Листинг 3.Результат выполнения dcod.gdb
Создадим командный файл GDB, дизассемблирующий блоки кода и отображающий значения регистров при выполнении инструкций блока main:
Листинг 4. dcodadv.gdb
Можно указать GDB использовать Intel-синтаксис Ассемблера (set disassembly-flavor intel
), т. к. по умолчанию используется синтаксис AT&T.
Для отображения областей памяти используется команда x (examine). В общем виде ее формат:
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/
Наряду с интерактивным режимом работы (управляющие команды вводятся пользователем непосредственно) в 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 комментариев