Виртуальная память в Microsoft Windows

Виртуальная память в Microsoft Windows

Здесь мы рассмотрим архитектуру памяти, применяемую в Microsoft Windows.

Виртуальное адресное пространство процесса

Каждому процессу выделяется собственное виртуальное адресное пространство. Для 32-разрядных процессов его размер составляет 4 Гб. Соответственно 32-битный указатель может быть любым числом от 0x00000000 до 0xFFFFFFFF. Всего, таким образом, указатель может принимать 4 294 967 296 значений, что как раз и перекрывает четырехгигабайтовый диапазон. Для 64-разрядных процессов размер адресного пространства равен 16 экзабайтам, поскольку 64-битный указатель может быть любым числом от 0x00000000 00000000 до 0xFFFFFFFF FFFFFFFF и принимать 18 446 744 073 709 551 616 значений, охватывая диапазон в 16 экзабайтов.Поскольку каждому процессу отводится закрытое адресное пространство, то, когда в процессе выполняется какой-нибудь поток, он получает доступ только к той памяти, которая принадлежит его процессу. Память, отведенная другим процессам, скрыта от этого потока и недоступна ему. В Windows 2000 память, принадлежащая собственно операционной системе, тоже скрыта от любого выполняемого потока. Иными словами, ни один поток не может случайно повредить ее данные.В Windows 2000, ни один поток не может получить доступ к памяти чужого процесса. Итак, адресное пространство процесса закрыто. Отсюда вытекает, что процесс А в своем адресном пространстве может хранить какую-то структуру данных по адресу 0x12345678, и одновременно у процесса В по тому же адресу — но уже в его адресном пространстве — может находиться совершенно иная структура данных. Обращаясь к памяти по адресу 0x12345678, потоки, выполняемые в процессе А, получают доступ к структуре данных процесса А, Но, когда по тому же адресу обращаются потоки, выполняемые в процессе В, они получают доступ к структуре данных процесса В. Иначе говоря, потоки процесса А не могут обратиться к структуре данных в адресном пространстве процесса В, и наоборот 

Как адресное пространство разбивается на разделы

Виртуальное адресное пространство каждого процесса разбивается на разделы. Их размер и назначение в какой-то мере зависят от конкретного ядра Windows (таблица 13-1) 

Раздел 

32-разрядная Windows 2000 (на х86 и Alpha) 

32-разрядная Windows 2000 (на х86 с ключом /3GB) 

64-разрядная Windows 2000 (на Alpha и А-64) 

Windows 98 

Для выявления 

0x00000000 

0x00000000 

0x00000000 00000000 

0x00000000 

нулевых указателей 

0x0000FFFF 

0x0000FFFF 

0x00000000 0000FFFF 

0x00000FFF 

Для совместимости с программами DOS и 16-разрядной Windows 

Hет 

Нет 

Нет 

0x00001000 0x003FFFFF 

Для кода и данных 

0x00010000 

0x00010000 

0x00000000 00010000 

0x00400000 

пользовательского режима 

0x7FFEFFFF 

0xBFFFFFFF 

0x000003FF FFFEFFFF 

0x7FFFFFFF 

Закрытый, 

0x7FFF0000 

0xBFFF0000 

0x000003FF FFFF0000 

Нет 

размером 64 Кб 

0x7FFFFFFF 

0xBFFFFFFF 

0x000003FF FFFFFFFF 



Для общих MMF (файлов, проецируемых в память) 

Нет 

Нет 

Нет 

0x80000000 0xBFFFFFFF 

Для кода и данных 

0x800000000 

0xC0000000 

0x00000400 00000000 

0xC0000000 

режима ядра 

0xFFFFFFFF 

0xFFFFFFFF 

0xFFFFFFFF FFFFFFFF 

0xFFFFFFFF 

Таблица 13-1. Так адресное пространство процесса разбивается на разделы 

Раздел для выявления нулевых указателей (Windows 2000 и Windows 98) 

