Ассемблер для Windows.
Предисловие автора
Если Вы, дорогой читатель, знакомы с книгой «Assembler: учебный курс» Вашего покорного слуги, то, наверное, обратили внимание, что программированию в операционной системе Windows было посвящено всего две главы. Это немного и может служить лишь введением в данную область. Пришло время заняться этим серьезно.
Прежде всего, как и полагается в предисловии, отвечу на возможное замечание: зачем нужен ассемблер в Windows, если есть, например, Си и другие языки. Зачем нужен ассемблер, я уже писал в упомянутой выше книге. Позволю себе процитировать ее: «Зачем нужен язык ассемблера? — спросят меня. Самой простой и убедительный ответ на поставленный вопрос такой — затем, что это язык процессора и, следовательно, он будет нужен до тех пор, пока будут существовать процессоры. Более пространный ответ на данный вопрос содержал бы в себе рассуждение о том, что ассемблер может понадобиться для оптимизации кода программ, написания драйверов, трансляторов, программирования некоторых внешних устройств и т.д. Для себя я, однако, имею и другой ответ: программирование на ассемблере дает ощущение власти над компьютером, а жажда власти — один из сильнейших инстинктов человека».
Что касается операционной системы Windows1, то здесь, как ни странно это прозвучит для уха некоторых программистов, программировать на ассемблере гораздо легче, чем в операционной системе MS DOS. В данной книге я берусь доказать, что программировать на ассемблере в Windows ничуть не сложнее чем на Си, и при этом получается компактный, эффективный и быстрый код. Работая с языками высокого уровня, мы теряем определенные алгоритмические навыки. И процесс заходит все дальше. Честное слово, только ради повышения своего профессионального уровня стоит заниматься программированием на ассемблере.
Как и предыдущая, эта книга будет содержать только работающие программы с подробным разбором и комментарием.
Сейчас существует два основных конкурирующих ассемблера MASM (Macro Assembler) и TASM (Turbo Assembler)2. Для всех программ будет оговорено, как транслировать их с помощью и MASM, и TASM.
И еще, в книгу вошел материал, который можно назвать «хакерским». Мы рассмотрим способы и средства анализа и исправления кода программ. Для тех, кто начнет говорить о безнравственности исправления чужих программ, замечу, что «хакеры» все равно существуют, а раз так, то почему бы и не познакомиться с тем, как они работают. Это будет полезно многим программистам.
Надо сказать, что в литературе по программированию для Windows 9Х образовалась некоторая брешь — авторы очень быстро перешли от чистого API-программирования 3 к описанию визуальных компонент тех или иных языков. Автору известна лишь одна, да и то переводная, книга по «чистому» программированию для Windows: Герберт Шилдт, Программирование на С и C++ для Windows 954 (см. также [12]). В своей книге я пытаюсь прикрыть эту брешь, рассматривая некоторые малоосвещенные в литературе вопросы: программирование в локальной сети, использование многозадачности, написание VXD-драйверов, обработка файлов и др.
Обычно книги по программированию тяготеют к одной из двух крайностей: описание языка программирования, описание средств программирования операционной системы. Мне хотелось удержаться посередине. Данная книга не руководство по языку ассемблера и не руководство по программированию в Windows. Это нечто среднее, можно сказать — симбиоз языка ассемблера и операционной системы Windows. Как я справился с данной задачей — судить Вам, дорогой читатель.
Ассемблер для Windows используя Visual Studio
Многие из нас изучали ассемблер в университете, но почти всегда это ограничивалось простыми алгоритмами под DOS. При разработке программ для Windows может возникнуть необходимость написать часть кода на ассемблер, в этой статье я хочу рассказать вам, как использовать ассемблер в ваших программах под Visual Studio 2005.
Создание проекта
В статье мы рассмотрим как вызывать ассемблер из С++ кода и обратно, передавать данные, а также использовать отладчик встроенный в Visual Studio 2005 для отладки кода на ассемблер.
Для начала нам нужно создать проект. Включаем Visual Studio, выбираем File > New > Project. В Visual Studio нет языка ассемблер в окне выбора типа проекта, поэтому создаем С++ Win32 проект. В окне настроек нового проекта выбираем «Empty Project».
По умолчанию Visual Studio не распознает файлы с кодом на ассемблер. Для того чтобы включить поддержку ассемблер нам необходимо настроить в проекте условия сборки указав какой программой необходимо компилировать файлы *.asm. Для этого выбираем пункт меню «Custom Build Rules. ».
В открывшемся окне мы можем указать специальные правила компиляции для различных файлов, Visual Studio 2005 уже имеет готовое правило для файлов *.asm, нам необходимо лишь включить его, установив напротив правила «Microsoft Macro Assembler» галочку.
Добавление исходного кода
Перейдем к написанию исходного кода нашего проекта. Начнем с добавления исходного кода на c++. Добавим новый файл в папку Source Files. В качестве Template выбираем C++ File и вводим желаемое имя файла, например main.cpp. Напишем функцию, которая будет считывать имя введенное пользователем, оформив это в виде функции readName() которая будет возвращать ссылку на считанное имя. Мы получим примерно следующее содержимое файла:
Теперь, когда мы знаем имя пользователя мы можем вывести приветствие, его будет выводить функция sayHello() которую мы напишем на ассемблер, чтобы использовать эту функцию сначала мы должны указать что она будет определена в другом файле, для этого добавим блок к main.cpp:
Этот блок говорит компилятору, что функция sayHello() будет объявлена в другом файле и будет иметь правила вызова «C». Компилятор C++ искажает имена функций так, что указание правил вызова обязательно. Кроме того мы хотим использовать функцию readName() из функции sayHello(), для этого необходимо добавить extern «C» перед определением функции readName(), это позволит вызывать эту функцию из других файлов используя правила вызова «C».
Пришло время добавить код на ассемблер, для этого добавим в Source Folder новый файл. Выбираем тип Text File (.txt) и в поле название заменяем .txt на .asm, назовем наш файл hello.asm. Объявим функцию sayHello() и укажем внешние функции, которые мы хотим использовать. Получим следующий код:
Теперь мы можем запустить проект, для этого просто выбираем Debug > Start Without Debugging или нажимаем комбинацию Ctrl-F5. Если все сделано верно, вы увидите окно программы:
Немного усложним задачу, попробуем написать на ассемблер функцию принимающую параметр и возвращающую значение. Для примера напишем функцию calcSumm() которая будет принимать целое число и возвращать сумму его цифр. Изменим наш код на С++ добавив в него информацию о функции calcSumm, ввод числа и собственно вызов функции. Добавим функцию в файл hello.asm, возвращаемое значение помещается в eax, параметры объявляются после ключевого слова PROC. Все параметры можно использовать в коде процедуры, они автоматически извлекутся из стека. Также в процедурах можно использовать локальные переменные. Вы не можете использовать эти переменные вне процедуры. Они сохранены в стеке и удаляются при возврате из процедуры:
Запустив проект мы увидим следующий результат выполнения:
Отладка
Конечно в данной задаче нет ничего сложного и она вовсе не требует использования ассемблер. Более интересным будет рассмотреть, а что же нам дает Visual Studio для разработки на ассемблер. Попробуем включить режим отладки и установим точку остановки в hello.asm, запустим проект, мы увидим следующее:
Окно Disassembly (Debug > Windows > Disassembly) показываем команды ассемблер для данного объектного файла. Код который мы написали на С++ показывается черным цветом. Disassembled code показывается серым после соответствующего ему кода на C++/ассемблер. Окно Disassembly позволяет отлаживать код и осуществлять stepping по нему.
Окно регистров (Debug > Windows > Registers) позволяет посмотреть значение регистров.
Окно памяти (Debug > Windows > Memory) позволяет посмотреть дамп памяти, слева мы видим шестнадцатеричные адрес, справа шеснадцатеричные значения соответствующих ячеек памяти, можно перемещаться, вводя адрес в соответствующее поле в верху окна.
Список ресурсов для изучения Ассемблера
Доброго времени суток!
Некоторым программистам иногда приходит в голову мысль «а не изучить ли мне ассемблер?». Ведь на нем пишут самые (с некоторыми оговорками) маленькие и быстрые программы, да и охота ощутить вкус низкоуровневого программирования берет свое. Ну и для общего развития не повредит.
Мысль эта не обошла стороной и меня. Вдохновившись историей одного байта, я ринулся в бой…
… но оказалось, что найти материал по интересующей теме не так просто, как хотелось бы. Посему решено было создать на хабре пополняющийся пост-индекс статей/книг/мануалов/etc. об этом, несомненно, великом языке.
Под катом находится, собственно, список с краткими комментариями, разбитый по категориям.
UPD
В список начали добавляться ресурсы по программингу микроконтроллеров.
Для начала
- ru.wikipedia.org/wiki/Ассемблер — ассемблер (не тоже самое, что «язык ассемблера», хотя эти понятия почти слились) в википедии
- ru.wikipedia.org/wiki/Язык_ассемблера — язык ассемблера там же
- wasm.ru/article.php?article=onebyte — история одного байта
- bitfry.narod.ru/00.htm — дневники чайника, довольно простые и интересные уроки для начинающих
- www.scribd.com/doc/267365/A-Beginners-Course-In-Assembly-Language — книга об основах ассемблера на английском языке
- Programming from the Ground Up — несложная книга на английском языке. Рекомендация megabrain
- www.osinavi.ru/asm — учебник по Ассемблеру «для квалифицированных чайников»
- habrahabr.ru/blogs/asm — блог, в котором, надеюсь, будет много статей об ассемблере
Ресурсы
- wasm.ru — наверное, самый крупный русскоязычный ресурс по Ассемблеру. Огромное количество статей, живой форум, новости
- cracklab.ru — огромный ресурс по исследованию/крэкингу программ
- www.insidepro.com/rus/doc.shtml — огромнейшее собрание статей Криса Касперски
- programmersclub.ru/assembler — курс asm&&win32
- www.proklondike.com/books/assembler.html — мини-библиотека книг по ассемблеру
- wiki.conus.info — большое количество заметок о reverse engineering на русском языке для начинающих и тех кто хочет научиться понимать создаваемый C/C++ компиляторами код
- wasm.ru/publist.php?list=1 — Уроки Iczelion’а переведенные
- www.nf-team.org/drmad/zf/zf1/zf1_006.htm — пособие начинающей технокрысы или как писать вирусы
Книги
Для книг я выкладываю только названия, без ссылок (или с ссылкой на интернет-магазин), так как я не знаю отношения некоторых людей к скачиванию чьей-то интеллектуальной собственности. Кому надо — тот найдет, где скачать.
- kpnc.opennet.ru — архив книг Криса Касперски
- Галисеев Г. В. Ассемблер для Win 32. Самоучитель
- Зубков С. В. Ассемблер для DOS, Windows и UNIX
- Кип Ирвин. Язык ассемблера для процессоров Intel = Assembly Language for Intel-Based Computers
- Калашников О. А. Ассемблер? Это просто! Учимся программировать
- Крис Касперски. Искусство дизассемблирования
- Владислав Пирогов. Ассемблер для Windows
- Владислав Пирогов. Ассемблер и дизассемблирование
- Ричард Саймон. Microsoft Windows API Справочник системного программиста
- Фрунзе А. В. Микроконтроллеры? Это же просто!
- Юров В., Хорошенко С. Assembler: учебный курс
- Абель — Ассемблер. Язык и программирование для IBM PC
- Эндрю Таненбаум — «Архитектура компьютера» — рекомендация lefty
- Чарльз Петцольд — «Код» — рекомендация lefty
- Assembly Language Step-by-step: Programming with DOS and Linux
- Юрий Ревич «Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера» — рекомендация Ryav
- Нортон П., Соухе Д. «Язык ассемблера для IBM PC» — рекомендация maotm
- Григорьев В. Л. «Микропроцессор i486. Архитектура и программирование.» — рекомендация Ghost_nsk
- Нортон П., Уилтон Р. «IBM PC и PS/2.руководство по программированию» — описана работа с прерываниями и простыми железками, рекомендация Ghost_nsk
Англоязычные ресурсы
- asm.sourceforge.net — Ассемблер под Linux
- orangejuiceliberationfront.com/intel-assembler-on-mac-os-x — Ассемблер под Mac
- blogs.conus.info — Различные заметки о reverse engineering, security research, Oracle RDBMS internals, и т.д.
- msdn.microsoft.com — огромная база знаний по технологиям Windows от Microsoft
- www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html — мануалы по Intel’овским инструкциям
- developer.amd.com/documentation/guides/Pages/default.aspx#manuals — аналогичные доки для AMD
- win32assembly.online.fr — Уроки Iczelion’а, домашняя страница
- www.gnu.org/s/gdb/documentation — GDB Manual
- www.securitytube.net/groups?operation=view&groupId=6 — видеокурс Windows Assembly Language Megaprimer
- www.securitytube.net/groups?operation=view&groupId=5 — видеокурс Assembly Language Megaprimer for Linux
- alexfru.narod.ru/emiscdocs.html — подборка доков из теплых ламповых времен
- www.agner.org/optimize — Software optimization resources
- x86asm.net — x86-x64 manuals
- www.ctyme.com/rbrown.htm — Ralf Brown Interrupt List with over 9000 linked pages and 350 indexes making the process of searching much easier
Инструменты
- www.masm32.com — MASM32 SDK
- flatassembler.net — flat assembler (FASM)
- www.nasm.us — The Netwide Assembler (NASM)
- www.ollydbg.de — OllyDbg, отладчик для Windows
- www.hex-rays.com/products/ida/index.shtml — IDA — интерактивный дизассемблер и отладчик
- www.idapro.ru — русская страница IDA
- research.microsoft.com/en-us/projects/detours — Библиотека от Microsoft Research для инъекции Dll и перехвата управления на себя
- conus.info/gt — отладчик командной строки для выполнения простых отладочных задач
Программинг микроконтроллеров
- habrahabr.ru/blogs/controllers — тематический блог на хабре, с количеством постов несколько большим, чем в блоге по ассемблеру
- programmators.ru — сайт по контроллерам семейства PIC
- myrobot.ru/stepbystep — сайт роботостроения, по ссылке статьи о микроконтроллерах AVR
- www.123avr.com/07.htm — МК AVR
- easyelectronics.ru/category/avr-uchebnyj-kurs — AVR
Прочее
- zx.pk.ru — форум ZX Spectrum
- bbs.pediy.com — форум по reverse engineering на китайском языке (спасибо KollinZ). Чтобы можно было понять о чем речь, можно воспользоваться кнопкой «перевести» в хроме (спасибо за совет mexanism)
- old-dos.ru — крупнейший в Рунете архив старых программ
Заключение
Надеюсь эта статья будет полезна как новичкам, так и тем, кто ищет новых знаний. Если вы знаете какие-либо интересные ресурсы по теме, смело пишите в комментарии, пост создавался, чтобы пополняться.