|
作者:Tesla.Angela
IDT是中断描述符表,它跟SSDT类似,记录了256个中断处理程序(函数)的地址。要HOOK的话,修改记录的地址即可。不过IDT的结构比起SSDT复杂得多,比起HOOK SSDT的难度,有一个好的方面和一个坏的方面。好的方面是,IDT记录的是绝对地址而非偏移地址;坏的方面是,这个地址被拆分成了2部分(WIN32)或3部分(WIN64)。
- typedef struct //32位结构体
- {
- WORD LowOffset; <-中断处理程序的低16位
- WORD Selector;
- BYTE unused_lo;
- UCHAR unusaed_hi:5;
- UCHAR DPL:2;
- UCHAR P:1;
- WORD HiOffset; <-中断处理程序的高16位
- } IDTENTRY32;
- typedef struct //64位结构体
- {
- USHORT OffsetLow; <-中断处理程序的低16位
- USHORT Selector; <-选择子
- USHORT BitInfo; <-位信息
- USHORT OffsetMiddle; <-中断处理程序的中16位
- ULONG OffsetHigh; <-中断处理程序的高32位
- ULONG Reserved1;
- } IDTENTRY64;
复制代码
要HOOK的话,只要把代理函数的地址拆分开N部分,再填入结构体的对应位置即可。此外,HOOK IDT还有好几个需要注意的地方。1.SSDT是系统级的,IDT是CPU级的,一个CPU核心就有一个IDT,即使是逻辑CPU核心(比如利用INTEL超线程技术“分身”出来的CPU核心)。2.要HOOK IDT的话,必须把所有CPU的的IDT都改了才行。网上的代码都是针对“单核CPU+XP系统”写的,早已过时。代码里有一份“在指定CPU核心执行代码”的模板。3.获得IDT的基址,32位驱动可以直接通过内嵌SIDT指令取出,64位驱动因为内嵌ASM不方便,我是用__readmsr读取0xC0000101寄存器,取出KPCR,再直接读取KPCR中的IDT基址。4.在WIN64系统上,IDT也是被PATCHGUARD保护的,想在IDT上做歪点子的可以及时打住了。
|
|