- •Введение
- •1. Лабораторная работа № 1
- •1.1. Цель работы
- •1.2. Теоретическое введение
- •1.2.1. Получение информации об операционной системе
- •1.2.2. Получение информации из реестра
- •1.2.3. Получение информации о системных каталогах Windows
- •1.2.4. Получение информации о диске
- •1.3. Создание приложения для получения характеристик компьютера и операционной системы
- •Контрольные вопросы
- •2. Лабораторная работа №2
- •2.1.Цель работы
- •2.2. Теоретическое введение
- •2.2.1. Процедуры и функции для работы с виртуальной памятью
- •2.3. Создание приложения, работающего с виртуальной памятью
- •2.4. Задание для самостоятельной работы
- •Контрольные вопросы
- •3. Лабораторная работа № 3
- •3.1. Цель работы
- •3.2. Пример использования механизма выделения виртуальной памяти для решения конкретных задач
- •3.3. Задания для самостоятельной работы
- •Контрольные вопросы
- •4. Лабораторная работа № 4
- •4.1. Цель работы
- •4. 2. Теоретическое введение
- •4.2.1 Создание или открытие объекта ядра «файла»
- •4.2.2 Создание объекта ядра «файл, проецируемый в память»
- •4.2.3 Проецирование файловых данных на адресное пространство процесса
- •4.2.4 Отмена проецирования на адресное пространство процесса объекта ядра «файл, проецируемый в память»
- •4.2.5 Закрытие объектов ядра «файл, проецируемый в память» и «файл»
- •4.3 Примеры программ, выполняющих проецирование в память
- •4.3.1 Пример 1
- •4.3.2 Пример 2
- •4.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •5. Лабораторная работа № 5
- •5.1.Цель работы
- •5.2. Теоретическое введение
- •5.2.1. Создание процесса
- •5.2.2. Запуск внешней программы функцией WinExec
- •5.2.3. Запуск внешней программы и открытие документа функцией ShellExecute
- •При успешном выполнении функция ShellExecute возвращает целое значение, большее 32. Значение меньшее или равное 32 указывает на ошибку. Значения эти те же, что и для функции WinExec.
- •5.2.4. Создание потока
- •5.2.5. Завершение процесса
- •5.2.6. Завершение потока
- •5.2.7. Изменение класса приоритета процесса
- •5.2.8. Получение информации о классе приоритета процесса
- •5.2.9. Изменение уровня приоритета потока
- •5.2.10. Получение информации о приоритете потока
- •5.3. Примеры программ для работы с процессами и потоками
- •5.3.1. Создание процесса с помощью функции CreateProcess.
- •5.3.2. Создание процесса с помощью функции WinExec.
- •5.3.3. Создание процесса с помощью функции ShellExecute.
- •5.3.4. Создание многопоточного приложения.
- •5.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •6. Лабораторная работа № 6
- •6.1. Цель работы
- •6.2. Теоретическое введение
- •6.2.1. Получение «мгновенного снимка» системы
- •6.2.2. Получение информации о процессах
- •6.2.3. Получение информации о потоках
- •6.2.4. Получение информации о модулях
- •6.2.5. Информация о кучах (heap)
- •6.2.6. Информация о виртуальной памяти.
- •6.2.7. Алгоритм работы функций ToolHelp
- •6.2.8. Как получить карту памяти любого процесса
- •6.3. Пример использования функций ToolHelp
- •6.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •7. Лабораторная работа № 7
- •7.1. Цель работы
- •7.2. Теоретическое введение
- •7.2.1. Критические секции
- •7.2.2. Синхронизация с использованием объектов ядра
- •7.2.3. Wait-функции
- •7.2.4. Синхронизация с использованием процессов и потоков
- •7.2.5. Объекты Mutex
- •7.2.6. Семафоры
- •7.2.7. События
- •7.3 Примеры работы с объектами синхронизации
- •7.3.1 Пример 1
- •7.3.1 Пример 2
- •7.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •8. Лабораторная работа № 8
- •8.1. Цель работы
- •8.2 Теоретическое введение
- •8.2.1 Создание dll
- •8.2.2 Неявная загрузка dll
- •8.2.3 Явная загрузка dll
- •8.2.4 Внедрение dll в адресное пространство другого процесса
- •8.3 Пример работы с dll
- •8.3.1 Создание dll, которая выполняет перехват нажатых клавиш
- •8.3.2 Разработка приложения, которое выполняет анализ и обработку нажатых клавиш.
- •8.4 Индивидуальные задания
- •Контрольные вопросы
- •9.2.2. Функции для работы с объектом «уведомление об изменении файловой системы»
- •9.3. Пример работы системы уведомления об изменениях в файловой системе
- •9.4. Задания для самостоятельной работы
- •Контрольные вопросы
- •Литература
- •214013 Г. Смоленск, Энергетический проезд, 1
Контрольные вопросы
С помощью какой функции можно получить информации о версии ОС?
Как получить информации о логическом диске?
С помощью какого объекта Delphi возможен программный доступ к реестру?
Как получить информацию о системных каталогах Windows?
Поясните различие между ассемблерными командами SUB и SBB.
2. Лабораторная работа №2
ИССЛЕДОВАНИЕ ВИРТУАЛЬНОЙ ПАМЯТИ
2.1.Цель работы
Целью работы является изучение основных функций ядра Kernel32.dll для работы с виртуальной памятью. Рассматриваемые в данной лабораторной работе функции позволяют:
получить информацию о состоянии системной памяти и виртуального адресного пространства любого процесса;
напрямую резервировать регион адресного пространства;
передавать зарезервированному региону физическую память;
освобождать регионы адресного пространства;
изменять атрибуты защиты страниц виртуальной памяти.
2.2. Теоретическое введение
2.2.1. Процедуры и функции для работы с виртуальной памятью
Процедура GetSystemInfo – получение системной информации.
Процедура имеет следующий вид:
procedure GetSystemInfo(var lpSystemInfo: TSystemInfo); stdcall;
При вызовы данная процедура работает со структурой SYSTEM_INFO
Структура SYSTEM_INFO имеет следующий вид
_SYSTEM_INFO = record
case Integer of
0: (
dwOemId: DWORD);
1: ( wProcessorArchitecture: Word; wReserved: Word;
dwPageSize: DWORD; lpMinimumApplicationAddress: Pointer;
lpMaximumApplicationAddress: Pointer;
dwActiveProcessorMask: DWORD; dwNumberOfProcessors: DWORD;
dwProcessorType: DWORD; dwAllocationGranularity: DWORD;
wProcessorLevel: Word; wProcessorRevision: Word);
end;
Описание полей структуры SYSTEM_INFO приведено в таблице 2.1.
Таблица 2.1 Описание полей структуры SYSTEM_INFO
Наименование поля |
Описание |
1 |
2 |
wProcessorArchitecture |
Используется начиная с Windows 2000; сообщает тип архитектуры процессора, например, Intel 386, 486 или Pentium |
wReserved |
Зарезервировано, пока не используется |
dwPageSize |
Размер страницы памяти. На процессорах x86 это значение равно 4096, а на процессорах Alpha – 8192 байта. |
1 |
2 |
lpMinimumApplicationAddress |
Минимальный адрес памяти доступного адресного пространства. В Windows 98 это значение равно – 4 194 304 (или 0х 00400000), поскольку нижние 4 Мб адресного пространства каждого процесса недоступны. В Windows 2000 и выше это значение равно 65 536 (или 0х00010000), так как в этой системе резервируются только первые 64 Кб адресного пространства каждого процесса. |
lpMaximumApplicationAddress |
Максимальный адрес памяти доступного адресного пространства, отведенного в «лмчное пользование» каждому процессу. В Windows 98 этот адрес равен – 2 147 483 647 (или 0х7FFFFFFF), так как верхние 2 Гб занимают общие файлы, проецируемые в память и разделяемый код операционной системы. В Windows 2000 и выше этот адрес соответствует началу раздела для кода и данных режима ядра за вычетом 64 Кб. |
dwActiveProcessorMask |
Битовая маска, которая сообщает, какие процессоры активны |
dwNumberOfProcessors |
Число процессоров в компьютере |
dwProcessorType |
Используется только в Windows 98; сообщает тип процессора, например, Intel 386, 486 или Pentium |
dwAllocationGranularity |
Гранулярность резервирования регионов адресного пространства. В настоящий момент равно 64Кб для всех платформ Windows. |
Продолжение таблицы 2.1
1 |
2 |
wProcessorLevel |
Используется только в Windows 2000 и выше. Сообщает дополнительные подробности об архитектуре процессора. Например, Intel Pentium Pro или Pentium II. |
wProcessorRevision |
Используется только в Windows 2000 и выше. Сообщает дополнительные подробности об уровне данной архитектуры процессора. |
Процедура GlobalMemoryStatus – отслеживает текущее состояние памяти
Процедура имеет следующий вид:
procedure GlobalMemoryStatus(var lpBuffer: TMemoryStatus); stdcall;
Результат работы данной процедуры заносится в структуру MEMORYSTATUS, которая имеет следующий вид:
_MEMORYSTATUS = record
dwLength: DWORD; dwMemoryLoad: DWORD; dwTotalPhys: DWORD; dwAvailPhys: DWORD;
dwTotalPageFile: DWORD; dwAvailPageFile: DWORD; dwTotalVirtual: DWORD; dwAvailVirtual: DWORD;
end;
Описание полей структуры MEMORYSTATUS приведены в таблице 2.2.
Таблица 2.2 Описание полей структуры MEMORYSTATUS
Наименование поля |
Описание |
dwLength |
Перед вызовом процедуры GlobalMemoryStatus в это поле надо записать размер структуры в байтах. |
dwMemoryLoad |
Примерная оценка занятости системы управления памятью. Это число может принимать значения в диапазоне от 0 до 100. |
dwTotalPhys |
Общий размер физической памяти в байтах |
dwAvailPhys |
Общее количество байт физической памяти, доступной для выделения. |
dwTotalPageFile |
Максимальное количество байтов, которое может содержаться в страничном файле на жестком диске. |
dwAvailPageFile |
Показывает количество байт памяти из страничного файла, которое может быть передано любому процессу. |
dwTotalVirtual |
Количество байт в адресном пространстве, принадлежащих «лично» данному процессу. |
dwAvailVirtual |
Суммарный размер всех свободных регионов в адресном пространстве вызывающего данную функцию процесса. |
Функция VirtualQuery – вывод информации об участке памяти по заданному адресу.
Функция имеет следующий вид:
function VirtualQuery(lpAddress: Pointer; var lpBuffer: MemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
Параметры данной функции приведены в таблице 2.3
Таблица 2.3 Параметры функции VirtualQuery
Наименование параметра |
Описание |
lpAddress |
Адрес виртуально памяти, о котором следует получить информацию |
lpBuffer |
Адрес структуры MEMORY_BASIC_INFORMATION |
dwLength |
Размер структуры MEMORY_BASIC_INFORMATION |
При вызове данная функция заполняет структуру MEMORY_BASIC_INFORMATION, которая состоит из следующих полей:
_MEMORY_BASIC_INFORMATION = record
BaseAddress : Pointer; AllocationBase : Pointer;
AllocationProtect : DWORD; RegionSize : DWORD;
State : DWORD; Protect : DWORD; Type : DWORD;
end;
Описание полей структуры MEMORY_BASIC_INFORMATION приведены в таблице 2.4.
Функция VirtualQuery возвращает количество байт, записываемых в структуру MEMORY_BASIC_INFORMATION.
Таблица 2.4 Описание полей структуры MEMORY_BASIC_INFORMATION
Наименование поля |
Описание |
1 |
2 |
BaseAddress |
Сообщает то же значение, что и параметр lpAddress, но округленное до ближайшего меньшего адреса, кратного размеру страницы |
AllocationBase |
Идентифицирует базовый адрес региона, включающего в себя адрес, указанный в параметре lpAddress |
AllocationProtect |
Идентифицирует атрибут защиты, присвоенный региону при его резервировании |
RegionSize |
Сообщает суммарный размер (в байтах) группы страниц, которые начинаются с базового адреса BaseAddress и имеют те же атрибуты защиты, состояние и тип, что и страница, расположенная по адресу, указанному в параметре lpAddress |
Продолжение таблицы 2.4
1 |
2 |
State |
Сообщает состояние (MEM_FREE, MEM_RESERVE или MEM_COMMIT) всех смежных страниц, которые имеют те же атрибуты защиты, состояние и тип, что и страница, расположенная по адресу, указанному в параметре lpAddress |
Protect |
Идентифицирует атрибут защиты (PAGE_*) всех смежных страниц, которые имеют те же атрибуты защиты, состояние и тип, что и страница, располо-женная по адресу, указанному в параметре lpAddress |
Type |
Идентифицирует тип физической памяти, (MEM_IMAGE, MEM_MAPPED или MEM_PRIVATE), связанной с группой смежных страниц, которые имеют те же атрибуты защиты, состояние и тип, что и страница, расположенная по адресу, указанному в параметре lpAddress. Подробное описание возможных типов физической памяти приведено в таблице 2.5. |
Таблица 2.5 Описание типов физической памяти
Наименование типа |
Описание |
MEM_PRIVATE |
Этот диапазон виртуальных адресов сопоставлен со страничным файлом. |
MEM_IMAGE |
Этот диапазон виртуальных адресов первоначально был сопоставлен с образом EXE- или DLL-файла, проецируемого в память, но в настоящий момент возможно уже нет. Например, при записи в глобальную переменную механизм поддержки «копирования при записи» выделяет соответствующую страницу памяти из страничного файла. |
MEM_MAPPED |
Этот диапазон виртуальных адресов первоначально был сопоставлен с файлом данных, проецируемым в память, но в настоящий момент возможно уже нет. Например, файл данных мог быть спроецирован с использованием механизма поддержки «копирования при записи». Любые операции записи в этот файл приведут к тому, что соответствующие страницы памяти будут выделены из страничного файла, а не из исходного файла данных. |
Для просмотра информации о памяти в любом другом процессе используется функция VirtualQueryEx:
function VirtualQueryEx(hProcess: THandle; lpAddress: Pointer; var lpBuffer: TMemoryBasicInformation; dwLength: DWORD): DWORD; stdcall;
Функция VirtualQueryEx отличается от парной функции VirtualQuery наличием параметра hProcess, который представляет собой дескриптор того процесса, информацию о памяти которого требуется получить. Алгоритм определения дескриптора любого процесса будет рассмотрен в лабораторной работе № 6.
Функция VirtualAlloc – резервирование региона в адресном пространстве
Функция имеет следующий вид:
function VirtualAlloc(lpvAddress: Pointer; dwSize, flAllocationType, flProtect: DWORD): Pointer; stdcall;
Параметры данной функции приведены в таблице 2.6
Таблица 2.6 Параметры функции VirtualAlloc
Наименование параметра |
Описание |
lpvAddress |
Адрес памяти, указывающий, где именно система должна зарезервировать адресное пространство. Если в качестве этого параметра указать nil, то операционная система сама выберет адрес резервируемого региона в адресном пространстве данного процесса. |
dwSize |
Размер резервируемого региона в байтах |
flAllocationType |
Сообщает системе, что необходимо сделать (зарезервировать регион или передать физическую память региону). Если требуется только зарезервировать регион без передачи ему физической памяти указывается ключ MEM_RESERVE. Для передачи физической памяти региону указывается ключ MEM_COMMIT. |
flProtect |
Атрибут защиты, присваиваемый региону |
Список атрибуты защиты региона приведен в таблице 2.7.
Таблица 2.7 Атрибуты защиты страниц виртуальной памяти
Наименование атрибута |
Описание |
1 |
2 |
PAGE_NOACCESS |
Попытка чтения, записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа |
PAGE_READONLY |
Попытка записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа |
Продолжение таблицы 2.7
1 |
2 |
PAGE_READWRITE |
Попытка исполнения содержимого памяти на этой странице вызывают нарушение доступа |
PAGE_EXECUTE |
Попытка чтения или записи на этой странице вызывают нарушение доступа |
PAGE_EXECUTE_READ |
Попытка записи на этой странице вызывают нарушение доступа |
PAGE_EXECUTE_READWRITE |
На этой странице возможны любые операции |
PAGE_WRITECOPY |
Попытка исполнения содержимого памяти на этой странице вызывают нарушение доступа. Попытка записи приводит к тому, что процессу предоставляется личная копия данной страницы |
PAGE_EXECUTE_WRITECOPY |
На этой странице возможны любые операции Попытка записи приводит к тому, что процессу предоставляется личная копия данной страницы. |
Функция VirtualAlloc возвращает виртуальный адрес региона. Если операционная система не сумеет найти в адресном пространстве подходящую область или не сумеет передать ей физическую память, то функция возвращает nil.
Функция VirtualFree – возврат физической памяти и освобождение региона
Функция имеет следующий вид:
function VirtualFree(lpAddress: Pointer; dwSize, dwFreeType: DWORD): BOOL; stdcall;
Параметры данной функции приведены в таблице 2.8
Таблица 2.8 Параметры функции VirtualFree
Наименование параметра |
Описание |
lpvAddress |
Базовый адрес региона. |
dwSize |
Размер региона в байтах |
dwFreeType |
Сообщает системе, что необходимо сделать: MEM_RELEASE – возврат системе все физической памяти, отображенной на регион и освобождение самого региона MEM_DECOMMIT – возвращает системе физическую память, переданную региону, не освобождая самого региона. |
При успешном выполнении данная функция возвращает значение TRUE, в случае ошибки возвращается значении – FALSE.
Функция VirtualProtect – изменение атрибутов защиты
Функция имеет следующий вид:
function VirtualProtect(lpAddress: Pointer; dwSize, flNewProtect: DWORD; lpflOldProtect: Pointer): BOOL; stdcall;
Параметры данной функции приведены в таблице 2.9
Таблица 2.9 Параметры функции VirtualProtect
Наименование параметра |
Описание |
lpvAddress |
Базовый адрес памяти. |
dwSize |
Число байтов, для которых изменяется атрибут защиты |
flNewProtect |
Один из идентификаторов PAGE_*, приведенных в таблице 2.7. |
lpflOldProtect |
Адрес переменной типа DWORD, в которую функция VirtualProtec заносит старое значение атрибута защиты для данной области памяти |
При успешном выполнении данная функция возвращает значение TRUE, в случае ошибки возвращается значении – FALSE.