Тема3.3 Основы 32-битного программирования в Windows 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Тема3.3 Основы 32-битного программирования в Windows



Вводная информация по средствам программирования на языке ассемблера предназначена для начинающих программирование на ассемблере, поэтому программистам более опытным ее можно пропустить без особого ущерба для себя. Технологии трансляции и в MS DOS, и в Windows весьма схожи. Однако программирование в MS DOS уходит в прошлое.

Двум стадиям трансляции соответствуют две основные программы: ассемблер ML.EXE и редактор связей LINK.EXE. Пусть файл с текстом программы на языке ассемблера называется PROG.ASM, тогда две стадии трансляции будут выглядеть следующим образом:

Стадия 1 - в результате появляется модуль PROG.OBJ.

Стадия 2 - в результате появляется исполняемый модуль PROG.EXE.

Формат конечного модуля зависит от операционной системы. Установив стандарт на структуру объектного модуля, мы получаем возможность:

использовать уже готовые объектные модули,

стыковать между собой программы, написанные на разных языках.

Если стандарт объектного модуля распространить на разные операционные системы, то можно использовать модули, написанные в разных операционных системах.

Ниже краткий обзор ряда других программ, которые часто используются при программировании на ассемблере.

Редакторы. Начну с редактора QEDITOR.EXE, который поставляется вместе с пакетом MASM32. Сам редактор и все сопутствующие ему утилиты написаны на ассемблере. Анализ их размера и возможностей действительно впечатляет. Например, сам редактор имеет длину всего 27 Кб, а утилита, используемая для просмотра отчетов о трансляции — всего 6 Кб. Редактор вполне годится для работы с небольшими одномодульными приложениями. Для работы с несколькими модулями он не очень удобен. Работа редактора основана на взаимодействии с различными утилитами посредством пакетных файлов. Например, трансляцию программ осуществляет пакетный файл ASSMBL.BAT, который использует ассемблер ML.EXE, а результат ассемблирования направляется в текстовый файл ASMBL.TXT. Далее для просмотра этого файла используется простая утилита THEGUN.EXE. Аналогично осуществляется редактирование связей. Для дизассемблирования исполняемого модуля используется утилита DUMPPE.EXE, результат работы этой утилиты помещается в текстовый файл DISASM.TXT.

Вторая программа, с которой я хочу познакомить читателя, это EAS.EXE (Easy Assembler Shell). Редактор, а точнее оболочка, позволяет создавать и транслировать довольно сложные проекты, состоящие из ASM-,OВJ-,RC-,RES-,DEF-файлов. Программа позволяет работать как с TASM, так и MASM, а также с другими утилитами (отладчиками, редакторами ресурсов и т.д.). Непосредственно в программе можно настроить компиляторы и редакторы связей на определенный режим работы путем задания ключей этих утилит.

Отладчики. Отладчики позволяют исполнять программу в пошаговом режиме. Несколько наиболее известных отладчиков CodeView (Микрософт), Turbo Debugger (Borland), Ice.

Дизассемблеры. Дизассемблеры переводят исполняемый модуль в ассемблерный код. Примером простейшего дизассемблера является программа DUMPPE.EXE, работающая в строковом режиме. Отмечу также дизассемблер W32Dasm и знаменитый дизассемблер IDA Pro.

Нех-редакторы. Нех-редакторы позволяют просматривать и редактировать загружаемые модули в шестнадцатеричном виде. Их великое множество, к тому же отладчики и дизассемблеры, как правило, имеют встроенные НЕХ-редакторы. Отмечу только, весьма популярную в хакерских кругах программу HIEW.EXE. Эта программа позволяет просматривать загружаемые модули как в шестнадцатеричном виде, так и в виде ассемблерного кода. И не только просматривать, но и редактировать.

Редакторы ресурсов. Ресурсы - это готовые шаюлоны, которые можно включать в коды. Простые ресурсы можно создавать в обычном текстовом редакторе. Язык описания ресурсов будет подробно рассмотрен далее.

Компиляторы ресурсов. Они превращают текст ресурса в модуль. В пакетах MASM32 и TASM32 есть компиляторы ресурсов, которые будут описаны ниже. Это программы RC.EXE и BRC32.EXE соответственно.

Для начала программирования на ассемблере в среде Windows важны два момента:

Вызов системных функций API (Application Program Interface, т.е. интерфейс программного приложения).

