0x2C
用户自定义
ntoskrnl.exe
KiSetLowWaitHighThread
0x2D
用户自定义
ntoskrnl.exe
KiDebugSerice
0x2E
用户自定义
ntoskrnl.exe
KiSystemService
0x2F
用户自定义
ntoskrnl.exe
KiTrap0F
0x30
用户自定义
hal.dll
HalpClockInterrupt
0x38
用户自定义
hal.dll
HalpProfileInterrupt
Windows 2000 的内存区域
W2k_mem.exe 的最后一个还未讨论的选项是:b 选项 。该选项会产生 4GB 地址空间中相邻内存区域的列表,这个列表非常大 。W2k_mem.exe 使用 Spy 设备的 IOCTL 函数 SPY_IO_PAGE_ENTRY 遍历整个 PTE 数组(位于地址 0xC0000000 )来生成这个列表 。在作为结果的每个 SPY_PAGE_ENTRY 结构中,通过将它们的 dSize 成员与其对应的 PTE 线性地址相加即可得到下一个 PTE 的地址 。列表 4-30 给出了该选项的实现方式 。
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"rnContiguous memory blocks:"
L"rn-------------------------rnrn");
do {
if (!IoControl (hDevice, SPY_IO_PAGE_ENTRY,
&pbPage, PVOID_,
&spe, SPY_PAGE_ENTRY_))
{
n= _printf (L" !!! Device I/O error !!!rn");
break;
}
if (spe.fPresent)
{
dPresent= spe.dSize;
}
if (spe.pe.dValue)
{
dTotal= spe.dSize;
if (pbBase == INVALID_ADDRESS)
{
n= _printf (L"%5lu : 0xlX ->",
dBlock, pbPage);
pbBase = pbPage;
}
}
else
{
if (pbBase != INVALID_ADDRESS)
{
n= _printf (L" 0xlX (0xlX bytes)rn",
pbPage-1, pbPage-pbBase);
pbBase = INVALID_ADDRESS;
}
}
}
while (pbPage= spe.dSize);
if (pbBase != INVALID_ADDRESS)
{
n= _printf (L"0xlXrn", pbPage-1);
}
n= _printf (L"rn"
L" Present bytes: 0xlXrn"
L" Total bytes: 0xlXrn",
dPresent, dTotal);
return n;
}
列表 4-30. 查找相邻的线性内存块
示列 4-16 摘录了在我的机器上使用b 选项的输出列表,可以看出其中的几个区域非常有趣 。一些非常明显的地址是: 0x00400000 ,这是 w2k_mem.exe 内存映像的起始地址(第 13 号块),还有一个是 0x10000000 ,此处是 w2k_lib.dll 的基地址(第 23 号块) 。TEB 和 PEB 页也很容易认出(第 104 号块), hal.dll (第 105 号块), ntoskrnl.exe (第 105 号块), win32k.sys (第 106 号块) 。第 340---350 号块是系统 PTE 数组的一小段,第 347 号块是页目录的一部分 。第 2122 号块包含 SharedUserData 区域,第 2123 号块由 KPCR 、 KPRCB 和包含线程和进程状态信息的 CONTEXT 结构组成 。
示列 4-16. 相邻内存块列表示列
还需要补充一下, W2k_mem.exe 的b 选项会报告有大量的内存被使用,这可能超出了一个合理的值(比如,你机器上的物理内存数) 。请注意 示列 4-16 底部给出的汇总信息 。我现在真的使用了 700MB 的内存吗? Windows 2000 的任务管理器显示是 150MB ,那么这儿的又是什么呢?这种奇特的效果都是由第 105 号内存块产生的,该内存块表示的范围: 0x80000000----0xA01A5FFF 占用了 0x201A6000 字节,也就是说占用了 538,599,424 字节 。这显然是不可能的 。问题是整个线性地址空间: 0x80000000 ---- 0x9FFFFFFF 都被映射到了物理内存: 0x00000000 ---- 0x1FFFFFFF ,在前面我已经提及过这一点 。该区域中的所有 4MB 页都对应地址 0xC0300000 处的页目录中的一个有效的 PDE ,我们可以使用 w2k_memd #0x200 0xC0300800 命令来证明这一点( 示列 4-17 ) 。因为结果列表中的所有 PDE 都是奇数( 译注:如果 PDE 为奇数,证明其 P 位肯定为 1 ),所以它们对应的页都必须存在;不过,它们并不需真正占用物理内存 。事实上,这一内存区域的大部分都是“空洞( hole )”,如果将其复制到缓冲区中,可发现它们都被 0xFF 填充 。因此,对于 w2k_mem.exe 输出的内存使用情况,你不需要过于认真 。
推荐阅读
- 奶酪陷阱大结局是什么
- 叶澜依结局
- 安装Microsoft Windows 2000 恢复控制台
- 4 《Undocumented Windows 2000 Secrets》翻译 --- 第三章
- 1 《Undocumented Windows 2000 Secrets》翻译 --- 第二章
- 浅谈非系统管理员用户本地登录Windows 2000 server
- 同床异梦秋瓷炫多少期
- Windows 2000进程细述
- 《Undocumented Windows 2000 Secrets》翻译 --- 3
- Windows2000的日志文件详述及删除方法
