!pcr的IDT和GDT地址为啥是0
有一个同行在格友公众号留言,询问如下问题:
“如何查看windows7 64位系统的全局描述符表(GDT)和中断描述符表(idt)? 在Windows XP可以用!pcr命令查看当前线程下cpu的gdtr和idtr,然后用db命令查看GDT表和idt 表。但是在windows7 64位系统下用!pcr命令查看到的gdtr和idtr都是0,虽然可以用!idt dumping出idt,但是我想用类似db命令查看idt表来验证windows7 64位系统的中断机制,或者说 Windows 7 64位系统采用apic后中断机制不一样,并不可以用像windows xp的方法了?”
简单来说,就是为什么在64位系统中,!pcr命令显示的IDT和GDT地址都是0?
举例来说:
0: kd> !pcr
KPCR for Processor 0 at fffff800045a2000:
Major 1 Minor 1
NtTib.ExceptionList: fffff80005e88000
NtTib.StackBase: fffff80005e89070
NtTib.StackLimit: 000000ddf4a7ca78
NtTib.SubSystemTib: fffff800045a2000
NtTib.Version: 00000000045a2180
NtTib.UserPointer: fffff800045a27f0
NtTib.SelfTib: 000000ddf3f98000
SelfPcr: 0000000000000000
Prcb: fffff800045a2180
Irql: 0000000000000000
IRR: 0000000000000000
IDR: 0000000000000000
InterruptMode: 0000000000000000
IDT: 0000000000000000
GDT: 0000000000000000
TSS: 0000000000000000
CurrentThread: ffffe001da5fe040
NextThread: 0000000000000000
IdleThread: fffff80004618740
不过,直接使用dt命令是可以看到值的:
0: kd> dt _KPCR fffff800045a2000
hal!_KPCR
+0x000 NtTib : _NT_TIB
+0x000 GdtBase : 0xfffff800`05e88000 _KGDTENTRY64
+0x008 TssBase : 0xfffff800`05e89070 _KTSS64
+0x010 UserRsp : 0x000000dd`f4a7ca78
+0x018 Self : 0xfffff800`045a2000 _KPCR
+0x020 CurrentPrcb : 0xfffff800`045a2180 _KPRCB
+0x028 LockArray : 0xfffff800`045a27f0 _KSPIN_LOCK_QUEUE
+0x030 Used_Self : 0x000000dd`f3f98000 Void
+0x038 IdtBase : 0xfffff800`05e88070 _KIDTENTRY64
+0x040 Unused : [2] 0
+0x050 Irql : 0 ''
+0x051 SecondLevelCacheAssociativity : 0x10 ''
+0x052 ObsoleteNumber : 0 ''
+0x053 Fill0 : 0 ''
+0x054 Unused0 : [3] 0
+0x060 MajorVersion : 1
+0x062 MinorVersion : 1
+0x064 StallScaleFactor : 0x5bb
+0x068 Unused1 : [3] (null)
+0x080 KernelReserved : [15] 0
+0x0bc SecondLevelCacheSize : 0x100000
+0x0c0 HalReserved : [16] 0x576b9bb0
+0x100 Unused2 : 0
+0x108 KdVersionBlock : (null)
+0x110 Unused3 : (null)
+0x118 PcrAlign1 : [24] 0
使用r命令直接观察寄存器也可以看到同样的结果:
0: kd> r idtr
idtr=fffff80005e88070
0: kd> r gdtr
gdtr=fffff80005e88000
那么为啥!pcr显示全0呢?应该是因为!pcr命令没有与时俱进,内核的数据结构变化了,但是这个扩展命令没有很好更新。