Home > Articles > Operating Systems, Server > Microsoft Servers

Windows 2000 Memory Internals

Along with the global separation of the 4-GB address space into user-mode and kernel-mode portions, these two halves are subdivided into various smaller blocks. As you might have guessed, most of them contain undocumented structures that serve undocumented purposes. It would be easy to forget about them if they were uninteresting. However, that's not the case—some of them are a real gold mine for anyone developing system diagnosis or debugging software.

Basic Operating System Information

Now the time has come to introduce one of the postponed command line options of the memory spy application w2k_mem.exe. If you take a look at the lower half of the program's help screen in Example 4-1, you will see a section titled "System Status Options." Let's try the option +o, named "display OS information." Example 4-12 shows a sample run on my machine. The data displayed here are the contents of the SPY_OS_INFO structure, defined in Listing 4-13 and set up by the spy device function SpyOutputOsInfo(), also included in Listing 4-13. In Example 4-12, you can already see some characteristic addresses within the 4-GB linear memory space of a process. For example, the valid user address range is reported to be 0x00010000 to 0x7FFEFFFF. You have probably read in other programming books about Windows NT or Windows 2000 that the first and last 64 KB of the user-mode half of linear memory are "no-access regions" that are there to catch wild pointers produced by common programming errors (cf. Solomon 1998, Chapter 5). The output of w2k_mem.exe proves that this is correct.

Example 4-12. Displaying Operating System Information

E:\>w2k_mem +o
[...]
OS information:
---------------

Memory page size         : 4096 bytes
Memory page shift        : 12 bits
Memory PTI  shift        : 12 bits
Memory PDI  shift        : 22 bits
Memory page mask         : 0xFFFFF000
Memory PTI  mask         : 0x003FF000
Memory PDI  mask         : 0xFFC00000
Memory PTE  array        : 0xC0000000
Memory PDE  array        : 0xC0300000

Lowest user address      : 0x00010000
Thread environment block : 0x7FFDE000
Highest user address     : 0x7FFEFFFF
User probe address       : 0x7FFF0000
System range start       : 0x80000000
Lowest system address    : 0xC0800000
Shared user data         : 0xFFDF0000
Processor control region : 0xFFDFF000
Processor control block  : 0xFFDFF120

Global flag              : 0x00000000
i386 machine type        : 0
Number of processors     : 1
Product type             : Windows NT Workstation (1)
Version & Build number   : 5.00.2195
System root              : "E:\WINNT"
[...]

The last three lines of Example 4-12 contain interesting information about the system, mostly extracted from the SharedUserData area at address 0xFFDF0000. The data structure maintained there by the system is called KUSER_SHARED_DATA and is defined in the DDK header file ntddk.h.

Windows 2000 Segments and Descriptors

Another fine option of w2k_mem.exe is +c, which displays and interprets the contents of the processor's segment registers and descriptor tables. Example 4-13 shows the typical output. The contents of the CS, DS, and ES segment registers clearly demonstrate that Windows 2000 provides each process with a flat 4-GB address space: These basic segments start at offset 0x00000000 and have a limit of 0xFFFFFFFF.

The flag characters in the rightmost column indicate the segment type as defined by its descriptor's Type member. The type attributes of code and data segments are symbolized by combinations of the characters "cra" and "ewa," respectively. A dash means that the corresponding attribute is not set. A Task State Segment (TSS) can have the attributes "a" (available) and "b" (busy) only. All applicable attributes are summarized in Table 4-5. Example 4-13 shows that the Windows 2000 CS segments are nonconforming and allow execute/read access, whereas the DS, ES, FS, and SS segments are of expand-up type and allow read/write access. Another inconspicuous but important detail is the different DPL of the CS, FS, and SS segments in user- and kernel-mode. DPL is the Descriptor Privilege Level. For nonconforming code segments, the DPL specifies the privilege level a caller must be on in order to be able to call into this segment (cf. Intel 1999c, pp. 4-8f). In user-mode, the required level is three; in kernel-mode, it is zero. For data segments, the DPL is the lowest privilege level required to be able to access the segment. This means that the FS and SS segments are accessible from all privilege levels in user-mode, whereas only level-0 accesses are allowed in kernel-mode.

Example 4-13. Displaying CPU Information

E:\>w2k_mem +c
[...]
CPU information:
----------------

User mode segments:

CS  : Selector = 001B, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = CODE -ra
DS  : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
ES  : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
FS  : Selector = 0038, Base = 7FFDE000, Limit = 00000FFF, DPL3, Type = DATA -wa
SS  : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
TSS : Selector = 0028, Base = 80244000, Limit = 000020AB, DPL0, Type = TSS32 b

Kernel mode segments:

CS  : Selector = 0008, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = CODE -ra
DS  : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
ES  : Selector = 0023, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
FS  : Selector = 0030, Base = FFDFF000, Limit = 00001FFF, DPL0, Type = DATA -wa
SS  : Selector = 0010, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = DATA -wa
TSS : Selector = 0028, Base = 80244000, Limit = 000020AB, DPL0, Type = TSS32 b

IDT : Limit    = 07FF, Base = 80036400
GDT : Limit    = 03FF, Base = 80036000
LDT : Selector = 0000

CR0 : Contents = 8001003B
CR2 : Contents = 00401050
CR3 : Contents = 06F70000
[...]

The contents of the IDT and GDT registers show that the GDT spans from linear address 0x80036000 to 800363FF, immediately followed by the IDT, occupying the address range 0x80036400 to 0x80036BFF. With each descriptor taking 64 bits, the GDT and IDT contain 128 and 256 entries, respectively. Note that the GDT could comprise as many as 8,192 entries, but Windows 2000 uses only a small fraction of them.

The w2k_mem.exe utility features two more options—+g and +i—that display more details about the GDT and IDT. Example 4-14 demonstrates the output of the +g option. It is similar to the "kernel-mode segments:" section of Example 4-13, but lists all segment selectors available in kernel-mode, not just those that are stored in segment registers. w2k_mem.exe compiles this list by looping through the entire GDT,

Table 4-5. Code and Data Segment Type Attributes

SEGMENT

ATTRIBUTE

DESCRIPTION

CODE

c

Conforming segment (may be entered by less privileged code)

CODE

r

Read-access allowed (as opposed to execute-only access)

CODE

a

Segment has been accessed

DATA

e

Expand-down segment (typical attribute for stack segments)

DATA

w

Write-access allowed (as opposed to read-only access)

DATA

a

Segment has been accessed

TSS32

a

Task State Segment is available

TSS32

b

Task State Segment is busy


querying the spy device for segment information by means of the IOCTL function SPY_IO_SEGMENT. Only valid selectors are displayed. It is interesting to compare Examples 4-13 and 4-14 with the GDT selector definitions in ntddk.h, summarized in Table 4-6. Obviously, they are in accordance with the details reported by w2k_mem.exe.

Example 4-14. Displaying GDT Descriptors

E:\>w2k_mem +g
[...]
GDT information:
----------------

001 : Selector = 0008, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = CODE -ra
002 : Selector = 0010, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = DATA -wa
003 : Selector = 0018, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = CODE -ra
004 : Selector = 0020, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
005 : Selector = 0028, Base = 80244000, Limit = 000020AB, DPL0, Type = TSS32 b
006 : Selector = 0030, Base = FFDFF000, Limit = 00001FFF, DPL0, Type = DATA -wa
007 : Selector = 0038, Base = 7FFDE000, Limit = 00000FFF, DPL3, Type = DATA -wa
008 : Selector = 0040, Base = 00000400, Limit = 0000FFFF, DPL3, Type = DATA -wa
009 : Selector = 0048, Base = E2E6A000, Limit = 00000177, DPL0, Type = LDT
00A : Selector = 0050, Base = 80470040, Limit = 00000068, DPL0, Type = TSS32 a
00B : Selector = 0058, Base = 804700A8, Limit = 00000068, DPL0, Type = TSS32 a
00C : Selector = 0060, Base = 00022AB0, Limit = 0000FFFF, DPL0, Type = DATA -wa
00D : Selector = 0068, Base = 000B8000, Limit = 00003FFF, DPL0, Type = DATA -w-
00E : Selector = 0070, Base = FFFF7000, Limit = 000003FF, DPL0, Type = DATA -w-
00F : Selector = 0078, Base = 80400000, Limit = 0000FFFF, DPL0, Type = CODE -r-
010 : Selector = 0080, Base = 80400000, Limit = 0000FFFF, DPL0, Type = DATA -w-
011 : Selector = 0088, Base = 00000000, Limit = 00000000, DPL0, Type = DATA -w-
014 : Selector = 00A0, Base = 814985A8, Limit = 00000068, DPL0, Type = TSS32 a
01C : Selector = 00E0, Base = F0430000, Limit = 0000FFFF, DPL0, Type = CODE cra
01D : Selector = 00E8, Base = 00000000, Limit = 0000FFFF, DPL0, Type = DATA -w-
01E : Selector = 00F0, Base = 8042DCE8, Limit = 000003B7, DPL0, Type = CODE —-
01F : Selector = 00F8, Base = 00000000, Limit = 0000FFFF, DPL0, Type = DATA -w-
020 : Selector = 0100, Base = F0440000, Limit = 0000FFFF, DPL0, Type = DATA -wa
021 : Selector = 0108, Base = F0440000, Limit = 0000FFFF, DPL0, Type = DATA -wa
022 : Selector = 0110, Base = F0440000, Limit = 0000FFFF, DPL0, Type = DATA –wa
[...]