Этот раздел адресного пространства резервируется для того, чтобы программисты могли выявлять нулевые указатели. Любая попытка чтения или записи в память по этим адресам вызывает нарушение доступа. Довольно часто в программах, написанных на С/С++, отсутствует скрупулезная обработки ошибок. Например, в следующем фрагменте кода такой обработки вообще нет: 

int* pnSomeInteger = (int*) malloc(sizeof(int)); 

*pnSomeInteger = 5; 

 При нехватке памяти malloc вернет NULL. Ho код не учитывает эту возможность и при ошибке обратится к памяти по адресу 0x00000000 А поскольку этот раздел адресного пространства заблокирован, возникнет нарушение доступа и данный процесс завершится Эта особенность помогает программистам находить "жучков* в своих приложениях. В Windows 2000 программы для MS-DOS и 16-разрядной Windows выполняются в собственных адресных пространствах; 32-разрядные приложения повлиять на них не могут. 

Раздел для кода и данных пользовательского режима (Windows 2000 и Windows 98) 

В этом разделе располагается закрытая (неразделяемая) часть адресного пространства процесса. Ни один процесс не может получить доступ к данным другого процесса, размещенным в этом разделе. Основной объем данных, принадлежащих процессу, хранится именно здесь (это касается всех приложений) Поэтому приложения менее зависимы от взаимных "капризов", и вся система функционирует устойчивее. В Windows 2000 сюда загружаются все EXE- и DLL-модули В каждом процессе эти DLL можно загружать по разным адресам в пределах данного раздела, но так делается крайне редко. На этот же раздел отображаются все проецируемые в память файлы, доступные данному процессу. В 64-разрядной Windows 2000 ядро наконец получит то пространство, которое ему нужно на самом деле. 

Увеличение раздела для кода и данных пользовательского режима до 3 Гб на процессорах x86 (только Windows 2000) 

 Microsoft предусмотрела в версиях Windows 2000 Advanced Server и Windows 2000 Data Center для процессоров x86 возможность увеличения этого пространства до 3 Гб. Чтобы все процессы использовали раздел для кода и данных пользовательского режима размером 3 Гб, а раздел для кода и данных режима ядра — объемом 1 Гб, Вы должны добавить ключ /3GB к нужной записи в системном файле Boot.ini. Как выглядит адресное пространство процесса в этом случае, показано в графе "32-разрядная Windows 2000 (на x86 с ключом /3GB)" таблицы 13-1. 

Уменьшение раздела для кода и данных пользовательского режима до 2 Гб в 64-разрядной Windows 2000 

Многие разработчики захотят как можно быстрее перенести свои 32-разрндные приложения в 64-разрядную среду. Но в исходном коде любых программ полно таких мест, где предполагается, что указатели являются 32-разрядными значениями. Простая перекомпиляция исходного кода приведет к ошибочному усечению указателей и некорректному обращению к памяти. Однако, если бы система как-то гарантировала, что память никогда не будет выделяться по адресам выше 0x00000000 7FFFFFFF, приложение работало бы нормально. И усечение 64-разрядного адреса до 32-разрядного, когда старшие 33 бита равны 0, не создало бы никаких проблем. Так вот, система дает такую гарантию при запуске приложения в "адресной песочнице" (address space sandbox), которая ограничивает полезное адресное пространство процесса до нижних 2 Гб. По умолчанию, когда Вы запускаете 64-разрядное приложение, система резервирует все адресное пространство пользовательского режима, начиная с 0x0000000 80000000, что обеспечивает выделение памяти исключительно в нижних 2 Гб 64-разрядного адресного пространства. Это и есть "адресная песочница". Большинству приложений этого пространства более чем достаточно. А чтобы 64-разрядное приложение могло адресоваться ко всему разделу пользовательского режима (объемом 4 Тб), его следует скомпоновать с ключом /LARGEADDRESSAWARE. 

Закрытый раздел размером 64 Кб (только Windows 2000) 

