Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #51, ФЕВРАЛЬ 2005 г.

Как *nix-системы потеряли портируемость

j1m (j1m@list.ru)

Спецвыпуск: Хакер, номер #051, стр. 051-092-3


Помимо непосредственного обращения к ядру операционной системы существует и другой, более высокоуровневый и удобный способ общения с внешним миром - стандартная библиотека языка C (далее просто Libc). В языке C нет многих операторов, присутствующих в других языках программирования. Например, нет оператора печати строки и оператора выделения памяти. Вместо этого предоставляется богатый выбор функций, выполняющих аналогичные действия и входящих в библиотеку Libc (в настоящее время доминирует Glibc - GNU Libc). Хотя эта библиотека и разрабатывалась для взаимодействия с языком C, никто не мешает тебе воспользоваться ее услугами из других языков, в том числе и ассемблера. Для этого достаточно знать низкоуровневый формат вызова функций языка C, а он, кстати, достаточно прост. Необходимо перед вызовом функции занести параметры в стек. Вызов функции на C выглядит так:

puts(message);

на ассемблере примет такой вид:

pushl $message # адрес строки в стек

call puts # вызов функции

В случае с BSD единственное, что придется изменить в коде, – это поставить знак подчеркивания перед именами всех функций.

Хотя использование Libc и кажется простым, на самом деле это не так. Многие функции принимают в качестве аргументов или возвращают структуры, работать с которыми на асме не очень приятно.

Описание всех функций Libc можно найти в третьей секции man-страниц.

Экипируемся!

Теория – это, конечно, хорошо, и знание, как известно, - сила, но без практики далеко не уедешь. Для практики потребуются некоторые инструменты, такие как сам ассемблер, линковщик, и еще кое-что.

В первую очередь понадобится ассемблер, то есть транслятор, который будет переводить наши программы в машинные коды. Здесь у тебя есть два пути: не усложнять себе жизнь и использовать "as" с AT&T-синтаксисом, входящий в любой дистрибутив Linux и BSD или взять nasm с Intel-синтаксисом и мучиться с переписыванием примеров.

Еще одно важное орудие труда ассемблерщика – линковщик, который создает полноценные бинарники из объектных файлов, создаваемых ассемблером. Будем использовать стандартный линковщик из пакета Binutils под незамысловатым названием "ld".

Также тебе может понадобиться отладчик. В любой системе можно найти неплохой отладчик GDB, но он больше рассчитан на отладку C-программ. Существует также инструмент, специально предназначенный для ассемблерщиков, - Ald (Assembly Language Debugger). Любителям виндового SoftIce советую посмотреть в сторону LinIce, который, кстати, представляет собой модуль ядра Linux (подробнее об отладчиках и отладке в *nix читай в этом Спеце).

Как же собирать программы? Способ создания исполняемых файлов зависит от того, используются ли в программе функции Libc. Для сборки программы, использующей только системные вызовы, проделай следующее:

Назад на стр. 051-092-2  Содержание  Вперед на стр. 051-092-4