Page 1 of 1

Interrupt Injection in Windows XP

Posted: Fri May 16, 2014 1:23 am
by watermirror
hi, i am develop a system about virturalization. i have a problem with injection interrupt.

my purpose is to take control the network communication of the windowsxp. let the VMM to control a NIC, after it receives data, delivery it to windowsxp.
I do not provide a emulation of a NIC in windows. so, in WDK's sample, there's a virtual driver netvmini, it seems right for me. but the virtual dirver have a key problem, since it is virtual ,i can not install any ISR by any API.
so , i think the if it possible install a isr directly to windowsxp's IDT. i get the idt's base address, found a null entry which vector is 0x20.then initialize the entry as interrupt gate, and store my isr's address into that gate.
the next thing for me is injection a interrupt to windowsxp.when there's a external interrupt, the VMExit happened, VMM start to work. If the VMM found there's data in NIC, it injection a interrupt which vector is 0x20 to windowxp.
at this time , my proble came out. the ISR i installed in IDT seems not working properly-windowsxp crash.

my isr is like this:

Code: Select all

void _declspec(naked) interrupt_handler()
{
    _asm pushad;
 
    //there's nothing here, i just want to see if the interrupt injection work correctly.
 
    _asm{
        popad
        iretd
    }
}
now , i do not know what could i do.is there any special things i am wrong in interrupt injection ?

Re: about interrupt injection

Posted: Fri May 16, 2014 3:27 am
by Nable
How do you modify IDT of guest OS?
What are the exact values that you write into IDT entry (what segment/offset/type/etc) ?
It would be nice if you give some details about the crash - is it a BSOD (then some additional information is shown on the screen) or something like immediate reboot (that may be caused by triple-fault)?

Btw, I'm just curious, what is your native language?

Re: Interrupt Injection in Windows XP

Posted: Fri May 16, 2014 6:14 am
by sortie
I have no idea what you are actually trying to accomplish, but from your partially incomprehensible post, you sound like a crazy person. Are you trying a global solution to fix a local problem? Why are you trying to take control of the Windows XP interrupt handling? How are you even doing so?

Re: Interrupt Injection in Windows XP

Posted: Fri May 16, 2014 6:31 am
by Nable
sortie wrote:I have no idea what you are actually trying to accomplish
I think that topic-starter wants to implement something like VirtIO driver. I may be wrong but at least it looks like a sane explanation of such efforts.

Re: Interrupt Injection in Windows XP

Posted: Sun May 18, 2014 7:31 pm
by watermirror
Hi, my design purpose is like the image in attach file.when there network communication data comming, the phisical NIC in VMM received it firstly. then the VMM must delivery these data to WindowsXP.the Virutal NIC Driver is the one I want to use to receive incomming data from VMM.So, i want to injection a interrupt to WindowsXP, to let the Virtual NIC Driver's ISR to copy the data to upper layer.

I initialize the Virtual NIC Driver's ISR in WindowsXP. Here is my IDT Entry structure:

Code: Select all

#pragma pack(1) 
typedef struct _idtr
{
   short        IDTLimit;
   unsigned int    IDTBase;
}IDTR,*PIDTR;

typedef struct _idtentry
{
   unsigned short    OffsetLow;
   unsigned short    Selector;
   unsigned char        Reserved;
   unsigned char        Type:4;
   unsigned char        SegmentFlag:1;
   unsigned char        DPL:2;
   unsigned char        Present:1;
   unsigned short    OffsetHigh;
}IDTENTRY,*PIDTENTRY;
The initialize function is :

Code: Select all