Table 4-6. GDT Selectors Defined in ntddk.h

SYMBOL

VALUE

COMMENTS

KGDT_NULL

0x0000

Null segment selector (invalid)

KGDT_R0_CODE

0x0008

CS register in kernel-mode

KGDT_R0_DATA

0x0010

SS register in kernel-mode

KGDT_R3_CODE

0x0018

CS register in user-mode

KGDT_R3_DATA

0x0020

DS, ES, and SS register in user-mode, DS and ES register in kernel-mode

KGDT_TSS

0x0028

Task State Segment in user- and kernel-mode

KGDT_R0_PCR

0x0030

FS register in kernel-mode (Processor Control Region)

KGDT_R3_TEB

0x0038

FS register in user-mode (Thread Environment Block)

KGDT_VDM_TILE

0x0040

Base 0x00000400, limit 0x0000FFFF (Virtual DOS Machine)

KGDT_LDT

0x0048

Local Descriptor Table

KGDT_DF_TSS

0x0050

ntoskrnl.exe variable KiDoubleFaultTSS

KGDT_NMI_TSS

0x0058

ntoskrnl.exe variable KiNMITSS


The selectors in Example 4-14 that are not listed in Table 4-6 can in part be identified by looking for familiar base addresses or memory contents, and by using the Kernel Debugger to look up the symbols for some of the base addresses. Table 4-7 comprises the selectors that I have identified so far.

The +i option of w2k_mem.exe dumps the gate descriptors stored in the IDT. Example 4-15 is an excerpt from this rather long list, comprising only the first 20 entries that have a predefined meaning assigned by Intel (Intel 1999c, pp. 5-6). Interrupts 0x14 to 0x1F are reserved for Intel; the remaining range 0x20 to 0xFF is available to the operating system.

In Table 4-8, I have summarized all interrupts that refer to identifiable and nontrivial interrupt, trap, and task gates. Most of the user defined interrupts point to dummy handlers named KiUnexpectedInterruptNNN(), as explained earlier in this chapter. Some interrupt handlers are located at addresses that can't be resolved to symbols by the Kernel Debugger.

Table 4-7. More GDT Selectors

VALUE

BASE

DESCRIPTION

0x0078

0x80400000

ntoskrnl.exe code segment

0x0080

0x80400000

ntoskrnl.exe data segment

0x00A0

0x814985A8

TSS (EIP member points to HalpMcaExceptionHandlerWrapper)

0x00E0

0xF0430000

ROM BIOS code segment

0x00F0

0x8042DCE8

ntoskrnl.exe function KiI386CallAbios

0x0100

0xF0440000

ROM BIOS data segment

0x0108

0xF0440000

ROM BIOS data segment

0x0110

0xF0440000

ROM BIOS data segment


Example 4-15. Displaying IDT Gate Descriptors

E:\>w2k_mem +i
[...]
IDT information:
----------------

