//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