In a msg on , to All, John Lobraico writes: JL> Does anybody have any code snippets that will show me how to hook JL> any interrupt in the protected mode interupt table. I'll be doing JL> this as a Vxd so protection shouldn't be a problem. Just like real mode, protected mode interrupts are handled through a table of vectors. Unlike real mode, however, this table can be anywhere in memory. Use the SIDT instruction to get the 48-bit base and limit into memory. From there you can do one of two things. Either you can search the GDT and LDT for a selector which matches the base and limit, or you can create a new selector since VxDs run in ring 0. Once you've done that, you can access the contents of the IDT. Now here's the tricky part. The IDT is a table of gates, one for each interrupt, up to a maximum of 256 interrupts. Unlike the GDT, the first entry in the IDT is used and is valid (for interrupt 0, of course). Each gate entry is eight bytes long and may be one of three possible kinds of descriptors: task gate, interrupt gate, or trap gate. The descriptors are as follows: Task Gate: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 <- bit +-----------------------------------------------+ | RESERVED | 6 +-----------------------------------------------+ | P| DPL | 0 0 1 0 1| RESERVED | 4 +-----------------------------------------------+ | TSS SEGMENT SELECTOR | 2 +-----------------------------------------------+ | RESERVED | 0 <- byte +-----------------------------------------------+ Interrupt Gate: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----------------------------------------------+ | OFFSET 31..16 | 6 +-----------------------------------------------+ | P| DPL | 0 1 1 1 0| 0 0 0| RESERVED | 4 +-----------------------------------------------+ | SEGMENT SELECTOR | 2 +-----------------------------------------------+ | OFFSET 15..0 | 0 +-----------------------------------------------+ Trap Gate: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 +-----------------------------------------------+ | OFFSET 31..16 | 6 +-----------------------------------------------+ | P| DPL | 0 1 1 1 1| 0 0 0| RESERVED | 4 +-----------------------------------------------+ | SEGMENT SELECTOR | 2 +-----------------------------------------------+ | OFFSET 15..0 | 0 +-----------------------------------------------+ DPL = descriptor privilege level OFFSET = offset to procedure entry point P = segment present bit RESERVED = do not use -- reserved by Intel SELECTOR = segment selector for destination code segment To reroute an interrupt vector to your own routine, you'd just have to multiply the interrupt number by eight and place the appropriate gate structure at that location (relative to the start of the IDT). Be warned, though, that whatever selector you load into the structure must still exist whenever the interrupt is triggered or you will suffer difficult-to-trace system crashes. Interrupt gates and trap gates are just like any other gate, but task gates are a bit more complex, referring to the base of a TSS descriptor instead of pointing to interrupt handler code. The part I'm not so sure about is how one would actually "chain" through to the original handler. You can't just JMP through a gate in the IDT since there'd be no way to address it, AFAIK. However, you could copy the original gate to the GDT or to an LDT and jump via that instead. If it's a task gate, I'm sure that will work; if it's a trap or interrupt gate, I'm not as sure since I've never tried it and my documents don't seem to say whether or not JMPing via a task gate is legal. If you go that route, let me know -- I'm curious now.