Этот раздел заблокирован, и любая попытка обращения к нему приводит к нарушению доступа Microsoft резервирует этот раздел специально, чтобы упростить внутреннюю реализацию операционной системы. Вспомните, когда Бы передаете Windows-функции адрес блока памяти и его размер, то она (функция), прежде чсм приступить к работе, проверяет, действителен ли данный блок. Допустим, Вы написали код: 

BYTE bBuf[70000]; DWORD dwNumBytesWritTen; WriteProcessMemory(GetCurrentProcess(), (PVOID) 0x7FFEEE90, bBuf, sizeof(bBuf), &dwNumBytesWntten); 

В случае функций типа WriteProcessMemory область памяти, в которую предполагается запись, проверяется кодом, работающим в режиме ядра, — только он имеет право обращаться к памяти, выделяемой под код и данные режима ядра (в 32-разрядных системах — по адресам выше 0x80000000). Если по этому адресу есть память, вызов WriteProcessMemory, показанный выше, благополучно запишет данные в ту область памяти, которая, по идее, доступна только коду, работающему в режиме ядра. Чтобы предотвратить это и в то же время ускорить проверку таких областей памяти, Microsoft предпочла заблокировать данный раздел, и поэтому любая попытка чтения или записи в нем всегда вызывает нарушение доступа. 

Раздел для кода и данных режима ядра (Windows 2000 и Windows 98) 

В этот раздел помещается код операционной системы, в том числе драйверы устройств и код низкоуровневого управления потоками, памятью, файловой системой, сетевой поддержкой. Все, что находится здесь, доступно любому процессу. В Windows 2000 эти компоненты полностью защищены. Поток, который попытается обратиться по одному из адресов памяти в этом разделе, вызовет нарушение доступа, а это приведет к тому, что система в конечном счете просто закроет его приложение. 64-разрядной Windows 2000 раздел пользовательского режима (4 Тб) выглядит непропорционально малым по сравнению с 16 777 212 Тб, отведенными под раздел для кода и данных режима ядра. Дело не в том, что ядру так уж необходимо все это виртуальное пространство, a просто 64-разрядное адресное пространство настолько огромно, что его большая часть не задействована. Система разрешает нашим программам использовать 4 Тб, а ядру — столько, сколько ему нужно. К счастью, какие-либо внутренние структуры данных для управления незадействованными частями раздела для кода и данных режима ядра не требуются. 

Регионы в адресном пространстве 

Адресное пространство, выделяемое процессу в момент создания, практически все свободно (незарезервировано). Поэтому, чтобы воспользоваться какой-нибудь его частью, нужно выделить в нем определенные регионы через функцию WirtualAlloc.Операция выделения региона называется резервированием (reserving). При резервировании система обязательно выравнивает начало региона с учетом так называемой гранулярности выделения памяти (allocation granularity). Последняя величина в принципе зависит от типа процессора, но для процессоров, рассматриваемых в книге (x86, 32- и 64-разрядных Alpha и IA-64), — она одинакова и составляет 64 Кб.Резервируя регион в адресном пространстве, система обеспечивает еще и кратность размера региона размеру страницы. Так называется единица объема памяти, используемая системой при управлении памятью. Как и гранулярность выделения ресурсов, размер страницы зависит от типа процессора В частности, для процессоров x86 он равен 4 Кб, а для Alpha (под управлением как 32-разрядной, так и 64-разядной Windows 2000) — 8 Кб. Иногда система сама резервирует некоторые регионы адресного пространства в интересах.Если Вы попытаетесь зарезервировать регион размером 10 Кб, система автоматически округлит заданное Вами значение до большей кратной величины. А зто значит что на x86 будет выделен регион размером 12 Кб, а на Alpha — 16 Кб.Когда зарезервированный регион адресного пространства становится не нужен, ею следует вернуть в общие ресурсы системы.Эта операция — освобождение (releasing) региона — осуществляется вызовом функции VirtualFree 

Передача региону физической памяти 

