3

I'm trying to alter my interrupt table to take over the keyboard interrupt. My end goal is to write my new interrupt routine, copy myself into RAM and make the real-mode interrupt table point to me.

I have found random sample code online but it is missing explanations on how to get the address of the original interrupt. They simply have variables in their place, and how to put itself into memory.

So my question is how do I figure out or print to my screen the real mode interrupt table?

And/OR if someone has any good code examples of doing this to either disable certain keys or beep on certain keys I'd really appreciate it.

Thanks!

starblue
  • 55,348
  • 14
  • 97
  • 151
Without Me It Just Aweso
  • 4,593
  • 10
  • 35
  • 53
  • This sounds like a worm implementation! – Nikolaos Oct 23 '09 at 19:55
  • 5
    Wouldn't be an effective worm since on any modern platform running in 32-bit protected mode you can't write to the interrupt descriptor table via this method. – Michael Oct 23 '09 at 20:00

2 Answers2

4

In 16-bit real mode, the interrupt table starts at address 0, with 256 4 byte entries. Each of the 256 interrupt vectors gets a 4 byte address (segment + offset) in that table.

http://en.wikipedia.org/wiki/Interrupt_descriptor_table has some more detail.

Michael
  • 54,279
  • 5
  • 125
  • 144
  • This is correct, with the exception that you can relocate the IDT using the `LIDT` instruction. You can see the current location of the IDT using the `SIDT` instruction. In real modes bits [15:0] of the result hold the IDT base. You access the relevant interrupt vector using that. – Nathan Fellman Oct 24 '09 at 07:06
  • Are they organized such that say I want address of int 16 it would be result of SIDT+(16*4bytes)? So every 4 bytes is the next sequential interrupt address? – Without Me It Just Aweso Oct 26 '09 at 11:50
  • @NathanFellman you're talking about the IDT, which is exclusive to protected mode. Real mode has only an IVT, which is different, and always at a fixed location in memory, beginning at address 0. – James M. Lay Jan 15 '17 at 00:41
  • @JamesM.Lay: I don't see anything in the SDM that keeps you from executing LIDT in RM, nor do I see a reference that says that vectoring during RM doesn't use the IDT. – Nathan Fellman Jan 15 '17 at 11:31
  • @NathanFellman Yeah, the information has kinda been lost to history. LIDT wasn't supported on x86 processors until the intel 80286, which was the first x86 processor to market to support protected mode (the chip was 16-bit, so we're talking about 16-bit protected mode. Not well documented these days). In other words, you can load an IDT, but it will not be functional until you enter protected mode. The system will still respect the IVT starting at 0x0000:0x0000. – James M. Lay Jan 15 '17 at 22:18
  • More information if anyone finds it helpful: https://en.wikipedia.org/wiki/Intel_80286#Protected_mode https://en.wikipedia.org/wiki/X86_instruction_listings http://ragestorm.net/downloads/286intel.txt (286 manual in text form) – James M. Lay Jan 15 '17 at 22:22
  • @JamesM.Lay: I just wrote some code to test this, and it appears that, at least in recent Intel processors, the IDT is used even in real mode. – Nathan Fellman Jan 16 '17 at 12:49
  • @NathanFellman, well I'll be darned! I also found a forum in which some person supposedly achieved moving the IVT to a different base address in real mode. I'll have to try it myself. – James M. Lay Jan 16 '17 at 14:28
2

If your program is running under DOS, you can (and probably should) use the DOS-provided API:

  MOV  AH,35H    ; function 35H is Get Vector
  MOV  Al,9      ; slot in IDT for keyboard interrupt
  INT  21H       ; call DOS, contents of old vector in ES:BX (save them somewhere)
   .
   .
  MOV  AH,25H    ; function 25H is Set Vector
  MOV  AL,9
  PUSH CS        ; the new vector is passed in DS:DX, so copy CS to DS
  POP  DS        :  (assuming your new handler is in the same seg as other code)
  MOV  DX,NewHandler
  INT 21H
I. J. Kennedy
  • 24,725
  • 16
  • 62
  • 87