- •WINDOWS
- •Джеффри Рихтер
- •ЧАCTЬ I МАТЕРИАЛЫ ДЛЯ ОБЯЗАТЕЛЬНОГО ЧТЕНИЯ
- •ГЛАВА 1. Обработка ошибок
- •Вы тоже можете это сделать
- •Программа-пример ErrorShow
- •ГЛАВА 2 Unicode
- •Наборы символов
- •Одно- и двухбайтовые наборы символов
- •Unicode: набор широких символов
- •Почему Unicode?
- •Windows 2000 и Unicode
- •Windows 98 и Unicode
- •Windows CE и Unicode
- •В чью пользу счет?
- •Unicode и СОМ
- •Как писать программу с использованием Unicode
- •Unicode и библиотека С
- •Типы данных, определенные в Windows для Unicode
- •Unicode- и ANSI-функции в Windows
- •Строковые функции Windows
- •Ресурсы
- •Текстовые файлы
- •Перекодировка строк из Unicode в ANSI и обратно
- •ГЛАВА 3 Объекты ядра
- •Что такое объект ядра
- •Учет пользователей объектов ядра
- •Защита
- •Таблица описателей объектов ядра
- •Создание объекта ядра
- •Закрытие объекта ядра
- •Совместное использование объектов ядра несколькими процессами
- •Наследование описателя объекта
- •Изменение флагов описателя
- •Именованные объекты
- •Пространства имен Terminal Server
- •Дублирование описателей объектов
- •ЧАСТЬ II НАЧИНАЕМ РАБОТАТЬ
- •ГЛАВА 4 Процессы
- •Ваше первое Windows-приложение
- •Описатель экземпляра процесса
- •Описатель предыдущего экземпляра процесса
- •Командная строка процесса
- •Переменные окружения
- •Привязка к процессорам
- •Режим обработки ошибок
- •Текущие диск и каталог для процесса
- •Текущие каталоги для процесса
- •Определение версии системы
- •Функция CreateProcess
- •Параметры pszApplicationName и pszCommandLine
- •Параметры psaProcess, psaThread и blnheritHandles
- •Параметр fdwCreate
- •Параметр pvEnvironment
- •Параметр pszCurDir
- •Параметр psiStartlnfo
- •Параметр ppiProclnfo
- •Завершение процесса
- •Возврат управления входной функцией первичного потока
- •Функция ExitProcess
- •Функция TerminateProcess
- •Когда все потоки процесса уходят
- •Что происходит при завершении процесса
- •Дочерние процессы
- •Запуск обособленных дочерних процессов
- •Перечисление процессов, выполняемых в системе
- •Программа-пример Processlnfo
- •ГЛАВА 5 Задания
- •Определение ограничений, налагаемых на процессы в задании
- •Включение процесса в задание
- •Завершение всех процессов в задании
- •Получение статистической информации о задании
- •Уведомления заданий
- •Программа-пример JobLab
- •ГЛАВА 6 Базовые сведения о потоках
- •В каких случаях потоки создаются
- •И в каких случаях потоки не создаются
- •Ваша первая функция потока
- •Функция CreateThread
- •Параметр psa
- •Параметр cbStack
- •Параметры pfnStartAddr и pvParam
- •Параметр fdwCreate
- •Параметр pdwThreadlD
- •Завершение потока
- •Возврат управления функцией потока
- •Функция ExitThread
- •Функция TerminateThread
- •Если завершается процесс
- •Что происходит при завершении потока
- •Кое-что о внутреннем устройстве потока
- •Некоторые соображения по библиотеке С/С++
- •Ой, вместо _beginthreadex я по ошибке вызвал CreateThread
- •Библиотечные функции, которые лучше не вызывать
- •Как узнать о себе
- •Преобразование псевдоописателя в настоящий описатель
- •ГЛАВА 7 Планирование потоков, приоритет и привязка к процессорам
- •Приостановка и возобновление потоков
- •Приостановка и возобновление процессов
- •Функция Sleep
- •Переключение потоков
- •Определение периодов выполнения потока
- •Структура CONTEXT
- •Приоритеты потоков
- •Абстрагирование приоритетов
- •Программирование приоритетов
- •Динамическое изменение уровня приоритета потока
- •Подстройка планировщика для активного процесса
- •Программа-пример Scheduling Lab
- •Привязка потоков к процессорам
- •ГЛАВА 8 Синхронизация потоков в пользовательском режиме
- •Кэш-линии
- •Более сложные методы синхронизации потоков
- •Худшее, что можно сделать
- •Критические секции
- •Критические секции: важное дополнение
- •Критические секции и спин-блокировка
- •Критические секции и обработка ошибок
- •Несколько полезных приемов
- •Не занимайте критические секции надолго
- •ГЛАВА 9 Синхронизация потоков с использованием объектов ядра
- •Wait-функции
- •Побочные эффекты успешного ожидания
- •События
- •Программа-пример Handshake
- •Ожидаемые таймеры
- •Ожидаемые таймеры и АРС-очередь
- •И еще кое-что о таймерах
- •Семафоры
- •Мьютексы
- •Отказ от объекта-мьютекса
- •Мьютексы и критические секции
- •Программа-пример Queue
- •Сводная таблица объектов, используемых для синхронизации потоков
- •Другие функции, применяемые в синхронизации потоков
- •Асинхронный ввод-вывод на устройствах
- •Функция WaitForlnputldle
- •Функция MsgWaitForMultipleObjects(Ex)
- •Функция WaitForDebugEvent
- •Функция SignalObjectAndWait
- •ГЛАВА 10 Полезные средства для синхронизации потоков
- •Реализация критической секции: объект-оптекс
- •Программа-пример Optex
- •Создание инверсных семафоров и типов данных, безопасных в многопоточной среде
- •Программа-пример lnterlockedType
- •Синхронизация в сценарии "один писатель/группа читателей"
- •Программа-пример SWMRG
- •Реализация функции WaitForMultipleExpressions
- •Программа-пример WaitForMultExp
- •ГЛАВА 11 Пулы потоков
- •Сценарий 1: асинхронный вызов функций
- •Сценарий 2: вызов функций через определенные интервалы времени
- •Программа-пример TimedMsgBox
- •Сценарий 3: вызов функций при освобождении отдельных объектов ядра
- •Сценарий 4; вызов функций по завершении запросов на асинхронный ввод-вывод
- •ГЛАВА 12 Волокна
- •Работа с волокнами
- •Программа-пример Counter
- •ЧАСТЬ III УПРАВЛЕНИЕ ПАМЯТЬЮ
- •Виртуальное адресное пространство процесса
- •Как адресное пространство разбивается на разделы
- •Увеличение раздела для кода и данных пользовательского режима до 3 Гб на процессорах x86 (только Windows 2000)
- •Закрытый раздел размером 64 Кб (только Windows 2000)
- •Раздел для общих MMF (только Windows 98)
- •Регионы в адресном пространстве
- •Передача региону физической памяти
- •Физическая память и страничный файл
- •Физическая память в страничном файле не хранится
- •Атрибуты защиты
- •Защита типа «копирование при записи»
- •Специальные флаги атрибутов защиты
- •Подводя итоги
- •Блоки внутри регионов
- •Особенности адресного пространства в Windows 98
- •Выравнивание данных
- •ГЛАВА 14 Исследование виртуальной памяти
- •Системная информация
- •Программа-пример Syslnfo
- •Статус виртуальной памяти
- •Программа-пример VMStat
- •Определение состояния адресного пространства
- •Функция VMQuery
- •Программа-пример VMMap
- •ГЛАВА 15 Использование виртуальной памяти в приложениях
- •Резервирование региона в адресном пространстве
- •Передача памяти зарезервированному региону
- •Резервирование региона с одновременной передачей физической памяти
- •В какой момент региону передают физическую память
- •Возврат физической памяти и освобождение региона
- •В какой момент физическую память возвращают системе
- •Программа-пример VMAIloc
- •Изменение атрибутов защиты
- •Сброс содержимого физической памяти
- •Программа-пример MemReset
- •Механизм Address Windowing Extensions (только Windows 2000)
- •Программа-пример AWE
- •ГЛАВА 16 Стек потока
- •Стек потока в Windows 98
- •Функция из библиотеки С/С++ для контроля стека
- •Программа-пример Summation
- •ГЛАВА 17 Проецируемые в память файлы
- •Проецирование в память EXE- и DLL-файлов
- •Статические данные не разделяются несколькими экземплярами EXE или DLL
- •Программа-пример Applnst
- •Файлы данных, проецируемые в память
- •Метод 1: один файл, один буфер
- •Метод 2: два файла, один буфер
- •Метод 3: один файл, два буфера
- •Метод 4: один файл и никаких буферов
- •Использование проецируемых в память файлов
- •Этап1: создание или открытие объекта ядра «файл»
- •Этап 2: создание объекта ядра «проекция файла»
- •Этап 3: проецирование файловых данных на адресное пространство процесса
- •Этап 4: отключение файла данных от адресного пространства процесса
- •Этапы 5 и 6: закрытие объектов «проекция файла» и «файл»
- •Программа-пример FileRev
- •Обработка больших файлов
- •Проецируемые файлы и когерентность
- •Базовый адрес файла, проецируемого в память
- •Особенности проецирования файлов на разных платформах
- •Совместный доступ процессов к данным через механизм проецирования
- •Файлы, проецируемые на физическую память из страничного файла
- •Программа-пример MMFShare
- •Частичная передача физической памяти проецируемым файлам
- •Программа-пример MMFSparse
- •ГЛАВА 18 Динамически распределяемая память
- •Стандартная куча процесса
- •Дополнительные кучи в процессе
- •Защита компонентов
- •Более эффективное управление памятью
- •Локальный доступ
- •Исключение издержек, связанных с синхронизацией потоков
- •Быстрое освобождение всей памяти в куче
- •Создание дополнительной кучи
- •Выделение блока памяти из кучи
- •Изменение размера блока
- •Определение размера блока
- •Освобождение блока
- •Уничтожение кучи
- •Использование куч в программах на С++
- •Другие функции управления кучами
- •ЧАСТЬ IV ДИНАМИЧЕСКИ ПОДКЛЮЧАЕМЫЕ БИБЛИОТЕКИ
- •ГЛАВА 19 DLL: основы
- •DLL и адресное пространство процесса
- •Общая картина
- •Создание DLL-модуля
- •Что такое экспорт
- •Создание DLL для использования с другими средствами разработки (отличными от Visual C++)
- •Создание ЕХЕ-модуля
- •Что такое импорт
- •Выполнение ЕХЕ-модуля
- •ГЛАВА 20 DLL: более сложные методы программирования
- •Явная загрузка DLL и связывание идентификаторов
- •Явная загрузка DLL
- •Явная выгрузка DLL
- •Явное подключение экспортируемого идентификатора
- •Функция входа/выхода
- •Уведомление DLL_PROCESS_ATTACH
- •Уведомление DLL_PROCESS_DETACH
- •Уведомление DLL_THREAD_ATTACH
- •Уведомление DLL_THREAD_DETACH
- •Как система упорядочивает вызовы DIIMain
- •Функция DllMain и библиотека С/С++
- •Отложенная загрузка DLL
- •Программа-пример DelayLoadApp
- •Переадресация вызовов функций
- •Известные DLL
- •Перенаправление DLL
- •Модификация базовых адресов модулей
- •Связывание модулей
- •ГЛАВА 21 Локальная память потока
- •Динамическая локальная память потока
- •Использование динамической TLS
- •Статическая локальная память потока
- •Пример внедрения DLL
- •Внедрение DLL c использованием реестра
- •Внедрение DLL с помощью ловушек
- •Утилита для сохранения позиций элементов на рабочем столе
- •Внедрение DLL с помощью удаленных потоков
- •Программа-пример lnjLib
- •Библиотека lmgWalk.dll
- •Внедрение троянской DLL
- •Внедрение DLL как отладчика
- •Внедрение кода в среде Windows 98 через проецируемый в память файл
- •Внедрение кода через функцию CreateProcess
- •Перехват API-вызовов: пример
- •Перехват API-вызовов подменой кода
- •Перехват API-вызовов с использованием раздела импорта
- •Программа-пример LastMsgBoxlnfo
- •ЧАСТЬ V СТРУКТУРНАЯ ОБРАБОТКА ИСКЛЮЧЕНИЙ
- •ГЛАВА 23 Обработчики завершения
- •Примеры использования обработчиков завершения
- •Funcenstein1
- •Funcenstein2
- •Funcenstein3
- •Funcfurter1
- •Проверьте себя: FuncaDoodleDoo
- •Funcenstein4
- •Funcarama1
- •Funcarama2
- •Funcarama3
- •Funcarama4: последний рубеж
- •И еще о блоке finally
- •Funcfurter2
- •Программа-пример SEHTerm
- •ГЛАВА 24 Фильтры и обработчики исключений
- •Примеры использования фильтров и обработчиков исключений
- •Funcmeister1
- •Funcmeister2
- •EXCEPTION_EXECUTE_HANDLER
- •Некоторые полезные примеры
- •Глобальная раскрутка
- •Остановка глобальной раскрутки
- •EXCEPTION_CONTINUE_EXECUTION
- •Будьте осторожны с EXCEPTION_CONTINUE_EXECUTION
- •EXCEPTION_CONTINUE_SEARCH
- •Функция GetExceptionCode
- •Функция GetExceptionlnformation
- •Программные исключения
- •ГЛАВА 25 Необработанные исключения и исключения С++
- •Отладка по запросу
- •Отключение вывода сообщений об исключении
- •Принудительное завершение процесса
- •Создание оболочки вокруг функции потока
- •Создание оболочки вокруг всех функций потоков
- •Автоматический вызов отладчика
- •Явный вызов функции UnhandledExceptionFilter
- •Функция UnhandledExceptionFilter изнутри
- •Исключения и отладчик
- •Программа-пример Spreadsheet
- •Исключения С++ и структурные исключения
- •Перехват структурных исключений в С++
- •ЧАСТЬ VI ОПЕРАЦИИ С ОКНАМИ
- •ГЛАВА 26 Оконные сообщения
- •Очередь сообщений потока
- •Посылка асинхронных сообщений в очередь потока
- •Посылка синхронных сообщений окну
- •Пробуждение потока
- •Флаги состояния очереди
- •Алгоритм выборки сообщений из очереди потока
- •Пробуждение потока с использованием объектов ядра или флагов состояния очереди
- •Передача данных через сообщения
- •Программа-пример CopyData
- •ГЛАВА 27 Модель аппаратного ввода и локальное состояние ввода
- •Поток необработанного ввода
- •Локальное состояние ввода
- •Ввод с клавиатуры и фокус
- •Управление курсором мыши
- •Подключение к очередям виртуального ввода и переменным локального состояния ввода
- •Программа-пример LISLab
- •Программа-пример LISWatch
Кроме того, при резервировании адресного пространства или передаче физической памяти через VirtualAlloc нельзя указывать атрибуты PAGE_WRITECOPY или
PAGE_EXECUTE_WRITECOPY. Иначе вызов VirtucuAlloc даст ошибку, a GetLastError
вернет код ERROR_INVALID_PARAMETER Дело в том, что эти два атрибута используются операционной системой, только когда она проецирует образы EXEили DLL-файлов
WINDOWS 98
Windows 98 не поддерживает «копирование при записи" Обнаружив запрос на применение такой защиты, Windows 98 тут же делает копии данных, не дожидаясь попытки записи в память.
Специальные флаги атрибутов защиты
Кроме рассмотренных атрибутов защиты, существует три флага атрибутов защиты
PAGE_NOCACHE, PAGE_WRITECOMBINE и PAGE_GUARU. Они комбинируются с любыми атрибутами защиты (кроме PAGE_NOACCESiS) побитовой операцией OR.
Флаг PAGE_NOCACHE отключает кэширование переданных страниц. Как правило, использовать этот флаг не рекомендуется; он предусмотрен главным образом для разработчиков драйверов устройств, которым нужно манипулировать буферами памяти.
Флаг PAGE_WRITECOMBINE тоже предназначен для разработчиков драйверов ycтройств. Он позволяет объединять несколько операций записи на устройство в одип пакет, что увеличивает скорость передачи данных
Флаг PAGE_GUARD позволнет приложениям получать уведомление (через механизм исключений) в тот момент, когда на страницу записывается какой-нибудь баит Window.s 2000 использует этот флаг при создании стека потока. Подробнее на эту тему см. раздел «Стек потока» в главе 16.
WINDOWS 98
Windows 98 игнорирует флаги атрибутов защиты PAGE_NOCACHE,
PAGE_WRITECOMBINE и PAGE_GUARD
Подводя итоги
А теперь попробуем осмыслить понятия адресных пространств, разделов, регионов, блоков и страниц как единое целое. Лучше всего начать с изучения карты виртуальной памяти, на которой изображены все регионы адресного пространства В пределах одного процесса. В качестве примера мы воспользуемся программой VMMap из главы 14. Чтобы
вполной мере разобраться в адресном пространстве процесса, рассмотрим его в том виде,
вкаком оно формируется при запуске VMMap под управлением Windows 2000 на 32разрядной процессорной платформе x86 Образец карты адресного пространства VMMap показан в таблице 13-2. На отличиях адресных пространств в Windows 2000 и Windows 98 я остановлюсь чуть позже.
Карта в таблице 13-2 показывает регионы, расположенные в адресном пространстве процесса. Каждому региону соответствует своя строка в таблице, а каждая строка состоит из шести полей.
В первом (крайнем слева) поле проставляется базовый адрес региона. Наверное, Вы заметили, что просмотр адресного пространства мы начали с региона по адресу 0x00000000 и закончили последним регионом используемого адресного простран-
ства, который начинается по адресу 0x7FFE0000. Все регионы непрерывны. Почти все базовые адреса занятых регионов начинаются со значений, кратных 64 Кб. Это связано с гранулярностью выделения памяти в адресном пространстве. А если Вы увидите какойнибудь регион, начало которого не выровнено по значению, кратному 64 Кб, значит, он выделен кодом операционной системы для управления Вашим процессом.
Базовый |
Тип |
Размер |
Блоки |
Атрибут( ы) |
Описание |
адрес |
|
|
|
защиты |
|
|
|
|
|
|
|
00000000 |
Free |
65536 |
|
|
|
|
|
|
|
|
|
00010000 |
Private |
4096 |
1 |
-RW- |
|
|
|
|
|
|
|
00011000 |
Free |
G1440 |
|
|
|
|
|
|
|||
|
|
|
|
|
|
00020000 |
Private |
4096 |
1 |
-RW- |
|
|
|
|
|
|
|
000? 1000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00030000 |
Private |
1048576 |
3 |
-HW- |
Стек потока |
|
|
|
|
|
|
00130000 |
Private |
1048576 |
2 |
-RW- |
|
|
|
|
|
|
|
00230000 |
Mapped |
65536 |
2 |
-RW- |
|
|
|
|
|
|
|
00240000 |
Mapped |
90112 |
1 |
-R- |
\Device\HarddiskVolume1\WINN7\system32\unicode.nls |
|
|
|
|
|
|
00256000 |
Free |
40960 |
|
|
|
|
|
|
|
|
|
00260000 |
Mapped |
208896 |
1 |
-R- |
\Device\HarddiskVolume1\WINNT\system32\locale.nIs |
|
|
|
|
|
|
00293000 |
Free |
53248 |
|
|
|
|
|
|
|
|
|
002A0000 |
Happed |
266240 |
1 |
-R- |
\Pevicc\HarddiskVolume1\WINNT\system32\sortkey.nls |
|
|
|
|
|
|
002E1000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
002F0000 |
Mapped |
16384 |
1 |
-R- |
\Device\HarddiskVolume1\WINNT\system32\sorttbls.nls |
|
|
|
|
|
|
002F4000 |
Free |
49152 |
|
|
|
|
|
|
|
|
|
00300000 |
Mapped |
819200 |
4 |
ER- |
|
|
|
|
|
|
|
0003С8000 |
Free |
229376 |
|
|
|
|
|
|
|
|
|
00400000 |
Image |
106496 |
5 |
ERWC |
С \CD\x86\Debug\14_VMMap.ехе |
|
|
|
|
|
|
0041A000 |
Free |
24576 |
|
|
|
|
|
|
|
|
|
00420000 |
Mapped |
274432 |
1 |
-R- |
|
|
|
|
|
|
|
00463000 |
Free |
53248 |
|
|
|
|
|
|
|
|
|
00470000 |
Mapped |
3145728 |
2 |
ER |
|
|
|
|
|
|
|
00770000 |
Private |
4096 |
1 |
-RW- |
|
|
|
|
|
|
|
00771000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00780000 |
Private |
4096 |
1 |
-RW- |
|
|
|
|
|
|
|
00781000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00790000 |
Private |
65536 |
2 |
-RW- |
|
|
|
|
|
|
|
007A0000 |
Mapped |
8192 |
1 |
-R- |
\Device\HarddiskVolume1\WINNT\system32\ctype.nls |
|
|
|
|
|
|
007А2000 |
Free |
1763893248 |
|
|
|
|
|
|
|
|
|
699D0000 |
Image |
45056 |
4 |
ERWC |
C:\WINNT\Systpm32\PSAPI dll |
|
|
|
|
|
|
6990В000 |
Free |
238505984 |
|
|
|
|
|
|
|
|
|
77D50000 |
Image |
450560 |
4 |
ERWC |
С:\WINNT\system32\RPCRT4 DLL |
|
|
|
|
|
|
770ВЕ000 |
Free |
8192 |
|
|
|
|
|
|
|
|
|
770С0000 |
Image |
344064 |
5 |
ERWC |
С:\WINNT\system32\ADVAPI32 dll |
|
|
|
|
|
|
77Е14000 |
Free |
49152 |
|
|
|
|
|
|
|
|
|
77E20000 |
Image |
401408 |
4 |
ERWC |
C:\WINNT\system32\USER32 dll |
|
|
|
|
|
|
77Е82000 |
Free |
57344 |
|
|
|
|
|
|
|
|
|
77Е90000 |
Image |
720896 |
5 |
ERWC |
С \WINNT\system32\KERNEL32.dll |
|
|
|
|
|
|
77F40000 |
Image |
241664 |
4 |
ERWC |
С \WINKT\system32\GUI32 DLL |
|
|
|
|
|
|
77F7В000 |
Free |
20480 |
|
|
|
|
|
|
|
|
|
77FB0000 |
image |
483328 |
5 |
ERWC |
С \WINNT\System32\ntdll.dll |
|
|
|
|
|
|
77FF000 |
Free |
40960 |
|
|
|
|
|
|
|
|
|
78000000 |
Image |
290816 |
6 |
bMWC |
С \WINNT\system32\MSVCRI.dll |
|
|
|
|
|
|
78047000 |
Free |
124424192 |
|
|
|
|
|
|
|
|
|
7F6F0000 |
Mapped |
1048576 |
2 |
ER-- |
|
|
|
|
|
|
|
7F7F0000 |
Free |
8126464 |
|
|
|
|
|
|
|
|
|
7FFB0000 |
Mapped |
147456 |
1 |
-R-- |
|
|
|
|
|
|
|
7FFD4000 |
Free |
40960 |
|
|
|
|
|
|
|
|
|
7FFDE000 |
Private |
4096 |
1 |
ERW- |
|
|
|
|
|
|
|
7FFDF000 |
Private |
4096 |
1 |
ERW- |
|
|
|
|
|
|
|
7FFE0000 |
Private |
65536 |
2 |
-R-- |
|
|
|
|
|
|
|
|
Таблица 13-2. Образец карты адресного пространства процесса в Windows 2000 на 32-разрядном |
|
процессоре типа x86 |
|
Во втором поле показывается тип региона Free (свободный), Private (закрытый), Image |
|
(образ) или Mapped (проецируемый) Эти типы описаны в следующей таблице, |
|
|
Тип |
Описание |
|
|
Free |
Этот диапазон виртуальных адресов не сопоставлен ни с каким типом физической памяти. Его адресное |
|
пространство не зарезервировано, приложение может зарезервировать регион по указанному базовому адресу или в |
|
любом месте в границах свободного региона |
Private |
Этот диапазон виртуальных адресов сопоставлен со страничным файлом. |
|
|
Image |
Этот диапазон виртуальных адресов изначально был сопоставлен с образом ЕХЕили DLL-файла, проецируемого в |
|
память, но теперь, возможно, уже нет Например, при записи в глобальную переменную из образа модуля механизм |
|
поддержки «копирования при записи» выделяет соответствующую страницу памяти из страничного файла, а не |
|
исходною образа файла |
|
|
Mapped Этот диапазон виртуальных адресов изначально был сопоставлен с файлом данных, проецируемым в память, но теперь, возможно, уже нет. Например, файл данных мог быть спроецирован с использованием механизма поддержки «копирования при записи" Любые операции записи в этот файл приведут к тому, что соответствующие страницы памяти будут выделены из страничного файла, а не из исходного файла данных.
Способ вычисления этого поля моей программой VMMap может давать неправильные результаты. Поясню почему Когда регион занят, VMMap пытается «прикинуть", к какому из трех оставшихся типов он может относиться, — в Windows нет функций, способных подсказать точное предназначение региона. Я определяю это сканированием всех блоков в границах исследуемого региона, по результатам которого программа делает обоснованное
предположение Но предположение есть предположение Если Вы хотите получше разобраться в том, как это делается, просмотрите исходный код VMMap, приведенный в главе 14.
В третьем поле сообщается размер региона в байтах. Например, система спроецировала образ User32.dll по адресу 0x77E20000. Когда она резервировала адресное
пространство для этого образа, ей понадобилось 401 408 байтов. Не забудьте, что в третьем поле всегда содержатся значения, кратные размеру страницы, характерному для данного процессора (4096 байтов для x86).
Вчетвертом поле показано количество блоков в зарезервированном регионе. Блок — это неразрывная группа страниц с одинаковыми атрибутами защиты, связанная с одним и тем же типом физической памяти (подробнее об этом мы поговорим в следующем разделе). Для свободных регионов это значение всегда равно 0, так как им не передается физическая память. (Поэтому в четвертой графе никаких данных для свободных регионов не приводится.) Но для занятых регионов это значение может колебаться в пределах от 1 до максимума (его вычисляют делением размера региона на размер страницы). Скажем, у региона, начинающегося с адреса Ox77E20000, размер — 401 408 байтов. Поскольку процесс выполняется на процессоре x86 (страницы памяти по 4096 байтов), максимальное количество блоков в этом регионе равно 98 (401 408/4096); ну а, судя по карте, в нем содержится 4 блока.
Впятом поле — атрибуты защиты региона. Здесь используются следующие сокращения:
E = execute (исполнение), R = read (чтение), W= write (запись), С = copy-onwrite
(копирование при записи). Если ни один из атрибутов в этой графе не указан, регион доступен без ограничений. Атрибуты защиты не присваиваются и свободным регионам. Кроме того, здесь Вы никогда не увидите флагов атрибутов защиты PAGE_ GUARD или PAGE_NOCACHE — они имеют смысл только для физической памяти, а не для зарезервированного адресного пространства. Атрибуты защиты присваиваются регионам только эффективности ради и всегда замещаются атрибутами защиты, присвоенными физической памяти.
Вшестом (и последнем) поле кратко описывается содержимое текущего региона. Для свободных регионов оно всегда пустое, а для закрытых — обычно пустое, так как у VMMap нет возможности выяснить, зачем приложение зарезервировало данный закрытый регион. Однако VMMap все жe распознает назначение тех закрытых регионов, в которых содержатся стеки потоков. Стеки потоков выдают себя тем, что содержат блок физической памяти с флагом атрибутов защиты PAGE_GUARD. Если же стек полностью заполнен, такого блока у него нет, и тогда VMMap не в состоянии распознать стск потока.
Для регионов типа Image программе VMMap удается определить полное имя файла, проецируемого на этот регион. Она получает эту информацию с помощью ToolHelpфункций, о которых я упоминал в конце главы 4. В Windows 2000 программа VMMap может идентифицировать регионы, сопоставленные с файлами данных; для этого она вызывает функцию GetMappedFileName (ее нет в Windows 98).
Блоки внутри регионов
Попробуем увеличить детализацию адресного пространства (по сравнению с тем, что показано в таблице 13-2). Например, таблица 13-3 показывает ту же карту адресного
пространства, но в другом «масштабе»: по ней можно узнать, из каких блоков состоит каждый регион.
Базовый адрес |
Тип |
Размер |
Блоки |
Атрибут(ы) |
Описание |
|
|
|
|
защиты |
|
|
|
|
|
|
|
00000000 |
Free |
65536 |
|
|
|
|
|
|
|
|
|
00010000 |
Private |
4096 |
1 |
-RW- |
|
|
|
|
|
|
|
00010000 |
Private |
4096 |
|
-RW- |
|
|
|
|
|
|
|
00011000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00020000 |
Private |
4096 |
1 |
-HW- |
|
|
|
|
|
|
|
00020000 |
Private |
4096 |
|
-HW- --- |
|
|
|
|
|
|
|
00021000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00030000 |
Private |
1048576 |
3 |
-RW- |
Стек потока |
|
|
|
|
|
|
00030000 |
Reserve |
905216 |
|
-RW- s— |
|
|
|
|
|
|
|
0010D000 |
Private |
4096 |
|
-RW- G- |
|
|
|
|
|
|
|
0010E000 |
Private |
139264 |
|
-RW- --- |
|
|
|
|
|
|
|
00130000 |
Private |
1048576 |
? |
-RW- |
|
|
|
|
|
|
|
00130000 |
Private |
36864 |
|
-RW- --- |
|
|
|
|
|
|
|
00139000 |
Reserve |
1011712 |
|
-RW- --- |
|
|
|
|
|
|
|
00230000 |
Mapped |
65536 |
2 |
-RW- |
|
|
|
|
|
|
|
00230000 |
Mapped |
4096 |
|
-RW- —— |
|
|
|
|
|
|
|
00231000 |
Reserve |
61440 |
|
-RW- --- |
|
|
|
|
|
|
|
00240000 |
Mapped |
90112 |
1 |
-R — |
\Device\HarddiskVoluume1\WTNNT\system32\unicode.nls |
|
|
|
|
|
|
00240000 |
Happed |
90112 |
|
R |
|
|
|
|
|
|
|
00256000 |
Free |
409GO |
|
|
|
|
|
|
|
|
|
00260000 |
Mapped |
208896 |
1 |
-R-- |
\Device\HarddiskVoluume1\WTNNT\system32\locale.nls |
|
|
|
|
|
|
00260000 |
Mapped |
208896 |
|
-R-- --- |
|
|
|
|
|
|
|
00293000 |
Free |
53248 |
|
|
|
|
|
|
|
|
|
002А0000 |
Happed |
266240 |
1 |
-R — |
\Device\HarddiskVoluume1\WTNNT\system32\sortkey.nls |
|
|
|
|
|
|
002А0000 |
Mapped |
266240 |
|
-R-- --- |
|
|
|
|
|
|
|
002Е1000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
002F0000 |
Mapped |
16384 |
1 |
-R- |
\Device\HarddiskVoluume1\WTNNT\system32\sorttbls.nls |
|
|
|
|
|
|
002F0000 |
Mapped |
16384 |
|
-R-- --- |
|
|
|
|
|
|
|
002F4000 |
Free |
49152 |
|
|
|
|
|
|
|
|
|
00300000 |
Mapped |
819200 |
4 |
ER- |
|
|
|
|
|
|
|
00300000 |
Mapped |
16384 |
|
ЕR-- —-- |
|
|
|
|
|
|
|
00304000 |
Reserve |
770048 |
|
ER-- --- |
|
|
|
|
|
|
|
003C0000 |
Mapped |
8192 |
|
ER-- --- |
|
|
|
|
|
|
|
ОО3С2000 |
Reserve |
24576 |
|
ER-- --- |
|
|
|
|
|
|
|
ОО3С8000 |
Free |
229376 |
|
|
|
|
|
|
|
|
|
00400000 |
Image |
106496 |
5 |
ERWC |
С:\CD\x86\Debug\14_VMMap.exe |
|
|
|
|
|
|
00400000 |
Image |
4096 |
|
-- ----R |
|
|
|
|
|
|
|
00401000 |
Image |
81920 |
|
ЕR-- —-- |
|
|
|
|
|
|
|
00415000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
00416000 |
Image |
8192 |
|
-RW- --- |
|
|
|
|
|
|
|
00418000 |
Image |
8192 |
|
-R-- --- |
|
|
|
|
|
|
|
0041А000 |
Free |
24576 |
|
|
|
|
|
|
|
|
|
00420000 |
Mapped |
274432 |
1 |
-R- |
|
|
|
|
|
|
|
00420000 |
Mapped |
274432 |
|
-R- --- |
|
|
|
|
|
|
|
00463000 |
Free |
53248 |
|
|
|
|
|
|
|
|
|
00470000 |
Mapped |
3145726 |
2 |
ER-- |
|
00470000 |
Mapped |
274432 |
|
ER-- --- |
|
|
|
|
|
|
|
004B3000 |
Reserve |
2871296 |
|
ER-- --- |
|
|
|
|
|
|
|
00770000 |
Private |
4096 |
1 |
-RW- --- |
|
|
|
|
|
|
|
00770000 |
Privale |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
00771000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00780000 |
Pr ivate |
4096 |
1 |
-RW- --- |
|
|
|
|
|
|
|
00780000 |
Private |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
00781000 |
Free |
61440 |
|
|
|
|
|
|
|
|
|
00790000 |
Private |
65536 |
2 |
-RW- --- |
|
|
|
|
|
|
|
00790000 |
Private |
20480 |
|
-RW- --- |
|
|
|
|
|
|
|
00795000 |
Reserve |
45056 |
|
-RW- --- |
|
|
|
|
|
|
|
007А0000 |
Mapped |
8192 |
1 |
-R-- --- |
\Device\HarddiskVolume1\WINNT\system32\ctype.nls |
|
|
|
|
|
|
007А0000 |
Mapped |
8192 |
|
-R-- --- |
|
|
|
|
|
|
|
007A2000 |
Free |
57344 |
|
|
|
|
|
|
|
|
|
007В0000 |
Private |
524288 |
2 |
-RW- --- |
|
|
|
|
|
|
|
007В0000 |
Private |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
007В1000 |
Reserve |
520192 |
|
-RW- --- |
|
|
|
|
|
|
|
00830000 |
Free |
1763311616 |
|
|
|
|
|
|
|
|
|
699D0000 |
Image |
45056 |
4 |
ERWC |
С:\WINNT\Systern32\PSAPI.dll |
|
|
|
|
|
|
699D0000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
69901000 |
Image |
16384 |
|
ER- --- |
|
|
|
|
|
|
|
699D5000 |
Image |
16384 |
|
-RWC --- |
|
|
|
|
|
|
|
699D9000 |
Image |
8192 |
|
-R-- --- |
|
|
|
|
|
|
|
699DB000 |
Free |
238505984 |
|
|
|
|
|
|
|
|
|
77D50000 |
Imago |
450560 |
4 |
ERWC |
C:\WINNT\system32\RPCRT4.DLL |
|
|
|
|
|
|
77D50000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
77D51000 |
image |
421888 |
|
ER-- --- |
|
|
|
|
|
|
|
77DB8000 |
Image |
409G |
|
-RW- --- |
|
|
|
|
|
|
|
77DB9000 |
Image |
20480 |
|
-R-- --- |
|
|
|
|
|
|
|
77DBE000 |
Free |
8192 |
|
|
|
|
|
|
|
|
|
77DC0000 |
Image |
344064 |
5 |
ERWC |
С:\WINNT\syatem32\ADVAPI32.dll |
|
|
|
|
|
|
77DC0000 |
Image |
4096 |
|
-- ----R |
|
|
|
|
|
|
|
77DС1000 |
Image |
307200 |
|
ER-- --- |
|
|
|
|
|
|
|
77Е0С000 |
Image |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
77E00000 |
Image |
4096 |
|
-RWC --- |
|
|
|
|
|
|
|
77Е0E000 |
Image |
24576 |
|
-R-- --- |
|
|
|
|
|
|
|
77Е14000 |
Free |
49152 |
|
|
|
|
|
|
|
|
|
77E20000 |
Image |
401408 |
4 |
ERWC |
С:\WINNT\system32\USER32.dll |
|
|
|
|
|
|
/7Е20000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
77Е21000 |
Image |
348160 |
|
ER-- --- |
|
|
|
|
|
|
|
77Е76000 |
Image |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
77Е77000 |
Image |
45056 |
|
-R-- --- |
|
|
|
|
|
|
|
77Е82000 |
Free |
57344 |
|
|
|
77Е90000 |
Image |
720896 |
5 |
ERWC |
С \WINNT\system32\KERNEL32.dll |
|
|
|
|
|
|
77Е90000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
77Е91000 |
Image |
368640 |
|
ER-- --- |
|
|
|
|
|
|
|
77ЕЕВ000 |
Image |
8192 |
|
-RW- --- |
|
|
|
|
|
|
|
77EED000 |
Image |
4096 |
|
-RWC --- |
|
|
|
|
|
|
|
77ЕЕЕ000 |
Image |
335872 |
|
-R-- --- |
|
|
|
|
|
|
|
77F40000 |
Image |
241664 |
4 |
ERWC |
С \WINNT\system32\GDI32.DLL |
|
|
|
|
|
|
77F40000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
77F41000 |
Image |
221184 |
|
ER-- --- |
|
|
|
|
|
|
|
77F77000 |
Image |
4096 |
|
-RW- --- |
|
|
|
|
|
|
|
77F78000 |
Image |
12288 |
|
-R-- --- |
|
|
|
|
|
|
|
77F7B000 |
Free |
20480 |
|
|
|
|
|
|
|
|
|
77F80000 |
Image |
483328 |
5 |
ERWC |
С \WINT\System32\ntdll.dll |
|
|
|
|
|
|
77F80000 |
Image |
409b |
|
-R-- --- |
|
|
|
|
|
|
|
77F81000 |
Image |
299008 |
|
ER-- --- |
|
|
|
|
|
|
|
77FCA000 |
Image |
8192 |
|
RW- --- |
|
|
|
|
|
|
|
77FCC000 |
Image |
4096 |
|
-RWC --- |
|
|
|
|
|
|
|
77FCD000 |
Image |
167936 |
|
-R-- --- |
|
|
|
|
|
|
|
77FF6000 |
Free |
40960 |
|
|
|
|
|
|
|
|
|
78000000 |
Image |
290816 |
6 |
ERWC |
С \WINNT\system32\MSVCRT.dll |
|
|
|
|
|
|
78000000 |
Image |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
78001000 |
Image |
208896 |
|
ER-- --- |
|
|
|
|
|
|
|
78031000 |
Image |
32768 |
|
-R-- --- |
|
|
|
|
|
|
|
7803С000 |
Image |
12288 |
|
-RW- --- |
|
|
|
|
|
|
|
7803F000 |
Image |
16384 |
|
-RWC --- |
|
|
|
|
|
|
|
78043000 |
Image |
16384 |
|
-R-- --- |
|
|
|
|
|
|
|
78047000 |
Free |
124424192 |
|
|
|
|
|
|
|
|
|
7F6F0000 |
Mapped |
1048576 |
2 |
ER-- --- |
|
|
|
|
|
|
|
7F6F0000 |
Mapped |
28672 |
|
ER-- --- |
|
|
|
|
|
|
|
7F6F7000 |
Reserve |
1019904 |
|
-- ---ER |
|
|
|
|
|
|
|
7F7F0000 |
Free |
8126464 |
|
|
|
|
|
|
|
|
|
7FFB0000 |
Mapped |
147456 |
1 |
-R-- --- |
|
|
|
|
|
|
|
7FFB0000 |
Mapped |
147456 |
|
-R-- --- |
|
|
|
|
|
|
|
7FFD4000 |
Free |
40960 |
|
|
|
|
|
|
|
|
|
7FFDE000 |
Private |
4096 |
1 |
ERW --- |
|
|
|
|
|
|
|
7FFDE000 |
Private |
4096 |
|
ERW --- |
|
|
|
|
|
|
|
7FFDF000 |
Private |
4096 |
1 |
ERW --- |
|
|
|
|
|
|
|
7FFDF000 |
Private |
4096 |
|
ERW --- |
|
|
|
|
|
|
|
7FFF0000 |
Private |
65536 |
2 |
-R-- --- |
|
|
|
|
|
|
|
7FFE0000 |
Private |
4096 |
|
-R-- --- |
|
|
|
|
|
|
|
7FFE1000 |
Reserve |
61440 |
|
-R-- --- |
|
|
|
|
|
|
|
Таблица 13-3. Образец карты адресного пространства процесса (с указанием блоков внутри регионов) в Windows 2000 на 32-разрядном процессоре типа x86
Разумеется, в свободных регионах блоков нет, поскольку им не переданы страни цы физической памяти. Строки с описанием блоков состоят из пяти полей.
В первом поле показывается адрес группы страниц с одинаковыми состоянием и атрибутами защиты. Например, по адресу 0x77E20000 передана единственная страница (4096 байтов) физической памяти с атрибутом защиты, разрешающим только чтение. А по адресу 0x77E21000 присутствует блок размером 85 страниц (348 160 байтов) переданной памяти с атрибутами, разрешающими и чтение, и исполнение. Если бы атрибуты защиты этих блоков совпадали, их можно было бы объединить, и тогда на карте памяти появился бы единый элемент размером в 86 страниц (352 256 байтов).
Во втором поле сообщается тип физической памяти, с которой связан тот или иной блок, расположенный в границах зарезервированного региона. В нем появляется одно из пяти возможных значений: Free (свободный), Private (закрытый), Mapped (проецируемый), Image (образ) или Reserve (резервный). Значения Private, Mapped и Image говорят о том,
что блок поддерживается физической памятью соответственно из страничного файла, файла данных, загруженного EXEили DLL-модуля. Если же в поле указано значение Free или Reserve, блок вообще не связан с физической памятью.
Чаще всего блоки в пределах одного региона связаны с однотипной физической памятью. Однако регион вполне может содержать несколько блоков, связанных с физической памятью разных типов. Например, образ файла, проецируемого в память, может быть связан с EXEили DLL-файлом. Если Вам понадобится что-то записать на одну из страниц в таком регионе с атрибутом защиты PAGEWRITECOPY или PAGE_EXECUTE_WRITECOPY, система подсунет Вашему процессу закрытую копию, связанную со страничным файлом, а не с образом файла. Эта новая страница получит те же атрибуты, что и исходная, но без защиты по типу «копирование при записи».
Втретьем поле проставляется размер блока. Все блоки непрерывны в границах региона, и никаких разрывов между ними быть не может.
Вчетвертом поле показывается количество блоков внутри зарезервированного региона.
