
- •Системное программирование на макроассемблере masm32
- •Содержание
- •Вступление
- •Префиксы «венгерской» нотации типов данных в описаниях вызовов функций аpi Win32 (Win64)
- •Работа с консолью
- •Цель работы
- •Теоретические сведения
- •Консоль
- •Начальные настройки
- •Как в cmd.Exe выделять-копировать-вставлять текст
- •История ввода команд
- •Заменяющие символы в шаблонах имён
- •Выполнение работы
- •Навигация по дискам и папкам
- •Поиск файлов и папок по имени или шаблону
- •Копирование, перенос, переименование и удаление файлов
- •Создание и уничтожение папок
- •Создание текстового файла
- •Просмотр содержимого файлов
- •Поиск файлов, содержащих нужную строку
- •Состав отчета по работе
- •Состав пакета масм
- •Последовательность создания исполняемого ехе-модуля на масм
- •Режимы компоновки
- •Выполнение работы
- •Создание консольной программы
- •Создание программы с графическим интерфейсом
- •Использование шаблона простой программы
- •Состав отчета по работе
- •Параметризация макросов
- •Уникальность меток при макрорасширениях
- •Макроконстанты
- •Макропеременные и макровычисления
- •Увидеть работу макрогенератора
- •Расширенный листинг
- •Выполнение работы
- •Макроопределение и макрорасширение
- •Повторение строк repeat
- •Цикл for
- •Анализ расширенного листинга программы
- •Состав отчета по работе
- •Потоки вывода и ввода
- •Вывод и ввод в консольных приложениях
- •Invoke GetStdHandle,std_output_handle ; манипулятор возвращен в еах, ...
- •InputBuffer db 25 dup (0) ; вводной буфер фрагмент 3
- •Высокоуровневый консольный ввод-вывод с использованием макросов
- •Макрос консольного вывода print
- •Макросыконсольного вводаinput и inkey
- •Преобразование строки в число
- •Inkey "Жду кнопочку."
- •Преобразование числа в строку
- •Выполнение работы
- •Invoke ExitProcess,0 ; выход в Windows
- •Эксперимент 1. Ввод-вывод функциями Win32
- •Эксперимент 2
- •Эксперимент 3
- •Эксперимент 4
- •Состав отчета по работе
- •Последовательное выполнение команд
- •Передача управления в другое место кода
- •Возврат управления в основную программу
- •Метка_к5:
- •Jmp Метка_к5
- •Call метка_процедуры
- •Передача параметров в процедуру
- •Внутренние переменные в процедурах
- •Как компилятор ml.ExEпомогает организовать работу с процедурами
- •Автоматическое создание пролога и эпилога
- •Автоматическое размещение внутренних переменных
- •Повышение надежности и облегчение вызовов – макрос invoke
- •Выполнение работы
- •Invoke ExitProcess,0 ; выход в Windows
- •Неразрешённые внешние ссылки
- •Выполнение работы
- •Программные инструменты для работы
- •Изготовление файлов для сравнений
- •Восстановление структуры двоичного представления объектного файла
- •Анализ неразрешенных внешних ссылок в объектном файле
- •Состав отчета по работе
- •Исполнение программы под отладчиком
- •Оперативная память «физическая» и виртуальная
- •Выполнение работы
- •Подготовка текстовых файлов для работы
- •Исследование структуры ехе-файла
- •Исследование выполнения программы под отладчиком
- •Карта размещения программы в виртуальной оперативной памяти
- •Действительные ссылки, бывшие раньше неразрешенными
- •Состав отчета по работе
- •Вопросы для самопроверки
- •Рекомендованная литература
Выполнение работы
Рекомендуем выполнять работу и одновременно писать протокол выполнения, на основе которого можно легко создать отчет о лабораторной работе.
Что конкретно нужно будет сделать.
Создать основную программу и описанные в ней две процедуры: одна простая (Р1), а вторая рекурсивная (Р2). Нужно будет в простейшем варианте организовать такую схему вызовов: 1) основная программа вызывает Р1, 2) Р1 вызывает Р2, 3) Р2 один раз рекурсивно вызывает самую себя. Текст этой программы включить в отчет.
С помощью пакетного файла LstExt.bat (см. п.3.3.4 настоящей методички) сделать расширенный листинг компиляции этой программы и включить его в отчет.
Откомпилировать и скомпоновать эту программу в исполняемый ехе-модуль.
Запустить эту программу под отладчиком OllyDbg, пошагово выполнить ее до момента ухода в рекурсивный второй вызов Р2.
В этом состоянии снять скриншот секции кода, где были бы видны основная программа, коды процедур Р1 и Р2.
Снять скриншот секции стека, где были бы видны стековый кадр процедуры Р1 и два стековых кадра процедуры Р2 (первичного и рекурсивного вызовов).
Включить скриншоты в отчет и вручную обвести упомянутые выше стековые кадры ручкой.
Найти в фрейме кода (у вас есть его скриншот) машинные коды всех трёх вызовов процедур и привести в отчете ручные (шариковой ручкой на бумаге) арифметические проверки, выполняются ли соотношения при вызовах процедур: EIPперехода =EIPтекущее + дистанция_перехода.
Крупно воспроизвести стековый кадр первого вызова процедуры Р2. Обвести в кадре и сделать поясняющие выноски, что по смыслу представляет каждая стековая ячейка этого кадра.
Сделать выводы по работе, оформить отчет.
Для помощи приводим текст примитивной программы, которая соответствует требованиям п. (а). Вы вправе модифицировать ее или написать свой вариант и работать с ним.
; ИЗУЧАЕМ ПРОЦЕДУРЫ !
include \masm32\include\masm32rt.inc
P1 PROTO :Dword, :DWORD
P2 PROTO :DWORD
.code
start:
invoke P1, 1, -1
;--------------------------------------
Invoke ExitProcess,0 ; выход в Windows
;-------------------------------------
P1 PROC a:DWORD, b: DWORD
mov eax, a
add eax, b
invoke P2, eax
ret
P1 endp
;-------------------------------------
P2 PROC par:dword
LOCAL d:dword
cmp par,0
ja stp
inc par
invoke P2, par ; рекурсия
stp:
RET
P2 endp
;-------------------------------------
end start
Состав отчета по работе
Номер и название работы, фамилия и группа студента.
Цель работы.
Протокол выполнения работы со всеми включаемыми элементами, упомянутыми в разделе «Выполнение работы».
Вопросы для самопроверки
Что такое процедура с точки зрения ассемблера?
Как оформляется процедура в исходном тексте программы?
Как передаются параметры в процедуру?
Как образуются внутренние переменные в процедурах?
Какую роль при работе с процедурами играет регистр EBP?
Что меняется в секции кода и в секции стека при рекурсивном вызове процедуры?
ИССЛЕДОВАНИЕ ОБЪЕКТНЫХ ФАЙЛОВ ФОРМАТА COFF
Цель работы
Изучить, каким образом компилятор преобразует исходный текст ассемблерной программы в объектный файл формата COFF. Изучить программные инструменты анализа бинарной структуры объектных файлов. Наглядно увидеть, что такое неразрешенные внешние ссылки в объектных файлах и где они размещаются.
Теоретические сведения
Компиляция и компоновка
Задача преобразования исходного текста в работоспособную программу непроста и не может быть решена «в одно действие». Эта работа напоминает создание сборного коттеджа: сначала изготавливаются крупные строительные модули основания, стен, крыши и т.п., а потом это все собирается воедино с установлением всех требуемых связей (электропроводка, подвод воды, газа и прочего)… Короче, вы поняли.
По аналогии со сказанным, программа из исходного asm модуля тоже создаётся «в два захода». Сначала выполняется компиляция – преобразование исходного текста в промежуточный COFF-формат объектного файла (обычно имеет расширение obj). Главная цель этого действия – получить «крупные строительные блоки» будущей программы, они носят название программных секций (или просто секций). Если сказать по-простому, то создаваемый в процессе компиляции объектный файл является контейнером заготовок программных секций.
Программисты в исходных текстах ассемблерных программ используют упрощенные секционные (еще говорят «сегментные») директивы, которые начинают секции разного типа:
.code – секции кода, в них размещаются команды программы;
.data – секци инициализированных данных программы.
Синтаксисом ассемблера предусмотрены еще и ряд других директив (кому интересно, смотрите http://msdn.microsoft.com/en-us/library/8t163bt0.aspx).
Каждая новая директива в исходнике закрывает предыдущую секцию и открывает новую соответствующего типа. Чередующихся секций в исходнике может быть сколько угодно.
Компилятор при компиляции все однотипные секции соединяет воедино, компилирует их, и их числовые образы (raw data) записывает в объектный файл. Кроме секций кода и данных, компилятор в объектном файле создает при необходимости и некоторые другие, нужные только ему. Например, имена секций объектника бывают такие (тут не все):
.text – это образ соединенной секции кода (в исходнике .code);
.data – образ соединенной секции данных;
.drectve – секция директив линкеру. В исходнике она не представлена никак, компилятор создает ее сам на основании директив include и includelib, содержащихся в исходнике. Используется на следующей фазе подготовки программы - компоновке.
Правда, кроме самих секций, в объектный файл помещают и всякую дополнительную информацию. Без неё нельзя обойтись на втором шаге – сборке исполняемого ехе модуля из секций объектного файла. Этот шаг еще называют компоновкой (иногда используют кальку с английского – «линковка»). О компоновке речь пойдет в следующей лабораторной работе.
В этой работе мы изучим структуру объектного файла типа COFF (Common Object File Format), который является стандартом объектных файлов, динамических библиотек и исполняемых модулей для ОС Windows и, кроме того, он поддерживается в unix-системах.