主要理解下面的内容:
1:
KiProcessorBlock数组的每一个非0项都是指向一个_kprcb结构,而_kprcb结构正是再_kpcr结构的+0x120处,_kpcr结构的+0x38就是_IDT结构地址。
2:
通过硬编码 使用ida找到 KiProcessorBlock
3:
IDt的表结构的理解, 进行函数过滤
详细使用代码 (xp3)
#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;
//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
}
}
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;
void ReadIdtInfo()
{
IDTR idtr;
ULONG idtBase;
PIDTENTRY pIDT;
ULONG uIndex;
__asm{
sidt idtr;
}
idtBase = MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);
DbgPrint("base: %X", idtBase);
pIDT = (PIDTENTRY)idtBase;
for (uIndex = 0; uIndex < (ULONG)idtr.IDT_limit / 8; uIndex++)
{
DbgPrint("%d,%X%X", uIndex, pIDT[uIndex].HiOffset, pIDT[uIndex].LowOffset);
}
}
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
};
pIdtEntry = (IDTENTRY *)MAKELONG(idtr.IDT_LOWbase, idtr.IDT_HIGbase);
return MAKELONG(pIdtEntry[InterruptIndex].LowOffset, pIdtEntry[InterruptIndex].HiOffset);//得到3号中断函数的地址 老地址 返回的是个4字节的
}
VOID SetInterrupt(ULONG InterruptIndex, ULONG NewInterruptFunc)//设置3号断点 跟新hook函数
{
ULONG u_fnKeSetIdealProcessorThread; //ULONG 4字节
UNICODE_STRING usFuncName;
ULONG u_index;
ULONG *u_KiProcessorBlock;
IDTENTRY *pIdtEntry;
PKGDTENTRY pGdt;
RtlInitUnicodeString(&usFuncName, L"KeSetIdealProcessorThread");
u_fnKeSetIdealProcessorThread = (ULONG)MmGetSystemRoutineAddress(&usFuncName);//得到系统程序地址 内核模块里的函数的地址
if (!MmIsAddressValid((PVOID)u_fnKeSetIdealProcessorThread))
{
return;
}
u_KiProcessorBlock = *(ULONG**)(u_fnKeSetIdealProcessorThread + 94);//定位得到 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 DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
DbgPrint("DriverUnload");
SetInterrupt(3, g_InterruptFunc3);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
{
//ReadIdtInfo();
//ShowIdtInfo();
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 = DriverUnload;
DbgPrint("DriverEntry");
return STATUS_SUCCESS;
}
0则评论给“[驱动开发] idt hook测试”