Чтобы зарезервированный регион адресного пространства можно было использовать, Вы должны выделить физическую память и спроецировать её на этот регион. Такая операция называется передачей физической памяти (committing physical storage). Чтобы передать физическую память зарезервированному региону, Вы обращаетесь все к той же функции VirtualAlloc.Передавая физическую память регионам, нет нужды отводить ее целому региону. Можно, скажем, зарезервировать регион размером 64 Кб и нередать физическую память только его второй и четвертой страницам. Когда физическая память, переданная зарезервированному региону, больше не нужна, ее освобождают. Эта операция — возврат физической памяти (decommitting physical storage) — выполняется вызовом функции VirtualFree. 

Физическую память следует рассматривать как данные, хранимые в дисковом файле со страничной структурой. Поэтому, когда приложение передает физическую память какому-нибудь региону адресного пространства (вызывая VirtualAttoc), она на самом деле выделяется из файла, размещенного на жестком диске. Размер страничного файла в системе — главный фактор, определяющий количество физической памяти, доступное приложениям. Реальный объем оперативной памяти имеет гораздо меньшее значение. Физическая память в страничном файле не хранится Windows 2000 может использовать несколько страничных файлов, и, если они расположены на разных физических дисках, операционная система работает гораздо быстрее, поскольку способна вести запись одновременно на нескольких дисках. Чтобы добавить или удалить страничный файл, откройте в Control Panel апплет System, выберите вкладку Advanced и щелкните кнопку Performance Options. Нa экране появится следующее диалоговое окно.



Однако система действует не так, иначе на загрузку и подготовку программы к запуску уходило бы слишком много времени.При запуске приложения система открывает его исполняемый файл и определяет объем кода и данных. Затем резервирует регион адресного пространства и помечает, что физическая память, связанная с этим регионом, — сам ЕХЕ-файл,то есть вместо выделения какого-то пространства из страничного файла система использует истинное содержимое, или образ (image) ЕХЕ-файла как зарезервированный регион адресного пространства программы. Благодаря этому приложение загружается очень быстро, а размер страничного файла удается заметно уменьшить. Образ исполняемого файла (т. e. EXE- или DLL-файл), размещенный на жестком диске и применяемый как физическая память для того или иного региона адресного пространства, называется проецируемым в память файлом (memory-mapped file). При загрузке EXF, или DLL система автоматически резервирует регион адресного пространства и проецирует на него образ файла. Помимо этого, система позволяет (с помощью набора функций) проецировать на регион адресного пространства еще и файлы данных 

Когда EXE- или DLL-файл загружается с дискеты Windows 2000 целиком копируют его в оперативную память, а в страничном файле выделяют такое пространство, чтобы в нем мог уместиться образ загружаемого файла. Если нагрузка на оперативную память в системе невелика, EXE- или DLLфайл всегда запускается непосредственно из оперативной памяти.Так сделано для корректной работы программ установки. Обычно программа установки запускается с первой дискеты, потом поочередно вставляются следующие диски, на которых собственно и содержится устанавливаемое приложение. Если системе понадобится какой-то фрагмент кода EXE- или DLLмодуля программы установки, на текущей дискете его, конечно же, пет. Но, поскольку система скопировала файл в оперативную память (и предусмотрела для него место в страничном файле), у нее не возникнет проблем с доступом к нужной части кода программы установки 

Атрибуты защиты 

Отдельным страницам физической памяти можно присвоить свои атрибуты защиты показанные в следующей таблице.

 Атрибут защиты 

Описание 

PAGE_NOACCESS 

Попытки чтения, записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа 

PAGE_READONLY 

Попытки записи или исполнения содержимого памяти на этой странице вызывают нарушение доступа 

PAGE_READWRITE 

Попытки исполнения содержимого памяти на этой странице вызывают нарушение доступа 

PAGE_EXECUTE 

Попытки чтения или записи на этой странице вызывают нарушение доступа 

PAGE_EXECUTE_READ 

Попытки записи на этой странице вызывают нарушение доступа 

PAGE_EXECUTE_READWRITE 

