了解_idt_hook

#include "ntddk.h"

#define WORD	USHORT
#define DWORD	ULONG
#define MAKELONG(a, b)      ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) \
	| ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))

typedef struct _IDTR{
	USHORT   IDT_limit;
	USHORT   IDT_LOWbase;
	USHORT   IDT_HIGbase;
}IDTR, *PIDTR;
typedef struct _IDTENTRY
{
	unsigned short LowOffset;
	unsigned short selector;
	unsigned char retention : 5;
	unsigned char zero1 : 3;
	unsigned char gate_type : 1;
	unsigned char zero2 : 1;
	unsigned char interrupt_gate_size : 1;
	unsigned char zero3 : 1;
	unsigned char zero4 : 1;
	unsigned char DPL : 2;
	unsigned char P : 1;
	unsigned short HiOffset;
} IDTENTRY, *PIDTENTRY;
typedef struct _KGDTENTRY {
	USHORT  LimitLow;
	USHORT  BaseLow;
	union {
		struct {
			UCHAR   BaseMid;
			UCHAR   Flags1;     // Declare as bytes to avoid alignment
			UCHAR   Flags2;     // Problems.
			UCHAR   BaseHi;
		} Bytes;
		struct {
			ULONG   BaseMid : 8;
			ULONG   Type : 5;
			ULONG   Dpl : 2;
			ULONG   Pres : 1;

			ULONG   LimitHi : 4;
			ULONG   Sys : 1;
			ULONG   Reserved_0 : 1;
			ULONG   Default_Big : 1;
			ULONG   Granularity : 1;
			ULONG   BaseHi : 8;
		} Bits;
	} HighWord;
} KGDTENTRY, *PKGDTENTRY;
//global
ULONG	g_InterruptFunc3;
void PageProtectOn()
{
	__asm{//恢复内存保护  
		mov  eax, cr0
			or   eax, 10000h
			mov  cr0, eax
			sti
	}
}

void PageProtectOff()
{
	__asm{//去掉内存保护
		cli
			mov  eax, cr0
			and  eax, not 10000h
			mov  cr0, eax
	}
}
void __stdcall FilterInterruptFunc3()
{
	USHORT u_es, u_ds;
	KdPrint(("当前进程:%s", (char*)PsGetCurrentProcess() + 0x174)); //当前进程触发了 中断历程 进入内核
	__asm{
		mov	u_es, es
			mov u_ds, ds
	}
	KdPrint(("%X,%X", u_es, u_ds));
}
__declspec(naked)
void NewInterruptFunc3()
{
	__asm{
		pushad
			pushfd
			push	fs
			push	0x30
			pop		fs
			call	FilterInterruptFunc3
			pop		fs
			popfd
			popad
			jmp		g_InterruptFunc3
	}
}
ULONG	GetInterruptFuncAddress(ULONG InterruptIndex)
{
	IDTR		idtr;
	IDTENTRY	*pIdtEntry;
	__asm	SIDT	idtr;//读idt表
	pIdtEntry = (IDTENTRY *)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);//求idt表的地址
	return MAKELONG(pIdtEntry[InterruptIndex].LowOffset, pIdtEntry[InterruptIndex].HiOffset);//得到3号中断函数的地址 老地址 返回的是个4字节的
}
VOID SetInterrupt(ULONG InterruptIndex, ULONG NewInterruptFunc)
{
	ULONG			u_fnKeSetTimeIncrement; //ULONG 4字节
	UNICODE_STRING	usFuncName;
	ULONG			u_index;
	ULONG			*u_KiProcessorBlock;
	IDTENTRY		*pIdtEntry;
	PKGDTENTRY		pGdt;
	RtlInitUnicodeString(&usFuncName, L"KeSetTimeIncrement");
	u_fnKeSetTimeIncrement = (ULONG)MmGetSystemRoutineAddress(&usFuncName);//得到系统程序地址 内核模块里的函数的地址
	if (!MmIsAddressValid((PVOID)u_fnKeSetTimeIncrement))
	{
		return;
	}
	u_KiProcessorBlock = *(ULONG**)(u_fnKeSetTimeIncrement + 44);//定位得到  全局变量的地址
	u_index = 0;
	while (u_KiProcessorBlock[u_index])// 多核4核cpu
	{
		pIdtEntry = *(IDTENTRY**)(u_KiProcessorBlock[u_index] - 0xE8);//找到idt表数组
		PageProtectOff();
		pIdtEntry[InterruptIndex].LowOffset = (unsigned short)((ULONG)NewInterruptFunc & 0xffff);//取新函数低4位值 16位二进制不变 前16位全是0   
		pIdtEntry[InterruptIndex].HiOffset = (unsigned short)((ULONG)NewInterruptFunc >> 16);//取新函数高4位值
		pGdt = *(PKGDTENTRY*)(u_KiProcessorBlock[u_index] - 0xE4);
		KdPrint(("GDT:%X--%X--%X--%X", pGdt, pGdt[1].BaseLow, pGdt[1].HighWord.Bits.BaseMid, pGdt[1].HighWord.Bits.BaseHi));
		PageProtectOn();
		u_index++;
	}
}

VOID MyUnload(PDRIVER_OBJECT	pDriverObject)
{
	SetInterrupt(3, g_InterruptFunc3);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT	pDriverObject, PUNICODE_STRING Reg_Path)
{
	USHORT u_cs;
	g_InterruptFunc3 = GetInterruptFuncAddress(3);
	__asm	mov		u_cs, cs;
	KdPrint(("%X--%X", NewInterruptFunc3, u_cs));
	SetInterrupt(3, (ULONG)NewInterruptFunc3);
	pDriverObject->DriverUnload = MyUnload;
	return STATUS_SUCCESS;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值