Возможные структуры программ для Windows. Можно выделить 3 типа структуры программ - классическая, диалоговая (основное окно — диалоговое), консольная (или безоконная)структура.

Начнем с нескольких общих положений о программировании в Windows. Те, кто уже имеет опыт программирования в среде Windows, могут на этом не останавливаться.

Программирование в Windows основывается на использовании функций API. Их количество достигает двух тысяч. Ваша программа в значительной степени будет состоять из таких вызовов. Все взаимодействие с внешними устройствами и ресурсами операционной системы будет происходить посредством таких функций.

Список функций API и их описание лучше всего брать из файла WIN32.HLP, который поставляется, например, с пакетом Borland C++.

Главным элементом программы в среде Windows является окно. Для каждого окна определяется своя процедура обработки сообщений (см. ниже).

Окно может содержать элементы управления: кнопки, списки, окна редактирования и др. Эти элементы, по сути, также являются окнами, но обладающими особыми свойствами. События, происходящие с этими элементами (и самим окном), приводят к приходу сообщений в процедуру окна.

Операционная система Windows использует линейную модель памяти. Другими словами, всю память можно рассматривать как один сегмент. Для программиста на языке ассемблера это означает, что адрес любой ячейки памяти будет определяться содержимым одного 32-битного регистра, например EBX.

Мы фактически не ограничены в объеме данных, кода или стека (объеме локальных переменных). Выделение в тексте программы сегмента кода и сегмента данных является теперь простой формальностью, улучшающей читаемость программы.

Операционная система Windows является многозадачной средой. Каждая задача имеет свое адресное пространство и свою очередь сообщений. Более того, даже в рамках одной программы может быть осуществлена многозадачность - любая процедура может быть запущена как самостоятельная задача.

Начнем с того, как можно вызвать функции API, например, MessageBox. Это ее синтаксис:

int MessageBox (HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);

Данная функция выводит на экран окно с сообщением и кнопкой (или кнопками) выхода. Для каждого аргумента определены тип (32-битные целые числа) и значение:

hWnd -дескриптор окна, в котором будет появляться окно-сообщение, тип HWND — 32-битное целое.

lpText - текст, который будет появляться в окне, тип LPCTSTR — 32-битный указатель на строку.

lpCaption - текст в заголовке окна, тип LPCTSTR — 32-битный указатель на строку.

uType - тип окна, в частности можно определить количество кнопок выхода. Тип UINT — 32-битное целое.

К имени функций нужно добавлять суффикс "А" при использовании кодировки символов ANSI, кроме того, при использовании MASM необходимо также в конце имени добавить @16. Вызов указанной функции будет выглядеть так:

CALL MessageBoxA@16.

Аргументы будут извлекаться из стека в порядке их упоминанию в функции. Чтобы это было возможно надлежит ввести в стек до вызова функции в обратном порядке.

Пример для MessageBox.

; Создать аргументы

МВ_ОК equ 0                     ; uType создать

STR1 DB "Неверный ввод! ",0; lpText создать

STR2 DB "Сообщение об ошибке.",0; lpCaption создать

HW  DWORD?                    ; hwind создать

; Поместить аргументы в стек

 

PUSH МВ_ОК                   ; uType в стек

PUSH OFFSET STR2           ; lpCaption в стек

PUSH OFFSET STR1           ; lpText в стек

PUSH HW                          ; hwind в стек

 

CALL MessageBoxA@16      ; вызов функции

Теперь обратимся к структуре всей программы.В классической структуре программы под Windows имеется главное окно, а следовательно, и процедура главного окна. В целом, в коде программы можно выделить следующие секции:

Регистрация класса окон.

Создание главного окна.

Цикл обработки очереди сообщений.

Процедура главного окна.

Регистрация класса окон. Регистрация класса окон осуществляется с помощью функции RegisterClassA, единственным параметром которой является указатель на структуру WNDCLASS, содержащую информацию об окне (см. пример ниже).

Создание окна. На основе зарегистрированного класса с помощью функции CreateWindowExA (или CreateWindowA) можно создать экземпляр окна.

Цикл обработки очереди сообщений. В нем используются функции:

GetMessage(), которая "отлавливает" очередное сообщение из ряда сообщений данного приложения и помещает его в структуру MSG.

TranslateMessage, которая используется для сообщений WM_KEYDOWN и WM_KEYUP, которые транслируются в WM_CHAR и WM_DEADCHAR,