На этой странице возможны любые операции 

PAGE_WRITECOPY 

Попытки исполнения содержимого памяти на этой странице выбывают нарушение доступа, попытка записи приводит к тому, что процессу предоставляется "личная" копия данной страницы 

PAGE_EXECUTE_WRITECOPY 

На этой странице возможны любые операции, попытка записи приводит к тому, что процессу предоставляется "личная" копия данной страницы 

Защита типа "копирование при записи" 

Атрибуты защиты, перечисленные в предыдущей таблице, достаточно понятны, кроме двух последних: PAGE_WRITECOPY и PAGE_EXECUTE_WRITECOPY. Они предназначены специально для экономного расходования оперативной памяти и места в страничном файле. Windows поддерживает мехянизм, позволяющий двум и более процессам разделять один и тот же блок памяти. Например, если Вы запустите 10 экземпляров программы Notepad, все экземпляры будут совместно использовать одни и те же страницы с кодом и данными этой программы. И обычно никяких проблем не возникает — пока процессы ничего не записывают в общие блоки памяти. Только представьте, что творилось бы в системе, если потоки из разных процессов начали бы одновременно записывать в один и тот же блок памяти! 

Чтобы предотвратить этот хаос, операционная система присваивает общему блоку памяти атрибут защиты "копирование при записи" (copy-on-write). Когда поток в одном процессе попытается что-нибудь записать в общий блок памяти, в дело тут же вступит система и проделает следующие операции:

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

Скопирует страницу с данными, которые поток пытается записать в общий блок памяти, на свободную страницу оперативной памяти, полученную на этапе 1. Последней присваивается атрибут защиты PAGE_WRITECOPY или PAGE_EXECUTE_WRITECOPY. Атрибут защиты и содержимое исходной страницы не меняются. 

Отобразит виртуальный адрес этой страницы в процессе на новую страницу в оперативной памяти. 

Когда система выполнит эти операции, процесс получит свою копию нужной страницы памяти.

Кроме того, при резервировании адресного пространства или передаче физической памяти через VirtualAlloc нельзя указывать атрибуты PAGE_WRITECOPY или PAGE_EXECUTE_WRITECOPY. Иначе вызов VirtualAlloc даст ошибку, a GetLastError вернет код ERROR_INVALID_PARAMETER. Дело в том, что эти два атрибута используются операционной системой, только когда она проецирует образы EXE- или DLL-файлов. 

Базовый адрес 

Тип 

Размер 

Блоки 

Атрибут( ы) защиты 

Описание 

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 

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

В третьем поле сообщается размер региона в байтах. Например, система спроецировала образ 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 — они имеют смысл только для физической памяти, а не для зарезервированного адресного пространства. Атрибуты защиты присваиваются регионам только эффективности ради и всегда замещаются атрибутами защиты, присвоенными физической памяти. 

В шестом (и последнем) поле кратко описывается содержимое текущего региона. Для свободных регионов оно всегда пустое, а для закрытых — обычно пустое

Блоки внутри регионов 

Попробуем увеличить детализацию адресного пространства (по сравнению с тем, что показано в таблице 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-файлом. Если Вам понадобится что-то записать на одну из страниц в таком регионе с атрибутом защиты PAGE_WRITECOPY или PAGE_EXECUTE_WRITECOPY, система подсунет Вашему процессу закрытую копию, связанную со страничным файлом, а не с образом файла. Эта новая страница получит те же атрибуты, что и исходная, но без защиты по типу "копирование при записи". 

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

В четвертом поле показывается количество блоков внутри зарезервированного региона. 

В пятом поле выводятся атрибуты защиты и флаги атрибутов защиты текущего блока. Атрибуты защиты блока замещают атрибуты защиты региона, содержащего данный блок. Их допустимые значения идентичны применяемым для регионов; кроме того, блоку могут быть присвоены флаги PAGE_GUARD, PAGE_WRITECOMBINE и PAGE_NOCACHE, недопустимые для региона.