#include <ntddk.h>
#include <ntstrsafe.h>
#include <WinDef.h>
#include <intrin.h>
#ifdef __cplusplus
extern "C"
{
#endif
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pPDriverObj, _In_ PUNICODE_STRING pRegistryPath);
VOID UnLoadDriver(_In_ PDRIVER_OBJECT pPDriverObj);
#ifdef __cplusplus
}
#endif
#pragma pack(push, 1)
typedef struct _IDTR //IDT基址
{
USHORT limit; //范围 占8位
ULONG64 base; //基地址 占32位 _IDT_ENTRY类型指针
}IDTR, *PIDTR;
typedef union _IDT_ENTRY
{
struct kidt
{
USHORT OffsetLow;
USHORT Selector;
USHORT IstIndex : 3;
USHORT Reserved0 : 5;
USHORT Type : 5;
USHORT Dpl : 2;
USHORT Present : 1;
USHORT OffsetMiddle;
ULONG OffsetHigh;
ULONG Reserved1;
}idt;
UINT64 Alignment;
} IDT_ENTRY, *PIDT_ENTRY;
#pragma pack(pop)
//输出调试内容
void DebugPrint(const char* fmt, ...)
{
UNREFERENCED_PARAMETER(fmt);
va_list ap;
va_start(ap, fmt);//将ap指向fmt后的第一个参数
vDbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, fmt, ap);
va_end(ap);//将ap置为NULL
return;
}
ULONG64 GetIdtAddr(ULONG64 pIdtBaseAddr, UCHAR pIndex)
/**
获取IDT表地址
**/
{
PIDT_ENTRY Pidt_info = (PIDT_ENTRY)(pIdtBaseAddr);
Pidt_info += pIndex;
ULONG64 vCurrentAddr = 0;
ULONG64 vCurrentHighAddr = 0;
vCurrentAddr = Pidt_info->idt.OffsetMiddle;
vCurrentAddr = vCurrentAddr << 16;
vCurrentAddr += Pidt_info->idt.OffsetLow;
vCurrentHighAddr = Pidt_info->idt.OffsetHigh;
vCurrentHighAddr = vCurrentHighAddr << 32;
vCurrentAddr += vCurrentHighAddr;
return vCurrentAddr;
}
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT pPDriverObj, _In_ PUNICODE_STRING pRegistryPath)
{
UNREFERENCED_PARAMETER(pRegistryPath);
pPDriverObj->DriverUnload = (PDRIVER_UNLOAD)UnLoadDriver;
DebugPrint("驱动加载\n");
/**
TP版KiPageFault
fffff880`09f54000 50 push rax
fffff880`09f54001 48b87830ce0980f8ffff mov rax,0FFFFF88009CE3078h ---- 这里实际上是真实处理函数的地址 需要 & 0xFFFFFFFFFFF00000
fffff880`09f5400b 4883ec08 sub rsp,8
fffff880`09f5400f 48890424 mov qword ptr [rsp],rax
fffff880`09f54013 48311424 xor qword ptr [rsp],rdx
fffff880`09f54017 e810000000 call fffff880`09f5402c
fffff880`09f5401c 896eff mov dword ptr [rsi-1],ebp
fffff880`09f5401f 230500000089 and eax,dword ptr [fffff87f`92f54025]
**/
//得到TP KiPageFault地址
_IDTR vContent;
__sidt(&vContent);
ULONG64 vTpKiPageFault = GetIdtAddr(vContent.base, 0xE);
//得到TP 动态内存起始值
ULONG64 vTpMemory = *(PULONG64)(vTpKiPageFault + 0x3) & 0xFFFFFFFFFFF00000;
//得到TP KiPageFault真实处理函数
ULONG64 vTpKiPageFaultFuncAddr = vTpMemory + 0x4CE7C;
if (MmIsAddressValid((PVOID)vTpKiPageFaultFuncAddr))
{//真实处理函数有效
//得到TP数据对象基地址
ULONG64 vTpDataObjectBase = *(PULONG)(vTpMemory + 0x1738B) + vTpMemory + 0x1738F;
if (MmIsAddressValid((PVOID)vTpDataObjectBase))
{//基地址有效
//得到TP 用来保存真实CR3 保存当前所属进程ID 的对象
ULONG64 vTpDataObject = *(PULONG64)vTpDataObjectBase;
DebugPrint("数据对象:0x%016llx, 真实CR3:0x%016llx, 所属进程ID:%d\n", vTpDataObject, *(PULONG64)(vTpDataObject + 0x70), *(PULONG)(vTpDataObject + 0x18));
}
else
DebugPrint("vTpDataObjectBase无法读取:0x%016llx\n", vTpDataObjectBase);
}
else
DebugPrint("vTpKiPageFaultFuncAddr无法读取:0x%016llx\n", vTpKiPageFaultFuncAddr);
return STATUS_SUCCESS;
}
/**
*卸载驱动
**/
VOID UnLoadDriver(_In_ PDRIVER_OBJECT pPDriverObj)
{
UNREFERENCED_PARAMETER(pPDriverObj);
DebugPrint("驱动卸载\n");
}