а также WM_SYSKEYDOWN и WM_SYSKEYUP, преобразующиеся в WM_SYSCHAR и WM_SYSDEADCHAR.

Смысл трансляции заключается не в замене, а в отправке дополнительных сообщений. Так, например, при нажатии и отпускании алфавитно-цифровой клавиши в окно сначала придет сообщение WM_KEYDOWN, затем WM_KEYUP, а затем уже WM_CHAR. Выход из цикла ожиданий имеет место только в том случае, если функция GetMessage возвращает 0. Это происходит только при получении сообщения о выходе (сообщение WM_QUIT). Таким образом, цикл ожидания играет двоякую роль: определенным образом преобразуются сообщения, предназначенные для какого-либо окна, и ожидается сообщение о выходе из программы.

Процедура главного окна. Используется функция WindowFunc. Ее прототип на языке C

WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

Для каждого аргумента определены тип (32-битные целые числа) и значение:

hWnd - дескриптор окна, в котором будет появляться окно-сообщение, тип HWND — 32-битное целое.

Message – идентификатор сообщения. Тип UINT — 32-битное целое.

WPARAM – уточнение. Тип wParam — 32-битное целое.

LPARAM - уточнение. Тип lParam — 32-битное целое..

Рассмотрим "скелет" этой функции на языке ассемблера.

; Создать аргументы

МВ_ОК equ 0                            ; uType создать

STR1 DB "Неверный ввод! ",0               ; lpText создать

STR2 DB "Сообщение об ошибке.",0; lpCaption создать

HW  DWORD?                             ; hwind создать

WNDPROC PROC                             ; определение функции WndProc

PUSH EBP                                ; получить адрес вершины стека

MOV EBP, ESP                              ; теперь EBP указывает на вершину стека

; поместить в стек контекст предыдущей программы

PUSH EBX

PUSH ESI

PUSH EDI

; поместить в стек аргументы функции окна через регистр EBP

PUSH DWORD PTR [EBP+14H]            ; LPARAM (lParam) в стек

PUSH DWORD PTR [EBP+10H]            ; WPARAM (wParam) в стек

PUSH DWORD PTR [EBP+0CH]           ; MES (message) в стек

PUSH DWORD PTR [EBP+08H]            ; HWND (hwnd) в стек

CALL DefWindowProcA@16        ; вызов внешней функции окна

; вернуть из стека контекст предыдущей программы (в обратном порядке)

POP EDI

POP ESI

POP EBX

POP EBP

RET 16                                       выход из функции освобождением стека

WNDPROC ENDP                         ; конец функции WndProc

Тема 3.4 API функции

Ниже перечислены основные функции API, применяемые в ассемблере.

