ShadowWalker1.0学习笔记4 ——Hook IDT

本文详细介绍了IDT断点钩子和解除钩子的实现过程,包括结构定义、函数实现及关键步骤解释,帮助开发者深入理解中断处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值