Низкоуровневый кодинг

Крис Касперски ака мыщъх

Хакер, номер #076, стр. 076-116-1

Учимся программировать на ассемблере

Добыча недокументированных функций и возможностей из недр операционной системы, создание и обезвреживание вирусов, адаптация приложений под собственные нужды, рассекречивание алгоритмов и заимствование чужих идей, взлом приложений… Список можно продолжать до бесконечности. Сфера применения ассемблера настолько широка, что сложно представить, как некоторые хакеры без него обходятся. Хакеру «асм» просто необходим. Именно поэтому в Кодинге и появляется эта новая замечательная рубрика, открывающая двери в удивительный мир, расположенный за фасадом высокоуровневого программирования.

Ассемблер - мощное оружие, дающее безграничную власть над системой. Это седьмое чувство и второе зрение. Когда выскакивает хорошо известное окошко с воплем о критической ошибке, прикладники лишь матерятся и разводят руками (мол, это карма у программы такая). Информация об ошибке для них китайская грамота. Но не для ассемблерщика! Он спокойно идет по указанному адресу и правит баг, зачастую даже без потери несохраняемых данных! Давай же разберемся, что такое на самом деле этот ассемблер и как им пользовать и как на нем программировать.

Философия ассемблера

Ассемблер - это низкоуровневый язык, оперирующий машинными понятиями и концепциями. Не ищи команду вывода строки "hello, world!". Здесь ее нет. В асме тебе придется довольствоваться тем, что умеет процессор. А умеет он вот что: сложить/вычесть/разделить/умножить/сравнить два числа и в зависимости от полученного результата передать управление на ту или иную ветку программы, переслать число с одного места в другое, записать число в порт или прочитать его оттуда. Управление периферией, кстати, осуществляется именно через порты или через специальную область памяти (например, видеопамять). Чтобы вывести символ на терминал необходимо обратиться к технической документации на видеокарту, а чтобы прочитать сектор с диска - к документации по накопителю. К счастью, эту часть работы берут на себя драйверы, и выполнять ее вручную обычно не требуется (к тому же, в нормальных операционных системах, таких, например, как Windows NT с прикладного уровня порты вообще недоступны).

Другой машинной концепцией является регистр. Объяснить, что это такое, не погрешив против истины, невозможно. Поэтому вместо того чтобы врубаться в определение (которое наверняка в ужасном виде можно найти в учебниках по асму), лучше просто запомнить, что основных регистров на x86 всего семь. И прежде чем складывать, вычитать или каким-нибудь другим образом манипулировать двумя числами, по крайней мере, одно из них необходимо загрузить в регистр. Другое же может находиться почти где угодно. Хочешь - в оперативке, хочешь - в регистре. Регистры предпочтительнее тем, что они намного быстрее оперативной памяти, частых обращений к которой следует избегать.

Все эти действия (работа с памятью и т.п.) происходят на арене, называемой адресным пространством. Адресное пространство - это просто совокупность ячеек виртуальной памяти, доступной процессору. Операционные системы типа Windows 9x и большинство *nix-систем создают для каждого приложения свой независимый 4 Гбайтный регион, в котором можно выделить, по меньшей мере, три области: область кода, область данных и стек.

Содержание  Вперед на стр. 076-116-2
ttfb: 3.2680034637451 ms