#include <ntddk.h>
#define MAKELONG(low, high) \
((ULONG)(((USHORT)((ULONG)(low) & 0xffff)) | ((ULONG)((USHORT)((ULONG)(high) & 0xffff))) << 16))
#define GET_LOW16_OF_32(data) \
((USHORT)(((ULONG)data) & 0xffff))
#define GET_HIGH16_OF_32(data) \
((USHORT)(((ULONG)data) >> 16))
#pragma pack(push,1)
typedef struct IDTR_
{
USHORT limit;
ULONG base;
} IDTR, *P_IDTR;
typedef struct IDTENTRY_
{
USHORT offset_low;
USHORT selector;
UCHAR reserved;
UCHAR type:4;
UCHAR always0:1;
UCHAR dpl:2;
UCHAR present:1;
USHORT offset_high;
} IDTENTRY, *P_IDTENTRY;
#pragma pack(pop)
ULONG Offset = 0;
ULONG HOOK_IDT_INDEX[] = {0x01, 0x03};
#define HOOK_IDT_NUM sizeof(HOOK_IDT_INDEX)/sizeof(ULONG)
VOID *g_old_entry[HOOK_IDT_NUM] = {0};
VOID *GetIdt()
{
IDTR idtr;
_asm sidt idtr
return (VOID *)idtr.base;
}
VOID MyUserFilter()
{
KdPrint(("Crurrent IRQL: %d\n",KeGetCurrentIrql()));
if (Offset > 0)
{
ULONG eprocess = (ULONG)PsGetCurrentProcess();
PULONG pDebugPort = (PULONG)(eprocess+Offset);
if (*pDebugPort > 0)
{
KdPrint(("DebugObject = %x\n", pDebugPort));
*pDebugPort = 0; //clear DebugPort
}
}
}
__declspec(naked) InterruptProc01()
{
__asm
{
pushfd // 保存标志寄存器
pushad // 保存所有的通用寄存器
push fs
__asm
{
mov ebx, 30H // Set FS to PCR.
mov fs, bx
}
call MyUserFilter
pop fs
popad // 恢复通用寄存器
popfd // 恢复标志寄存器
jmp g_old_entry[0] // 跳到原来的中断服务程序
}
}
__declspec(naked) InterruptProc03()
{
__asm
{
pushfd // 保存标志寄存器
pushad // 保存所有的通用寄存器
push fs
__asm
{
mov ebx, 30H // Set FS to PCR.
mov fs, bx
}
call MyUserFilter
pop fs
popad // 恢复通用寄存器
popfd // 恢复标志寄存器
jmp g_old_entry[4] // 跳到原来的中断服务程序
}
}
VOID *g_new_entry[HOOK_IDT_NUM] = {InterruptProc01, InterruptProc03};
VOID ModifyInterrupt(BOOLEAN hook_or_unhook)
{
USHORT i;
P_IDTENTRY idt_addr = (P_IDTENTRY)GetIdt();
//SetWriteProtect(FALSE, &orgcr0);
for (i = 0; i < HOOK_IDT_NUM; i++)
{
KdPrint(("the current address for index %02x = %x\n", HOOK_IDT_INDEX[i],
(VOID *)MAKELONG(idt_addr[HOOK_IDT_INDEX[i]].offset_low, idt_addr[HOOK_IDT_INDEX[i]].offset_high)));
if(hook_or_unhook)
{
KdPrint(("try to hook this interrupt\n"));
g_old_entry[i] = (VOID *)MAKELONG(idt_addr[HOOK_IDT_INDEX[i]].offset_low, idt_addr[HOOK_IDT_INDEX[i]].offset_high);
idt_addr[HOOK_IDT_INDEX[i]].offset_low = GET_LOW16_OF_32(g_new_entry[i]);
idt_addr[HOOK_IDT_INDEX[i]].offset_high = GET_HIGH16_OF_32(g_new_entry[i]);
}
else
{
KdPrint(("try to recovery interrupt for index %02x\n", HOOK_IDT_INDEX[i]));
idt_addr[HOOK_IDT_INDEX[i]].offset_low = GET_LOW16_OF_32(g_old_entry[i]);
idt_addr[HOOK_IDT_INDEX[i]].offset_high = GET_HIGH16_OF_32(g_old_entry[i]);
}
KdPrint(("the current address = %x\n",
(VOID *)MAKELONG(idt_addr[HOOK_IDT_INDEX[i]].offset_low, idt_addr[HOOK_IDT_INDEX[i]].offset_high)));
}//for
//SetWriteProtect(TRUE, &orgcr0);
}
VOID HookIDT(BOOLEAN hook_or_unhook)
{
KAFFINITY ActiveProcessors, CurrentAffinity;
ActiveProcessors=KeQueryActiveProcessors();
KdPrint(("KeActiveProcessors = %d\n", ActiveProcessors));
for (CurrentAffinity = 1; ActiveProcessors; CurrentAffinity <<= 1)
{
if (ActiveProcessors & CurrentAffinity)
{
ActiveProcessors &= ~CurrentAffinity;
KeSetSystemAffinityThread(CurrentAffinity);
KdPrint(("At %d CPU IDT:\n", CurrentAffinity));
ModifyInterrupt(hook_or_unhook);
KdPrint(("\n"));
}
}
}
VOID Unload(PDRIVER_OBJECT drv)
{
HookIDT(FALSE);
KdPrint (("Unload Driver\n"));
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
RTL_OSVERSIONINFOEXW osverinfo = {sizeof(osverinfo)};
KdPrint (("Entering DriverEntry\n"));
DriverObject->DriverUnload = Unload;
RtlGetVersion((PRTL_OSVERSIONINFOW)&osverinfo);
KdPrint(("OSVersion NT %d.%d:%d sp%d.%d\n",
osverinfo.dwMajorVersion, osverinfo.dwMinorVersion, osverinfo.dwBuildNumber,
osverinfo.wServicePackMajor, osverinfo.wServicePackMinor));
if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 0)
Offset = 0x120; //WINDOWS_VERSION_2K
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 1)
Offset = 0xbc; //WINDOWS_VERSION_XP
else if (osverinfo.dwMajorVersion == 5 && osverinfo.dwMinorVersion == 2)
Offset = 0xcc; //WINDOWS_VERSION_2003
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 0)
Offset = 0xd4; //WINDOWS_VERSION_VISTA
else if (osverinfo.dwMajorVersion == 6 && osverinfo.dwMinorVersion == 1)
Offset = 0xec; //WINDOWS_VERSION_WIN7
else
Offset = 0;
HookIDT(TRUE);
return STATUS_SUCCESS;
}
这个方法很简单:hook int1,int3
然后清除DebugPort,简单明了~~
代码适用于多核,多系统~~~