Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Adding a software interrupt (XP on x86)

I would like to add a new software interrupt to the Interrupt Descriptor Table (IDT) while executing a E-series device driver in kernel mode.
My problem is that I get a 0xC0000005: STATUS_ACCESS_VIOLATION error when I access an entry in the IDT. I access the IDT as part of an AddInterrupt() routine I call in HandleStartDevice(). I am baffled.
Thank you.

HandleStartDevice() {
...
AddInterrupt()
}
 
/* Interrupt to be added */
#define ADDINT 0x22
 
/* sidt instruction stores the base and limit of IDTR in this format */
typedef struct idtr {
short Limit; // 16 bits
unsigned int Base; // 32 bits
} Idtr_t, *PIdtr_t;
 
/* Decriptor Entry corresponding to interrupt gate */
typedef struct idtentry { // is 8 bytes bytes : should be 8 bytes
unsigned short OffsetLow;  // 2 bytes  : 2 bytes   ok
unsigned short Selector;   // 2 bytes  : 2 bytes   ok
unsigned char Reserved;    // 8 bits
unsigned char Always1:3;    // 3 bits
unsigned char Type:1;      // 1 bits
unsigned char Always0:1;   // 1 bits
unsigned char Dpl:2;       // 2 bits
unsigned char Present:1;   // 1 bits
unsigned short OffsetHigh; // 2 bytes
} IdtEntry_t, *PIdtEntry_t;
 
/* Old Idt Entry */
IdtEntry_t OldIdtEntry;
 
/* Buffer to store result of sidt instruction */
char buffer[6]; // 48 bits: 16 bits LIMIT, 32 bits BASE
 
/* Pointer to structure to identify the limit and base of IDTR*/
PIdtr_t Idtr= (PIdtr_t) buffer;
 
NTSTATUS AddInterrupt() {
 PIdtEntry_t  IdtEntry;
 /* Get the Base and Limit of IDT table */
 _asm sidt buffer
 IdtEntry=(PIdtEntry_t)Idtr->Base;
 
 if ((IdtEntry[ADDINT].OffsetLow!=0) || (IdtEntry[ADDINT].OffsetHigh!=0))
   return STATUS_UNSUCCESSFUL;
--> // 0xC0000005: STATUS_ACCESS_VIOLATION
...
}
0 Kudos
Message 1 of 5
(9,639 Views)
Hi,

I don't think you should/can be manipulating the IDT directly.  That's something you would do in DOS.  Instead use the windows API functions IoConnectInterrupt and IoDisconnectInterrupt.

You can get most of the parameters required by the IoConnectInterrupt when handling IRP_MN_START_DEVICE (HandleStartDevice() in your code).  Refer to the Comments section of IoConnectInterrupt for details.

Diego.


0 Kudos
Message 2 of 5
(9,562 Views)

Thanks, Diego. Do you know if you can use IoConnectInterrupt to connect a software interrupt ? I couldn't find instances of this being done in driver books or on google.

0 Kudos
Message 3 of 5
(9,555 Views)
Hi,

My bad, I missed the fact that you were talking about a software interrupts, a la 'int 21h' in DOS.  I don't know how that would work.  It doesn't seem like IoConnectInterrupt will work and I wouldn't be surprise if in XP this is not allowed, at least with the documented API available to drivers.  All the references I found talk about Win9x or doing some hacky things in WinNT.  I also found your post on the OSR forums, which is probably a better place for this sort of questions.  I haven't had a chance to read all of it, but I'm curious to see the suggestions you've received.

I don't know if this article is related to what you are trying to do, but here it is anyway: Hooking the kernel directly.  What I found interesting is that you may want to look at using an existing exception (like int3 for breakpoints) instead of adding a new one.  After all, how does a kernel debugger, like Softice, work?  Maybe looking at how debuggers work can give you some alternative ideas.  Windows also allows 3rd party real-time executives to run, which probably need to mess with interrupts and exceptions.

Diego

0 Kudos
Message 4 of 5
(9,548 Views)
I suggest that you have STATUS_ACCESS_VIOLATION because of page attributes. I think MmProtectMdlSystemAddress will help you to set new page protection. Set PAGE_READWRITE, write data and restore old protection

Message Edited by _Great_ on 03-04-2007 11:06 AM

0 Kudos
Message 5 of 5
(9,216 Views)