00 : Pointer = 0008:804625E6, Base = 00000000, Limit = FFFFFFFF, Type = INT32
01 : Pointer = 0008:80462736, Base = 00000000, Limit = FFFFFFFF, Type = INT32
02 : TSS     = 0058,          Base = 804700A8, Limit = 00000068, Type = TASK
03 : Pointer = 0008:80462A0E, Base = 00000000, Limit = FFFFFFFF, Type = INT32
04 : Pointer = 0008:80462B72, Base = 00000000, Limit = FFFFFFFF, Type = INT32
05 : Pointer = 0008:80462CB6, Base = 00000000, Limit = FFFFFFFF, Type = INT32
06 : Pointer = 0008:80462E1A, Base = 00000000, Limit = FFFFFFFF, Type = INT32
07 : Pointer = 0008:80463350, Base = 00000000, Limit = FFFFFFFF, Type = INT32
08 : TSS     = 0050,          Base = 80470040, Limit = 00000068, Type = TASK
09 : Pointer = 0008:8046370C, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0A : Pointer = 0008:80463814, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0B : Pointer = 0008:80463940, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0C : Pointer = 0008:80463C44, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0D : Pointer = 0008:80463E50, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0E : Pointer = 0008:804648A4, Base = 00000000, Limit = FFFFFFFF, Type = INT32
0F : Pointer = 0008:80464C3F, Base = 00000000, Limit = FFFFFFFF, Type = INT32
10 : Pointer = 0008:80464D47, Base = 00000000, Limit = FFFFFFFF, Type = INT32
11 : Pointer = 0008:80464E6B, Base = 00000000, Limit = FFFFFFFF, Type = INT32
12 : TSS     = 00A0,          Base = 814985A8, Limit = 00000068, Type = TASK
13 : Pointer = 0008:80464C3F, Base = 00000000, Limit = FFFFFFFF, Type = INT32
[...]

Table 4-8. Windows 2000 Interrupt, Trap, and Task Gates

INT

INTEL DESCRIPTION

OWNER

HANDLER/TSS

0x00

Divide Error (DE)

ntoskrnl.exe

KiTrap00

0x01

Debug (DB)

ntoskrnl.exe

KiTrap01

0x02

NMI Interrupt

ntoskrnl.exe

KiNMITSS

0x03

Breakpoint (BP)

ntoskrnl.exe

KiTrap03

0x04

Overflow (OF)

ntoskrnl.exe

KiTrap04

0x05

BOUND Range Exceeded (BR)

ntoskrnl.exe

KiTrap05

0x06

Undefined Opcode (UD)

ntoskrnl.exe

KiTrap06

0x07

No Math Coprocessor (NM)

ntoskrnl.exe

KiTrap07

0x08

Double Fault (DF)

ntoskrnl.exe

KiDouble

0x09

Coprocessor Segment Overrun

ntoskrnl.exe

KiTrap09

0x0A

Invalid TSS (TS)

ntoskrnl.exe

KiTrap0A

0x0B

Segment Not Present (NP)

ntoskrnl.exe

KiTrap0B

0x0C

Stack-Segment Fault (SS)

ntoskrnl.exe

KiTrap0C

0x0D

General Protection (GP)

ntoskrnl.exe

KiTrap0D

0x0E

Page Fault (PF)

ntoskrnl.exe

KiTrap0E

0x0F

(Intel reserved)

ntoskrnl.exe

KiTrap0F

0x10

Math Fault (MF)

ntoskrnl.exe

KiTrap10

0x11

Alignment Check (AC)

ntoskrnl.exe

KiTrap11

0x12

Machine Check (MC)

?

?

0x13

Streaming SIMD Extensions

ntoskrnl.exe

KiTrap0F

0x14-0x1F

(Intel reserved)

ntoskrnl.exe

KiTrap0F

0x2A

User Defined

ntoskrnl.exe

KiGetTickCount

0x2B

User Defined

ntoskrnl.exe

KiCallbackReturn

0x2C

User Defined

ntoskrnl.exe

KiSetLowWaitHighThread

0x2D

User Defined

ntoskrnl.exe

KiDebugService

0x2E

User Defined

ntoskrnl.exe

KiSystemService

0x2F

User Defined

ntoskrnl.exe

KiTrap0F

0x30

User Defined

hal.dll

HalpClockInterrupt

0x38

User Defined

hal.dll

HalpProfileInterrupt


Windows 2000 Memory Areas

The last w2k_mem.exe option that remains to be discussed is the +b switch. It generates an enormously long list of contiguous memory regions within the 4-GB linear address space. w2k_mem.exe builds this list by walking through the entire PTE array at address 0xC0000000, using the spy device's IOCTL function SPY_IO_PAGE_ENTRY. The dSize member contained in each resulting SPY_PAGE_ENTRY structure is added to the linear address associated with the PTE to get the linear address of the next PTE to be retrieved. Listing 4-30 shows the implementation of this option.

Listing 4-30. Finding Contiguous Linear Memory Blocks

