在win32中,如何HOOK IDT呢?
IDT的结构定义
typedef unsigned char P2C_U8;
typedef unsigned short P2C_U16;
typedef unsigned long P2C_U32;
#pragma pack(push,1)
typedef struct P2C_IDTR_
{
P2C_U16 limit;
P2C_U32 base;
}P2C_IDTR,*PP2C_IDTR;
#pragma pack(pop)
#pragma pack(push,1)
typedef struct P2C_IDT_ENTRY_
{
P2C_U16 offset_low;
P2C_U16 selector;
P2C_U8 reserved;
P2C_U8 type:4;
P2C_U8 always0:1;
P2C_U8 dpl:2;
P2C_U8 present:1;
P2C_U16 offset_high;
}P2C_IDTENTRY,*PP2C_IDTENTRY;
#pragma pack(pop)
获取IDT地址
void *p2cGetIdt()
{
P2C_IDTR idtr;
_asm sidt idtr;
return (void*)idtr.base;
}
获取IDT项中的处理函数地址
#define P2C_MAKELONG(low,high) ((P2C_U32)(((P2C_U16)((P2C_U32)(low)&0xffff)) | ((P2C_U32)((P2C_U16)((P2C_U32)(high)&0xffff)))<<16))
#define P2C_LOW16_OF_32(data) ((P2C_U16)(((P2C_U32)data)&0xffff))
#define P2C_HIGH16_OF_32(data) ((P2C_U16)(((P2C_U32)data)>>16))
HOOK IDT第93项为例
ULONG g_p2c_old;
void p2cUserFilter()
{
//加入过滤代码。
}
__declspec(naked) p2cInterruptProc()
{
__asm
{
pushad
pushfd
call p2cUserFilter // 过滤函数
popfd
popad
jmp g_p2c_old //原本函数
}
}
void p2cHookInt93(bool hook_or_unhook)
{
PP2C_IDTENTRY idt_addr = (PP2C_IDTENTRY)p2cGetIdt();
idt_addr += 0x93;
if(hook_or_unhook)
{
/*保存旧地址*/
g_p2c_old=(ULONG)(void*)P2C_MAKELONG(idt_addr->offset_low,idt_addr->offset_high);
/*写入新地址*/
idt_addr->offset_low = P2C_LOW16_OF_32(p2cInterruptProc);
idt_addr->offset_high = P2C_HIGH16_OF_32(p2cInterruptProc);
}else
{
idt_addr->offset_low=P2C_LOW16_OF_32(g_p2c_old);
idt_addr->offset_high=P2C_HIGH16_OF_32(g_p2c_old);
}
}