Функция Назначение функции
AllocConsole Создать консоль
Arc Рисовать дугу
BeginPaint Получить контекст при получении сообщения WM_PAINT
BitBlt Скопировать виртуальную прямоугольную область в окно
CallNextHookEx Продолжить выполнение других фильтров.
CallWindowProc Вызвать процедуру окна.
CharToOem Функция перекодировки строки.
CloseHandle Закрыть объект: файл, консоль, коммуникационный канал.
CreateCompatibleBitmap Создать карту бит, совместимую с заданным контекстом.
CreateCompatibleDC Создать контекст, совместимый с данным окном.
CreateDialogParam Создать немодальное диалоговое окно.
CreateEvent Создать событие.
CreateFile Создать файл, консоль, коммуникационный канал и т.п.
CreateFileMapping Создать отображаемый файл.
CreateFont Задать параметры шрифта.
CreateFontIndirect Задать параметры шрифта.
CreateMutex Создать объект синхронизации "взаимоисключение"
CreatePen Создать перо.
CreatePipe Создать канал обмена информацией.
CreateProcess Создать новый процесс.
CreateSemaphore Создать семафор.
CreateSolidBrush Определить кисть.
CreateThread Создать поток.
CreateWindow Создать окно.
CreateWindowEx Расширенное создание окна.
DefWindowProc Для сообщений, которые не обрабатываются функцией окна.
DeleteCriticalSection Удалить объект "критическая секция".
DeleteDC Удалить контекст.
DeleteObject Удалить объект, выбранный функцией SelectObject.
DestroyMenu Удалить меню из памяти.
DestroyWindow Удалить окно из памяти.
DeviceIoControl Вызов сервиса динамического виртуального драйвера.
DialogBox Создать модальное диалоговое окно.
DialogBoxParam Создать немодальное диалоговое окно.
DispatchMessage Вернуть управление Windows.
Ellipse Рисовать эллипс.
EndDialog Удалить модальное диалоговое окно.
EndPaint Удалить контекст, полученный при помощи BeginPaint.
EnterCriticalSection Войти в критическую секцию.
EnumWindows Пересчитать окна.
ExitProcess Закончить данный процесс со всеми подзадачами (потоками).
ExitThread Выход из потока с указанием кода выхода.
FindFirstFile Первый поиск файлов в каталоге.
FindNextFile Осуществить последующий поиск в каталоге.
FlushViewOfFile Сохранить отображаемый файл или его часть на диск.
FreeConsole Освободить консоль.
FreeLibrary Выгрузить динамическую библиотеку.
GetCommandLine Получить командную строку программы.
GetCursorPos Получить положение курсора в экранных координатах.
GetDC Получить контекст окна.
GetDiskFreeSpace Определяет объем свободного пространства на диске.
GetDlgItem Получить дескриптор управляющего элемента в окне.
GetDriveType Получить тип устройства.
GetLocalTime Получить местное время.
GetMenuItemInfo Получить информацию о выбранном пункте меню.
GetMessage Получить очередное сообщение из очереди сообщений.
GetModuleHandle Получить дескриптор приложения.
GetProcAddress Получить адрес процедуры (в динамической библиотеке).
GetStdHandle Получить дескриптор консоли.
GetStockObject Определить дескриптор стандартного объекта.
GetSystemDirectory Получить системный каталог.
GetSystemMetrics Определить значение системных характеристик.
GetSystemTime Получить время по Гринвичу.
GetTextExtentPoint32 Определить параметры текста в данном окне.
GetWindowRect Определить размер окна.
GetWindowsDirectory Получить каталог Windows.
GetWindowText Получить заголовок окна.
GetWindowThreadProcessId Получить идентификатор процесса.
GlobalAlloc Выделить блок памяти.
GlobalDiscard Удалить удаляемый блок памяти.
GlobalFree Освободить блок памяти.
GlobalLock Фиксировать перемещаемый блок памяти.
GlobalReAlloc Изменить размер блока памяти.
GlobalUnlock Снять фиксацию блока памяти.
InitializeCriticalSection Создать объект критическая секция.
InvalidateRect Перерисовать окно.
KillTimer Удалить таймер.
LeaveCriticalSection Покинуть критическую секцию.
LineTo Провести линию от текущей точки к заданной.
LoadAccelerators Загрузить таблицу акселераторов.
LoadCursor Загрузить системный курсор.
LoadIcon Загрузить системную иконку.
LoadLibrary Загрузить динамическую библиотеку.
LoadMenu Загрузить меню, которое определено в файле ресурсов.
LoadString Загрузить строку, определенную в файле ресурсов.
lstrcat Производит конкатенацию двух строк.
lstrcpy Скопировать одну строку в другую.
lstrlen Получить длину строки.
MapViewOfFile Скопировать файл или части файла в память.
MessageBox Выдать окно сообщения.
MoveToEx Сменить текущую точку.
MoveWindow Установить новое положение программа окна.
OpenEvent Открыть событие.
OpenSemaphore Открыть семафор.
PatBlt Заполнить заданную прямоугольную область.
Pie Рисовать сектор эллипса.
PostMessage Аналогична SendMessage, но сразу возвращает управление.
PostQuitMessage Послать текущему приложению сообщение WM_QUIT.
ReadConsole Читать из консоли.
ReadFile Читать из файла.
Rectangle Рисовать прямоугольник.
RegisterClass Зарегистрировать класс окон.
RegisterHotKey Зарегистрировать горячую клавишу.
ReleaseDC Удалить контекст, полученный при помощи GetDC
ReleaseSemaphore Освободить семафор
ResetEvent Сбросить событие
ResumeThread Запустить "спящий" процесс.
RoundRect Рисовать прямоугольник с округленными углами.
RtlMoveMemory Копировать блок памяти в другой блок.
SelectObject Выбрать объект (перо, кисть) в указанном контексте.
SendDlgItemMessage Послать сообщение управляющему элементу окна.
SendMessage Послать сообщение окну.
SetBkColor Установить цвет фона для вывода текста.
SetConsoleCursorPosition Установить курсор в заданную позицию в консоли.
SetConsoleScreenBufferSize Установить размер буфера консоли.
SetConsoleTextAttribute Установить цвет текста в консоли.
SetConsoleTitle Установить название окна консоли.
SetEvent Подать сигнал о наступлении события.
SetFocus Установить фокус на заданное окно.
SetLocalTime Установить время и дату.
SetMapMode Соотношение между логическими единицами и пикселями.
SetMenu Назначить новое меню данному окну.
SetPixel Установить заданный цвет пикселя.
SetSystemTime Установить время, используя гринвичские координаты.
SetTextColor Установить цвет текста.
SetTimer Установить таймер.
SetViewportExtEx Установить область вывода.
SetViewportOrgEx Установить начало области вывода.
SetWindowLong Изменить атрибут уже созданного окна.
SetWindowsHookEx Установить процедуру-фильтр.
Shell_NotifyIcon Поместить иконку приложения на системную панель.
SHFileOperation Групповая операция над файлами и каталогами.
SHGetDesktopFolder Выводит диалоговое окно для выбора каталогов и файлов.
ShowWindow Показать окно, установить статус показа.
Sleep Вызывает задержку.
TerminateProcess Уничтожить процесс.
TerminateThread Удалить поток.
TextOut Вывести текст в окно.
timeKillEvent Удалить таймер.
timeSetEvent Установить таймер.
TranslateAccelerator Транслирует акселераторные клавиши в команду выбора.
TranslateMessage Транслировать клавиатурные сообщения в ASCII-коды.
UnhookWindowsHookEx Снять процедуру-фильтр.
UnmapViewOfFile Сделать указатель на файл недействительным.
UnregisterHotKey Снять регистрацию горячей клавиши.
UpdateWindow Обновить рабочую область окна.
VirtualAlloc Зарезервировать блок виртуальной памяти.
VirtualFree Снять резервирование с блока виртуальной памяти.
WaitForSingleObject Ожидает одно из двух событий.
WNetAddConnection2 Соединение с сетевым ресурсом локальной сети.
WNetCancelConnection2 Отсоединить от ресурса локальной сети.
WNetCloseEnum Найти все ресурсы локальной сети данного уровня.
WNetGetConnection Получить информацию о данном соединении.
WNetOpenEnum Открыть поиск ресурсов в локальной сети.
WriteConsole Вывод в консоль.
wsprintf Преобразовать последовательность параметров в строку.

