Programming Applications for Microsoft Windows (Microsoft Programming Series)
In this section, we'll bring address spaces, partitions, regions, blocks, and pages all together. The best way to start is by examining a virtual memory map that shows all the regions of address space within a single process. The process happens to be the VMMap sample application presented in Chapter 14. To fully understand the process's address space, we'll begin by discussing the address space as it appears when VMMap is running under Windows 2000 on a 32-bit x86 machine. A sample address space map is shown in Table 13-2. Later I'll discuss the differences between the Windows 2000 and Windows 98 address spaces.
Table 13-2. A sample address space map showing regions under Windows 2000 on a 32-bit x86 machine
| Base Address | Type | Size | Blocks | Protection Attribute(s) | Description |
|---|---|---|---|---|---|
| 00000000 | Free | 65536 | |||
| 00010000 | Private | 4096 | 1 | -RW- | |
| 00011000 | Free | 61440 | |||
| 00020000 | Private | 4096 | 1 | -RW- | |
| 00021000 | Free | 61440 | |||
| 00030000 | Private | 1048576 | 3 | -RW- | Thread Stack |
| 00130000 | Private | 1048576 | 2 | -RW- | |
| 00230000 | Mapped | 65536 | 2 | -RW- | |
| 00240000 | Mapped | 90112 | 1 | -R-- | \Device\HarddiskVolume1\WINNT\system32\ unicode.nls |
| 00256000 | Free | 40960 | |||
| 00260000 | Mapped | 208896 | 1 | -R-- | \Device\HarddiskVolume1\WINNT\system32\ locale.nls |
| 00293000 | Free | 53248 | |||
| 002A0000 | Mapped | 266240 | 1 | -R-- | \Device\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-- | |
| 003C8000 | Free | 229376 | |||
| 00400000 | Image | 106496 | 5 | ERWC | C:\CD\x86\Debug\14 VMMap.exe |
| 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 |
| 007A2000 | Free | 1763893248 | |||
| 699D0000 | Image | 45056 | 4 | ERWC | C:\WINNT\System32\PSAPI.dll |
| 699DB000 | Free | 238505984 | |||
| 77D50000 | Image | 450560 | 4 | ERWC | C:\WINNT\system32\RPCRT4.DLL |
| 77DBE000 | Free | 8192 | |||
| 77DC0000 | Image | 344064 | 5 | ERWC | C:\WINNT\system32\ADVAPI32.dll |
| 77E14000 | Free | 49152 | |||
| 77E20000 | Image | 401408 | 4 | ERWC | C:\WINNT\system32\USER32.dll |
| 77E82000 | Free | 57344 | |||
| 77E90000 | Image | 720896 | 5 | ERWC | C:\WINNT\system32\KERNEL32.dll |
| 77F40000 | Image | 241664 | 4 | ERWC | C:\WINNT\system32\GDI32.DLL |
| 77F7B000 | Free | 20480 | |||
| 77F80000 | Image | 483328 | 5 | ERWC | C:\WINNT\System32\ntdll.dll |
| 77FF6000 | Free | 40960 | |||
| 78000000 | Image | 290816 | 6 | ERWC | C:\WINNT\system32\MSVCRT.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-- |
The address space map in Table 13-2 shows the various regions in the process's address space. There is one region shown per line, and each line contains six columns.
The first, or leftmost, column shows the region's base address. You'll notice that we start walking the process's address space with the region at address 0x00000000 and end with the last region of usable address space, which begins at address 0x7FFE0000. All regions are contiguous. You'll also notice that almost all the base addresses for non-free regions start on a multiple of 64 KB. This is because of the allocation granularity of address space reservation imposed by the system. A region that does not start on an allocation granularity boundary represents a region that was allocated by operating system code on your process's behalf.
The second column shows the region's type, which is one of the four values—Free, Private, Image, or Mapped—described in the following table.
| Type | Description |
|---|---|
| Free | The region's virtual addresses are not backed by any storage. This address space is not reserved; the application can reserve a region either at the shown base address or anywhere within the free region. |
| Private | The region's virtual addresses are backed by the system's paging file. |
| Image | The region's virtual addresses were originally backed by a memory-mapped image file (such as an .exe or DLL file). The virtual addresses might not be backed by the image file anymore. For example, when a global variable in a module's image is written to, the copy-on-write mechanism backs the specific page from the paging file instead of the original image file. |
| Mapped | The region's virtual addresses were originally backed by a memory-mapped data file. The virtual addresses might not be backed by the data file anymore. For example, a data file might be mapped using copy-on-write protection. Any writes to the file cause the specific pages to be backed by the paging file instead of the original data. |
The way that my VMMap application calculates this column might lead to misleading results. When the region is not free, the VMMap sample application guesses which of the three remaining values applies—there is no function we can call to request this region's exact usage. I calculate this column's value by scanning all of the blocks within the region and taking an educated guess. You should examine my code in Chapter 14 to better understand the way I calculate a column's value.
The third column shows the number of bytes that were reserved for the region. For example, the system mapped the image of User32.DLL at memory address 0x77E20000. When the system reserved address space for this image, it needed to reserve 401,408 bytes. The number in the third column will always be a multiple of the CPU's page size (4096 bytes for an x86).
The fourth column shows the number of blocks within the reserved region. A block is a set of contiguous pages that all have the same protection attributes and that are all backed by the same type of physical storage—I'll talk more about this in the next section of this chapter. For free regions, this value will always be 0 because no storage can be committed within a free region. (Nothing is displayed in the fourth column for a free region.) For the non-free region, this value can be anywhere from 1 to a maximum number of (region size/page size). For example, the region that begins at memory address 0x77E20000 has a region size of 401,408 bytes. Because this process is running on an x86 CPU, for which the page size is 4096 bytes, the maximum number of different committed blocks is 98 (401,408/4096); the map shows that there are 4 blocks in the region.
The fifth column on the line shows the region's protection attributes. The individual letters represent the following: E = execute, R = read, W = write, C = copy-on-write. If the region does not show any of these protection attributes, the region has no access protection. The free regions show no protection attributes because unreserved regions do not have protection attributes associated with them. Neither the guard protection attribute flag nor the no-cache protection attribute flag will ever appear here; these flags have meaning only when associated with physical storage, not reserved address space. Protection attributes are given to a region for the sake of efficiency only and are always overridden by protection attributes assigned to physical storage.
The sixth and last column shows a text description of what's in the region. For free regions, this column will always be blank; for private regions, it will usually be blank because VMMap has no way of knowing why the application reserved this private region of address space. However, VMMap can identify private regions that contain a thread's stack. VMMap can usually detect thread stacks because they will commonly have a block of physical storage within them with the guard protection attribute. However, when a thread's stack is full it will not have a block with the guard protection attribute, and VMMap will be unable to detect it.
For image regions, VMMap displays the full pathname of the file that is mapped into the region. VMMap obtains this information using the ToolHelp functions (mentioned at the end of Chapter 4). In Windows 2000, VMMap can show regions backed by data files by calling the GetMappedFileName function (which does not exist in Windows 98).
Inside the Regions
It is possible to break down the regions even further than shown in Table 13-2. Table13-3 shows the same address space map as Table 13-2, but the blocks contained inside each region are also displayed.
Table 13-3. A sample address space map showing regions and blocks under Windows 2000 on a 32-bitx86 machine
| Base Address | Type | Size | Blocks | Protection Attribute(s) | Description |
|---|---|---|---|---|---|
| 00000000 | Free | 65536 | |||
| 00010000 | Private | 4096 | 1 | -RW- | |
| 00010000 | Private | 4096 | -RW- --- | ||
| 00011000 | Free | 61440 | |||
| 00020000 | Private | 4096 | 1 | -RW- | |
| 00020000 | Private | 4096 | -RW- --- | ||
| 00021000 | Free | 61440 | |||
| 00030000 | Private | 1048576 | 3 | -RW- | Thread Stack |
| 00030000 | Reserve | 905216 | -RW- --- | ||
| 0010D000 | Private | 4096 | -RW- G-- | ||
| 0010E000 | Private | 139264 | -RW- --- | ||
| 00130000 | Private | 1048576 | 2 | -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\HarddiskVolume1\WINNT\ system32\unicode.nls |
| 00240000 | Mapped | 90112 | -R-- --- | ||
| 00256000 | Free | 40960 | |||
| 00260000 | Mapped | 208896 | 1 | -R-- | \Device\HarddiskVolume1\WINNT\ system32\locale.nls |
| 00260000 | Mapped | 208896 | -R-- --- | ||
| 00293000 | Free | 53248 | |||
| 002A0000 | Mapped | 266240 | 1 | -R-- | \Device\HarddiskVolume1\WINNT\ system32\sortkey.nls |
| 002A0000 | Mapped | 266240 | -R-- --- | ||
| 002E1000 | Free | 61440 | |||
| 002F0000 | Mapped | 16384 | 1 | -R-- | \Device\HarddiskVolume1\WINNT\ system32\sorttbls.nls |
| 002F0000 | Mapped | 16384 | -R-- --- | ||
| 002F4000 | Free | 49152 | |||
| 00300000 | Mapped | 819200 | 4 | ER-- | |
| 00300000 | Mapped | 16384 | ER-- --- | ||
| 00304000 | Reserve | 770048 | ER-- --- | ||
| 003C0000 | Mapped | 8192 | ER-- --- | ||
| 003C2000 | Reserve | 24576 | ER-- --- | ||
| 003C8000 | Free | 229376 | |||
| 00400000 | Image | 106496 | 5 | ERWC | C:\CD\x86\Debug\14 VMMap.exe |
| 00400000 | Image | 4096 | -R-- --- | ||
| 00401000 | Image | 81920 | ER-- --- | ||
| 00415000 | Image | 4096 | -R-- --- | ||
| 00416000 | Image | 8192 | -RW- --- | ||
| 00418000 | Image | 8192 | -R-- --- | ||
| 0041A000 | Free | 24576 | |||
| 00420000 | Mapped | 274432 | 1 | -R-- | |
| 00420000 | Mapped | 274432 | -R-- --- | ||
| 00463000 | Free | 53248 | |||
| 00470000 | Mapped | 3145728 | 2 | ER-- | |
| 00470000 | Mapped | 274432 | ER-- --- | ||
| 004B3000 | Reserve | 2871296 | ER-- --- | ||
| 00770000 | Private | 4096 | 1 | -RW- | |
| 00770000 | Private | 4096 | -RW- --- | ||
| 00771000 | Free | 61440 | |||
| 00780000 | Private | 4096 | 1 | -RW- | |
| 00780000 | Private | 4096 | -RW- --- | ||
| 00781000 | Free | 61440 | |||
| 00790000 | Private | 65536 | 2 | -RW- | |
| 00790000 | Private | 20480 | -RW- --- | ||
| 00795000 | Reserve | 45056 | -RW- --- | ||
| 007A0000 | Mapped | 8192 | 1 | -R-- | \Device\HarddiskVolume1\ WINNT\system32\ctype.nls |
| 007A0000 | Mapped | 8192 | -R-- --- | ||
| 007A2000 | Free | 57344 | |||
| 007B0000 | Private | 524288 | 2 | -RW- | |
| 007B0000 | Private | 4096 | -RW- --- | ||
| 007B1000 | Reserve | 520192 | -RW- --- | ||
| 00830000 | Free | 1763311616 | |||
| 699D0000 | Image | 45056 | 4 | ERWC | C:\WINNT\System32\PSAPI.dll |
| 699D0000 | Image | 4096 | -R-- --- | ||
| 699D1000 | Image | 16384 | ER-- --- | ||
| 699D5000 | Image | 16384 | -RWC --- | ||
| 699D9000 | Image | 8192 | -R-- --- | ||
| 699DB000 | Free | 238505984 | |||
| 77D50000 | Image | 450560 | 4 | ERWC | C:\WINNT\system32\ RPCRT4.DLL |
| 77D50000 | Image | 4096 | -R-- --- | ||
| 77D51000 | Image | 421888 | ER-- --- | ||
| 77DB8000 | Image | 4096 | -RW- --- | ||
| 77DB9000 | Image | 20480 | -R-- --- | ||
| 77DBE000 | Free | 8192 | |||
| 77DC0000 | Image | 344064 | 5 | ERWC | C:\WINNT\system32\ ADVAPI32.dll |
| 77DC0000 | Image | 4096 | -R-- --- | ||
| 77DC1000 | Image | 307200 | ER-- --- | ||
| 77E0C000 | Image | 4096 | -RW- --- | ||
| 77E0D000 | Image | 4096 | -RWC --- | ||
| 77E0E000 | Image | 24576 | -R-- --- | ||
| 77E14000 | Free | 49152 | |||
| 77E20000 | Image | 401408 | 4 | ERWC | C:\WINNT\system32\USER32.dll |
| 77E20000 | Image | 4096 | -R-- --- | ||
| 77E21000 | Image | 348160 | ER-- --- | ||
| 77E76000 | Image | 4096 | -RW- --- | ||
| 77E77000 | Image | 45056 | -R-- --- | ||
| 77E82000 | Free | 57344 | |||
| 77E90000 | Image | 720896 | 5 | ERWC | C:\WINNT\system32\KERNEL32.dll |
| 77E90000 | Image | 4096 | -R-- --- | ||
| 77E91000 | Image | 368640 | ER-- --- | ||
| 77EEB000 | Image | 8192 | -RW- --- | ||
| 77EED000 | Image | 4096 | -RWC --- | ||
| 77EEE000 | Image | 335872 | -R-- --- | ||
| 77F40000 | Image | 241664 | 4 | ERWC | C:\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 | C:\WINT\System32\ntdll.dll |
| 77F80000 | Image | 4096 | -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 | C:\WINNT\system32\MSVCRT.dll |
| 78000000 | Image | 4096 | -R-- --- | ||
| 78001000 | Image | 208896 | ER-- --- | ||
| 78034000 | Image | 32768 | -R-- --- | ||
| 7803C000 | 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- --- | ||
| 7FFE0000 | Private | 65536 | 2 | -R-- | |
| 7FFE0000 | Private | 4096 | -R-- --- | ||
| 7FFE1000 | Reserve | 61440 | -R-- --- |
Of course, free regions do not expand at all because they have no committed pages of storage within them. Each block line shows four columns, which I'll explain here.
The first column shows the address of a set of pages all having the same state and protection attributes. For example, a single page (4096 bytes) of memory with read-only protection is committed at address 0x77E20000. At address 0x77E21000, there is a block of 85 pages (348,160 bytes) of committed storage that has execute and read protection. If both of these blocks had the same protection attributes, the two would be combined and would appear as a single 86-page (352,256-byte) entry in the memory map.
The second column shows what type of physical storage is backing the block within the reserved region. One of five possible values can appear in this column: Free, Private, Mapped, Image, or Reserve. A value of Private, Mapped, or Image indicates that the block is backed by physical storage in the paging file, a data file, or a loaded .exe or DLL file, respectively. If the value is Free or Reserve, the block is not backed by any physical storage at all.
For the most part, the same type of physical storage backs all the committed blocks within a single region. However, it is possible for different committed blocks within a single region to be backed by different types of physical storage. For example, a memory-mapped file image will be backed by an .exe or a DLL file. If you were to write to a single page in this region that had PAGE_WRITECOPY or PAGE_EXECUTE_WRITECOPY, the system would make your process a private copy of the page backed by the paging file instead of the file image. This new page would have the same attributes as the original page without the copy-on-write protection attribute.
The third column shows the size of the block. All blocks are contiguous within a region—there will not be any gaps.
The fourth column shows the number of blocks within the reserved region.
The fifth column shows the protection attributes and protection attribute flags of the block. A block's protection attributes override the protection attributes of the region that contains the block. The possible protection attributes are identical to those that can be specified for a region; however, the protection attribute flags PAGE_GUARD, PAGE_NOCACHE, and PAGE_WRITECOMBINE—which are never associated with a region—can be associated with a block.
Address Space Differences for Windows 98
Table 13-4 shows the address space map when the same VMMap program is executed under Windows 98. To conserve space, the range of virtual addresses between 0x80018000 and 0x85620000 is not shown.
Table 13-4. A sample address space map showing blocks within regions under Windows 98
| Base Address | Type | Size | Blocks | Protection Attribute(s) | Description |
|---|---|---|---|---|---|
| 00000000 | Free | 4194304 | |||
| 00400000 | Private | 131072 | 6 | ---- | C:\CD\X86\DEBUG\14 VMMAP.EXE |
| 00400000 | Private | 8192 | -R-- --- | ||
| 00402000 | Private | 8192 | -RW- --- | ||
| 00404000 | Private | 73728 | -R-- --- | ||
| 00416000 | Private | 8192 | -RW- --- | ||
| 00418000 | Private | 8192 | -R-- --- | ||
| 0041A000 | Reserve | 24576 | ---- --- | ||
| 00420000 | Private | 1114112 | 4 | ---- | |
| 00420000 | Private | 20480 | -RW- --- | ||
| 00425000 | Reserve | 1028096 | ---- --- | ||
| 00520000 | Private | 4096 | -RW- --- | ||
| 00521000 | Reserve | 61440 | ---- --- | ||
| 00530000 | Private | 65536 | 2 | -RW- | |
| 00530000 | Private | 4096 | -RW- --- | ||
| 00531000 | Reserve | 61440 | -RW- --- | ||
| 00540000 | Private | 1179648 | 6 | ---- | Thread Stack |
| 00540000 | Reserve | 942080 | ---- --- | ||
| 00626000 | Private | 4096 | -RW- --- | ||
| 00627000 | Reserve | 24576 | ---- --- | ||
| 0062D000 | Private | 4096 | ---- --- | ||
| 0062E000 | Private | 139264 | -RW- --- | ||
| 00650000 | Reserve | 65536 | ---- --- | ||
| 00660000 | Private | 1114112 | 4 | ---- | |
| 00660000 | Private | 20480 | -RW- --- | ||
| 00665000 | Reserve | 1028096 | ---- --- | ||
| 00760000 | Private | 4096 | -RW- --- | ||
| 00761000 | Reserve | 61440 | ---- --- | ||
| 00770000 | Private | 1048576 | 2 | -RW- | |
| 00770000 | Private | 32768 | -RW- --- | ||
| 00778000 | Reserve | 1015808 | -RW- --- | ||
| 00870000 | Free | 2004418560 | |||
| 78000000 | Private | 262144 | 3 | ---- | C:\WINDOWS\SYSTEM\MSVCRT.DLL |
| 78000000 | Private | 188416 | -R-- --- | ||
| 7802E000 | Private | 57344 | -RW- --- | ||
| 7803C000 | Private | 16384 | -R-- --- | ||
| 78040000 | Free | 133955584 | |||
| 80000000 | Private | 4096 | 1 | ---- | |
| 80000000 | Reserve | 4096 | ---- --- | ||
| 80001000 | Private | 4096 | 1 | ---- | |
| 80001000 | Private | 4096 | -RW- --- | ||
| 80002000 | Private | 4096 | 1 | ---- | |
| 80002000 | Private | 4096 | -RW- --- | ||
| 80003000 | Private | 4096 | 1 | ---- | |
| 80003000 | Private | 4096 | -RW- --- | ||
| 80004000 | Private | 65536 | 2 | ---- | |
| 80004000 | Private | 32768 | -RW- --- | ||
| 8000C000 | Reserve | 32768 | ---- --- | ||
| 80014000 | Private | 4096 | 1 | ---- | |
| 80014000 | Private | 4096 | -RW- --- | ||
| 80015000 | Private | 4096 | 1 | ---- | |
| 80015000 | Private | 4096 | -RW- --- | ||
| 80016000 | Private | 4096 | 1 | ---- | |
| 80016000 | Private | 4096 | -RW- --- | ||
| 80017000 | Private | 4096 | 1 | ---- | |
| 80017000 | Private | 4096 | -RW- --- | ||
| 85620000 | Free | 9773056 | |||
| 85F72000 | Private | 151552 | 1 | ---- | |
| 85F72000 | Private | 151552 | -R-- --- | ||
| 85F97000 | Private | 327680 | 1 | ---- | |
| 85F97000 | Private | 327680 | -R-- --- | ||
| 85FE7000 | Free | 22052864 | |||
| 874EF000 | Private | 4194304 | 1 | ---- | |
| 874EF000 | Reserve | 4194304 | ---- --- | ||
| 878EF000 | Free | 679219200 | |||
| B00B0000 | Private | 880640 | 3 | ---- | |
| B00B0000 | Private | 233472 | -R-- --- | ||
| B00E9000 | Private | 20480 | -RW- --- | ||
| B00EE000 | Private | 626688 | -R-- --- | ||
| B0187000 | Free | 177311744 | |||
| BAAA0000 | Private | 315392 | 7 | ---- | |
| BAAA0000 | Private | 4096 | -R-- --- | ||
| BAAA1000 | Private | 4096 | -RW- --- | ||
| BAAA2000 | Private | 241664 | -R-- --- | ||
| BAADD000 | Private | 4096 | -RW- --- | ||
| BAADE000 | Private | 4096 | -R-- --- | ||
| BAADF000 | Private | 32768 | -RW- --- | ||
| BAAE7000 | Private | 24576 | -R-- --- | ||
| BAAED000 | Free | 86978560 | |||
| BFDE0000 | Private | 20480 | 1 | ---- | |
| BFDE0000 | Private | 20480 | -R-- --- | ||
| BFDE5000 | Free | 45056 | |||
| BFDF0000 | Private | 65536 | 3 | ---- | |
| BFDF0000 | Private | 40960 | -R-- --- | ||
| BFDFA000 | Private | 4096 | -RW- --- | ||
| BFDFB000 | Private | 20480 | -R-- --- | ||
| BFE00000 | Free | 131072 | |||
| BFE20000 | Private | 16384 | 3 | ---- | |
| BFE20000 | Private | 8192 | -R-- --- | ||
| BFE22000 | Private | 4096 | -RW- --- | ||
| BFE23000 | Private | 4096 | -R-- --- | ||
| BFE24000 | Free | 245760 | |||
| BFE60000 | Private | 24576 | 3 | ---- | |
| BFE60000 | Private | 8192 | -R-- --- | ||
| BFE62000 | Private | 4096 | -RW- --- | ||
| BFE63000 | Private | 12288 | -R-- --- | ||
| BFE66000 | Free | 40960 | |||
| BFE70000 | Private | 24576 | 3 | ---- | |
| BFE70000 | Private | 8192 | -R-- --- | ||
| BFE72000 | Private | 4096 | -RW- --- | ||
| BFE73000 | Private | 12288 | -R-- --- | ||
| BFE76000 | Free | 40960 | |||
| BFE80000 | Private | 65536 | 3 | ---- | C:\WINDOWS\SYSTEM\ADVAPI32.DLL |
| BFE80000 | Private | 49152 | -R-- --- | ||
| BFE8C000 | Private | 4096 | -RW- --- | ||
| BFE8D000 | Private | 12288 | -R-- --- | ||
| BFE90000 | Private | 573440 | 3 | ---- | |
| BFE90000 | Private | 425984 | -R-- --- | ||
| BFEF8000 | Private | 4096 | -RW- --- | ||
| BFEF9000 | Private | 143360 | -R-- --- | ||
| BFF1C000 | Free | 16384 | |||
| BFF20000 | Private | 155648 | 5 | ---- | C:\WINDOWS\SYSTEM\GDI32.DLL |
| BFF20000 | Private | 126976 | -R-- --- | ||
| BFF3F000 | Private | 8192 | -RW- --- | ||
| BFF41000 | Private | 4096 | -R-- --- | ||
| BFF42000 | Private | 4096 | -RW- --- | ||
| BFF43000 | Private | 12288 | -R-- --- | ||
| BFF46000 | Free | 40960 | |||
| BFF50000 | Private | 69632 | 3 | ---- | C:\WINDOWS\SYSTEM\USER32.DLL |
| BFF50000 | Private | 53248 | -R-- --- | ||
| BFF5D000 | Private | 4096 | -RW- --- | ||
| BFF5E000 | Private | 12288 | -R-- --- | ||
| BFF61000 | Free | 61440 | |||
| BFF70000 | Private | 585728 | 5 | ---- | C:\WINDOWS\SYSTEM\KERNEL32.DLL |
| BFF70000 | Private | 352256 | -R-- --- | ||
| BFFC6000 | Reserve | 12288 | ---- --- | ||
| BFFC9000 | Private | 16384 | -RW- --- | ||
| BFFCD000 | Private | 90112 | -R-- --- | ||
| BFFE3000 | Reserve | 114688 | ---- --- | ||
| BFFFF000 | Free | 4096 |
The biggest difference between the two address space maps is the lack of information offered under Windows 98. For example, each region and block will reflect whether the area of address space is Free, Reserve, or Private. You will never see the words Mapped or Image because Windows 98 does not offer the additional information indicating whether the physical storage backing the region is a memory-mapped file or is contained in an .exe or a DLL's file image.
You'll notice that most of the region sizes are exact multiples of the allocation granularity (64 KB). If the sizes of the blocks contained within a region do not add up to a multiple of the allocation granularity, there is frequently a block of reserved address space at the end of the region. This block is whatever size is needed to bring the region to an allocation granularity boundary (64 KB). For example, the region starting at address 0x00530000 consists of 2 blocks: a 4-KB committed block of storage and a reserved block that occupies a 60-KB range of memory addresses.
Finally, the protection flags never reflect execute or copy-on-write access because Windows 98 does not support these flags. The three protection attribute flags—PAGE_NOCACHE, PAGE_WRITECOMBINE, and PAGE_GUARD— are also not supported. Because the PAGE_GUARD flag is not supported, VMMap uses a more complicated technique to determine whether a region of address space is reserved for a thread's stack.
You will notice that, unlike Windows 2000, in Windows 98 the region of address space between 0x80000000 and 0xBFFFFFFF can be examined. This is the partition that contains the address space shared by all 32-bit applications. As you can see, the four system DLLs are loaded into this region of address space and are therefore available to all processes.