您的位置:首页 > 其它

了解_idt_hook

2017-05-11 13:34 176 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: