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?