void InitISR()
{
	 IDTR        idtr;
    PIDTENTRY    IdtEntry;
	unsigned int isradd = (unsigned int)interrupt_handler;
	unsigned short selector = 0;
	int i = 0;

    __asm sidt    idtr;

    IdtEntry = (PIDTENTRY)idtr.IDTBase;
    
   
    for ( i = 0;i < 255; i++)
    {
    	 if (IdtEntry[i].Present == 0 && IdtEntry[i].OffsetLow == 0 && IdtEntry[i].OffsetHigh == 0)
    	 {
    	 	vector = i;
		break;
    	 }
    }	

	memset(IdtEntry + vector, 0 , sizeof(IdtEntry[vector]));
	IdtEntry[vector].Present = 1;
	IdtEntry[vector].OffsetLow = isradd & 0xFFFF;
	IdtEntry[vector].OffsetHigh = (isradd >> 16) & 0xffff;
	IdtEntry[vector].Type = 0xe;
	_asm{
		push ax
		mov ax, cs
		mov selector, ax		

		mov ax, ds
		mov ds_selector, ax
		
		mov ax, es
		mov es_selector, ax
		
		mov ax, fs
		mov fs_selector, ax
		
		mov ax, ss
		mov ss_selector, ax
		
		mov ax, gs
		mov gs_selector, ax
		pop ax
	}
	IdtEntry[vector].Selector = selector;
}
ISR:

Code: Select all

void  _declspec(naked) interrupt_handler()
{

	_asm
	{
		cli
		mov esp, stack_end
		pushad	
		
		mov ax, ds
		push ax
		
		mov ax, es
		push ax
		
		mov ax, ss
		push ax
		
		mov ax, fs
		push ax
		
		mov ax, gs
		push ax
		
		mov ax, ds_selector
		mov ds, ax
		mov ax, es_selector
		mov es, ax
		mov ax, ss_selector
		mov ss, ax
		mov ax, fs_selector
		mov fs, ax
		mov ax, gs_selector
		mov gs, ax
		
		
	}	

	
	_asm
	{
		//pop esp
		pop ax
		mov gs, ax
		pop ax
		mov fs, ax
		pop ax
		mov ss, ax
		pop ax
		mov es, ax
		pop ax
		mov ds, ax
		
		popad	
		sti	
		iretd
	}
}

Re: Interrupt Injection in Windows XP

Posted: Mon May 19, 2014 3:00 am
by feryno
Hi, you must enable external interrupt exiting and also enable acknowledge interrupt on exit (just to know interrupt vector). Then your hypervisor receives all external interrupts and it should inject them back to guest OS.
But the question is what interrupt vector is used for your NIC. Here I'm unable to help you, you must study ms win kernel internals.
You don't need to modify IDT, it is wrong way. Hypervisor may handle everything transparently, no need to modify anything in the guest. Your hypervisor may handle everything itself and then decide whether it already fully handled the external interrupt and discard it (that means execute vmresume/vmrun without injecting the interrupt to the guest) or whether hypervisor didn't handle it and then inject it to the guest on vm entry.

The solution you want to achieve may be used for peaceful as well for bad purposes - you may check for infections as well cause infections.

Re: Interrupt Injection in Windows XP

Posted: Mon May 19, 2014 9:00 pm
by watermirror
feryno wrote:Hi, you must enable external interrupt exiting and also enable acknowledge interrupt on exit (just to know interrupt vector). Then your hypervisor receives all external interrupts and it should inject them back to guest OS.
But the question is what interrupt vector is used for your NIC. Here I'm unable to help you, you must study ms win kernel internals.
You don't need to modify IDT, it is wrong way. Hypervisor may handle everything transparently, no need to modify anything in the guest. Your hypervisor may handle everything itself and then decide whether it already fully handled the external interrupt and discard it (that means execute vmresume/vmrun without injecting the interrupt to the guest) or whether hypervisor didn't handle it and then inject it to the guest on vm entry.

The solution you want to achieve may be used for peaceful as well for bad purposes - you may check for infections as well cause infections.
Hi,I have already enable external interrupt exiting and also enable acknowledge interrupt on exit. Because my virtual NIC is a virtual driver, not actually device, so i can not install the ISR by WDK or WDM's interface. so the only choice for me is to modify IDT.

is there any good resouce about ms win kernel?