83 번 인 터 럽 트 벡터 주 소 를 가 져 오 는 계산 방법

#include <ntddk.h>
#define Print(message, value) { DbgPrint("[vmm] %-20s 0x[%08X]
", 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 


좋은 웹페이지 즐겨찾기