DWORD WINAPI DisplayMemoryBlocks (HANDLE hDevice)
    {
    SPY_PAGE_ENTRY spe;
    PBYTE          pbPage, pbBase;
    DWORD          dBlock, dPresent, dTotal;
    DWORD          n = 0;

    pbPage   = 0;
    pbBase   = INVALID_ADDRESS;
    dBlock   = 0;
    dPresent = 0;
    dTotal   = 0;

    n += _printf (L"\r\nContiguous memory blocks:"
                  L"\r\n-------------\r\n\r\n");

    do  {
        if (!IoControl (hDevice, SPY_IO_PAGE_ENTRY,
                        &pbPage, PVOID_,
                        &spe,    SPY_PAGE_ENTRY_))
            {
            n += _printf (L" !!! Device I/O error !!!\r\n");
            break;
            }
        if (spe.fPresent)
            {
            dPresent += spe.dSize;
            }
        if (spe.pe.dValue)
            {
            dTotal += spe.dSize;

            if (pbBase == INVALID_ADDRESS)
                {
                n += _printf (L"%5lu : 0x%08lX ->",
                              ++dBlock, pbPage);

                pbBase = pbPage;
                }
            }
        else
            {
            if (pbBase != INVALID_ADDRESS)
                {
                n += _printf (L" 0x%08lX (0x%08lX bytes)\r\n",
                              pbPage-1, pbPage-pbBase);                pbBase = INVALID_ADDRESS;
                }
            }
        }
    while (pbPage += spe.Size);

    if (pbBase != INVALID_ADDRESS)
        {
        n += _printf (L"0x%08lX\r\n", pbPage-1);
        }
    n += _printf (L"\r\n"
                  L" Present bytes: 0x%08lX\r\n"
                  L" Total   bytes: 0x%08lX\r\n",
                  dPresent, dTotal);
    return n;
    }

