#include <ntddk.h>
#define Print(message, value) { DbgPrint("[vmm] %-20s 0x[%08X]\n", message, value); }
//
VOID UnloadDriver(IN PDRIVER_OBJECT DriverObject);
/
typedef struct _IDTR {
unsigned Limit :16;
unsigned BaseLo :16;
unsigned BaseHi :16;
} IDTR;
typedef struct _GDTR
{
unsigned Limit :16;
unsigned BaseLo :16;
unsigned BaseHi :16;
} GDTR;
typedef struct {
unsigned LowOffset :16;
unsigned Selector :16;
unsigned Access :16;
unsigned HighOffset :16;
} IDT_ENTRY, *PIDT_ENTRY;
typedef struct
{
unsigned LimitLo :16;
unsigned BaseLo :16;
unsigned BaseMid :8;
unsigned Type :4;
unsigned System :1;
unsigned DPL :2;
unsigned Present :1;
unsigned LimitHi :4;
unsigned AVL :1;
unsigned L :1;
unsigned DB :1;
unsigned Gran :1; // Granularity
unsigned BaseHi :8;
} SEGMENT_DESCRIPTOR, *PSEGMENT_DESCRIPTOR;
ULONG RegGetIDTBase()
{
IDTR idt = {0};
ULONG temp=0;
__asm SIDT idt
temp = idt.BaseHi;
temp <<= 16;
temp |= idt.BaseLo;
return temp;
}
ULONG RegGetGDTBase()
{
GDTR gdt = {0};
ULONG temp=0;
__asm SGDT gdt
temp = gdt.BaseHi;
temp <<= 16;
temp |= gdt.BaseLo;
return temp;
}
ULONG GetSegmentDescriptorBase(ULONG gdt_base, USHORT seg_selector)
{
ULONG base = 0;
SEGMENT_DESCRIPTOR segDescriptor = {0};
RtlCopyBytes( &segDescriptor, (ULONG *)(gdt_base + (seg_selector >> 3) * 8), 8 );
base = segDescriptor.BaseHi;
base <<= 8;
base |= segDescriptor.BaseMid;
base <<= 16;
base |= segDescriptor.BaseLo;
return base;
}
void UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("UnloadDriver ! ");
}
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
#if DBG
// __asm int 3
#endif
ULONG IDT=0x83; //这里可改为需要得到的中断号
IDT_ENTRY IdtEntry;
ULONG IdtBase=RegGetIDTBase();
ULONG IdtLocation=IdtBase+IDT*8;
RtlCopyBytes( &IdtEntry,(ULONG*)IdtLocation,8 );
ULONG GdtBase=RegGetGDTBase();
ULONG GdtLocation=GetSegmentDescriptorBase(RegGetGDTBase(),IdtEntry.Selector)+(IdtEntry.HighOffset<<16|IdtEntry.LowOffset);
Print("IdtBase",IdtBase);
Print("IdtLocation",IdtLocation);
Print("IdtEntry.LowOffset",IdtEntry.LowOffset);
Print("IdtEntry.Selector",IdtEntry.Selector);
Print("IdtEntry.Access",IdtEntry.Access);
Print("IdtEntry.HighOffset",IdtEntry.HighOffset);
Print("GdtBase",GdtBase);
Print("GdtLocation",GdtLocation);
Print("中断向量执行首地址",GdtLocation);
DriverObject->DriverUnload = UnloadDriver;
return STATUS_SUCCESS;
}
获得的结果为:
00000001 0.00000000 [vmm] IdtBase 0x[B9B44590]
00000002 0.01813673 [vmm] IdtLocation 0x[B9B449A8]
00000003 0.03627276 [vmm] IdtEntry.LowOffset 0x[000032AC]
00000004 0.05437448 [vmm] IdtEntry.Selector 0x[00000008]
00000005 0.07247846 [vmm] IdtEntry.Access 0x[00008E00]
00000006 0.09058317 [vmm] IdtEntry.HighOffset 0x[00008997]
00000007 10.51305771 [vmm] GdtBase 0x[B9B44190]
00000008 10.53115940 [vmm] GdtLocation 0x[899732AC]
00000009 10.54927540 [vmm] 中断向量执行首地址 0x[899732AC]
与通过windbg获得的中断向量表的地址是一致的:
1: kd> !idt
Dumping IDT:
37: 806e7864
3d: 806e8e2c
41: 806e8c88
50: 806e793c
63: 899cae54 b9159e54 (KINTERRUPT 899cae18)
b9159e54 (KINTERRUPT 89afb9c8)
73: 89df16cc b954367e (KINTERRUPT 89df1690)
b954367e (KINTERRUPT 89d8eb80)
83: 899732ac b91c9cb8 (KINTERRUPT 89973270)
b91a2dfc (KINTERRUPT 89a77dc8)
b9453e10 (KINTERRUPT 89bc4270)
94: 89b88ca4 b9159e54 (KINTERRUPT 89b88c68)
a4: 89b22a0c b9159e54 (KINTERRUPT 89b229d0)
b1: 89d97acc b95ca31e (KINTERRUPT 89d97a90)
b4: 89ab4ad4 b9159e54 (KINTERRUPT 89ab4a98)
c1: 806e7ac0
d1: 806e72a0
e1: 806e8048
e3: 806e7dac
fd: 806e85a8
fe: 806e8748