当前位置:早雪网网络学院编程文档其他语言 → 《Undocumented Windows 2000 Secrets》翻译 --- 第四章(9)

《Undocumented Windows 2000 Secrets》翻译 --- 第四章(9)

减小字体 增大字体 作者:未知  来源:supcode.com收集整理  发布时间:2005-7-1 14:43:21

第四章  探索Windows 2000的内存管理机制

翻译:Kendiv( fcczj@263.net )

更新:Tuesday, February 22, 2005

 

声明:转载请注明出处,并保证文章的完整性,本人保留译文的所有权利。

 

Windows 2000的分段和描述符

w2k_mem.exe的另一个很棒的选项是+e,该选项将显示和说明处理器的段寄存器和描述表的内容。示列4-13给出了其典型输出。CSDSES段寄存器的内容非常清晰的证明了Windows 2000为每个进程提供了平坦的4GB地址空间:起始于0x00000000,终止于0xFFFFFFFF示列4-13中最右边的标志符用来表示段的类型,该段的类型由它的描述符的Type成员给出。代码和数据段的Type属性可分别符号化为“cra”和“ewa”。省略号“-”意味着相应的属性没有设置。一个任务状态段(Task State SegmentTSS)仅能有“a”(可用)和“b”(忙)两种属性。4-5给出了所有可用的属性。示列4-13展示了Windows 2000CS段的不一致性,CS段允许执行和读取,而DSESFSSS段的属性则是可扩展和读/写访问。另一个不明显但十分重要的细节是CSFSSS段的DPL在用户模式和内核模式并不相同。DPL是描述符特权级别(Descriptor Privilege Level)。对于代码段(CS),仅当调用者位于其DPL指定的特权级时才能调用该段中的代码(参考Intel 1999c, pp. 4-8f)。在用户模式,CS段的DPL3;在内核模式,其DPL0。对于数据段(DS),其DPL是最低的特权级,在用户模式下,所有特权级都可访问它,而在内核模式下,仅允许特权0访问。

 

示列4-13.  显示CPU信息

 

IDTGDT寄存器的内容显示了GDT的范围是:0x8003F000 --- 0x8003F3FF,紧随其后的就是IDT,其地址范围是:0x8003F400 --- 0x8003FBFF。由于每个描述符占用64位,故GDTIDT分别包含128256个项。注意,GDT可容纳8,192个项,但Windows 2000仅使用了其中的一小部分。

 

4-5   代码和数据段的Type属性

 

         

CODE

c

使段一致(低特权的代码可能进入)

CODE

r

允许读访问(和仅执行访问相斥)

CODE

a

段可以访问

DATA

e

向下扩展段(堆栈段的典型属性)

DATA

w

允许写访问(和仅读取访问相斥)

DATA

a

段可以访问

TSS32

a

任务状态段可用

TSS32

b

任务状态段繁忙

 

 

W2k_mem.exe还提供了两个很有特色的选项----+g+i,这两个选项可显示GDTIDT的更多细节。示列4-14示范了+g选项的输出。它很类似于示列4-13中的“kernel-model segment:”一节,但列出了在内核模式下所有可用的段选择子(selector),而不仅仅是存储在段寄存器中的那些。W2k_mem.exe通过遍历整个GDT来获取所有的段选择子,可通过IOCTL函数SPY_IO_SEGMENT来指示Spy设备查询段信息。仅显示有效的选择子。比较示列4-134-14中的GDT选择子将十分有趣,GDT的选择子定义于ntddk.h中,汇总在4-6。显然,它们与w2k_mem.exe的输出是一致的。

 

示列4-14.   显示GDT描述符

 

4-6.  定义于ntddk.h中的GDT选择子(selector

   

        

KGDT_NULL

0x0000

空的段选择子(无效)

KGDT_R0_CODE

0x0008

内核模式的CS寄存器

KGDT_R0_DATA

0x0010

内核模式的SS寄存器

KGDT_R3_CODE

0x0018

用户模式的CS寄存器

KGDT_R3_DATA

0x0020

用户模式的DSESSS寄存器,内核模式的DSES寄存器

KGDT_TSS

0x0028

位于用户和内核的任务状态段

KGDT_R0_PCR

0x0030

内核模式的FS寄存器(处理器控制区域)

KGDT_R3_TEB

0x0038

用户模式的FS寄存器(线程环境块)

KGDT_VDM_TILE

0x0040

基地址0x00000400,限制0x0000FFFFDOS虚拟机)

KGDT_LDT

0x0048

本地描述符表

KGDT_DF_TSS

0x0050

Ntoskrnl.exe 变量 KiDoubleFaultTSS

KGDT_NMI_TSS

0x0058

Ntoskrnl.exe 变量 KiNMITSS

 

示列4-14中的选择子(selector)没有在4-6中列出,其中的某些选择子可以通过查找熟悉的基地址或其内存内容来确认它们。使用内核调试器可查找其中某些选择子的基地址对应的符号。4-7给出了我已经确认的选择子。

 

W2k_mem.exe+i选项可转储IDT中的门描述符(Gate Descriptor)。示列4-15给出了IDT的门描述符的部分内容,Intel仅定义了IDT中的前20个门描述符(Intel 1999c, pp. 5-6)。IDT中的中断0x140x1FIntel保留;剩余的0x200xFF由操作系统使用。

 

4-8中,我给出了所有可确认的特殊的中断、陷阱和任务门。大多数用户自定义的中断都指向哑元例程---KiUnexpectedinterruptnNNN(),在前面我们已经解释过它。对于某些中断处理例程的地址,内核调试器也无法解析其地址对应的符号。

 

4-7.  更多的GDT选择子(selector

基地址

            

0x0078

0x80400000

Ntoskrnl.exe的代码段

0x0080

0x80400000

Ntoskrnl.exe的数据段

0x00A0

0x814985A8

TSSEIP成员指向HalpMcaExceptionHandlerWrapper

0x00E0

0xF0430000

ROM BIOS代码段

0x00F0

0x8042DCE8

Ntoskrnl.exe函数KiI386CallAbios

0x0100

0xF0440000

ROM BIOS数据段

0x0108

0xF0440000

ROM BIOS数据段

0x0110

0xF0440000

ROM BIOS数据段

 

示列4-15.  显示IDT门描述符

 

4-8.  Windows 2000 中断、陷阱和任务门

INT

Intel定义的描述符

拥有者

处理例程/TSS

0x00

整除错误(DE

ntoskrnl.exe

KiTrap00

0x01

调试(DB

ntoskrnl.exe

KiTrap01

0x02

NMI中断

ntoskrnl.exe

KiNMITSS

0x03

断点(BP

ntoskrnl.exe

KiTrap03

0x04

溢出(OF

ntoskrnl.exe

KiTrap04

0x05

越界(BR

ntoskrnl.exe

KiTrap05

0x06

未定义的操作码(UD

ntoskrnl.exe

KiTrap06

0x07

没有数学协处理器(NM

ntoskrnl.exe

KiTrap07

0x08

Double FaultDF

ntoskrnl.exe

KiDouble

0x09

协处理器段溢出

ntoskrnl.exe

KiTrap09

0x0A

无效的TSSTS

ntoskrnl.exe

KiTrap0A

0x0B

段不存在(NP

ntoskrnl.exe

KiTrap0B

0x0C

堆栈段故障(SS

ntoskrnl.exe

KiTrap0C

0x0D

常规保护(GP

ntoskrnl.exe

KiTrap0D

0x0E

页故障(PF

ntoskrnl.exe

KiTrap0E

0x0F