Example 4-16 is an excerpt from a sample run on my machine, showing some of the more interesting regions. Some very obvious addresses are 0x00400000, where the image of w2k_mem.exe starts (block #13), and 0x10000000, where the image of w2k_lib.dll is located (block #23). The TEB and PEB pages also are clearly discernible (block #104), as are the hal.dll, ntoskrnl.exe, and win32k.sys areas (blocks #105 and 106). Blocks #340 to 350 are, of course, the valid fragments of the system's PTE array, featuring the page-directory as part of block #347. Block #2122 contains the SharedUserData area, and #2123 comprises the KPCR, KPRCB, and CONTEXT structures containing thread and processor status information.

Example 4-16. A Sample List of Contiguous Memory Blocks

E:\>w2k_mem +b
[...]
Contiguous memory blocks:
-------------------------

    1 : 0x00010000 -> 0x00010FFF (0x00001000 bytes)
    2 : 0x00020000 -> 0x00020FFF (0x00001000 bytes)
    3 : 0x0012D000 -> 0x00138FFF (0x0000C000 bytes)
    4 : 0x00230000 -> 0x00230FFF (0x00001000 bytes)
    5 : 0x00240000 -> 0x00241FFF (0x00002000 bytes)
    6 : 0x00247000 -> 0x00247FFF (0x00001000 bytes)
    7 : 0x0024F000 -> 0x00250FFF (0x00002000 bytes)
    8 : 0x00260000 -> 0x00260FFF (0x00001000 bytes)
    9 : 0x00290000 -> 0x00290FFF (0x00001000 bytes)
   10 : 0x002E0000 -> 0x002E0FFF (0x00001000 bytes)
   11 : 0x002E2000 -> 0x002E3FFF (0x00002000 bytes)
   12 : 0x003B0000 -> 0x003B1FFF (0x00002000 bytes)
   13 : 0x00400000 -> 0x00404FFF (0x00005000 bytes)
   14 : 0x00406000 -> 0x00406FFF (0x00001000 bytes)
   15 : 0x00410000 -> 0x00410FFF (0x00001000 bytes)
   16 : 0x00419000 -> 0x00419FFF (0x00001000 bytes)
   17 : 0x0041B000 -> 0x0041BFFF (0x00001000 bytes)
   18 : 0x00450000 -> 0x00450FFF (0x00001000 bytes)
   19 : 0x00760000 -> 0x00760FFF (0x00001000 bytes)
   20 : 0x00770000 -> 0x00770FFF (0x00001000 bytes)
   21 : 0x00780000 -> 0x00783FFF (0x00004000 bytes)
   22 : 0x00790000 -> 0x00791FFF (0x00002000 bytes)
   23 : 0x10000000 -> 0x10003FFF (0x00004000 bytes)
   24 : 0x10005000 -> 0x10005FFF (0x00001000 bytes)
   25 : 0x1000E000 -> 0x10016FFF (0x00009000 bytes)
   26 : 0x759B0000 -> 0x759B1FFF (0x00002000 bytes)
[...]
  103 : 0x7FFD2000 -> 0x7FFD3FFF (0x00002000 bytes)
  104 : 0x7FFDE000 -> 0x7FFE0FFF (0x00003000 bytes)
  105 : 0x80000000 -> 0xA01A5FFF (0x201A6000 bytes)
  106 : 0xA01B0000 -> 0xA01F2FFF (0x00043000 bytes)
  107 : 0xA0200000 -> 0xA02C7FFF (0x000C8000 bytes)
  108 : 0xA02F0000 -> 0xA03FFFFF (0x00110000 bytes)
  109 : 0xA4000000 -> 0xA4001FFF (0x00002000 bytes)
  110 : 0xBE63B000 -> 0xBE63CFFF (0x00002000 bytes)
[...]
  340 : 0xC0000000 -> 0xC0001FFF (0x00002000 bytes)
  341 : 0xC0040000 -> 0xC0040FFF (0x00001000 bytes)
  342 : 0xC01D6000 -> 0xC01D6FFF (0x00001000 bytes)
  343 : 0xC01DA000 -> 0xC01DAFFF (0x00001000 bytes)
  344 : 0xC01DD000 -> 0xC01E0FFF (0x00004000 bytes)
  345 : 0xC01FD000 -> 0xC01FDFFF (0x00001000 bytes)
  346 : 0xC01FF000 -> 0xC0280FFF (0x00082000 bytes)
  347 : 0xC0290000 -> 0xC0301FFF (0x00072000 bytes)
  348 : 0xC0303000 -> 0xC0386FFF (0x00084000 bytes)
  349 : 0xC0389000 -> 0xC038CFFF (0x00004000 bytes)
  350 : 0xC039E000 -> 0xC03FFFFF (0x00062000 bytes)
[...]
 2121 : 0xFFC00000 -> 0xFFD0FFFF (0x00110000 bytes)
 2122 : 0xFFDF0000 -> 0xFFDF0FFF (0x00001000 bytes)
 2123 : 0xFFDFF000 -> 0xFFDFFFFF (0x00001000 bytes)
[...]
 Present bytes: 0x22AA9000
 Total   bytes: 0x2B8BA000
[...]

The odd thing about the +b option of w2k_mem.exe is that it reports an amount of used memory that is far beyond any reasonable value. Note the summary lines at the end of Example 4-16. Am I really using 700 MB of memory now? The Windows 2000 Task Manager indicates 150 MB—so what's going on here? This strange effect comes from memory block #105, which is reported to range from 0x80000000 to 0xA01A5FFF, spanning 0x201A6000 bytes, which equals 538,599,424 bytes. This is obviously nonsense. The problem is that the entire linear address range from 0x80000000 to 0x9FFFFFFF is mapped to the physical address range 0x00000000 to 0x1FFFFFFF, as already noted earlier in this chapter. All 4-MB pages in this range have valid PDEs in the page-directory at address 0xC0300000, which can be proved by issuing the command w2k_mem +d #0x200 0xC0300800 (Example 4-17). Because all PDEs in the resulting list are odd numbers, the corresponding pages must be present; however, they are not necessarily backed up by physical memory. In fact, large portions of this memory range are really "holes" and seem to be filled with 0xFF bytes if copied to a buffer. Therefore, you shouldn't take the memory usage summary displayed by w2k_mem.exe too seriously.

Example 4-17. The PDEs of the Address Range 0x80000000 to 0x9FFFFFFF

E:\>w2k_mem +d #0x200 0xC0300800
[...]
C0300800..C03009FF: 512 valid bytes

Address  | 00000000 - 00000004 : 00000008 - 0000000C | 0000 0004 0008 000C
---------|---------------------:---------------------|--------------------
C0300800 | 000001E3 - 004001E3 : 008001E3 - 00C001E3 | ...ã .@.ã .?.ã .À.ã
C0300810 | 010001E3 - 014001E3 : 018001E3 - 01C001E3 | ...ã .@.ã .?.ã .À.ã
C0300820 | 020001E3 - 024001E3 : 028001E3 - 02C001E3 | ...ã .@.ã .?.ã .À.ã
C0300830 | 030001E3 - 034001E3 : 038001E3 - 03C001E3 | ...ã .@.ã .?.ã .À.ã
C0300840 | 040001E3 - 044001E3 : 048001E3 - 04C001E3 | ...ã .@.ã .?.ã .À.ã
C0300850 | 050001E3 - 054001E3 : 058001E3 - 05C001E3 | ...ã .@.ã .?.ã .À.ã
C0300860 | 060001E3 - 064001E3 : 068001E3 - 06C001E3 | ...ã .@.ã .?.ã .À.ã
C0300870 | 070001E3 - 074001E3 : 078001E3 - 07C001E3 | ...ã .@.ã .?.ã .À.ã
C0300880 | 080001E3 - 084001E3 : 088001E3 - 08C001E3 | ...ã .@.ã .?.ã .À.ã
C0300890 | 090001E3 - 094001E3 : 098001E3 - 09C001E3 | ...ã .@.ã .?.ã .À.ã
C03008A0 | 0A0001E3 - 0A4001E3 : 0A8001E3 - 0AC001E3 | ...ã .@.ã .?.ã .À.ã
C03008B0 | 0B0001E3 - 0B4001E3 : 0B8001E3 - 0BC001E3 | ...ã .@.ã .?.ã .À.ã
C03008C0 | 0C0001E3 - 0C4001E3 : 0C8001E3 - 0CC001E3 | ...ã .@.ã .?.ã .À.ã
C03008D0 | 0D0001E3 - 0D4001E3 : 0D8001E3 - 0DC001E3 | ...ã .@.ã .?.ã .À.ã
C03008E0 | 0E0001E3 - 0E4001E3 : 0E8001E3 - 0EC001E3 | ...ã .@.ã .?.ã .À.ã
C03008F0 | 0F0001E3 - 0F4001E3 : 0F8001E3 - 0FC001E3 | ...ã .@.ã .?.ã .À.ã
C0300900 | 100001E3 - 104001E3 : 108001E3 - 10C001E3 | ...ã .@.ã .?.ã .À.ã
C0300910 | 110001E3 - 114001E3 : 118001E3 - 11C001E3 | ...ã .@.ã .?.ã .À.ã
C0300920 | 120001E3 - 124001E3 : 128001E3 - 12C001E3 | ...ã .@.ã .?.ã .À.ã
C0300930 | 130001E3 - 134001E3 : 138001E3 - 13C001E3 | ...ã .@.ã .?.ã .À.ã
C0300940 | 140001E3 - 144001E3 : 148001E3 - 14C001E3 | ...ã .@.ã .?.ã .À.ã
C0300950 | 150001E3 - 154001E3 : 158001E3 - 15C001E3 | ...ã .@.ã .?.ã .À.ã
C0300960 | 160001E3 - 164001E3 : 168001E3 - 16C001E3 | ...ã .@.ã .?.ã .À.ã
C0300970 | 170001E3 - 174001E3 : 178001E3 - 17C001E3 | ...ã .@.ã .?.ã .À.ã
C0300980 | 180001E3 - 184001E3 : 188001E3 - 18C001E3 | ...ã .@.ã .?.ã .À.ã
C0300990 | 190001E3 - 194001E3 : 198001E3 - 19C001E3 | ...ã .@.ã .?.ã .À.ã
C03009A0 | 1A0001E3 - 1A4001E3 : 1A8001E3 - 1AC001E3 | ...ã .@.ã .?.ã .À.ã
C03009B0 | 1B0001E3 - 1B4001E3 : 1B8001E3 - 1BC001E3 | ...ã .@.ã .?.ã .À.ã
C03009C0 | 1C0001E3 - 1C4001E3 : 1C8001E3 - 1CC001E3 | ...ã .@.ã .?.ã .À.ã
C03009D0 | 1D0001E3 - 1D4001E3 : 1D8001E3 - 1DC001E3 | ...ã .@.ã .?.ã .À.ã
C03009E0 | 1E0001E3 - 1E4001E3 : 1E8001E3 - 1EC001E3 | ...ã .@.ã .?.ã .À.ã
C03009F0 | 1F0001E3 - 1F4001E3 : 1F8001E3 - 1FC001E3 | ...ã .@.ã .?.ã .À.ã
[...]

The Windows 2000 Memory Map

The last part of this chapter is dedicated to the general layout of the 4-GB linear address space as it is "seen" by a Windows 2000 process. Table 4-9 lists the address ranges of various essential data structures. The big holes between them are used for several purposes, such as load areas for process modules and device drivers, memory pools, working set lists, and the like. Note that some addresses and block sizes might vary considerably from system to system, depending on the memory and hardware configuration, the process properties, and several other variables. Therefore, use this list only as a rough sketch, not as an accurate roadmap.

Some physical memory blocks appear twice or more in the linear address space. For example, the SharedUserData area at linear address 0xFFDF0000 is mirrored at address 0x7FFE0000. Both refer to the same page in physical memory—writing a byte to 0xFFDF0000+n mysteriously changes the value of the byte at 0x7FFE0000+n. This is the world of virtual memory—a physical address can be mapped anywhere into the linear address space, even to several addresses at the same time. It's just a matter of setting up the page-directory and page-tables appropriately. Please recall Figures 4-3 and 4-4, which clearly show that linear addresses are fake. Their Directory and Table bit fields are just pointers to structures that determine the real location of the data. And if the PFNs of two PTEs happen to be identical, the corresponding linear addresses refer to the same physical memory location.

Table 4-9. Identifiable Memory Regions in the Address Space of a Process

START

END

HEX SIZE

TYPE/DESCRIPTION

0x00000000

0x0000FFFF

10000

Lower guard block

0x00010000

0x0001FFFF

10000

WCHAR[]/Environment strings, allocated in 4-KB pages

0x00020000

0x0002FFFF

10000

PROCESS_PARAMETERS/allocated in 4-KB pages

0x00030000

0x0012FFFF

100000

DWORD [4000]/Process stack (default: 1 MB)

0x7FFDD000

0x7FFDDFFF

1000

TEB/Thread Environment Block of thread #2

0x7FFDE000

0x7FFDEFFF

1000

TEB/Thread Environment Block of thread #1

0x7FFDF000

0x7FFDFFFF

1000

PEB/Process Environment Block

0x7FFE0000

0x7FFE02D7

2D8

KUSER_SHARED_DATA/SharedUserData in user-mode

0x7FFF0000

0x7FFFFFFF

10000

Upper guard block

0x80000000

0x800003FF

400

IVT/Interrupt Vector Table

0x80036000

0x800363FF

400

KGDTENTRY[80]/Global Descriptor Table

0x80036400

0x80036BFF

800

KIDTENTRY[100]/Interrupt Descriptor Table

0x800C0000

0x800FFFFF

40000

VGA/ROM BIOS

0x80244000

0x802460AA

20AB

KTSS/user/kernel Task State Segment (busy)

0x8046AB80

0x8046ABBF

40

KeServiceDescriptorTable

0x8046ABC0

0x8046ABFF

40

KeServiceDescriptorTableShadow

0x80470040

0x804700A7

68

KTSS/KiDoubleFaultTSS

0x804700A8

0x8047010F

68

KTSS/KiNMITSS

0x804704D8

0x804708B7

3E0

PROC[F8]/KiServiceTable

0x804708B8

0x804708BB

4

DWORD/KiServiceLimit

0x804708BC

0x804709B3

F8

BYTE[F8]/KiArgumentTable

0x814C6000

0x82CC5FFF

1800000

PFN[100000]/MmPfnDatabase (max. for 4 GB)

0xA01859F0

0xA01863EB

9FC

PROC[27F]/W32pServiceTable

0xA0186670

0xA01868EE

27F

BYTE[27F]/W32pArgumentTable

0xC0000000

0xC03FFFFF

400000

X86_PE[100000]/page-directory and page-tables

0xC1000000

0xE0FFFFFF

20000000

System Cache (MmSystemCacheStart, MmSystemCacheEnd)

0xE1000000

0xE77FFFFF

6800000

Paged Pool (MmPagedPoolStart, MmPagedPoolEnd)

0xF0430000

0xF043FFFF

10000

ROM BIOS code segment

0xF0440000

0xF044FFFF

10000

ROM BIOS data segment

0xFFDF0000

0xFFDF02D7

2D8

KUSER_SHARED_DATA/SharedUserData in kernel-mode

0xFFDFF000

0xFFDFF053

54

KPCR/Processor Control Region (kernel-mode FS segment)

0xFFDFF120

0xFFDFF13B

1C

KPRCB/Processor Control Block

0xFFDFF13C

0xFFDFF407

2CC

CONTEXT/Thread Context (CPU state)

0xFFDFF620

0xFFDFF71F

100

Lookaside list directories


InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.

Overview


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information


To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.

Surveys

Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.

Newsletters

If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information


Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.

Security


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.

Children


This site is not directed to children under the age of 13.

Marketing


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information


If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.

Choice/Opt-out


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information


Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents


California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure


Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.

Links


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact


Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice


We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020