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