//Hook & Unhook IDT
//俩函数,位于idtHook.cpp中。
//功能就是根据中断号Hook/Unhook IDT
struct IDT_GATE
{
unsigned OffsetLo : 16 ; //bits 15....0
unsigned Selector : 16 ; //segment selector
unsigned Reserved : 13 ; //bits we don't need
unsigned Dpl : 2 ; //descriptor privilege level
unsigned Present : 1 ; //segment present flag
unsigned OffsetHi : 16 ; //bits 32...16
};
struct IDT_INFO
{
unsigned short wReserved ;
unsigned short wLimit ; //size of the table
IDT_GATE * pIdt ; //base address of the table
};
//Hook函数
int HookInt ( unsigned long * pOldHandler , unsigned long NewHandler , int IntNumber )
{
IDT_INFO IdtInfo = { 0 };
__asm cli
__asm sidt IdtInfo . wLimit
//!-_-我很不习惯这种写法
PVOID pInt = & IdtInfo . pIdt [ IntNumber ];
//根据调用号获得中断处理例程的地址
PPTE pPteIdt = GetPteAddress ( pInt );
//得到PTE的地址
if ( (( int ) pPteIdt != ERROR_PTE_NOT_PRESENT ) && (( int ) pPteIdt != ERROR_PAGE_NOT_PRESENT ) )
{
ULONG oldPteIdt = ( ULONG )* pPteIdt ;
MarkPageReadWrite ( pPteIdt );
//把改页改为可写
__asm invlpg pInt
//清空TLB,用于刷新
* pOldHandler = ( unsigned int ) IdtInfo . pIdt [ IntNumber ]. OffsetHi << 16
| IdtInfo . pIdt [ IntNumber ]. OffsetLo ;
//保存原始中断向量
IdtInfo . pIdt [ IntNumber ]. OffsetLo = ( unsigned short ) NewHandler ;
IdtInfo . pIdt [ IntNumber ]. OffsetHi = ( unsigned short )(( unsigned int ) NewHandler >> 16 );
//Hook!
( ULONG )* pPteIdt = oldPteIdt ;
//还原原始属性
__asm invlpg pInt
//刷新
__asm sti
//开中断
return true ;
}
__asm sti
return ( int ) pPteIdt ;
}
//差不多的,不注释了,留原版的。
int UnhookInt ( unsigned long OldHandler , int IntNumber )
{
IDT_INFO IdtInfo = { 0 };
__asm cli //disable interrupts
//get the base address of the IDT
__asm sidt IdtInfo . wLimit
//un-write-protect the IDT if it is write protected
PVOID pInt = & IdtInfo . pIdt [ IntNumber ];
PPTE pPteIdt = GetPteAddress ( pInt );
if ( (( int ) pPteIdt != ERROR_PTE_NOT_PRESENT ) && (( int ) pPteIdt != ERROR_PAGE_NOT_PRESENT ) ) //the idt should never be "not present", but playing it safe
{
ULONG oldPteIdt = ( ULONG )* pPteIdt ;
MarkPageReadWrite ( pPteIdt );
__asm invlpg pInt
//restore the old handler
IdtInfo . pIdt [ IntNumber ]. OffsetLo = ( unsigned short ) OldHandler ;
IdtInfo . pIdt [ IntNumber ]. OffsetHi = ( unsigned short )(( unsigned int ) OldHandler >> 16 );
//restore the old writability of the idt
( ULONG )* pPteIdt = oldPteIdt ;
__asm invlpg pInt
__asm sti //reenable interrupts
return true ;
} //end if
__asm sti
return ( int ) pPteIdt ;
} //end UnhookInt
//俩函数,位于idtHook.cpp中。
//功能就是根据中断号Hook/Unhook IDT
struct IDT_GATE
{
unsigned OffsetLo : 16 ; //bits 15....0
unsigned Selector : 16 ; //segment selector
unsigned Reserved : 13 ; //bits we don't need
unsigned Dpl : 2 ; //descriptor privilege level
unsigned Present : 1 ; //segment present flag
unsigned OffsetHi : 16 ; //bits 32...16
};
struct IDT_INFO
{
unsigned short wReserved ;
unsigned short wLimit ; //size of the table
IDT_GATE * pIdt ; //base address of the table
};
//Hook函数
int HookInt ( unsigned long * pOldHandler , unsigned long NewHandler , int IntNumber )
{
IDT_INFO IdtInfo = { 0 };
__asm cli
__asm sidt IdtInfo . wLimit
//!-_-我很不习惯这种写法
PVOID pInt = & IdtInfo . pIdt [ IntNumber ];
//根据调用号获得中断处理例程的地址
PPTE pPteIdt = GetPteAddress ( pInt );
//得到PTE的地址
if ( (( int ) pPteIdt != ERROR_PTE_NOT_PRESENT ) && (( int ) pPteIdt != ERROR_PAGE_NOT_PRESENT ) )
{
ULONG oldPteIdt = ( ULONG )* pPteIdt ;
MarkPageReadWrite ( pPteIdt );
//把改页改为可写
__asm invlpg pInt
//清空TLB,用于刷新
* pOldHandler = ( unsigned int ) IdtInfo . pIdt [ IntNumber ]. OffsetHi << 16
| IdtInfo . pIdt [ IntNumber ]. OffsetLo ;
//保存原始中断向量
IdtInfo . pIdt [ IntNumber ]. OffsetLo = ( unsigned short ) NewHandler ;
IdtInfo . pIdt [ IntNumber ]. OffsetHi = ( unsigned short )(( unsigned int ) NewHandler >> 16 );
//Hook!
( ULONG )* pPteIdt = oldPteIdt ;
//还原原始属性
__asm invlpg pInt
//刷新
__asm sti
//开中断
return true ;
}
__asm sti
return ( int ) pPteIdt ;
}
//差不多的,不注释了,留原版的。
int UnhookInt ( unsigned long OldHandler , int IntNumber )
{
IDT_INFO IdtInfo = { 0 };
__asm cli //disable interrupts
//get the base address of the IDT
__asm sidt IdtInfo . wLimit
//un-write-protect the IDT if it is write protected
PVOID pInt = & IdtInfo . pIdt [ IntNumber ];
PPTE pPteIdt = GetPteAddress ( pInt );
if ( (( int ) pPteIdt != ERROR_PTE_NOT_PRESENT ) && (( int ) pPteIdt != ERROR_PAGE_NOT_PRESENT ) ) //the idt should never be "not present", but playing it safe
{
ULONG oldPteIdt = ( ULONG )* pPteIdt ;
MarkPageReadWrite ( pPteIdt );
__asm invlpg pInt
//restore the old handler
IdtInfo . pIdt [ IntNumber ]. OffsetLo = ( unsigned short ) OldHandler ;
IdtInfo . pIdt [ IntNumber ]. OffsetHi = ( unsigned short )(( unsigned int ) OldHandler >> 16 );
//restore the old writability of the idt
( ULONG )* pPteIdt = oldPteIdt ;
__asm invlpg pInt
__asm sti //reenable interrupts
return true ;
} //end if
__asm sti
return ( int ) pPteIdt ;
} //end UnhookInt