#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{ //idt表
USHORT IDT_limit;
USHORT IDT_LOWbase;
USHORT IDT_HIGbase;
}IDTR, *PIDTR;
typedef struct _IDTENTRY //idt表的函数的结构体
{
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 { //gdt表 全局变量结构体 存放 段基址
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\n", 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)//得到老3号中断地址
{
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)//设置3号断点 跟新hook函数
{
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);//定位得到 cpu全局变量的地址
u_index = 0;
while (u_KiProcessorBlock[u_index])// 多核4核cpu
{
pIdtEntry = *(IDTENTRY**)(u_KiProcessorBlock[u_index] - 0xE8);//找到idt表数组
pGdt = *(PKGDTENTRY*)(u_KiProcessorBlock[u_index] - 0xE4);//得到gdt表地址
KdPrint(("Idt段基址选择符%x\n", pIdtEntry[3].selector));//得到3号中断 段选择符 为8
KdPrint(("GDT表:%X--%X--%X--%X\n", pGdt, pGdt[1].BaseLow, pGdt[1].HighWord.Bits.BaseMid, pGdt[1].HighWord.Bits.BaseHi));//由8二进制1000得到内核层gdt表的数组1号元素的 段内偏移
//KdPrint(("pGdt%x\n", pGdt));数组为1的就是段基址
PageProtectOff();
pIdtEntry[InterruptIndex].LowOffset = (unsigned short)((ULONG)NewInterruptFunc & 0xffff);//取新函数低4位值 16位二进制不变 前16位全是0
pIdtEntry[InterruptIndex].HiOffset = (unsigned short)((ULONG)NewInterruptFunc >> 16);//取新函数高4位值
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(("\n%X--%X\n", NewInterruptFunc3, u_cs));
SetInterrupt(3, (ULONG)NewInterruptFunc3);
pDriverObject->DriverUnload = MyUnload;
return STATUS_SUCCESS;
}
idt hook 原版
最新推荐文章于 2018-10-08 19:30:10 发布