Самый маленький эльф Крис Касперски ака мыщъх Хакер, номер #090, стр. 090-110-3 Отладка ассемблерных программ — это тот вопрос, который большинство составителей tutorial'ов предпочитают обходить стороной. Существует даже мнение, что нормальных отладчиков под UNIX вообще нет, а "великий и могучий" gdb-ассемблер не переваривает в принципе. Что ж! Давай посмотрим, насколько это утверждение близко к истине. Пропустим ассемблерную программу через gcc, но на этот раз не будем удалять символьную информацию, которая, собственно говоря, для отладчика и предназначена. Загружаем elf_libc в gdb ("gdb elf_libc"), тут же брякаемся на main ("b main"), запускаем программу командой "r" и, дождавшись срабатывания точки останова, пробуем трассировать (команда "s" — трассировка без захода в функции, "n" – с заходом). Отладчик тут же слетает с катушек, ругаясь на отсутствие информации о номерах строк. И хотя отладка на ассемблерном уровне (не путать с уровнем исходных текстов!) все-таки доступна (даем команду "display/i $pc" для отображения ассемблерных мнемоник и ведем трассировку командами "si" и "ni"), но в этом случае мы теряем всю информацию об именах функций, метках и переменных. Короче говоря, львиная доля смысла листинга уходит в никуда. Но, если отладочной информации нет, это еще не означает, что ее нельзя подключить! В частности, у gcc за это отвечает ключ "-g", а сам процесс сборки выглядит так: $ gcc -g -o elf_libc elf_libc.S $ dbg elf_libc Ого! Размер файла после подключения отладочной информации возрос до 12,268 байт, что на 172 байта больше, чем у файла, собранного нормальным способом (без отрезания символьной информации, конечно). Грузим программу в отладчик, вновь брякаемся на main, говорим "r" и... чудо! Команды "s" и "n" теперь нормально работают, отображая программу так, как она выглядела в исходном тексте! Правда, под FreeBSD этот прием не срабатывает, и для подключения отладочной информации приходится собирать программу вручную. Транслятору ассемблера необходимо указать ключ "--gstabs", а у линкера — отобрать ключ "-s", отвечающий за удаление всей отладочной информации. Переводя на язык команд, это выглядит так: $ as --gstabs -o elf_libc.o elf_libc.S $ ld -o elf_libc /usr/lib/crt1.o elf_libc.o -lc $ gdb elf_libc Размер файла с отладочной информацией составляет всего 3,145 байта, что намного меньше, чем при автоматической сборке с gcc, при этом программа нормально отлаживается! Так что делаем выводы и решаем, на чем сидеть и с кем дружить! Программирование без libc — штурм ядра] Интерфейс системных вызовов (они же syscall'ы) - это "задний двор" операционной системы, ее собственная и к тому же недокументированная кухня. Реально в syscall'ах нуждаются одни лишь черви, распространяющиеся через переполняющиеся буферы. Они крайне ограничены в размерах, чтобы реализовать процедуру поиска libc в памяти. И еще — драйвера. Но драйвера пишутся под конкретные системы, и никто не собирается требовать от них переносимости, а мы говорим про прикладные программы! Какой ассемблерный tutor не возьми, там обязательно будут syscall'ы, так что мы их и рассмотрим. |