4,6 The Native API
A Closer Look at the IDT
When Windows starts up, it checks to see what sort of processor it's running
on and adjusts Its system call invocations accordingly. Specifically, if the
processor predates the Pentium II, the INT Ox2E instruction is used to make
system calls. For more recent IA-32 processors, Windows relieves the IDT of
this duty in favor of using the special-purpose SYSENTER instruction to make
the jump to kerncl-space code. Hence, most contemporary installations of
Windows only use the IDT to respond to hardware-generated signals and
handle processor exceptions.
>-
Note: Each processor has its own IDTR register. Thus, it makes sense that each procesĀ¬
sor will also have its own IDT. This way, different processors can invoke different ISRs
(interrupt service routines) if they need to. For instance, on a machine with multiple
processors, all of the processors must acknowledge the clock interrupt. However, only
one processor increments the system clock.
According to the Intel specifications, the IDT (which Intel refers to as the
interrupt descriptor table) can contain at most 256 descriptors, each of which
is 8 bytes in size. We can detemnine the base address and size of the IDT by
dumping the descriptor registers.
Itd> rM 0x100
gdtr=82430000 gdtl=03ff idtr=82430400 idtl=07ff tr=0028 1dtr=0000
This tells us that the IDT begins at linear address 0x82430400 and has 256
entries. The address of the IDT's last byte is the sum of the base address in
IDTR and the limit in IDTL.
If we wanted to, we could dump the values in memory from linear address
0x82430400 to 0x82430BFF and then decode the descriptors manually. There is,
however, an easier way. The ! i vt kernel-mode debugger extension comĀ¬
mand can be used to dump the name and addresses of the corresponding ISR
routines.
kd> !idt -a
00: 8188d5bO ntlKiTrapOO
01; 8188d830 ntlKiTrapOl
02: Task SGlector = 0x0058
03: 8188dc84 nt!KiTrap03
Parti I 157