Сообщения Windows

Ниже перечислены основные cообщения Windows, применяемые в ассемблере.

Сообщение системы Назначение
WM_ACTIVATE Посылается функции окна перед активизацией окна.
WM_CLOSE Сообщение, приходящее на процедуру окна при его закрытии.
WM_COMMAND Сообщение, приходящее при наступлении.
WM_CREATE Первое сообщение, приходящее на функцию окна при создании.
WM_DEADCHAR Сообщение, возникающее при трансляции сообщения.
WM_DESTROY Сообщение, приходящее на функцию окна при уничтожении.
WM_GETTEXT Посылается окну для получения текстовой строки.
WM_HOTKEY Генерируется при нажатии горячей клавиши.
WM_KEYDOWN Сообщение, генерируемое при нажатии клавиши клавиатуры.
WM_KEYUP Сообщение, генерируемое при отпускании клавиши клавиатуры.
WM_LBUTTONDOWN Сообщение генерируется при нажатии левой кнопки мыши.
WM_MENUSELECT Посылается окну, содержащему меню, при выборе пункта меню.
WM_PAINT Сообщение посылается окну перед его перерисовкой.
WM_RBUTTONDOWN Сообщение генерируется при нажатии правой кнопки мыши.
WM_SETFOCUS Сообщение, посылаемое окну, после получения фокуса.
WM_SETTEXT Сообщение для посылки текстовой строки.
WM_SIZE Посылается функции окна после изменения его размера.
WM_SYSCOMMAND Генерируется при выборе пунктов меню.
WM_SYSDEADCHAR Сообщение, возникающее при трансляции сообщения.
WM_TIMER Сообщение, приходящее после определения интервала таймера.

Тема 3.5 Версии ассемблеров



Поделиться:


Последнее изменение этой страницы: 2021-02-07; просмотров: 149; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.218.215 (0.034 с.)